00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00087 #include <string.h>
00088 #include <sys/types.h>
00089 #include <netinet/in.h>
00090
00091 #include "playercommon.h"
00092
00093 #include "lifomcom.h"
00094
00095 #ifdef MCOM_PLUGIN
00096
00097 #endif
00098
00099
00100
00101
00102
00103
00104
00105 LifoMCom::LifoMCom( ConfigFile* cf, int section)
00106 : Driver(cf, section, true, PLAYER_MSGQUEUE_DEFAULT_MAXLEN, PLAYER_MCOM_CODE, PLAYER_ALL_MODE)
00107 {
00108 printf("Constructing LifoMCom\n");
00109 }
00110
00111
00112 Driver* LifoMCom_Init( ConfigFile* cf, int section)
00113 {
00114 return((Driver*)(new LifoMCom( cf, section)));
00115 }
00116
00117
00118 void LifoMCom_Register(DriverTable* t) {
00119 t->AddDriver("lifomcom", LifoMCom_Init);
00120 }
00121
00123
00124 int LifoMCom::ProcessMessage(ClientData * client, player_msghdr * hdr, uint8_t * data, uint8_t * resp_data, size_t * resp_len)
00125 {
00126 assert(hdr);
00127 assert(data);
00128 assert(resp_len);
00129 if (hdr->size < sizeof(player_mcom_config_t))
00130 return -1;
00131
00132 player_mcom_config_t* cfg = reinterpret_cast<player_mcom_config_t*> (data);
00133 cfg->type = ntohs(cfg->type);
00134
00135 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_MCOM_REQ_PUSH, device_id))
00136 {
00137 Data.Push(cfg->data, cfg->type, cfg->channel);
00138 *resp_len = 0;
00139 return PLAYER_MSGTYPE_RESP_ACK;
00140 }
00141
00142 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_MCOM_REQ_POP, device_id))
00143 {
00144 assert(*resp_data >= sizeof(player_mcom_return_t));
00145 player_mcom_return_t & ret = *reinterpret_cast<player_mcom_return_t *> (resp_data);
00146 ret.data = Data.Pop(cfg->type, cfg->channel);
00147 if(ret.data.full)
00148 {
00149 ret.type = htons(cfg->type);
00150 strcpy(ret.channel, cfg->channel);
00151 *resp_len = sizeof(player_mcom_return_t);
00152 return PLAYER_MSGTYPE_RESP_ACK;
00153 }
00154 else
00155 {
00156 *resp_len = 0;
00157 return PLAYER_MSGTYPE_RESP_NACK;
00158 }
00159 }
00160
00161 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_MCOM_REQ_READ, device_id))
00162 {
00163 assert(*resp_data >= sizeof(player_mcom_return_t));
00164 player_mcom_return_t & ret = *reinterpret_cast<player_mcom_return_t *> (resp_data);
00165
00166 ret.data = Data.Read(cfg->type, cfg->channel);
00167 if(ret.data.full)
00168 {
00169 ret.type = htons(cfg->type);
00170 strcpy(ret.channel, cfg->channel);
00171 Unlock();
00172 *resp_len = sizeof(player_mcom_return_t);
00173 return PLAYER_MSGTYPE_RESP_ACK;
00174 }
00175 else
00176 {
00177 *resp_len = 0;
00178 return PLAYER_MSGTYPE_RESP_NACK;
00179 }
00180 }
00181
00182 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_MCOM_REQ_CLEAR, device_id))
00183 {
00184 Data.Clear(cfg->type, cfg->channel);
00185 *resp_len = 0;
00186 return PLAYER_MSGTYPE_RESP_ACK;
00187 }
00188
00189 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_MCOM_REQ_SET_CAPACITY, device_id))
00190 {
00191 Data.SetCapacity(cfg->type, cfg->channel, cfg->data.data[0]);
00192 *resp_len = 0;
00193 return PLAYER_MSGTYPE_RESP_ACK;
00194 }
00195
00196 *resp_len = 0;
00197 return -1;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 LifoMCom::Buffer::Buffer() {
00263 top = 0;
00264 capacity = MCOM_N_BUFS;
00265 for(int x = 0 ; x < MCOM_N_BUFS; x++) {
00266 dat[x].full=0;
00267 strcpy(dat[x].data,MCOM_EMPTY_STRING);
00268 }
00269 }
00270
00271 LifoMCom::Buffer::~Buffer(){
00272 }
00273
00274 void LifoMCom::Buffer::Push(player_mcom_data_t newdat) {
00275 top++;
00276 top %= capacity;
00277
00278
00279
00280 dat[top]=newdat;
00281 dat[top].full=1;
00282 }
00283
00284 player_mcom_data_t LifoMCom::Buffer::Pop(){
00285 player_mcom_data_t ret;
00286 ret=dat[top];
00287 dat[top].full=0;
00288 strcpy(dat[top].data, MCOM_EMPTY_STRING);
00289
00290 if(--top < 0) {
00291
00292 top += capacity;
00293 }
00294 return ret;
00295 }
00296
00297 player_mcom_data_t LifoMCom::Buffer::Read(){
00298 player_mcom_data_t ret;
00299 ret=dat[top];
00300 return ret;
00301 }
00302
00303 void LifoMCom::Buffer::Clear(){
00304 int s;
00305 for(s=0;s<MCOM_N_BUFS;s++)
00306 dat[s].full=0;
00307 }
00308
00309 void LifoMCom::Buffer::print(){
00310 int x;
00311 printf("mcom buffer dump of type %i channel %s buffer\n",type,channel);
00312 for(x=0;x<MCOM_N_BUFS;x++)
00313 printf("%s :: %i\n",dat[x].data,dat[x].full);
00314 }
00315
00316 void
00317 LifoMCom::Buffer::SetCapacity(int cap)
00318 {
00319 capacity = cap;
00320 }
00321
00322 LifoMCom::LinkList::LinkList() : top(NULL) {
00323 }
00324
00325 LifoMCom::LinkList::~LinkList(){
00326 Link *p=top;
00327 Link *next=p;
00328 while(p!=NULL){
00329 next=p->next;
00330 delete p;
00331 p=next;
00332 }
00333 }
00334
00335 void LifoMCom::LinkList::Push(player_mcom_data_t d,int type, char channel[MCOM_CHANNEL_LEN]){
00336 Link * p=top;
00337 if(p==NULL){
00338 top=new Link;
00339 top->next=NULL;
00340 top->buf.type=type;
00341 strncpy(top->buf.channel, channel, MCOM_CHANNEL_LEN);
00342 p=top;
00343 } else {
00344 while(p->next!=NULL && (p->buf.type!=type || strcmp(p->buf.channel,channel))) {
00345 p=p->next;
00346 }
00347
00348 if(p->buf.type!=type || strcmp(p->buf.channel,channel)){
00349 p->next = new Link;
00350 p=p->next;
00351 p->next=NULL;
00352 p->buf.type=type;
00353 strncpy(p->buf.channel, channel, MCOM_CHANNEL_LEN);
00354 }
00355 }
00356 p->buf.Push(d);
00357 }
00358
00359 player_mcom_data_t LifoMCom::LinkList::Pop(int type, char channel[MCOM_CHANNEL_LEN]){
00360 Link *p=top;
00361 Link *last;
00362 player_mcom_data_t ret;
00363 strcpy(ret.data, MCOM_EMPTY_STRING);
00364 ret.full=0;
00365 if(p==NULL){
00366 return ret;
00367 }else{
00368 while(p->next!=NULL && (p->buf.type!=type || strcmp(p->buf.channel,channel))){
00369 last=p;
00370 p=p->next;
00371 }
00372 if(p->buf.type!=type || strcmp(p->buf.channel,channel)){
00373 return ret;
00374 }else{
00375 ret = p->buf.Pop();
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 }
00390 }
00391 return ret;
00392 }
00393
00394 player_mcom_data_t LifoMCom::LinkList::Read(int type,char channel[MCOM_CHANNEL_LEN]){
00395 Link * p=top;
00396 player_mcom_data_t ret;
00397 ret.full=0;
00398 strcpy(ret.data, MCOM_EMPTY_STRING);
00399 if(p==NULL)
00400 return ret;
00401 else{
00402 while(p->next!=NULL && (p->buf.type!=type || strcmp(p->buf.channel,channel))){
00403 p=p->next;
00404 }
00405 if(p->buf.type!=type || strcmp(p->buf.channel,channel))
00406 return ret;
00407 else{
00408 return p->buf.Read();
00409 }
00410 }
00411 }
00412
00413 void LifoMCom::LinkList::Clear(int type, char channel[MCOM_CHANNEL_LEN]) {
00414 Link *p = top;
00415 Link *last = NULL;
00416 if(p == NULL)
00417 return;
00418 else{
00419 while(p->next != NULL && (p->buf.type != type || strcmp(p->buf.channel, channel))){
00420 last = p;
00421 p = p->next;
00422 }
00423 if(p->buf.type != type || strcmp(p->buf.channel, channel))
00424 return;
00425 else{
00426 last->next=p->next->next;
00427 p->buf.Clear();
00428 delete p;
00429 }
00430 }
00431 }
00432
00433 void
00434 LifoMCom::LinkList::SetCapacity(int type, char channel[MCOM_CHANNEL_LEN],
00435 unsigned char cap)
00436 {
00437 Link *link = FindLink(type, channel);
00438
00439 if (link != NULL) {
00440 link->buf.SetCapacity((int)cap);
00441 }
00442 }
00443
00444 LifoMCom::Link *
00445 LifoMCom::LinkList::FindLink(int type, char channel[MCOM_CHANNEL_LEN])
00446 {
00447 Link *p = top, *last = NULL;
00448
00449 if (p == NULL) {
00450 return NULL;
00451 }
00452
00453 while (p->next != NULL && (p->buf.type != type ||
00454 strcmp(p->buf.channel, channel))) {
00455 last = p;
00456 p = p->next;
00457 }
00458
00459 if (p->buf.type == type && !strcmp(p->buf.channel, channel)) {
00460 return p;
00461 }
00462
00463 return NULL;
00464 }