7 | | /* DESCRIPTION OF FILE. |
| 7 | /* When a CE connects, the address of it's local socket is stored and it is assigned an ID number. |
| 8 | * Until it sends a message ending communication, any communications from it are processed with |
| 9 | * that ID number. The "sendto" command uses the address data to send messages directly back to |
| 10 | * it's local socket, allowing us to get away with a single-socket implementation on the SML-side. |
| 11 | * |
| 12 | * Services are stored in a SQLite DB by the ID of the CE that registered them. |
| 13 | * |
| 14 | * Mission support has not been implemented yet, but will be soon. |
| 15 | */ |
| 16 | |
| 17 | /* KNOWN ISSUE: Note that this implementation would be unstable for CE's on any sort of network |
| 18 | * since it relies on asyncronous communication occuring linearly and with one partner at a time. |
| 19 | * The breakdown occurs specifically when the CE has to send ack messages back to the SML; |
| 20 | * since there may be other messages queued on the socket since communication started, |
| 21 | * there is no guarentee that the message would be the first up and I have yet to discover a method |
| 22 | * for peaking more than 1 item into the message queue without starting to pop messages off first. |
| 23 | * Still a work in progress though... |
| 101 | CreateServicesDB(); |
| 102 | } |
| 103 | |
| 104 | void |
| 105 | CreateServicesDB() |
| 106 | { |
| 107 | _services_DB = (services_DB) malloc(sizeof(struct services_s)); |
| 108 | |
| 109 | // create database |
| 110 | |
| 111 | // copy filename |
| 112 | unsigned int i=0; |
| 113 | strcpy(_services_DB->filename, "Services_Table"); |
| 114 | |
| 115 | // execute create database command |
| 116 | // database handle |
| 117 | //_services_DB->db = NULL; |
| 118 | sqlite3_open(_services_DB->filename, &(_services_DB->db)); |
| 119 | char* cols[] = {"ID_Num", "Service_Name"}; |
| 120 | |
| 121 | // create table |
| 122 | |
| 123 | // copy tablename |
| 124 | strcpy(_services_DB->tablename, "Services"); |
| 125 | |
| 126 | // number of columns in the table |
| 127 | _services_DB->num_columns = 2; |
| 128 | |
| 129 | // generate command |
| 130 | strcpy(_services_DB->command, "CREATE TABLE "); |
| 131 | strcat(_services_DB->command, _services_DB->tablename); |
| 132 | strcat(_services_DB->command, "("); |
| 133 | strcat(_services_DB->command, cols[0]); |
| 134 | strcat(_services_DB->command, " INT, "); |
| 135 | strcat(_services_DB->command, cols[1]); |
| 136 | strcat(_services_DB->command, " TEXT"); |
| 137 | strcat(_services_DB->command, ");"); |
| 138 | |
| 139 | // execute create table command |
| 140 | sqlite3_exec(_services_DB->db, _services_DB->command, NULL, 0, NULL); |
191 | | } |
192 | | |
193 | | |
| 266 | struct timeval selTimeout; |
| 267 | fd_set sockSet; |
| 268 | int32_t rc = 0; |
| 269 | char buffer[256]; |
| 270 | //Send data until the CE sends an ACK message back |
| 271 | while(rc == 0){ |
| 272 | memset(buffer, 0, 256); |
| 273 | //Receive data from Shell |
| 274 | ReadMessage(shellSocketFD, buffer); |
| 275 | //Send data to CE |
| 276 | sendto(cogEngSrv, buffer, 256, NULL, (struct sockaddr*) CE_List[ID].sock_ptr, CE_List[ID].sock_len); |
| 277 | FD_ZERO(&sockSet); |
| 278 | FD_SET(cogEngSrv, &sockSet); |
| 279 | selTimeout.tv_sec = 0; |
| 280 | selTimeout.tv_usec = 0; |
| 281 | //Check if there is a message on the CE socket ready to be processed |
| 282 | rc = select(cogEngSrv + 1, &sockSet, NULL, NULL, &selTimeout); |
| 283 | } |
| 284 | memset(buffer, 0, 256); |
| 285 | //Once there is a message on the CE socket, read it and forward it on to the shell |
| 286 | ReadMessage(cogEngSrv, buffer); |
| 287 | SendMessage(shellSocketFD, buffer); |
| 288 | } |
| 289 | |
| 290 | //Simmilar to TransferRadioConfig, just with Experience data |
197 | | } |
198 | | |
199 | | |
200 | | void |
201 | | ServiceManagementLayer::ReceiveServices() |
202 | | { |
| 294 | struct timeval selTimeout; |
| 295 | fd_set sockSet; |
| 296 | int32_t rc = 0; |
| 297 | char buffer[256]; |
| 298 | //Send data until the CE sends an ACK message back |
| 299 | while(rc == 0){ |
| 300 | memset(buffer, 0, 256); |
| 301 | //Receive data from Shell |
| 302 | ReadMessage(shellSocketFD, buffer); |
| 303 | //Send data to CE |
| 304 | sendto(cogEngSrv, buffer, 256, NULL, (struct sockaddr*) CE_List[ID].sock_ptr, CE_List[ID].sock_len); |
| 305 | FD_ZERO(&sockSet); |
| 306 | FD_SET(cogEngSrv, &sockSet); |
| 307 | selTimeout.tv_sec = 0; |
| 308 | selTimeout.tv_usec = 0; |
| 309 | //Check if there is a message on the CE socket ready to be processed |
| 310 | rc = select(cogEngSrv + 1, &sockSet, NULL, NULL, &selTimeout); |
| 311 | } |
| 312 | memset(buffer, 0, 256); |
| 313 | //Once there is a message on the CE socket, read it and forward it on to the shell |
| 314 | ReadMessage(cogEngSrv, buffer); |
| 315 | SendMessage(shellSocketFD, buffer); |
| 316 | } |
| 317 | |
| 318 | |
| 319 | void |
| 320 | ServiceManagementLayer::ReceiveServices(int32_t ID) |
| 321 | { |
| 322 | char buffer[256]; |
| 323 | memset(buffer, 0, 256); |
| 324 | ReadMessage(cogEngSrv, buffer); |
| 325 | char* cols[] = {"ID_Num", "Service_Name"}; |
| 326 | |
| 327 | // generate command |
| 328 | //printf("%s\n", _services_DB->command); |
| 329 | strcpy(_services_DB->command, "insert into "); |
| 330 | strcat(_services_DB->command, _services_DB->tablename); |
| 331 | strcat(_services_DB->command, " ("); |
| 332 | strcat(_services_DB->command, cols[0]); |
| 333 | strcat(_services_DB->command, ", "); |
| 334 | strcat(_services_DB->command, cols[1]); |
| 335 | strcat(_services_DB->command, ") "); |
| 336 | strcat(_services_DB->command, " values("); |
| 337 | sprintf(_services_DB->command, "%s%d", _services_DB->command, ID); |
| 338 | strcat(_services_DB->command, ", "); |
| 339 | strcat(_services_DB->command, buffer); |
| 340 | strcat(_services_DB->command, ");"); |
| 341 | |
| 342 | //printf("search command: %s\n", _services_DB->command); |
| 343 | // execute add command |
| 344 | sqlite3_exec(_services_DB->db, _services_DB->command, NULL, 0, NULL); |
| 345 | |
| 358 | // generate commandi |
| 359 | strcpy(_services_DB->command, "select "); |
| 360 | strcat(_services_DB->command, _services_DB->tablename); |
| 361 | strcat(_services_DB->command, ".* from "); |
| 362 | strcat(_services_DB->command, _services_DB->tablename); |
| 363 | strcat(_services_DB->command, ";"); |
| 364 | |
| 365 | // execute print (select all) command |
| 366 | sqlite3_exec(_services_DB->db, _services_DB->command, NULL, 0, NULL); |
| 367 | printf("database %s, table %s:\n", _services_DB->filename, _services_DB->tablename); |
244 | | |
245 | | void |
246 | | ServiceManagementLayer::DeregisterCognitiveEngine(int32_t socketFD) |
247 | | { |
248 | | LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n"); |
| 397 | void |
| 398 | ServiceManagementLayer::DeregisterServices(int32_t ID) |
| 399 | { |
| 400 | char str_buffer[64]; |
| 401 | strcpy(_services_DB->command, "delete "); |
| 402 | strcat(_services_DB->command, _services_DB->tablename); |
| 403 | strcat(_services_DB->command, ".* from "); |
| 404 | strcat(_services_DB->command, _services_DB->tablename); |
| 405 | strcat(_services_DB->command, " where "); |
| 406 | strcat(_services_DB->command, "ID_Num"); |
| 407 | strcat(_services_DB->command, "=="); |
| 408 | sprintf(str_buffer, "%d;", ID); |
| 409 | strcat(_services_DB->command, str_buffer); |
| 410 | sqlite3_exec(_services_DB->db, _services_DB->command, NULL, 0, NULL); |
| 411 | } |
| 412 | |
| 413 | |
| 414 | void |
| 415 | ServiceManagementLayer::DeregisterCognitiveEngine(int32_t ID) |
| 416 | { |
| 417 | LOG("ServiceManagementLayer:: CE deregistration message forwarded to shell.\n"); |
254 | | SendMessage(socketFD, "deregister_ack"); |
255 | | shutdown(socketFD, 2); |
256 | | close(socketFD); |
| 423 | SendMessage(shellSocketFD, "deregister_engine_cognitive"); |
| 424 | char buffer[256]; |
| 425 | memset(buffer, 0, 256); |
| 426 | ReadMessage(shellSocketFD, buffer); |
| 427 | sendto(cogEngSrv, buffer, 256, NULL, (struct sockaddr*) CE_List[ID].sock_ptr, CE_List[ID].sock_len); |
| 428 | if(strcmp("deregister_ack", buffer) != 0) { |
| 429 | ERROR(1, "SML:: Failed to close CE socket\n"); |
| 430 | } |
| 431 | CE_List[ID].sock_ptr = NULL; |
| 432 | CE_List[ID].ID_num = -1; |
| 433 | |