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
00027
00028
00029
00030
00031
00032 #if defined(__CYGWIN__) || defined(__FreeBSD__)
00033
00034
00035 #define swap_type(type,a,b) { type t=(a); (a)=(b); (b)=t; }
00036 int64_t bswap_64( int64_t n )
00037 {
00038 int8_t* p = (int8_t*)&n;
00039 swap_type( int8_t, p[0], p[7] );
00040 swap_type( int8_t, p[1], p[6] );
00041 swap_type( int8_t, p[2], p[5] );
00042 swap_type( int8_t, p[3], p[4] );
00043 return n;
00044 }
00045
00046 #endif
00047
00048 #if defined(__CYGWIN__)
00049
00050 #define htonll(x) bswap_64(x)
00051 #define ntohll(x) bswap_64(x)
00052
00053 #elif defined(__FreeBSD__)
00054
00055 #include <machine/endian.h>
00056
00057 #if BYTE_ORDER == BIG_ENDIAN
00058 #error
00059 # define htonll(x) (x)
00060 # define ntohll(x) (x)
00061 #else
00062 # define htonll(x) bswap_64(x)
00063 # define ntohll(x) bswap_64(x)
00064 #endif
00065
00066 #else//if defined(__CYGWIN__)
00067
00068 #if __BYTE_ORDER == __BIG_ENDIAN
00069 # define htonll(x) (x)
00070 # define ntohll(x) (x)
00071 #else
00072 # if __BYTE_ORDER == __LITTLE_ENDIAN
00073 # define htonll(x) __bswap_64(x)
00074 # define ntohll(x) __bswap_64(x)
00075 # endif
00076 #endif
00077
00078 #endif//if defined(__CYGWIN__)
00079
00080 #define localAddr INADDR_LOOPBACK
00081 #define EC_DEBUG(_x)
00082
00083 int commandServerSocket = -1;
00084 int eventServerSocket = -1;
00085 int commandClients[MAX_CLIENT_CONNECTIONS];
00086 uint8_t batchState[MAX_CLIENT_CONNECTIONS];
00087 norace int eventClients[MAX_CLIENT_CONNECTIONS];
00088 norace uint16_t eventMask;
00089
00090 pthread_t eventAcceptThread;
00091 pthread_t commandReadThread;
00092 pthread_mutex_t eventClientsLock;
00093 pthread_cond_t eventClientsCond;
00094
00095
00096 TOS_Msg external_comm_msgs_[TOSNODES];
00097 TOS_MsgPtr external_comm_buffers_[TOSNODES];
00098 norace static int GUI_enabled;
00099
00100 int createServerSocket(short port);
00101 void *eventAcceptThreadFunc(void *arg);
00102 void *commandReadThreadFunc(void *arg);
00103
00104 #if NESC >= 111
00105
00106 static int __nesc_nido_resolve(int __nesc_mote,
00107 char* varname,
00108 uintptr_t* addr, size_t* size);
00109
00110 #else
00111
00112 static int __nesc_nido_resolve(int __nesc_mote,
00113 char* varname,
00114 uintptr_t* addr, size_t* size)
00115 {
00116 return -1;
00117 }
00118
00119 #endif
00120
00121
00122
00123
00124
00125 void initializeSockets() {
00126 int i;
00127 dbg_clear(DBG_SIM, "SIM: Initializing sockets\n");
00128
00129 pthread_mutex_init(&(tos_state.pause_lock), NULL);
00130 pthread_cond_init(&(tos_state.pause_cond), NULL);
00131 pthread_cond_init(&(tos_state.pause_ack_cond), NULL);
00132
00133 for (i = 0; i < MAX_CLIENT_CONNECTIONS; i++) {
00134 commandClients[i] = -1;
00135 eventClients[i] = -1;
00136 batchState[i] = 0;
00137 }
00138 eventMask = 0xffff;
00139 commandServerSocket = createServerSocket(COMMAND_PORT);
00140 eventServerSocket = createServerSocket(EVENT_PORT);
00141 pthread_mutex_init(&eventClientsLock, NULL);
00142 pthread_cond_init(&eventClientsCond, NULL);
00143 pthread_create(&eventAcceptThread, NULL, eventAcceptThreadFunc, NULL);
00144 pthread_create(&commandReadThread, NULL, commandReadThreadFunc, NULL);
00145 socketsInitialized = 1;
00146 }
00147
00148
00149
00150
00151
00152 int acceptConnection(int servfd) {
00153 struct sockaddr_in cli_addr;
00154 unsigned int clilen = sizeof(cli_addr);
00155 int clifd;
00156
00157 EC_DEBUG(dbg_clear(DBG_SIM, "SIM: Waiting for connection on socket %d\n", servfd));
00158 clifd = accept(servfd, (struct sockaddr*)&cli_addr, &clilen);
00159 if (clifd < 0) {
00160 EC_DEBUG(dbg_clear(DBG_SIM, "SIM: Could not accept socket: %s\n", strerror(errno)));
00161
00162 exit(-1);
00163 }
00164 EC_DEBUG(dbg_clear(DBG_SIM, "SIM: Accepted client socket: fd %d\n", clifd));
00165 return clifd;
00166 }
00167
00168 int createServerSocket(short port) {
00169 struct sockaddr_in sock;
00170 int sfd;
00171 int rval = -1;
00172 long enable = 1;
00173
00174 sfd = socket(AF_INET, SOCK_STREAM, 0);
00175 if (sfd < 0) {
00176 dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not create server socket: %s\n", strerror(errno));
00177 exit(-1);
00178 }
00179 setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(int));
00180
00181 memset(&sock, 0, sizeof(sock));
00182 sock.sin_family = AF_INET;
00183 sock.sin_port = htons(port);
00184 sock.sin_addr.s_addr = htonl(localAddr);
00185
00186 while(rval < 0) {
00187 short p = port;
00188 while(rval < 0 && p > 1024) {
00189 sock.sin_port = htons(p);
00190 rval = bind(sfd, (struct sockaddr*)&sock, sizeof(sock));
00191 if (rval < 0)
00192 p--;
00193 }
00194 if (rval < 0) {
00195 dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not bind server socket to port %d: %s\n", port, strerror(errno));
00196 dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Perhaps another copy of TOSSIM is already running?\n");
00197 dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Will retry in 10 seconds.\n");
00198 sleep(10);
00199 }
00200 }
00201
00202 if (listen(sfd, 1) < 0) {
00203 dbg_clear(DBG_SIM|DBG_ERROR, "SIM: Could not listen on server socket: %s\n", strerror(errno));
00204 exit(-1);
00205 }
00206 dbg_clear(DBG_SIM, "SIM: Created server socket listening on port %d.\n", port);
00207 return sfd;
00208 }
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 void waitForGuiConnection() {
00232 int numclients = 0;
00233 int n;
00234
00235 dbg_clear(DBG_SIM, "SIM: Waiting for connection from GUI...\n");
00236 pthread_mutex_lock(&eventClientsLock);
00237 while (numclients == 0) {
00238 for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
00239 if (eventClients[n] != -1) {
00240 dbg_clear(DBG_SIM, "SIM: Got client connection fd %d\n", eventClients[n]);
00241 numclients++;
00242 }
00243 }
00244 if (numclients == 0) {
00245 pthread_cond_wait(&eventClientsCond, &eventClientsLock);
00246 }
00247 }
00248 pthread_mutex_unlock(&eventClientsLock);
00249 }
00250
00251 int printOtherTime(char* buf, int len, long long int ftime) {
00252 int hours;
00253 int minutes;
00254 int seconds;
00255 int secondBillionths;
00256
00257 secondBillionths = (int)(ftime % (long long) 4000000);
00258 seconds = (int)(ftime / (long long) 4000000);
00259 minutes = seconds / 60;
00260 hours = minutes / 60;
00261 secondBillionths *= (long long) 25;
00262 seconds %= 60;
00263 minutes %= 60;
00264
00265 return snprintf(buf, len, "%i:%i:%i.%08i", hours, minutes, seconds, secondBillionths);
00266 }
00267
00268 int printTime(char* buf, int len) {
00269 return printOtherTime(buf, len, tos_state.tos_time);
00270 }
00271
00272 char* currentTime() {
00273 static char timeBuf[128];
00274 printTime(timeBuf, 128);
00275 return timeBuf;
00276 }
00277
00278 void addClient(int *clientSockets, int clifd) {
00279 int i;
00280
00281 for (i = 0; i < MAX_CLIENT_CONNECTIONS; i++) {
00282 if (clientSockets[i] == -1) {
00283 clientSockets[i] = clifd;
00284 return;
00285 }
00286 }
00287
00288
00289 close(clifd);
00290 }
00291
00292 void sendInitEvent(int clifd) {
00293 TossimInitEvent initEv;
00294 unsigned char* msg;
00295 int total_size;
00296
00297 memset((char*)&initEv, 0, sizeof(TossimInitEvent));
00298 initEv.numMotes = tos_state.num_nodes;
00299 initEv.radioModel = tos_state.radioModel;
00300 initEv.rate = get_sim_rate();
00301 buildTossimEvent(0, AM_TOSSIMINITEVENT,
00302 tos_state.tos_time, &initEv, &msg, &total_size);
00303 writeTossimEvent(msg, total_size, clifd);
00304 free(msg);
00305 }
00306
00307
00308
00309
00310
00311 void *eventAcceptThreadFunc(void *arg) {
00312 int clifd;
00313 fd_set acceptset;
00314
00315 dbg_clear(DBG_SIM, "SIM: eventAcceptThread running.\n");
00316
00317 while (1) {
00318 FD_ZERO(&acceptset);
00319 FD_SET(eventServerSocket, &acceptset);
00320 EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: calling select\n"));
00321 if (select(eventServerSocket + 1, &acceptset, NULL, NULL, NULL) < 0) {
00322 EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThreadFunc: error in select(): %s\n", strerror(errno)));
00323 }
00324 EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: select returned\n"));
00325
00326 if (FD_ISSET(eventServerSocket, &acceptset)) {
00327 EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: Checking for event connection\n"));
00328 clifd = acceptConnection(eventServerSocket);
00329 EC_DEBUG(fprintf(stderr, "SIM: eventAcceptThread: Got event connection %d\n", clifd));
00330 pthread_mutex_lock(&eventClientsLock);
00331 addClient(eventClients, clifd);
00332 sendInitEvent(clifd);
00333 pthread_cond_broadcast(&eventClientsCond);
00334 pthread_mutex_unlock(&eventClientsLock);
00335 }
00336 }
00337 return 0;
00338 }
00339
00340 int net_connect(char* host) {
00341 struct hostent *he;
00342 struct sockaddr_in evt_addr, cmd_addr;
00343 int i, evtfd, cmdfd;
00344 dbg_clear(DBG_SIM, "SIM: Initializing simulator sockets\n");
00345
00346 pthread_mutex_init(&(tos_state.pause_lock), NULL);
00347 pthread_cond_init(&(tos_state.pause_cond), NULL);
00348 pthread_cond_init(&(tos_state.pause_ack_cond), NULL);
00349 pthread_mutex_init(&eventClientsLock, NULL);
00350
00351 for (i = 0; i < MAX_CLIENT_CONNECTIONS; i++) {
00352 commandClients[i] = -1;
00353 eventClients[i] = -1;
00354 batchState[i] = 0;
00355 }
00356 eventMask = 0xffff;
00357
00358 pthread_mutex_lock(&eventClientsLock);
00359
00360 if ((evtfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
00361 perror("socket");
00362 return -1;
00363 }
00364 if ((cmdfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
00365 perror("socket");
00366 return -1;
00367 }
00368
00369 if ((he = gethostbyname(host)) == NULL) {
00370 perror("gethostbyname");
00371 return -1;
00372 }
00373 memset(&evt_addr, 0, sizeof(struct sockaddr_in));
00374 evt_addr.sin_family = AF_INET;
00375 evt_addr.sin_port = htons(EVENT_PORT);
00376 evt_addr.sin_addr = *((struct in_addr *)he->h_addr);
00377 memset(&cmd_addr, 0, sizeof(struct sockaddr_in));
00378 cmd_addr.sin_family = AF_INET;
00379 cmd_addr.sin_port = htons(COMMAND_PORT);
00380 cmd_addr.sin_addr = *((struct in_addr *)he->h_addr);
00381
00382 dbg_clear(DBG_SIM, "SIM: Connecting to network simulator.\n");
00383
00384 if (connect(evtfd, (struct sockaddr *)&evt_addr,
00385 sizeof(struct sockaddr)) < 0) {
00386 dbg_clear(DBG_SIM, "SIM: Could not connect socket: %s\n", strerror(errno));
00387
00388 exit(-1);
00389 }
00390 if (connect(cmdfd, (struct sockaddr *)&cmd_addr,
00391 sizeof(struct sockaddr)) < 0) {
00392 dbg_clear(DBG_SIM, "SIM: Could not connect socket: %s\n", strerror(errno));
00393
00394 exit(-1);
00395 }
00396 dbg_clear(DBG_SIM, "SIM: Connected event socket: fd %d\n", evtfd);
00397 dbg_clear(DBG_SIM, "SIM: Connected command socket: fd %d\n", cmdfd);
00398
00399 addClient(eventClients, evtfd);
00400 addClient(commandClients, cmdfd);
00401
00402 if (pthread_create(&commandReadThread, NULL,
00403 commandReadThreadFunc, NULL) < 0) {
00404 perror("pthread_create");
00405 return -1;
00406 }
00407 socketsInitialized = 1;
00408
00409 sendInitEvent(evtfd);
00410 pthread_mutex_unlock(&eventClientsLock);
00411 return 0;
00412 }
00413
00414
00415
00416
00417
00418
00419 typedef struct {
00420 GuiMsg* msg;
00421 char* payLoad;
00422 } incoming_command_data_t;
00423
00424
00425
00426 void nido_start_mote(uint16_t moteID);
00427 void nido_stop_mote(uint16_t moteID);
00428 TOS_MsgPtr NIDO_received_radio(TOS_MsgPtr packet);
00429 TOS_MsgPtr NIDO_received_uart(TOS_MsgPtr packet);
00430 void set_link_prob_value(uint16_t moteID1, uint16_t moteID2, double prob);
00431
00432 void event_command_cleanup(event_t* event) {
00433 incoming_command_data_t* cmdData = (incoming_command_data_t*)event->data;
00434 free(cmdData->msg);
00435 free(cmdData->payLoad);
00436 event_total_cleanup(event);
00437 }
00438 void event_command_in_handle(event_t* event,
00439 struct TOS_state* state);
00440 void event_command_in_create(event_t* event,
00441 GuiMsg* msg,
00442 char* payLoad) {
00443 incoming_command_data_t* data = (incoming_command_data_t*)malloc(sizeof(incoming_command_data_t));
00444 data->msg = msg;
00445 data->payLoad = payLoad;
00446
00447 event->mote = (int)(msg->moteID & 0xffff);
00448 if (event->mote < TOSNODES &&
00449 event->mote >= 0) {
00450 event->force = 1;
00451 }
00452 event->pause = 1;
00453 event->data = data;
00454 event->time = msg->time;
00455 event->handle = event_command_in_handle;
00456 event->cleanup = event_command_cleanup;
00457 }
00458
00459
00460
00461
00462 int processCommand(int clifd, int clidx, GuiMsg *msg, char *payLoad,
00463 unsigned char** replyMsg, int* replyLen) {
00464 int ret = 0;
00465 bool msg_handled = TRUE;
00466 switch (msg->msgType) {
00467
00468 case AM_SETLINKPROBCOMMAND:
00469 {
00470 SetLinkProbCommand *linkmsg = (SetLinkProbCommand*)payLoad;
00471 double prob = ((double)linkmsg->scaledProb)/10000;
00472 set_link_prob_value(msg->moteID, linkmsg->moteReceiver, prob);
00473 break;
00474 }
00475 case AM_SETADCPORTVALUECOMMAND:
00476 {
00477 SetADCPortValueCommand *adcmsg = (SetADCPortValueCommand*)payLoad;
00478 set_adc_value(msg->moteID, adcmsg->port, adcmsg->value);
00479 break;
00480 }
00481 case AM_SETRATECOMMAND:
00482 {
00483 SetRateCommand *ratemsg = (SetRateCommand*)payLoad;
00484 set_sim_rate(ratemsg->rate);
00485 break;
00486 }
00487 case AM_VARIABLERESOLVECOMMAND:
00488 {
00489 VariableResolveResponse varResult;
00490 VariableResolveCommand *rmsg = (VariableResolveCommand*)payLoad;
00491
00492
00493
00494
00495
00496 if (__nesc_nido_resolve(msg->moteID, (char*)rmsg->name,
00497 (uintptr_t*)&varResult.addr,
00498 (size_t*)&varResult.length) != 0)
00499 {
00500 varResult.addr = 0;
00501 varResult.length = -1;
00502 }
00503
00504 dbg_clear(DBG_SIM, "SIM: Resolving variable %s for mote %d: 0x%x %d\n",
00505 rmsg->name, msg->moteID, varResult.addr, varResult.length);
00506
00507 buildTossimEvent(TOS_BCAST_ADDR, AM_VARIABLERESOLVERESPONSE,
00508 tos_state.tos_time, &varResult, replyMsg, replyLen);
00509 ret = 1;
00510 break;
00511 }
00512 case AM_VARIABLEREQUESTCOMMAND:
00513 {
00514 VariableRequestResponse varResult;
00515 VariableRequestCommand *rmsg = (VariableRequestCommand*)payLoad;
00516 uint8_t* ptr = (uint8_t*)rmsg->addr;
00517 varResult.length = rmsg->length;
00518
00519 if (varResult.length == 0)
00520 varResult.length = 256;
00521
00522 memcpy(varResult.value, ptr, varResult.length);
00523
00524 buildTossimEvent(TOS_BCAST_ADDR, AM_VARIABLEREQUESTRESPONSE,
00525 tos_state.tos_time, &varResult, replyMsg, replyLen);
00526 ret = 1;
00527 break;
00528 }
00529
00530 case AM_GETMOTECOUNTCOMMAND:
00531 {
00532 int i;
00533 GetMoteCountResponse countResponse;
00534
00535 countResponse.totalMotes = tos_state.num_nodes;
00536 bzero(&countResponse.bitmask, sizeof(countResponse.bitmask));
00537
00538 for (i = 0; i < TOSNODES; i++) {
00539 countResponse.bitmask[i/8] |= (1 << (7 - (i % 8)));
00540 }
00541
00542 buildTossimEvent(TOS_BCAST_ADDR, AM_GETMOTECOUNTRESPONSE,
00543 tos_state.tos_time, &countResponse, replyMsg, replyLen);
00544 ret = 1;
00545 break;
00546 }
00547 case AM_SETDBGCOMMAND:
00548 {
00549 SetDBGCommand* cmd = (SetDBGCommand*)payLoad;
00550 dbg_set(cmd->dbg);
00551 break;
00552 }
00553 case AM_SETEVENTMASKCOMMAND:
00554 {
00555 SetEventMaskCommand* setMaskCommand = (SetEventMaskCommand*)payLoad;
00556 eventMask = setMaskCommand->mask;
00557 break;
00558 }
00559 case AM_BEGINBATCHCOMMAND:
00560 {
00561 if (batchState[clidx] != 0) {
00562 dbg(DBG_SIM|DBG_ERROR, "SIM: duplicate begin batch");
00563 }
00564 dbg(DBG_SIM, "SIM: begin batch");
00565 batchState[clidx] = 1;
00566 break;
00567 }
00568 case AM_ENDBATCHCOMMAND:
00569 {
00570 if (batchState[clidx] == 0) {
00571 dbg(DBG_SIM|DBG_ERROR, "SIM: end batch without begin");
00572 }
00573 dbg(DBG_SIM, "SIM: end batch");
00574 batchState[clidx] = 0;
00575 break;
00576 }
00577
00578 default:
00579 {
00580
00581
00582 event_t* event = (event_t*)malloc(sizeof(event_t));
00583 event_command_in_create(event, msg, payLoad);
00584 dbg(DBG_SIM, "SIM: Enqueuing command event 0x%lx\n", (unsigned long)event);
00585 TOS_queue_insert_event(event);
00586 msg_handled = FALSE;
00587 }
00588 }
00589
00590 if (msg_handled == TRUE) {
00591 free(msg);
00592 free(payLoad);
00593 }
00594
00595 return ret;
00596 }
00597
00598
00599 void event_command_in_handle(event_t* event,
00600 struct TOS_state* state) {
00601 incoming_command_data_t* cmdData = (incoming_command_data_t*)event->data;
00602 GuiMsg* msg = cmdData->msg;
00603 dbg_clear(DBG_SIM, "SIM: Handling incoming command type %d for mote %d\n", msg->msgType, msg->moteID);
00604
00605 switch (msg->msgType) {
00606
00607 case AM_TURNONMOTECOMMAND:
00608 dbg_clear(DBG_SIM, "SIM: Turning on mote %d\n", msg->moteID);
00609 nido_start_mote(msg->moteID);
00610 break;
00611
00612 case AM_TURNOFFMOTECOMMAND:
00613 dbg_clear(DBG_SIM, "SIM: Turning off mote %d\n", msg->moteID);
00614 nido_stop_mote(msg->moteID);
00615 break;
00616
00617 case AM_RADIOMSGSENDCOMMAND:
00618 {
00619 RadioMsgSendCommand *rmsg = (RadioMsgSendCommand*)cmdData->payLoad;
00620 TOS_MsgPtr buffer;
00621
00622 dbg_clear(DBG_SIM, "SIM: Enqueueing radio message for mote %d (payloadlen %d)\n", msg->moteID, msg->payLoadLen);
00623 if (external_comm_buffers_[msg->moteID] == NULL)
00624 external_comm_buffers_[msg->moteID] = &external_comm_msgs_[msg->moteID];
00625 buffer = external_comm_buffers_[msg->moteID];
00626 memcpy(buffer, &(rmsg->message), msg->payLoadLen);
00627 buffer->group = TOS_AM_GROUP;
00628 external_comm_buffers_[msg->moteID] = NIDO_received_radio(buffer);
00629 }
00630 break;
00631
00632 case AM_UARTMSGSENDCOMMAND:
00633 {
00634 UARTMsgSendCommand *umsg = (UARTMsgSendCommand*)cmdData->payLoad;
00635 TOS_MsgPtr buffer;
00636 int len = (msg->payLoadLen > sizeof(TOS_Msg))? sizeof(TOS_Msg):msg->payLoadLen;
00637
00638 dbg_clear(DBG_SIM, "SIM: Enqueueing UART message for mote %d (payloadlen %d)\n", msg->moteID, msg->payLoadLen);
00639 if (external_comm_buffers_[msg->moteID] == NULL)
00640 external_comm_buffers_[msg->moteID] = &external_comm_msgs_[msg->moteID];
00641 buffer = external_comm_buffers_[msg->moteID];
00642
00643 memcpy(buffer, &(umsg->message), len);
00644 buffer->group = TOS_AM_GROUP;
00645 external_comm_buffers_[msg->moteID] = NIDO_received_uart(buffer);
00646 }
00647 break;
00648
00649 case AM_INTERRUPTCOMMAND:
00650 {
00651 InterruptEvent interruptEvent;
00652 InterruptCommand* pcmd = (InterruptCommand*)cmdData->payLoad;
00653 interruptEvent.id = pcmd->id;
00654 dbg_clear(DBG_TEMP, "\nSIM: Interrupt command, id: %i.\n\n", pcmd->id);
00655 sendTossimEvent(TOS_BCAST_ADDR, AM_INTERRUPTEVENT,
00656 tos_state.tos_time, &interruptEvent);
00657 break;
00658 }
00659
00660 default:
00661 dbg_clear(DBG_SIM, "SIM: Unrecognizable command type received from TinyViz %i\n", msg->msgType);
00662 break;
00663 }
00664
00665 event_cleanup(event);
00666 }
00667
00668
00669
00670 int readTossimCommand(int clifd, int clidx) {
00671 GuiMsg* msg;
00672 unsigned char header[GUI_MSG_HEADER_LENGTH];
00673 char* payLoad = NULL;
00674 int curlen = 0;
00675 int rval;
00676 unsigned char ack;
00677 int reply;
00678 unsigned char* replyMsg = 0;
00679 int replyLen = 0;
00680
00681 dbg_clear(DBG_SIM, "SIM: Reading command from client fd %d\n", clifd);
00682
00683 msg = (GuiMsg*)malloc(sizeof(GuiMsg));
00684
00685 curlen = 0;
00686 while (curlen < GUI_MSG_HEADER_LENGTH) {
00687 dbg_clear(DBG_SIM, "SIM: Reading in GuiMsg header of size %d with length %d\n", GUI_MSG_HEADER_LENGTH, curlen);
00688 rval = read(clifd, header + curlen, GUI_MSG_HEADER_LENGTH - curlen);
00689 if (rval <= 0) {
00690 dbg_clear(DBG_SIM, "SIM: Closing client socket %d.\n", clifd);
00691 free(msg);
00692 close(clifd);
00693 goto done;
00694 } else {
00695 curlen += rval;
00696 }
00697 }
00698
00699
00700 msg->msgType = ntohs(*(unsigned short *)&header[0]);
00701 msg->moteID = ntohs(*(unsigned short *)&header[2]);
00702 msg->time = ntohll(*(long long *)&header[4]);
00703 msg->payLoadLen = ntohs(*(unsigned short *)&header[12]);
00704 dbg_clear(DBG_SIM, "SIM: Command type %d mote %d time 0x%lx payloadlen %d\n", msg->msgType, msg->moteID, msg->time, msg->payLoadLen);
00705 if (msg->time < tos_state.tos_time) {
00706 msg->time = tos_state.tos_time;
00707 }
00708
00709
00710 if (msg->payLoadLen > 0) {
00711 payLoad = (char*)malloc(msg->payLoadLen);
00712 curlen = 0;
00713 while (curlen < msg->payLoadLen) {
00714 dbg(DBG_SIM, "SIM: Reading in GuiMsg payload of size %d with length %d\n", msg->payLoadLen, curlen);
00715 rval = read(clifd, payLoad + curlen, msg->payLoadLen - curlen);
00716 if (rval <= 0) {
00717 dbg(DBG_SIM, "SIM: Closing client socket %d.\n", clifd);
00718 free(msg);
00719 free(payLoad);
00720 goto done;
00721 } else {
00722 curlen += rval;
00723 dbg(DBG_SIM, "SIM: Read from command port, total: %d, need %d\n", curlen, msg->payLoadLen - curlen);
00724 }
00725 }
00726 }
00727
00728
00729
00730 reply = processCommand(clifd, clidx, msg, payLoad, &replyMsg, &replyLen);
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 if (batchState[clidx] != 0) {
00741 if (reply) {
00742 dbg(DBG_SIM|DBG_ERROR, "SIM: unexpected command response in batch!!\n");
00743 }
00744 return 0;
00745 }
00746
00747 do {
00748 rval = write(clifd, &ack, 1);
00749 if (rval < 0) {
00750 dbg(DBG_SIM, "SIM: Closing client socket %d.\n", clifd);
00751 goto done;
00752 }
00753 } while (rval != 1);
00754
00755 if (reply) {
00756 dbg(DBG_SIM, "SIM: Sending %d byte reply.\n", replyLen);
00757 writeTossimEvent(replyMsg, replyLen, clifd);
00758 free(replyMsg);
00759 }
00760
00761 done:
00762 return 0;
00763 }
00764
00765
00766
00767
00768
00769 void *commandReadThreadFunc(void *arg) {
00770 int i;
00771 fd_set readset, exceptset;
00772 int highest = -1;
00773 int numclients;
00774
00775 dbg_clear(DBG_SIM, "SIM: commandReadThread running.\n");
00776
00777 while (1) {
00778
00779 FD_ZERO(&readset);
00780 FD_ZERO(&exceptset);
00781 if (commandServerSocket > 0) {
00782 FD_SET(commandServerSocket, &readset);
00783 FD_SET(commandServerSocket, &exceptset);
00784 highest = commandServerSocket;
00785 }
00786 numclients = 0;
00787
00788 for (i = 0; i < MAX_CLIENT_CONNECTIONS; i++) {
00789 if (commandClients[i] != -1) {
00790 if (commandClients[i] > highest) highest = commandClients[i];
00791 EC_DEBUG(fprintf(stderr, "SIM: commandReadThread: Adding fd %d to select set\n",
00792 commandClients[i]));
00793 FD_SET(commandClients[i], &readset);
00794 FD_SET(commandClients[i], &exceptset);
00795 numclients++;
00796 }
00797 }
00798
00799 EC_DEBUG(fprintf(stderr, "SIM: commandReadThread: Doing select, %d clients, highest %d\n",
00800 numclients, highest));
00801
00802 if (select(highest+1, &readset, NULL, &exceptset, 0) < 0) {
00803 dbg_clear(DBG_SIM, "SIM: commandReadThreadFunc: error in select(): %s\n", strerror(errno));
00804 }
00805 EC_DEBUG(fprintf(stderr, "SIM: commandReadThread: Returned from select\n"));
00806
00807
00808 for (i = 0; i < MAX_CLIENT_CONNECTIONS; i++) {
00809
00810
00811
00812
00813
00814
00815 if (commandClients[i] != -1 && FD_ISSET(commandClients[i], &readset)) {
00816 if (readTossimCommand(commandClients[i], i) < 0) {
00817 close(commandClients[i]);
00818 commandClients[i] = -1;
00819 }
00820 }
00821 if (commandClients[i] != -1 && FD_ISSET(commandClients[i], &exceptset)) {
00822
00823 close(commandClients[i]);
00824 commandClients[i] = -1;
00825 }
00826 }
00827
00828
00829 if (commandServerSocket > 0 && FD_ISSET(commandServerSocket, &readset)) {
00830 int clifd;
00831 EC_DEBUG(fprintf(stderr, "SIM: commandReadThread: accepting command connection\n"));
00832 clifd = acceptConnection(commandServerSocket);
00833 EC_DEBUG(fprintf(stderr, "SIM: commandReadThread: Got command connection %d\n", clifd));
00834 addClient(commandClients, clifd);
00835 }
00836 }
00837 return 0;
00838 }
00839
00840
00841
00842
00843
00844
00845
00846 int writeTossimEvent(void *data, int datalen, int clifd) {
00847 unsigned char ack;
00848 int i, j;
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858 EC_DEBUG(fprintf(stderr, "writeTossimEvent: fd %d datalen %d (0x%2x)\n", clifd, datalen, datalen));
00859 j = 0;
00860
00861
00862 i = send(clifd, data, datalen, 0);
00863 EC_DEBUG(fprintf(stderr, "writeTossimEvent: waiting for ack...\n"));
00864 if (i >= 0) j = read(clifd, &ack, 1);
00865 EC_DEBUG(fprintf(stderr, "writeTossimEvent: ack received...\n"));
00866 if ((i < 0) || (j < 0)) {
00867 EC_DEBUG(fprintf(stderr, "writeTossimEvent: Socket closed: %s\n", strerror(errno)));
00868 close(clifd);
00869 return -1;
00870
00871
00872 }
00873 EC_DEBUG(fprintf(stderr, "writeTossimEvent: done\n"));
00874 return 0;
00875 }
00876
00877 void buildTossimEvent(uint16_t moteID, uint16_t type, long long ftime, void *data,
00878 unsigned char **msgp, int *lenp) {
00879 unsigned char *msg;
00880 int payload_size, total_size;
00881
00882
00883
00884 switch (type) {
00885 case AM_DEBUGMSGEVENT:
00886 payload_size = sizeof(DebugMsgEvent);
00887 break;
00888 case AM_RADIOMSGSENTEVENT:
00889 payload_size = sizeof(RadioMsgSentEvent);
00890 break;
00891 case AM_UARTMSGSENTEVENT:
00892 payload_size = sizeof(RadioMsgSentEvent);
00893 break;
00894 case AM_ADCDATAREADYEVENT:
00895 payload_size = sizeof(ADCDataReadyEvent);
00896 break;
00897 case AM_TOSSIMINITEVENT:
00898 payload_size = sizeof(TossimInitEvent);
00899 break;
00900 case AM_VARIABLERESOLVERESPONSE:
00901 payload_size = sizeof(VariableResolveResponse);
00902 break;
00903 case AM_VARIABLEREQUESTRESPONSE:
00904 payload_size = sizeof(VariableRequestResponse);
00905 break;
00906 case AM_INTERRUPTEVENT:
00907 payload_size = sizeof(InterruptEvent);
00908 dbg(DBG_TEMP, "SIM: Sending InterruptEvent, payload is %i\n", (int)payload_size);
00909 break;
00910 case AM_LEDEVENT:
00911 payload_size = sizeof(LedEvent);
00912 break;
00913 default:
00914 EC_DEBUG(fprintf(stderr, "buildTossimEvent for invalid type: %d", type));
00915 return;
00916 }
00917
00918 total_size = GUI_MSG_HEADER_LENGTH + payload_size;
00919 msg = (unsigned char *)malloc(total_size);
00920
00921 *(unsigned short *)(&msg[0]) = htons(type);
00922 *(unsigned short *)(&msg[2]) = htons(moteID);
00923 *(long long *)(&msg[4]) = htonll(ftime);
00924 *(unsigned short *)(&msg[12]) = htons(payload_size);
00925 memcpy(((unsigned char *)msg)+GUI_MSG_HEADER_LENGTH, data, payload_size);
00926
00927 EC_DEBUG(fprintf(stderr, "buildTossimEvent: msgType %d (0x%02x) moteID %d (0x%02x) payload size %d total size %d\n", type, type, moteID, moteID, payload_size, total_size));
00928
00929
00930 *msgp = msg;
00931 *lenp = total_size;
00932 }
00933
00934
00935
00936
00937 void sendTossimEvent (uint16_t moteID, uint16_t type, long long ftime, void *data) {
00938 unsigned char *msg;
00939 int total_size;
00940 int n;
00941 int numclients = 0;
00942 int clients[MAX_CLIENT_CONNECTIONS];
00943
00944 if (!socketsInitialized) return;
00945
00946 pthread_mutex_lock(&eventClientsLock);
00947 while (numclients == 0) {
00948 for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
00949 clients[n] = -1;
00950 if (eventClients[n] != -1) {
00951 clients[n] = eventClients[n];
00952 numclients++;
00953 }
00954 }
00955
00956 if (numclients == 0 && GUI_enabled) {
00957 EC_DEBUG(fprintf(stderr, "sendTossimEvent waiting for connection\n"));
00958 pthread_cond_wait(&eventClientsCond, &eventClientsLock);
00959 EC_DEBUG(fprintf(stderr, "sendTossimEvent woke up\n"));
00960 } else if (numclients == 0) {
00961
00962 pthread_mutex_unlock(&eventClientsLock);
00963 return;
00964 }
00965 }
00966 pthread_mutex_unlock(&eventClientsLock);
00967
00968 EC_DEBUG(fprintf(stderr, "sendTossimEvent: msgType %d (0x%02x) moteID %d (0x%02x)\n", type, type, moteID, moteID));
00969
00970 buildTossimEvent(moteID, type, ftime, data, &msg, &total_size);
00971
00972 for (n = 0; n < MAX_CLIENT_CONNECTIONS; n++) {
00973 if (clients[n] != -1 && ((type & eventMask) != 0)) {
00974 if (writeTossimEvent(msg, total_size, clients[n]) < 0) {
00975
00976 pthread_mutex_lock(&eventClientsLock);
00977 eventClients[n] = -1;
00978 pthread_mutex_unlock(&eventClientsLock);
00979 }
00980 }
00981 }
00982 EC_DEBUG(fprintf(stderr, "Sent.\n"));
00983 free(msg);
00984 }
00985