root/vtcross/trunk/src/service_management_layer/ServiceManagementLayer.cpp @ 287

Revision 287, 74.2 KB (checked in by wrodgers, 15 years ago)

Begun work on nested conditionals, direct communication. This should work for linear ordering of statements, and may work for nonlinear ordering too, although that has yet to be fully tested

Line 
1/* Virginia Tech Cognitive Radio Open Source Systems
2 * Virginia Tech, 2009
3 *
4 * LICENSE INFORMATION GOES HERE
5 */
6
7/* Inter-component communication handled by sockets and FD's. 
8 * Server support has been completely implemented and tested.
9 *
10 * Services are stored in a SQLite DB by the ID of the CE that registered them.  Service
11 * support has been completely implemented and tested.
12 *
13 * Missions are loaded from an XML file, connected with services provided by components,
14 * and run.  See the documentation for the "PerformActiveMission" below for important
15 * info. 
16 */
17
18//TODO Add nested conditional support
19//TODO Verify update functionality
20//TODO Better shutdown
21//TODO Verify Deregister services
22//TODO printf's
23
24#include <stdlib.h>
25#include <string.h>
26#include <stdio.h>
27#include <cstring>
28#include <stdint.h>
29
30#include "vtcross/common.h"
31
32#include "components.h"
33#include "vtcross/containers.h"
34#include "vtcross/debug.h"
35#include "vtcross/error.h"
36#include "vtcross/socketcomm.h"
37#include <cstring>
38#include <stdint.h>
39#include <math.h>
40
41#include <arpa/inet.h>
42#include <iostream>
43#include <netinet/in.h>
44#include <netdb.h>
45#include <fcntl.h>
46#include <sys/ioctl.h>
47#include <sys/mman.h>
48#include <sys/socket.h>
49#include <sys/types.h>
50#include <sys/wait.h>
51
52#include "tinyxml/tinyxml.h"
53#include "tinyxml/tinystr.h"
54
55#include "sqlite3.h"
56
57typedef struct services_s *services_DB;
58typedef struct data_s *data_DB;
59
60using namespace std;
61
62struct services_s {
63    char filename[64];
64    char tablename[64];
65    char command[2048];
66    sqlite3 *db;
67    unsigned int num_columns;
68};
69
70struct data_s {
71    char filename[64];
72    char tablename[64];
73    char command[2048];
74    sqlite3 *db;
75    unsigned int num_columns;
76};
77
78services_DB _services_DB;
79data_DB _data_DB;
80const char *_SML_Config;
81
82//Callback function used internally by some of the SQLite3 commands
83int callback(void *notUsed, int argc, char **argv, char **azColName){
84    int i;
85    for(i=0; i<argc; i++){
86        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
87    }
88    printf("\n");
89    return 0;
90}
91
92
93
94ServiceManagementLayer::ServiceManagementLayer()
95{
96    LOG("Creating Service Management Layer.\n");
97    shellSocketFD = -1;
98    numberOfCognitiveEngines = 0;
99    CE_Present = false;
100    cogEngSrv = 1;
101}
102
103//Free and clear the DB's associated with this SML in the destructor
104//Note that exiting with an error condition will cause SML to not be destructed,
105// resulting in the DB's staying in memory until the destructor is encountered in future executions
106ServiceManagementLayer::~ServiceManagementLayer()
107{
108    char *errorMsg;
109    strcpy(_services_DB->command, "drop table ");
110    strcat(_services_DB->command, _services_DB->tablename);
111    int rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
112    if( rc!=SQLITE_OK && rc!=101 )
113        fprintf(stderr, "ServiceManagementLayer::Destructor services 'drop table' error: %s\n", errorMsg);
114    strcpy(_services_DB->command, "vacuum");
115    rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
116    if( rc!=SQLITE_OK && rc!=101 )
117        fprintf(stderr, "ServiceManagementLayer::Destructor services 'vacuum' error: %s\n", errorMsg);
118    free(_services_DB);
119
120    strcpy(_data_DB->command, "drop table ");
121    strcat(_data_DB->command, _data_DB->tablename);
122    rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
123    if( rc!=SQLITE_OK && rc!=101 )
124        fprintf(stderr, "ServiceManagementLayer::Destructor data 'drop table' error: %s\n", errorMsg);
125    strcpy(_data_DB->command, "vacuum");
126    rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
127    if( rc!=SQLITE_OK && rc!=101 )
128        fprintf(stderr, "ServiceManagementLayer::Destructor data 'vacuum' error: %s\n", errorMsg);
129    free(_data_DB);
130}
131
132//Note that sizes of CE_List, miss, and service are hardcoded for now.
133//Also, their sizes are hardcoded into the code in various places; a fix for a future version.
134ServiceManagementLayer::ServiceManagementLayer(const char* SML_Config, \
135        const char* serverName, const char* serverPort, int16_t clientPort)
136{
137    LOG("Creating Service Management Layer.\n");
138    _SML_Config = SML_Config;
139    SMLport = clientPort;
140
141    ConnectToShell(serverName, serverPort);
142    CE_List = (CE_Reg *) malloc(10*sizeof(struct CE_Reg));
143    CE_List = new CE_Reg[10];
144
145    miss = new Mission[10];
146    for(int i = 0; i < 10; i++)
147        miss[i].services = new Service[20];
148
149    Current_ID = 0;
150
151    LoadConfiguration(SML_Config, miss);
152    CreateServicesDB();
153    CreateDataDB();
154}
155
156/* CALLED BY: constructor
157 * INPUTS: <none>
158 * OUTPUTS: <none>
159 *
160 * DESCRIPTION: Create and initialize a DB to hold the services registered by components
161 */
162void
163ServiceManagementLayer::CreateServicesDB()
164{
165
166
167  sqlite3_stmt *ppStmt;  /* OUT: Statement handle */
168  const char *pzTail;     /* OUT: Pointer to unused portion of zSql */
169
170
171    _services_DB = (services_DB) malloc(sizeof(struct services_s));
172   // char *errorMsg;
173
174    // create database
175
176    // copy filename
177    strcpy(_services_DB->filename, "Services_Table");
178
179    // execute create database command
180    // database handle
181    //_services_DB->db = NULL;
182    sqlite3_open(_services_DB->filename, &(_services_DB->db));
183    char* cols[] = {(char *)"ID_Num", (char *)"Service_Name"};
184
185    // create table
186
187    // copy tablename
188    strcpy(_services_DB->tablename, "Services");
189    sprintf(_services_DB->command, "DROP TABLE IF EXISTS Services;");     
190
191    int rc = sqlite3_prepare_v2(_services_DB->db, _services_DB->command, 128, &ppStmt, &pzTail);
192    if( rc!=SQLITE_OK && rc!=101 )
193        printf("ServiceManagementLayer::CreateServicesDB 'prepare_stmt' error %d\n", rc);
194    rc = sqlite3_step(ppStmt);
195    if( rc!=SQLITE_OK && rc!=101 )
196        printf("ServiceManagementLayer::CreateServicesDB 'step' error\n");
197
198    // number of columns in the table
199    _services_DB->num_columns = 2;
200
201    // generate command
202    strcpy(_services_DB->command, "CREATE TABLE ");
203    strcat(_services_DB->command, _services_DB->tablename);
204    strcat(_services_DB->command, "(");
205    strcat(_services_DB->command, cols[0]);
206    strcat(_services_DB->command, " INT, ");
207    strcat(_services_DB->command, cols[1]);
208    strcat(_services_DB->command, " TEXT");
209    strcat(_services_DB->command, ");");
210
211    // execute create table command
212
213    rc = sqlite3_prepare_v2(_services_DB->db, _services_DB->command, 128, &ppStmt, &pzTail);
214    if( rc!=SQLITE_OK && rc!=101 )
215        printf("ServiceManagementLayer::CreateServicesDB 'prepare_stmt' error %d\n", rc);
216    rc = sqlite3_step(ppStmt);
217    if( rc!=SQLITE_OK && rc!=101 )
218        printf("ServiceManagementLayer::CreateServicesDB 'step' error\n");
219}
220
221/* CALLED BY: constructor
222 * INPUTS: <none>
223 * OUTPUTS: <none>
224 *
225 * DESCRIPTION: Create and initialize a DB to hold the data sent by components
226 */
227void
228ServiceManagementLayer::CreateDataDB()
229{
230    _data_DB = (data_DB) malloc(sizeof(struct data_s));
231    //char *errorMsg;
232  sqlite3_stmt *ppStmt;  /* OUT: Statement handle */
233  const char *pzTail;     /* OUT: Pointer to unused portion of zSql */
234
235    // create database
236
237    // copy filename
238    strcpy(_data_DB->filename, "Data_Table");
239    // execute create database command
240    // database handle
241    //_services_DB->db = NULL;
242    sqlite3_open(_data_DB->filename, &(_data_DB->db));
243    char* cols[] = {(char *)"Tag", (char *)"Data"};
244
245    // create table
246
247    // copy tablename
248    strcpy(_data_DB->tablename, "Data");
249    sprintf(_data_DB->command, "DROP TABLE IF EXISTS Data;");     
250
251    int rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, 128, &ppStmt, &pzTail);
252    if( rc!=SQLITE_OK && rc!=101 )
253        printf("ServiceManagementLayer::CreateServicesDB 'prepare_stmt' error %d\n", rc);
254    rc = sqlite3_step(ppStmt);
255    if( rc!=SQLITE_OK && rc!=101 )
256        printf("ServiceManagementLayer::CreateServicesDB 'step' error\n");
257
258
259    // number of columns in the table
260    _data_DB->num_columns = 2;
261
262    // generate command
263    strcpy(_data_DB->command, "CREATE TABLE ");
264    strcat(_data_DB->command, _data_DB->tablename);
265    strcat(_data_DB->command, "(");
266    strcat(_data_DB->command, cols[0]);
267    //First column is the name of the data (coresponding to the name of the output/input pair)
268    //It is the primary key so any subsequent data with the same name will replace the row
269    strcat(_data_DB->command, " TEXT PRIMARY KEY ON CONFLICT REPLACE, ");
270    strcat(_data_DB->command, cols[1]);
271    strcat(_data_DB->command, " TEXT");
272    strcat(_data_DB->command, ");");
273
274    // execute create table command
275
276    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, 128, &ppStmt, &pzTail);
277    if( rc!=SQLITE_OK && rc!=101 )
278        printf("ServiceManagementLayer::CreateDataDB 'prepare_stmt' error %d\n", rc);
279    rc = sqlite3_step(ppStmt);
280    if( rc!=SQLITE_OK && rc!=101 )
281        printf("ServiceManagementLayer::CreateDataDB 'step' error\n");
282}
283
284/* CALLED BY: MessageHandler
285 * INPUTS: <none>
286 * OUTPUTS: <none>
287 *
288 * DESCRIPTION: Sends a message identifying this component as an SML to the Shell
289 */
290void
291ServiceManagementLayer::SendComponentType()
292{
293    SendMessage(shellSocketFD, "response_sml");
294    LOG("SML responded to GetRemoteComponentType query.\n");
295}
296
297/* CALLED BY: constructor
298 * INPUTS: |serverName| the IPv4 name of the server (127.0.0.1 for localhost)
299 *         |serverPort| the port on the server to connect to
300 * OUTPUTS: <none>
301 *
302 * DESCRIPTION: Connecting to the shell takes 2 steps
303 * 1) Establish a client socket for communication
304 * 2) Run the initial Registration/handshake routine
305 */
306void
307ServiceManagementLayer::ConnectToShell(const char* serverName, \
308        const char* serverPort)
309{
310    shellSocketFD = ClientSocket(serverName, serverPort);
311    RegisterComponent();
312}
313
314/* CALLED BY: StartSMLServer
315 * INPUTS: |ID| The ID number of the CE that has a message wating
316 * OUTPUTS: <none>
317 *
318 * DESCRIPTION: Called whenever a socket is identified as being ready for communication
319 *              This funciton reads the message and calls the appropriate helper
320 */
321void
322ServiceManagementLayer::MessageHandler(int32_t ID)
323{
324    char buffer[256];   
325    memset(buffer, 0, 256); 
326    int32_t _FD; 
327   
328    if(ID != -1)
329        _FD = CE_List[ID].FD;
330    else
331        _FD = shellSocketFD;
332    ReadMessage(_FD, buffer);
333    //printf("MH_buffer = %s\n", buffer);
334   
335    //--------Policy Engine Stuff - no policy engine support in this version-------//
336
337    //printf("********* %s **********\n", buffer);
338    // TODO
339    // If we send integer op codes rather than strings, this process will be
340    // MUCH faster since instead of donig string compares we can simply
341    // switch on the integer value...
342    /*if(strcmp(buffer, "register_service") == 0) {
343        if(strcmp(buffer, "policy_geo") == 0) {
344        }
345        else if(strcmp(buffer, "policy_time") == 0) {
346        }
347        else if(strcmp(buffer, "policy_spectrum") == 0) {
348        }
349        else if(strcmp(buffer, "policy_spacial") == 0) {
350        }
351    }
352    else if(strcmp(buffer, "deregister_service") == 0) {
353        if(strcmp(buffer, "policy_geo") == 0) {
354        }
355        else if(strcmp(buffer, "policy_time") == 0) {
356        }
357        else if(strcmp(buffer, "policy_spectrum") == 0) {
358        }
359        else if(strcmp(buffer, "policy_spacial") == 0) {
360        }
361    }*/
362
363    //Go down the list to call the appropriate function
364    if(strcmp(buffer, "query_component_type") == 0) {
365        SendComponentType();
366    }
367    else if(strcmp(buffer, "reset_sml") == 0) {
368        Reset();
369    }
370    else if(strcmp(buffer, "shutdown_sml") == 0) {
371        Shutdown();
372    }
373    else if(strcmp(buffer, "register_engine_cognitive") == 0) {
374        RegisterCognitiveEngine(ID);
375    }
376    else if(strcmp(buffer, "register_service") == 0) {
377        ReceiveServices(ID);
378    }
379    else if(strcmp(buffer, "send_component_type") == 0) {
380        SendComponentType();
381    }
382    else if(strcmp(buffer, "list_services") == 0) {
383        ListServices();
384    }
385    else if(strcmp(buffer, "set_active_mission") == 0) {
386        SetActiveMission();
387    }
388    else if(strcmp(buffer, "request_optimization") == 0) {
389        PerformActiveMission();
390    }
391    else if(strcmp(buffer, "deregister_engine_cognitive") == 0) {
392        DeregisterCognitiveEngine(ID);
393    }
394    else if(strcmp(buffer, "deregister_service") == 0) {
395        DeregisterServices(ID);
396    }
397}
398
399//TODO Finish
400/* CALLED BY: MessageHandler
401 * INPUTS: <none>
402 * OUTPUTS: <none>
403 *
404 * DESCRIPTION: Deregisters the component from the Shell.
405 */
406void
407ServiceManagementLayer::Shutdown()
408{
409    DeregisterComponent();
410}
411
412//TODO Finish
413/* CALLED BY: MessageHandler
414 * INPUTS: <none>
415 * OUTPUTS: <none>
416 *
417 * DESCRIPTION: Deregisters the component from the Shell
418 */
419void
420ServiceManagementLayer::Reset()
421{
422    DeregisterComponent();
423    ReloadConfiguration();
424}
425
426/* CALLED BY: ConnectToShell
427 * INPUTS: <none>
428 * OUTPUTS: <none>
429 *
430 * DESCRIPTION: Sends the registration message to the Shell
431 */
432void
433ServiceManagementLayer::RegisterComponent()
434{
435    SendMessage(shellSocketFD, "register_sml");
436    LOG("ServiceManagementLayer:: Registration message sent.\n");
437    //printf("SSFD = %d\n", shellSocketFD);
438}
439
440/* CALLED BY: Shutdown
441 * INPUTS: <none>
442 * OUTPUTS: <none>
443 *
444 * DESCRIPTION: Closes the client socket with the shell, sends a deregstration message
445 */
446void
447ServiceManagementLayer::DeregisterComponent()
448{
449    SendMessage(shellSocketFD, "deregister_sml");
450    LOG("ServiceManagementLayer:: Deregistration message sent.\n");
451
452    shutdown(shellSocketFD, 2);
453    close(shellSocketFD);
454    shellSocketFD = -1;
455    LOG("ServiceManagementLayer:: Shell socket closed.\n");
456}
457
458
459/* CALLED BY: RegisterCognitiveEngine
460 * INPUTS: |ID| The ID number of the component where the data is to be transfered to
461 * OUTPUTS: <none>
462 *
463 * DESCRIPTION: Streams config data directly from the shell to the CE, and checks
464 * for an "ack" message from the CE after every sent message
465 * to know when to stop communication.
466 */
467
468//Modified to check the incoming message buffer rather than the outgoing message buffer to avoid a portion of the delay
469void
470ServiceManagementLayer::TransferRadioConfiguration(int32_t ID)
471{
472    //printf("transRadConfig\n");
473    struct timeval selTimeout;
474    fd_set sockSet;
475    int32_t rc = 1;
476    char buffer[256];
477    //Send data until the CE sends an ACK message back
478    while(rc!=0){
479        memset(buffer, 0, 256);
480        //Receive data from Shell
481        ReadMessage(shellSocketFD, buffer);
482        //printf("buffer = %s\n", buffer);
483        //Send data to CE
484        SendMessage(CE_List[ID].FD, buffer);
485        FD_ZERO(&sockSet);
486        FD_SET(shellSocketFD, &sockSet);
487        selTimeout.tv_sec = 0;
488        selTimeout.tv_usec = 50000;
489        //Check if there is a message on the shell ready to be processed
490        rc=select(shellSocketFD + 1, &sockSet, NULL, NULL, &selTimeout);
491    }
492    memset(buffer, 0, 256);
493    ReadMessage(CE_List[ID].FD, buffer);
494    SendMessage(shellSocketFD, buffer);
495    //printf("transfer done!\n");
496}
497
498
499/* CALLED BY: RegisterCognitiveEngine
500 * INPUTS: |ID| The ID number of the component where the data is to be transfered to
501 * OUTPUTS: <none>
502 *
503 * DESCRIPTION: Simmilar to TransferRadioConfig, just with Experience data
504 */
505
506//Modified to check the incoming message buffer rather than the outgoing message buffer to avoid a portion of the delay
507void
508ServiceManagementLayer::TransferExperience(int32_t ID)
509{
510    struct timeval selTimeout;
511    fd_set sockSet;
512    int32_t rc = 1;
513    char buffer[256];
514    //Send data until the CE sends an ACK message back
515    while(rc!=0){
516        //printf("transfering...\n");
517        memset(buffer, 0, 256);
518        //Receive data from Shell
519        ReadMessage(shellSocketFD, buffer);
520        //printf("buffer = %s\n", buffer);
521        //Send data to CE
522        SendMessage(CE_List[ID].FD, buffer);
523        FD_ZERO(&sockSet);
524        FD_SET(shellSocketFD, &sockSet);
525        selTimeout.tv_sec = 0;
526        selTimeout.tv_usec = 50000;
527        //Check if there is a message on the shell ready to be processed
528        rc=select(shellSocketFD + 1, &sockSet, NULL, NULL, &selTimeout);
529    }
530    memset(buffer, 0, 256);
531    //printf("done trans exp!\n");
532    ReadMessage(CE_List[ID].FD, buffer);
533    SendMessage(shellSocketFD, buffer);
534}
535
536/* CALLED BY: MessageHandler
537 * INPUTS: |ID| The ID number of the component where service is located
538 * OUTPUTS: <none>
539 *
540 * DESCRIPTION: Inserts a service into the DB with the ID of the component where it exists
541 */
542void
543ServiceManagementLayer::ReceiveServices(int32_t ID)
544{
545    char buffer[256];
546    memset(buffer, 0, 256);
547    ReadMessage(CE_List[ID].FD, buffer);
548    char* cols[] = {(char *)"ID_Num", (char *)"Service_Name"};
549    //printf("RS_buffer = %s\n", buffer);
550    // generate command
551    strcpy(_services_DB->command, "insert into ");
552    strcat(_services_DB->command, _services_DB->tablename);
553    strcat(_services_DB->command, " (");
554    strcat(_services_DB->command, cols[0]);
555    strcat(_services_DB->command, ", ");
556    strcat(_services_DB->command, cols[1]);
557    strcat(_services_DB->command, ") ");
558    strcat(_services_DB->command, " values(");
559    sprintf(_services_DB->command, "%s%d", _services_DB->command, ID);
560    strcat(_services_DB->command, ", '");
561    strcat(_services_DB->command, buffer);
562    strcat(_services_DB->command, "');");
563   
564    //printf("search command: %s\n", _services_DB->command);
565    // execute add command
566    char *errorMsg;
567    int rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
568    if( rc!=SQLITE_OK && rc!=101 )
569        fprintf(stderr, "ServiceManagementLayer::RecieveServices DB Error %s\n", errorMsg);
570    /*sprintf(outBuffer, "SML: Registering service '%s' from component number '%d'", buffer, ID);
571    LOG(outBuffer);*/
572}
573
574/* CALLED BY: MessageHandler
575 * INPUTS: <none>
576 * OUTPUTS: <none>
577 *
578 * DESCRIPTION: This method associates the services that components provide with the services that are requested in the mission
579 * Each service in the mission is given the ID and FD of a component that has registered to provide that service
580 * Deregistration is okay until this method is called without a reload, but if deregistration occurs after this
581 * method is called it needs to be called again even if other engines also provide the services
582 */
583void
584ServiceManagementLayer::SetActiveMission()
585{
586    char buffer[256];
587    memset(buffer, 0, 256);
588    ReadMessage(shellSocketFD, buffer);
589    uint32_t missID = atoi(buffer);
590    for(activeMission = 0; activeMission < 10; activeMission++)
591    {
592        //Find the active mission by comparing mission ID's
593        if(miss[activeMission].missionID == missID)
594            break;
595    }
596
597    LOG("ServiceManagementLayer:: Received Set Active Mission command: %i.\n",missID);
598    //For each service in the mission
599    for(uint16_t i = 0; i < miss[activeMission].numServices; i++)
600    {   
601        //Check whether the current service is an actual service or a conditional
602        if(miss[activeMission].services[i].name.compare("if") && miss[activeMission].services[i].name.compare("while") && \
603           miss[activeMission].services[i].name.compare("shell")){
604            //If it is a service, search the database of registered services to find the ID of the component that registered it
605            strcpy(_services_DB->command, "select ");
606            strcat(_services_DB->command, _services_DB->tablename);
607            strcat(_services_DB->command, ".* from ");
608            strcat(_services_DB->command, _services_DB->tablename);
609            strcat(_services_DB->command, " where Service_Name==");
610            sprintf(_services_DB->command, "%s'%s';", _services_DB->command, miss[activeMission].services[i].name.c_str());
611       
612            sqlite3_stmt * pStatement;
613            int rc = sqlite3_prepare_v2(_services_DB->db, _services_DB->command, -1, &pStatement, NULL);
614            if (rc == SQLITE_OK){
615                if (sqlite3_step(pStatement) == SQLITE_ROW)
616                     miss[activeMission].services[i].componentID =  sqlite3_column_int(pStatement, 0);
617                else {
618                    printf("services_DB:: Mission requires service %s not provided by any connected component.\n",miss[activeMission].services[i].name.c_str());
619                    rc=31337;
620                }
621             } else {
622                printf("services_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_services_DB->command);
623            }
624                //printf("s_name=%s\n",miss[activeMission].services[i].name.c_str());
625            sqlite3_finalize(pStatement);
626            miss[activeMission].services[i].socketFD = CE_List[miss[activeMission].services[i].componentID].FD;
627            //Set the FD and ID of the service to refer to the component where the service exists
628        }
629        //Nothing to be done for conditionals at this stage
630    }
631 
632    SendMessage(shellSocketFD, "ack");
633    LOG("ServiceManagementLayer:: Done setting active mission.\n");
634    //printf("\nhere ---%d, %d---\n", miss[activeMission].services[0].componentID, miss[activeMission].services[1].componentID);
635}
636
637/* CALLED BY: PerformActiveMission
638 * INPUTS: |sourceID| ID of the service that is being processed
639 * OUTPUTS: <none>
640 *
641 * DESCRIPTION: This is a helper method for the "PerformActiveMission" function
642 * NOTE: This function has changed durrastically from the previous implementation
643 * Takes an ID of a service
644 * For that service, finds inputs in DB and forwords those on to the engine after sending comm-starting messages
645 * Afterwords, listenes for the outputs so that it can store those in the database for future services or the overall output
646 */
647void
648ServiceManagementLayer::TransactData(int32_t sourceID)
649{
650    LOG("ServiceManagementLayer:: Data transaction occuring.\n");
651    char buffer[256];
652    std::string data;
653    char* cols[] = {(char *)"Tag", (char *)"Data"};
654    int i = 0;
655    fd_set sockSet;
656    char *token;
657    struct timeval selTimeout;
658
659   //Send a message directly to the shell
660   //printf("name = %s\n", miss[activeMission].services[sourceID].name.c_str());
661   if(miss[activeMission].services[sourceID].name.find("shell")!=string::npos)
662   {
663        //printf("caught shell\n");
664        //If the name on the output doesn't start with "~", search the DB to find the output that should be returned
665        if(miss[activeMission].services[sourceID].output[0].find("~") == string::npos){
666           // printf("taken1\n");
667            memset(buffer, 0 , 256);
668            strcpy(_data_DB->command, "select ");
669            strcat(_data_DB->command, _data_DB->tablename);
670            strcat(_data_DB->command, ".* from ");
671            strcat(_data_DB->command, _data_DB->tablename);
672            strcat(_data_DB->command, " where Tag==");
673            sprintf(_data_DB->command, "%s'%s';", _data_DB->command, miss[activeMission].services[sourceID].output[0].c_str());
674            sqlite3_stmt * pStatement;
675            int rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
676            if (rc == SQLITE_OK){
677                if (sqlite3_step(pStatement) == SQLITE_ROW)
678                    data.append((const char*) sqlite3_column_text(pStatement, 1));
679                else {
680                    printf("data_DB:: Data not yet in DB.\n");
681                    rc=31337;
682                }
683            }
684            else {
685                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
686            }
687            sqlite3_finalize(pStatement);
688            token = strtok((char *)data.c_str(), "@");
689            SendMessage(shellSocketFD, token);
690            token = strtok(NULL, "@");
691            while(token){
692                SendMessage(shellSocketFD, token);
693                token = strtok(NULL, "@");
694            }
695        }
696        //Otherwise, just return the value specified by output TODO (in 1 - <output name> - <output name> format)
697        else{
698            printf("taken2\n");
699            memset(buffer, 0, 256);
700            SendMessage(shellSocketFD, "1");
701            miss[activeMission].services[sourceID].output[0].erase(0);
702            SendMessage(shellSocketFD, miss[activeMission].services[sourceID].output[0].c_str());
703            SendMessage(shellSocketFD, miss[activeMission].services[sourceID].output[0].c_str());
704        }
705        //printf("done shell\n");
706        return;
707   }
708
709
710
711    //Transmission starting messages
712    SendMessage(miss[activeMission].services[sourceID].socketFD, "request_optimization_service");
713    SendMessage(miss[activeMission].services[sourceID].socketFD, miss[activeMission].services[sourceID].name.c_str());
714    //Find and load the input data
715    while(i < 5 && !miss[activeMission].services[sourceID].input[i].empty()){
716        //printf("pulling input data out of DB for ID#=%d\n", sourceID);
717        strcpy(_data_DB->command, "select ");
718        strcat(_data_DB->command, _data_DB->tablename);
719        strcat(_data_DB->command, ".* from ");
720        strcat(_data_DB->command, _data_DB->tablename);
721        strcat(_data_DB->command, " where Tag==");
722        char temp[100];
723        strcpy(temp, miss[activeMission].services[sourceID].input[i].c_str());
724        char *temp2 = strtok(temp, "+");
725        sprintf(_data_DB->command, "%s'%s';", _data_DB->command, temp2);
726        sqlite3_stmt * pStatement;
727        int rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
728        if (rc == SQLITE_OK){
729            if (sqlite3_step(pStatement) == SQLITE_ROW)
730                 data.append((const char*) sqlite3_column_text(pStatement, 1));
731            else {
732                    printf("data_DB:: Data not yet in DB.\n");
733                    rc=31337;
734            }
735        }
736        else {
737            printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
738        }
739        sqlite3_finalize(pStatement);
740        char *data_ch = (char *) data.c_str();
741        int32_t numStatements = 0;
742        temp2 = strtok(NULL, "+");
743        while(temp2){
744            numStatements++;
745            temp2 = strtok(NULL, "+");
746        }
747        //printf("here1%d\n", numStatements);
748        char temp4[10];
749        memset(temp4, 0, 10);
750        sprintf(temp4, "%d", numStatements);
751        //Tokenize the data and pass it along
752        //printf("here2 %s\n", temp4);
753        if(strstr(miss[activeMission].services[sourceID].input[i].c_str(), "+")){
754            SendMessage(miss[activeMission].services[sourceID].socketFD, temp4);
755            token = strtok(data_ch, "@");
756        }
757        else{
758            token = strtok(data_ch, "@");
759            SendMessage(miss[activeMission].services[sourceID].socketFD, token);
760        }
761        token = strtok(NULL, "@");
762
763
764        //Either have to send whole block of memory or just one piece
765        while(token){
766            if(strstr(miss[activeMission].services[sourceID].input[i].c_str(), token))
767            {
768                //printf("1tokenizing %s %s!\n", miss[activeMission].services[sourceID].input[i].c_str(), token);
769                SendMessage(miss[activeMission].services[sourceID].socketFD, token);
770                token = strtok(NULL, "@");
771                SendMessage(miss[activeMission].services[sourceID].socketFD, token);
772            }
773            else if(!strstr(miss[activeMission].services[sourceID].input[i].c_str(), "+"))
774            {
775                //printf("t not detected tokenizing %s %s!\n", miss[activeMission].services[sourceID].input[i].c_str(), token);
776                SendMessage(miss[activeMission].services[sourceID].socketFD, token);
777                token = strtok(NULL, "@");
778                SendMessage(miss[activeMission].services[sourceID].socketFD, token);
779            }
780            else{
781                //printf("3tokenizing %s %s!\n", miss[activeMission].services[sourceID].input[i].c_str(), token);
782                token = strtok(NULL, "@");}
783            token = strtok(NULL, "@");
784        }
785        //printf("done\n");
786        //printf("done pulling input data out of DB for ID#=%d\n", sourceID);
787        i++;
788        data.clear();
789    }
790    int32_t j = 0;
791    FD_ZERO(&sockSet);
792    FD_SET(miss[activeMission].services[sourceID].socketFD, &sockSet);
793    //TODO neccessary?
794    selTimeout.tv_sec = 5;
795    selTimeout.tv_usec = 0;
796    //Use select command to force wait for processing to finish
797    select(miss[activeMission].services[sourceID].socketFD + 1, &sockSet, NULL, NULL, &selTimeout);
798        //printf("done\n");
799   //TODO rewrite part of data on output?
800   //TODO true false format?
801    while(j < 5 && !miss[activeMission].services[sourceID].output[j].empty()){
802        int rc;
803        memset(buffer, 0, 256);
804        ReadMessage(miss[activeMission].services[sourceID].socketFD, buffer);
805       // printf("waiting\n");     
806        data.append(buffer);
807        data.append("@");
808        int t = atoi(buffer);
809        //printf("%d\n", t);
810        for(int k = 0; k < t; k++){
811            //Read the data incrementally and deliminate it with the "@" symbol
812            memset(buffer, 0, 256);
813            ReadMessage(miss[activeMission].services[sourceID].socketFD, buffer);
814            if(!strcmp(buffer, "TF")){
815                ReadMessage(miss[activeMission].services[sourceID].socketFD, buffer);
816                data.append(buffer);
817                data.append("@");
818            }
819            else{
820                data.append(buffer);
821                data.append("@");
822                memset(buffer, 0, 256);
823                ReadMessage(miss[activeMission].services[sourceID].socketFD, buffer);
824                data.append(buffer);
825                data.append("@");
826            }
827        }
828        //printf("SML: putting output data into DB for ID#=%d\n", sourceID);
829
830        strcpy(_data_DB->command, "insert or replace into ");
831        strcat(_data_DB->command, _data_DB->tablename);
832        strcat(_data_DB->command, " (");
833        strcat(_data_DB->command, cols[0]);
834        strcat(_data_DB->command, ", ");
835        strcat(_data_DB->command, cols[1]);
836        strcat(_data_DB->command, ") ");
837        strcat(_data_DB->command, " values('");
838        strcat(_data_DB->command, miss[activeMission].services[sourceID].output[j].c_str());
839        strcat(_data_DB->command, "', '");
840        strcat(_data_DB->command, data.c_str());
841        strcat(_data_DB->command, "');");
842        char *errorMsg;
843        rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
844        if( rc!=SQLITE_OK && rc!=101 )
845            fprintf(stderr, "SQL error: %s\n", errorMsg);
846        //printf("S: done putting ouptut data into DB for ID#='%d', data=%s\n", sourceID, data.c_str());
847        j++;
848        data.clear();
849    }
850    //printf("done transact data!\n");
851    LOG("ServiceManagementLayer:: Finished with data transaction.\n");
852
853
854    /*printf("\n\n\n");
855    // generate commandi
856    strcpy(_data_DB->command, "select ");
857    strcat(_data_DB->command, _data_DB->tablename);
858    strcat(_data_DB->command, ".* from ");
859    strcat(_data_DB->command, _data_DB->tablename);
860    strcat(_data_DB->command, ";");
861
862    // execute print (select all)  command   
863    char *errorMsg;
864    int rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
865    if( rc!=SQLITE_OK && rc!=101 )
866        fprintf(stderr, "SQL error: %s\n", errorMsg);
867    printf("database %s, table %s:\n", _data_DB->filename, _data_DB->tablename);
868    printf("\n\n\n");*/
869}
870
871
872
873/* CALLED BY: MessageHandler
874 * INPUTS: <none>
875 * OUTPUTS: <none>
876 *
877 * DESCRIPTION: This function works by first sending the inputs from the shell to the appropriate components
878 * The first service should begin immeadiately, as should any others who have all of their input paramaters
879 * When they complete, the output path is found and the data is transfered as it becomes available
880 * Presumably at this point the second function has all of it's paramaters, so it begins to compute, and the cycle repeats
881 * If the generated output is an overall output, it is sent on to the shell
882 * "if" and "while" statements are handled by setting up a faux service that has a true input, a false input, and a boolean flag
883 * If the true input is non-NULL and the flag is true, the statements execute
884 * Likewise, if the false input is non-NULL and the flag is false, the statements execute
885 * These flags are set during execution any time one of these faux services' inputs appear in an output statement 
886 * 
887 *
888 * Rules for active missions (currently)
889 * -Three inputs/outputs per service and per mission
890 * -Inputs simply define a path, so multiple variables can be transmitted over the same input
891 * -Each component that sends data must include the "output_finished" statement after each output is finished sending it's data
892 * -All ordering constraints have been relaxed in this version; all data is stored locally and only sent when requested
893 * -If support fully implemented
894 * -Conditions must be boolean flags
895 * -Flags are set by putting either the character string "true" or "false" on the buffer
896 * -IMPORTANT: DB uses '@' to seperate individual statements; using '@' in the data stream will result in incorrect behavior
897 */
898
899//IF-IF-IF
900//IF-IF-WHILE
901//IF-WHILE
902//WHILE
903void
904ServiceManagementLayer::PerformActiveMission()
905{
906    uint16_t i = 0;
907    std::string data_param, data_obsv, data;
908    std::string input;
909    std::string check;
910    char buffer[256];
911    char* cols[] = {(char *)"Tag", (char *)"Data"};
912    //Get the inputs
913    memset(buffer, 0, 256);
914    ReadMessage(shellSocketFD, buffer);
915    LOG("ServiceManagementLayer:: Received PerformActiveMission command.\n");
916        data_obsv.append(buffer);
917        data_obsv.append("@");
918
919    int t = atoi(buffer);
920   // printf("****%d****\n", t);
921    for(int k = 0; k < t; k++) {
922        memset(buffer, 0, 256);
923        ReadMessage(shellSocketFD, buffer);
924        data_obsv.append(buffer);
925        data_obsv.append("@");
926   
927        memset(buffer, 0, 256);
928        ReadMessage(shellSocketFD, buffer);
929        data_obsv.append(buffer);
930        data_obsv.append("@");
931        //printf("data=%s\n", data_obsv.c_str());
932    }
933
934        strcpy(_data_DB->command, "insert into ");
935        strcat(_data_DB->command, _data_DB->tablename);
936        strcat(_data_DB->command, " (");
937        strcat(_data_DB->command, cols[0]);
938        strcat(_data_DB->command, ", ");
939        strcat(_data_DB->command, cols[1]);
940        strcat(_data_DB->command, ") ");
941        strcat(_data_DB->command, " values('observables', '");
942        strcat(_data_DB->command, data_obsv.c_str());
943        strcat(_data_DB->command, "');");
944        char *errorMsg;
945        int rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
946        if( rc!=SQLITE_OK && rc!=101 )
947            fprintf(stderr, "SQL error: %s\n", errorMsg);
948
949    /* Receive Set of Parameters */
950    memset(buffer, 0, 256);
951    ReadMessage(shellSocketFD, buffer);
952        data_param.append(buffer);
953        data_param.append("@");
954    t=atoi(buffer);
955    for(int k = 0; k < t; k++) {
956        memset(buffer, 0, 256);
957        ReadMessage(shellSocketFD, buffer);
958        data_param.append(buffer);
959        data_param.append("@");
960   
961        memset(buffer, 0, 256);
962        ReadMessage(shellSocketFD, buffer);
963        data_param.append(buffer);
964        data_param.append("@");
965    }
966        //printf("data=%s\n", data_param.c_str());
967
968        strcpy(_data_DB->command, "insert into ");
969        strcat(_data_DB->command, _data_DB->tablename);
970        strcat(_data_DB->command, " (");
971        strcat(_data_DB->command, cols[0]);
972        strcat(_data_DB->command, ", ");
973        strcat(_data_DB->command, cols[1]);
974        strcat(_data_DB->command, ") ");
975        strcat(_data_DB->command, " values('paramaters', '");
976        strcat(_data_DB->command, data_param.c_str());
977        strcat(_data_DB->command, "');");
978        rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
979        if( rc!=SQLITE_OK && rc!=101 )
980            fprintf(stderr, "SQL error: %s\n", errorMsg);
981
982
983    /*printf("\n\n\n");
984    // generate commandi
985    strcpy(_data_DB->command, "select ");
986    strcat(_data_DB->command, _data_DB->tablename);
987    strcat(_data_DB->command, ".* from ");
988    strcat(_data_DB->command, _data_DB->tablename);
989    strcat(_data_DB->command, ";");
990
991    // execute print (select all)  command 
992    rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
993    if( rc!=SQLITE_OK && rc!=101 )
994        fprintf(stderr, "SQL error: %s\n", errorMsg);
995    printf("database %s, table %s:\n", _data_DB->filename, _data_DB->tablename);
996    printf("\n\n\n");*/
997
998
999
1000
1001   // printf("done\n");
1002    i=0;
1003    data.clear();
1004    while(i < miss[activeMission].numServices)
1005    {
1006        if(miss[activeMission].services[i].name.compare("if")==0)
1007        {
1008           // printf("L0:if detected\n");
1009            input.clear();
1010            check.clear();
1011            if(!miss[activeMission].services[i].input[0].empty()){
1012                input=miss[activeMission].services[i].input[0];
1013                check = "1@true@";
1014            }
1015            else{
1016                input=miss[activeMission].services[i].input[1];
1017                check = "1@false@";
1018            }
1019            //printf("L0:input=%s\n", input.c_str());
1020
1021            strcpy(_data_DB->command, "SELECT ");
1022            strcat(_data_DB->command, _data_DB->tablename);
1023            strcat(_data_DB->command, ".* from ");
1024            strcat(_data_DB->command, _data_DB->tablename);
1025            strcat(_data_DB->command, " where Tag==");
1026            sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1027            sqlite3_stmt * pStatement;
1028            rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1029            if (rc == SQLITE_OK){
1030                if (sqlite3_step(pStatement) == SQLITE_ROW)
1031                     data = (const char *) sqlite3_column_text(pStatement, 1);
1032                else {
1033                        printf("1 data_DB:: Data not yet in DB. %d\n", i);
1034                        rc=31337;
1035                }
1036            } else {
1037                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1038            }
1039
1040            sqlite3_finalize(pStatement);
1041           // printf("L0:data=%s, check=%s\n", data.c_str(), check.c_str());
1042           // printf("L0:--- %d  %d---\n", miss[activeMission].services[i].num_conds, i);
1043            if(data.compare(check)==0){
1044                //printf("L0:if taken\n");
1045               
1046                for(int k = i + 1; k <= i + miss[activeMission].services[i].num_conds; k++){
1047                        //printf("k=%d\n", k);
1048                        if(miss[activeMission].services[k].name.compare("if")==0)
1049                        {
1050                            //printf("L1:if detected\n");
1051                            input.clear();
1052                            check.clear();
1053                            if(!miss[activeMission].services[k].input[0].empty()){
1054                                input=miss[activeMission].services[k].input[0];
1055                                check = "1@true@";
1056                            }
1057                            else{
1058                                input=miss[activeMission].services[k].input[1];
1059                                check = "1@false@";
1060                            }
1061                            //printf("input=%s\n", input.c_str());
1062
1063                            strcpy(_data_DB->command, "SELECT ");
1064                            strcat(_data_DB->command, _data_DB->tablename);
1065                            strcat(_data_DB->command, ".* from ");
1066                            strcat(_data_DB->command, _data_DB->tablename);
1067                            strcat(_data_DB->command, " where Tag==");
1068                            sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1069                            sqlite3_stmt * pStatement;
1070                            rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1071                            if (rc == SQLITE_OK){
1072                                if (sqlite3_step(pStatement) == SQLITE_ROW)
1073                                     data = (const char *) sqlite3_column_text(pStatement, 1);
1074                                else {
1075                                        printf("1 data_DB:: Data not yet in DB. %d\n", k);
1076                                        rc=31337;
1077                                }
1078                            } else {
1079                                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1080                            }
1081
1082                            sqlite3_finalize(pStatement);
1083                            //printf("L1:data=%s, check=%s\n", data.c_str(), check.c_str());
1084                            //printf("L1:--- %d  %d---\n", miss[activeMission].services[i].num_conds, k);
1085                            if(data.compare(check)==0){
1086                                //printf("L1:if taken\n");
1087                                for(int j = k + 1; j <= k + miss[activeMission].services[k].num_conds; j++){
1088                                   // printf("j=%d\n", k);
1089                                    //printf("name!!!! = %s\n", miss[activeMission].services[j].name.c_str());
1090                                    if(miss[activeMission].services[j].name.compare("if")==0)
1091                                    {
1092                                           // printf("L2:if detected\n");
1093                                            input.clear();
1094                                            check.clear();
1095                                            if(!miss[activeMission].services[j].input[0].empty()){
1096                                                input=miss[activeMission].services[j].input[0];
1097                                                check = "1@true@";
1098                                            }
1099                                            else{
1100                                                input=miss[activeMission].services[j].input[1];
1101                                                check = "1@false@";
1102                                            }
1103                                            //printf("L2:input=%s\n", input.c_str());
1104
1105                                            strcpy(_data_DB->command, "SELECT ");
1106                                            strcat(_data_DB->command, _data_DB->tablename);
1107                                            strcat(_data_DB->command, ".* from ");
1108                                            strcat(_data_DB->command, _data_DB->tablename);
1109                                            strcat(_data_DB->command, " where Tag==");
1110                                            sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1111                                            sqlite3_stmt * pStatement;
1112                                            rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1113                                            if (rc == SQLITE_OK){
1114                                                if (sqlite3_step(pStatement) == SQLITE_ROW)
1115                                                     data = (const char *) sqlite3_column_text(pStatement, 1);
1116                                                else {
1117                                                        printf("1 data_DB:: Data not yet in DB. %d\n", k);
1118                                                        rc=31337;
1119                                                }
1120                                            } else {
1121                                                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1122                                            }
1123
1124                                            sqlite3_finalize(pStatement);
1125                                           // printf("L2:data=%s, check=%s\n", data.c_str(), check.c_str());
1126                                           // printf("L2:--- %d  %d---\n", miss[activeMission].services[i].num_conds, k);
1127                                            if(data.compare(check)==0){
1128                                                //printf("L2:if taken\n");
1129                                                for(int p = j + 1; p <= j + miss[activeMission].services[j].num_conds; p++)
1130                                                    TransactData(p);
1131                                            }
1132                                            else{
1133                                                //printf("L2:if not taken %d\n", miss[activeMission].services[j].num_conds);
1134                                            }
1135                                        j+=miss[activeMission].services[j].num_conds;
1136                                    }
1137
1138                                    else if(miss[activeMission].services[j].name.compare("while")==0)
1139                                    {
1140                                        //printf("while detected\n");
1141                                        while(true){
1142                                            data.clear();
1143                                            input.clear();
1144                                            check.clear();
1145                                            if(!miss[activeMission].services[j].input[0].empty()){
1146                                                input=miss[activeMission].services[j].input[0];
1147                                                check = "1@true@";
1148                                            }
1149                                            else{
1150                                                input=miss[activeMission].services[j].input[1];
1151                                                check = "1@false@";
1152                                            }
1153                                            strcpy(_data_DB->command, "select ");
1154                                            strcat(_data_DB->command, _data_DB->tablename);
1155                                            strcat(_data_DB->command, ".* from ");
1156                                            strcat(_data_DB->command, _data_DB->tablename);
1157                                            strcat(_data_DB->command, " where Tag==");
1158                                            sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1159                                            sqlite3_stmt * pStatement;
1160                                            rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1161                                            if (rc == SQLITE_OK){
1162                                                if (sqlite3_step(pStatement) == SQLITE_ROW)
1163                                                    data = (const char *) sqlite3_column_text(pStatement, 1);
1164                                                else
1165                                                    printf("1 data_DB:: Data not yet in DB. %d\n", i);
1166                                            }
1167                                            else {
1168                                                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1169                                            }
1170
1171                                            sqlite3_finalize(pStatement);
1172                                            printf("data=%s, check=%s\n", data.c_str(), check.c_str());
1173                                            if(data.compare(check)==0){
1174                                                printf("while taken\n");
1175                                                for(int p = j + 1; p <= j + miss[activeMission].services[j].num_conds; p++)
1176                                                    TransactData(p);
1177                                            }
1178                                            else{
1179                                                printf("while not taken %d\n", miss[activeMission].services[k].num_conds);
1180                                                 j+=miss[activeMission].services[j].num_conds;
1181                                                break;
1182                                            }
1183                                        }
1184                                    }
1185                                    else{
1186                                        printf("L2: nocond transact\n");
1187                                        TransactData(j);}
1188                                    j++;
1189                                }
1190                            }
1191                            else{
1192                                //printf("if not taken %d\n", miss[activeMission].services[k].num_conds);
1193                            }
1194                            k+=miss[activeMission].services[k].num_conds;
1195                        }
1196                        else if(miss[activeMission].services[k].name.compare("while")==0)
1197                        {
1198                            //printf("while detected\n");
1199                            while(true){
1200                                    data.clear();
1201                                    input.clear();
1202                                    check.clear();
1203                                    if(!miss[activeMission].services[k].input[0].empty()){
1204                                        input=miss[activeMission].services[k].input[0];
1205                                        check = "1@true@";
1206                                    }
1207                                    else{
1208                                        input=miss[activeMission].services[k].input[1];
1209                                        check = "1@false@";
1210                                    }
1211                                    strcpy(_data_DB->command, "select ");
1212                                    strcat(_data_DB->command, _data_DB->tablename);
1213                                    strcat(_data_DB->command, ".* from ");
1214                                    strcat(_data_DB->command, _data_DB->tablename);
1215                                    strcat(_data_DB->command, " where Tag==");
1216                                    sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1217                                    sqlite3_stmt * pStatement;
1218                                    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1219                                    if (rc == SQLITE_OK){
1220                                        if (sqlite3_step(pStatement) == SQLITE_ROW)
1221                                            data = (const char *) sqlite3_column_text(pStatement, 1);
1222                                        else
1223                                            printf("1 data_DB:: Data not yet in DB. %d\n", i);
1224                                    }
1225                                    else {
1226                                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1227                                    }
1228
1229                                    sqlite3_finalize(pStatement);
1230                                    printf("data=%s, check=%s\n", data.c_str(), check.c_str());
1231                                    if(data.compare(check)==0){
1232                                        printf("while taken\n");
1233                                        for(int k = i + 1; k <= i + miss[activeMission].services[i].num_conds; k++)
1234                                            TransactData(k);
1235                                    }
1236                                    else{
1237                                        printf("while not taken %d\n", miss[activeMission].services[k].num_conds);
1238                                        k+=miss[activeMission].services[k].num_conds;
1239                                        break;
1240                                    }
1241                            }
1242                        }
1243                        else{
1244                            //printf("L1: nocond transact\n");
1245                            TransactData(k);}
1246                        k++;
1247                }
1248            }
1249            else{
1250                printf("La2 if not taken %d\n", miss[activeMission].services[i].num_conds);
1251            }
1252            //printf("i=%d\n", i);
1253            i+=miss[activeMission].services[i].num_conds;
1254            //printf("i=%d\n", i);
1255        }
1256        else if(miss[activeMission].services[i].name.compare("while")==0)
1257        {
1258            //printf("while detected\n");
1259            while(true){
1260                    data.clear();
1261                    input.clear();
1262                    check.clear();
1263                    if(!miss[activeMission].services[i].input[0].empty()){
1264                        input=miss[activeMission].services[i].input[0];
1265                        check = "1@true@";
1266                    }
1267                    else{
1268                        input=miss[activeMission].services[i].input[1];
1269                        check = "1@false@";
1270                    }
1271                    strcpy(_data_DB->command, "select ");
1272                    strcat(_data_DB->command, _data_DB->tablename);
1273                    strcat(_data_DB->command, ".* from ");
1274                    strcat(_data_DB->command, _data_DB->tablename);
1275                    strcat(_data_DB->command, " where Tag==");
1276                    sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1277                    sqlite3_stmt * pStatement;
1278                    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1279                    if (rc == SQLITE_OK){
1280                        if (sqlite3_step(pStatement) == SQLITE_ROW)
1281                            data = (const char *) sqlite3_column_text(pStatement, 1);
1282                        else
1283                            printf("1 data_DB:: Data not yet in DB. %d\n", i);
1284                    }
1285                    else {
1286                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1287                    }
1288
1289                    sqlite3_finalize(pStatement);
1290                    //printf("data=%s, check=%s\n", data.c_str(), check.c_str());
1291                    if(data.compare(check)==0){
1292                        printf("while taken\n");
1293                        for(int k = i + 1; k <= i + miss[activeMission].services[i].num_conds; k++)
1294                            TransactData(k);
1295                    }
1296                    else{
1297                        printf("while not taken %d\n", miss[activeMission].services[i].num_conds);
1298                        i+=miss[activeMission].services[i].num_conds;
1299                        break;
1300                    }
1301            }
1302        }
1303        else{
1304           // printf("L0 nocond transact\n");
1305            TransactData(i);}
1306        i++;
1307        //printf("i=%d\n", i);
1308    }
1309    i=0;
1310    data.clear();
1311    //get the ouptuts
1312    while(i < 5 && !miss[activeMission].output[i].empty()){
1313        //printf("sending output data to shell\n");
1314        strcpy(_data_DB->command, "select ");
1315        strcat(_data_DB->command, _data_DB->tablename);
1316        strcat(_data_DB->command, ".* from ");
1317        strcat(_data_DB->command, _data_DB->tablename);
1318        strcat(_data_DB->command, " where Tag==");
1319        sprintf(_data_DB->command, "%s'%s';", _data_DB->command, miss[activeMission].output[i].c_str());
1320        sqlite3_stmt * pStatement;
1321        int rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1322        if (rc == SQLITE_OK){
1323            if (sqlite3_step(pStatement) == SQLITE_ROW)
1324                 data.append((const char*) sqlite3_column_text(pStatement, 1));
1325            else {
1326                    printf("data_DB:: Data not yet in DB.\n");
1327                    rc=31337;
1328            }
1329        }
1330        else {
1331            printf("services_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1332        }
1333        //printf("here %s\n", data.c_str());
1334        sqlite3_finalize(pStatement);
1335        char *data_ch = (char *) data.c_str();
1336        char *token = strtok(data_ch, "@");
1337        SendMessage(shellSocketFD, token);
1338        token = strtok(NULL, "@");
1339        while(token){
1340            SendMessage(shellSocketFD, token);
1341            //printf("token1 = %s\n", token);
1342            token = strtok(NULL, "@");
1343            SendMessage(shellSocketFD, token);
1344            //printf("token2 = %s\n", token);
1345            token = strtok(NULL, "@");
1346        }
1347        i++;
1348        data.clear();
1349    }
1350    LOG("ServiceManagementLayer:: Done sending output data to shell from PerformActiveMission.\n");
1351}
1352
1353
1354/* CALLED BY: MessageHandler
1355 * INPUTS: <none>
1356 * OUTPUTS: <none>
1357 *
1358 * DESCRIPTION: Print a list of the services currently registered and the ID's of the components that registered them
1359 */
1360void
1361ServiceManagementLayer::ListServices()
1362{
1363    // generate commandi
1364    strcpy(_services_DB->command, "select ");
1365    strcat(_services_DB->command, _services_DB->tablename);
1366    strcat(_services_DB->command, ".* from ");
1367    strcat(_services_DB->command, _services_DB->tablename);
1368    strcat(_services_DB->command, ";");
1369
1370    // execute print (select all)  command   
1371    char *errorMsg;
1372    int rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
1373    if( rc!=SQLITE_OK && rc!=101 )
1374        fprintf(stderr, "SQL error: %s\n", errorMsg);
1375    printf("database %s, table %s:\n", _services_DB->filename, _services_DB->tablename);
1376}
1377
1378/* CALLED BY: Reset
1379 * INPUTS: <none>
1380 * OUTPUTS: <none>
1381 *
1382 * DESCRIPTION: Clear and reinitialize the mission array, then reload the configuration file
1383 */
1384void
1385ServiceManagementLayer::ReloadConfiguration()
1386{
1387    LOG("ServiceManagementLayer:: Reloading Configuration.\n");
1388    free(miss);
1389    miss = new Mission[10];
1390    for(int i = 0; i < 10; i++)
1391        miss[i].services = new Service[20];
1392    LoadConfiguration(_SML_Config, miss);
1393}
1394
1395/* CALLED BY: constructor
1396 * INPUTS: |SML_Config| Address (either relitive or full) of the XML file containing mission data
1397 *         |mList| Mission array to be modified
1398 * OUTPUTS: <none>
1399 *
1400 * DESCRIPTION: IMPORTANT - See formatting instructions for correct parsing of data
1401 * Can currently handle 3 inputs and 3 outputs per service, but easily expandable
1402 * Also, can handle one layer of nested conditional statements, but could
1403 * be expanded to meet additional needs.  Only support now is for straight bool flags,
1404 * but support could be added for more complex conditionals later.
1405 *
1406 * Components assigned to mission during "set active mission" stage so that
1407 * components can still continue to register after the configuration is loaded
1408 */
1409void
1410ServiceManagementLayer::LoadConfiguration(const char *SML_Config, Mission* &mList)
1411{
1412    TiXmlElement *pMission;
1413    TiXmlElement *pService;
1414    TiXmlElement *pChild0, *pChild1, *pChild2, *pChild3, *pChild4;
1415    TiXmlHandle hRoot(0);
1416    //printf("ServiceManagementLayer:: Loading Configuration.\n");
1417    TiXmlDocument doc(".");
1418    doc.LoadFile(SML_Config);
1419    bool loadOkay = doc.LoadFile();
1420    if(!loadOkay)
1421        printf("Loading SML configuration failed: %s\n", SML_Config);
1422
1423    TiXmlHandle hDoc(&doc);
1424   
1425    pMission = hDoc.FirstChildElement().Element();
1426
1427    if(!pMission)
1428        printf("No valid root!");
1429
1430    hRoot = TiXmlHandle(pMission);
1431    pService = pMission->FirstChildElement();
1432    int32_t mission_num = 0;
1433    //Iterate through the missions
1434    for(pChild0 = pMission->FirstChildElement(); pChild0 ; \
1435        pChild0 = pChild0->NextSiblingElement())
1436    {
1437        int32_t service_num = 0;
1438        uint16_t cond_array[] = {0, 0, 0};
1439        //printf("mission_num = %d\n", mission_num);
1440        //memset(cond_array, 0, 2);
1441       
1442        for(pChild1  = pChild0->FirstChildElement(); pChild1; \
1443            pChild1  = pChild1->NextSiblingElement())
1444        {
1445            int32_t conditional_0 = service_num;
1446            for(pChild2 = pChild1->FirstChildElement(); \
1447                pChild2; pChild2 = pChild2->NextSiblingElement())
1448            {
1449                service_num++;
1450                int32_t conditional_1 = service_num;
1451                for(pChild3 = pChild2->FirstChildElement(); \
1452                    pChild3; pChild3 = pChild3 ->NextSiblingElement())
1453                {
1454                    service_num++;
1455                    int32_t conditional_2 = service_num;
1456                        for(pChild4 = pChild3->FirstChildElement(); \
1457                            pChild4; pChild4 = pChild4 ->NextSiblingElement())
1458                        {
1459                            service_num++;
1460                            mList[mission_num].services[service_num].name = pChild4->Attribute("name");
1461                            if(pChild4->Attribute("input1"))
1462                                mList[mission_num].services[service_num].input[0] = pChild4->Attribute("input1");
1463                            if(pChild4->Attribute("input2"))
1464                                mList[mission_num].services[service_num].input[1] = pChild4->Attribute("input2");
1465                            if(pChild4->Attribute("input3"))
1466                                mList[mission_num].services[service_num].input[2] = pChild4->Attribute("input3");
1467                            if(pChild4->Attribute("input4"))
1468                                mList[mission_num].services[service_num].input[3] = pChild4->Attribute("input4");
1469                            if(pChild4->Attribute("input5"))
1470                                mList[mission_num].services[service_num].input[4] = pChild4->Attribute("input5");
1471                            if(pChild4->Attribute("output1"))
1472                                mList[mission_num].services[service_num].output[0] = pChild4->Attribute("output1");
1473                            if(pChild4->Attribute("output2"))
1474                                mList[mission_num].services[service_num].output[1] = pChild4->Attribute("output2");
1475                            if(pChild4->Attribute("output3"))
1476                                mList[mission_num].services[service_num].output[2] = pChild4->Attribute("output3");
1477                            if(pChild4->Attribute("output4"))
1478                                mList[mission_num].services[service_num].output[3] = pChild4->Attribute("output4");
1479                            if(pChild4->Attribute("output5"))
1480                                mList[mission_num].services[service_num].output[4] = pChild4->Attribute("output5");
1481                            cond_array[2]++;
1482                        }
1483                        if(!strcmp(pChild3->Value(), "shell")) {
1484                            mList[mission_num].services[conditional_2].name = pChild3->Value();
1485                            mList[mission_num].services[conditional_2].output[0] = pChild3->Attribute("output1");
1486                //printf("2shell detected\n");
1487                        }
1488                        else if(conditional_2 != service_num){
1489                            mList[mission_num].services[conditional_2].name = pChild3->Value();
1490                            if(pChild3->Attribute("input_t"))
1491                                mList[mission_num].services[conditional_2].input[0] = pChild3->Attribute("input_t");
1492                            if(pChild3->Attribute("input_f"))
1493                                mList[mission_num].services[conditional_2].input[1] = pChild3->Attribute("input_f");
1494                        }
1495                        else{
1496                            mList[mission_num].services[service_num].name = pChild3->Attribute("name");
1497                            if(pChild3->Attribute("input1"))
1498                                mList[mission_num].services[service_num].input[0] = pChild3->Attribute("input1");
1499                            if(pChild3->Attribute("input2"))
1500                                mList[mission_num].services[service_num].input[1] = pChild3->Attribute("input2");
1501                            if(pChild3->Attribute("input3"))
1502                                mList[mission_num].services[service_num].input[2] = pChild3->Attribute("input3");
1503                            if(pChild3->Attribute("input4"))
1504                                mList[mission_num].services[service_num].input[3] = pChild3->Attribute("input4");
1505                            if(pChild3->Attribute("input5"))
1506                                mList[mission_num].services[service_num].input[4] = pChild3->Attribute("input5");
1507                            if(pChild3->Attribute("output1"))
1508                                mList[mission_num].services[service_num].output[0] = pChild3->Attribute("output1");
1509                            if(pChild3->Attribute("output2"))
1510                                mList[mission_num].services[service_num].output[1] = pChild3->Attribute("output2");
1511                            if(pChild3->Attribute("output3"))
1512                                mList[mission_num].services[service_num].output[2] = pChild3->Attribute("output3");
1513                            if(pChild3->Attribute("output4"))
1514                                mList[mission_num].services[service_num].output[3] = pChild3->Attribute("output4");
1515                            if(pChild3->Attribute("output5"))
1516                                mList[mission_num].services[service_num].output[4] = pChild3->Attribute("output5");
1517                        }
1518                        mList[mission_num].services[conditional_2].num_conds = cond_array[2];
1519                        cond_array[1]+=cond_array[2]+1;
1520                        //printf("cond_array[2]%d\n", cond_array[2]);
1521                        cond_array[2] = 0;
1522
1523
1524                }
1525                //printf("here\n");
1526                if(!strcmp(pChild2->Value(), "shell")) {
1527                    mList[mission_num].services[conditional_1].name = pChild2->Value();
1528                    mList[mission_num].services[conditional_1].output[0] = pChild2->Attribute("output1");
1529                //printf("1shell detected\n");
1530                }
1531                else if(conditional_1 != service_num){
1532                    mList[mission_num].services[conditional_1].name = pChild2->Value();
1533                    if(pChild2->Attribute("input_t"))
1534                        mList[mission_num].services[conditional_1].input[0] = pChild2->Attribute("input_t");
1535                    if(pChild2->Attribute("input_f"))
1536                        mList[mission_num].services[conditional_1].input[1] = pChild2->Attribute("input_f");
1537                }
1538                else{
1539                    mList[mission_num].services[service_num].name = pChild2->Attribute("name");
1540                    if(pChild2->Attribute("input1"))
1541                        mList[mission_num].services[service_num].input[0] = pChild2->Attribute("input1");
1542                    if(pChild2->Attribute("input2"))
1543                        mList[mission_num].services[service_num].input[1] = pChild2->Attribute("input2");
1544                    if(pChild2->Attribute("input3"))
1545                        mList[mission_num].services[service_num].input[2] = pChild2->Attribute("input3");
1546                    if(pChild2->Attribute("input4"))
1547                        mList[mission_num].services[service_num].input[3] = pChild2->Attribute("input4");
1548                    if(pChild2->Attribute("input5"))
1549                        mList[mission_num].services[service_num].input[4] = pChild2->Attribute("input5");
1550                    if(pChild2->Attribute("output1"))
1551                        mList[mission_num].services[service_num].output[0] = pChild2->Attribute("output1");
1552                    if(pChild2->Attribute("output2"))
1553                        mList[mission_num].services[service_num].output[1] = pChild2->Attribute("output2");
1554                    if(pChild2->Attribute("output3"))
1555                        mList[mission_num].services[service_num].output[2] = pChild2->Attribute("output3");
1556                    if(pChild2->Attribute("output4"))
1557                        mList[mission_num].services[service_num].output[3] = pChild2->Attribute("output4");
1558                    if(pChild2->Attribute("output5"))
1559                        mList[mission_num].services[service_num].output[4] = pChild2->Attribute("output5");
1560                }
1561
1562                mList[mission_num].services[conditional_1].num_conds = cond_array[1];
1563                cond_array[0]+=cond_array[1]+1;
1564                //printf("cond_array[1]%d\n", cond_array[1]);
1565                cond_array[1] = 0;
1566            }
1567           
1568            if(!strcmp(pChild1->Value(), "shell")) {
1569                //printf("shell detected\n");
1570                mList[mission_num].services[conditional_0].name = pChild1->Value();
1571                mList[mission_num].services[conditional_0].output[0] = pChild1->Attribute("output1");
1572            }
1573            else if(conditional_0 != service_num){
1574                mList[mission_num].services[conditional_0].name = pChild1->Value();
1575                    if(pChild1->Attribute("input_t"))
1576                        mList[mission_num].services[conditional_0].input[0] = pChild1->Attribute("input_t");
1577                    if(pChild1->Attribute("input_f"))
1578                        mList[mission_num].services[conditional_0].input[1] = pChild1->Attribute("input_f");
1579                //printf("---input_t=%s\n", mList[mission_num].services[conditional_0].input[0].c_str());
1580            }
1581            else{
1582                mList[mission_num].services[conditional_0].name = pChild1->Attribute("name");
1583                //printf("name=%s\n", mList[mission_num].services[conditional_0].name.c_str());
1584                if(pChild1->Attribute("input1"))
1585                    mList[mission_num].services[service_num].input[0] = pChild1->Attribute("input1");
1586                if(pChild1->Attribute("input2"))
1587                    mList[mission_num].services[service_num].input[1] = pChild1->Attribute("input2");
1588                if(pChild1->Attribute("input3"))
1589                    mList[mission_num].services[service_num].input[2] = pChild1->Attribute("input3");
1590                if(pChild1->Attribute("input4"))
1591                    mList[mission_num].services[service_num].input[3] = pChild1->Attribute("input4");
1592                if(pChild1->Attribute("input5"))
1593                    mList[mission_num].services[service_num].input[4] = pChild1->Attribute("input5");
1594                if(pChild1->Attribute("output1"))
1595                    mList[mission_num].services[service_num].output[0] = pChild1->Attribute("output1");
1596                if(pChild1->Attribute("output2"))
1597                    mList[mission_num].services[service_num].output[1] = pChild1->Attribute("output2");
1598                if(pChild1->Attribute("output3"))
1599                    mList[mission_num].services[service_num].output[2] = pChild1->Attribute("output3");
1600                if(pChild1->Attribute("output4"))
1601                    mList[mission_num].services[service_num].output[3] = pChild1->Attribute("output4");
1602                if(pChild1->Attribute("output5"))
1603                    mList[mission_num].services[service_num].output[4] = pChild1->Attribute("output4");
1604            }
1605
1606            mList[mission_num].services[conditional_0].num_conds = cond_array[0];
1607            cond_array[0] = 0;
1608            service_num++;
1609        }
1610        //for(int i = 0; i < service_num; i++)
1611         //printf("ttt%d\n", mList[mission_num].services[i].num_conds);
1612       
1613        mList[mission_num].numServices = service_num;
1614        mList[mission_num].name = pChild0->Attribute("name");
1615        mList[mission_num].missionID = atoi(pChild0->Attribute("id"));
1616        if(pChild0->Attribute("input1"))
1617            mList[mission_num].input[0] = pChild0->Attribute("input1");
1618        if(pChild0->Attribute("input2"))
1619            mList[mission_num].input[1] = pChild0->Attribute("input2");
1620        if(pChild0->Attribute("input3"))
1621            mList[mission_num].input[2] = pChild0->Attribute("input3");
1622        if(pChild0->Attribute("input4"))
1623            mList[mission_num].input[3] = pChild0->Attribute("input4");
1624        if(pChild0->Attribute("input5"))
1625            mList[mission_num].input[4] = pChild0->Attribute("input4");
1626        if(pChild0->Attribute("output1"))
1627            mList[mission_num].output[0] = pChild0->Attribute("output1");
1628        if(pChild0->Attribute("output2"))
1629            mList[mission_num].output[1] = pChild0->Attribute("output2");
1630        if(pChild0->Attribute("output3"))
1631            mList[mission_num].output[2] = pChild0->Attribute("output3");
1632        if(pChild0->Attribute("output4"))
1633            mList[mission_num].output[3] = pChild0->Attribute("output4");
1634        if(pChild0->Attribute("output5"))
1635            mList[mission_num].output[4] = pChild0->Attribute("output5");
1636        //printf("mis, input1=%s, output1=%s\n", mList[mission_num].input[0].c_str(), mList[mission_num].output[0].c_str());
1637        //printf("NUMSERVICES = %d\n", mList[mission_num].numServices);
1638        mission_num++;
1639    }
1640}
1641
1642/* CALLED BY: MessageHandler
1643 * INPUTS: |ID| The ID number of the engine to be registered
1644 * OUTPUTS: <none>
1645 *
1646 * DESCRIPTION: Sends a registration message onto the shell and sends the ACK back to the component
1647 */
1648void
1649ServiceManagementLayer::RegisterCognitiveEngine(int32_t ID)
1650{
1651    //LOG("SML::regcogeng");
1652    SendMessage(shellSocketFD, "register_engine_cognitive");
1653
1654   // printf("SSFD = %d\n", shellSocketFD);
1655    LOG("ServiceManagementLayer:: CE registration message forwarded to shell.\n");
1656    char buffer[256];
1657    memset(buffer, 0, 256);
1658    ReadMessage(shellSocketFD, buffer);
1659    //printf("ServiceManagementLayer::buffer = %s\n", buffer);
1660    SendMessage(CE_List[ID].FD, buffer);
1661
1662    TransferRadioConfiguration(ID);
1663    memset(buffer, 0, 256);
1664    //printf("start trans exp\n");
1665    TransferExperience(ID);
1666    memset(buffer, 0, 256);
1667    numberOfCognitiveEngines++;
1668    CE_Present = true;
1669    //printf("done registering CE!\n");
1670}
1671
1672/* CALLED BY: MessageHandler
1673 * INPUTS: |ID| The ID number of the engine to have it's services deregistered
1674 * OUTPUTS: <none>
1675 *
1676 * DESCRIPTION: Deletes individual services from the DB
1677 * NOTE THAT this function only needs to be called if service deregistration is going
1678 * to be done at a different time than component deregistration; it is handled
1679 * more efficiently and directly during that deregistration process.
1680 */
1681void
1682ServiceManagementLayer::DeregisterServices(int32_t ID)
1683{
1684    char buffer[256];
1685    memset(buffer, 0, 256);
1686    ReadMessage(CE_List[ID].FD, buffer);
1687    strcpy(_services_DB->command, "DELETE FROM ");
1688    strcat(_services_DB->command, _services_DB->tablename);
1689    strcat(_services_DB->command, " WHERE ID_Num IN (SELECT");
1690    sprintf(_services_DB->command, " %s %d",_services_DB->command, ID);
1691    strcat(_services_DB->command, " FROM ");
1692    strcat(_services_DB->command, _services_DB->tablename);
1693    strcat(_services_DB->command, " WHERE Service_Name");
1694    strcat(_services_DB->command, "==");
1695    sprintf(_services_DB->command, "%s'%s');", _services_DB->command, buffer);
1696    char *errorMsg;
1697    int rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
1698    if( rc!=SQLITE_OK && rc!=101 )
1699        fprintf(stderr, "SQL error: %s\n", errorMsg);
1700}
1701
1702/* CALLED BY: MessageHandler
1703 * INPUTS: |ID| The ID number of the engine to have it's services deregistered
1704 * OUTPUTS: <none>
1705 *
1706 * DESCRIPTION: Deletes the contact info for the cognitive engine, forwards a deregistration message to the shell
1707 * Also, deletes the services from the DB
1708 */
1709void
1710ServiceManagementLayer::DeregisterCognitiveEngine(int32_t ID)
1711{
1712    LOG("ServiceManagementLayer:: CE deregistration message forwarded to shell.\n");
1713
1714    numberOfCognitiveEngines--;
1715    if(numberOfCognitiveEngines == 0)
1716        CE_Present = false;
1717
1718    SendMessage(shellSocketFD, "deregister_engine_cognitive");
1719    char buffer[256];
1720    memset(buffer, 0, 256);
1721    ReadMessage(shellSocketFD, buffer);
1722    SendMessage(CE_List[ID].FD, buffer);
1723    if(strcmp("deregister_ack", buffer) != 0) {
1724        ERROR(1, "SML:: Failed to close CE socket\n");
1725    }
1726
1727    //Deregister the services
1728    strcpy(_services_DB->command, "DELETE FROM ");
1729    strcat(_services_DB->command, _services_DB->tablename);
1730    strcat(_services_DB->command, " WHERE ");
1731    strcat(_services_DB->command, "ID_Num");
1732    strcat(_services_DB->command, "==");
1733    sprintf(_services_DB->command, "%s%d;", _services_DB->command, ID);
1734    char *errorMsg;
1735    int rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
1736    if( rc!=SQLITE_OK && rc!=101 )
1737        fprintf(stderr, "SQL error: %s\n", errorMsg);
1738
1739
1740    CE_List[ID].FD = -1;
1741    CE_List[ID].ID_num = -1;
1742
1743    LOG("Cognitive Radio Shell:: CE Socket closed for engine #%d.\n", ID);
1744}
1745
1746
1747/* CALLED BY: test class
1748 * INPUTS: <none>
1749 * OUTPUTS: <none>
1750 *
1751 * DESCRIPTION: Sets up a server socket and listens for communication on either that or the shell socket
1752 */
1753void
1754ServiceManagementLayer::StartSMLServer()
1755{
1756    //printf("Ready for CE Signal! (registration done)\n");
1757    struct timeval selTimeout;
1758    int32_t running = 1;
1759    int32_t port, rc, new_sd = 1;
1760    int32_t desc_ready = 1;
1761                //If there is, call the MessageHandler with the Shell_Msg code of -1
1762    fd_set sockSet, shellSet;
1763
1764    cogEngSrv = CreateTCPServerSocket(SMLport);
1765    int32_t maxDescriptor = cogEngSrv;
1766
1767    if(InitializeTCPServerPort(cogEngSrv) == -1)
1768        ERROR(1,"Error initializing primary port\n");
1769
1770    int i = 10000000;  //TODO change to "running" if endpoint can be reached
1771    while (running) {
1772        i--;
1773        /* Zero socket descriptor vector and set for server sockets */
1774        /* This must be reset every time select() is called */
1775        FD_ZERO(&sockSet);
1776        FD_SET(cogEngSrv, &sockSet);
1777        for(uint16_t k = 0; k < Current_ID; k++){
1778            if(CE_List[k].ID_num != -1)
1779                FD_SET(CE_List[k].FD, &sockSet);
1780        }
1781            //printf("k=%d, CID=%d\n", k, CE_List[k].FD);
1782
1783        /* Timeout specification */
1784        /* This must be reset every time select() is called */
1785        selTimeout.tv_sec = 0;       /* timeout (secs.) */
1786        selTimeout.tv_usec = 0;            /* 0 microseconds */
1787        //Changed both to zero so that select will check messages from the shell instead of blocking
1788        //when there is no command from the CE's to be processed
1789
1790        //Check if there is a message on the socket waiting to be read
1791        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
1792        //printf("rc=%d\n", rc);
1793        if(rc == 0){
1794            //LOG("No echo requests for %i secs...Server still alive\n", timeout);
1795       
1796            FD_ZERO(&shellSet);
1797            FD_SET(shellSocketFD, &shellSet);
1798            selTimeout.tv_sec = 0;
1799            selTimeout.tv_usec = 0;
1800            //Check if there is a message on the shell socket ready to be processed
1801            select(shellSocketFD + 1, &shellSet, NULL, NULL, &selTimeout);
1802            //printf("rc2=%d\n", rc2);
1803                //If there is, call the MessageHandler with the Shell_Msg code of -1
1804            if(FD_ISSET(shellSocketFD, &shellSet)){
1805                //printf("shell_msg, %d\n", rc2);
1806                MessageHandler(-1);}
1807        }
1808        else {
1809            desc_ready = rc;
1810            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
1811                if(FD_ISSET(port, &sockSet)) {
1812                    desc_ready -= 1;
1813
1814                    //Check if request is new or on an existing open descriptor
1815                    if(port == cogEngSrv) {
1816                        //If new, assign it a descriptor and give it an ID
1817                        new_sd = AcceptTCPConnection(port);
1818                         
1819                        if(new_sd < 0)
1820                            break;
1821
1822                        CE_List[Current_ID].FD = new_sd;
1823                        CE_List[Current_ID].ID_num = Current_ID;
1824                        MessageHandler(Current_ID);
1825                        Current_ID++;
1826       
1827                        FD_SET(new_sd,&sockSet);
1828                        if(new_sd > maxDescriptor)
1829                           maxDescriptor = new_sd;
1830                    }
1831                    else {
1832                        //If old, figure out which ID it coresponds to and handle it accordingly
1833                        for(uint16_t z = 0; z < Current_ID; z++)
1834                        {
1835                                if(CE_List[z].FD == port){
1836                                        MessageHandler(z);}
1837                        }
1838                    }
1839                }
1840            }
1841        }
1842    }       
1843
1844    /* Close sockets */
1845    close(cogEngSrv);
1846
1847    //delete &cogEngSrv;
1848    return;
1849}
1850
1851
1852
1853
1854    /*TiXmlElement *pMission;
1855    TiXmlElement *pService;
1856    TiXmlElement *pChild0, *pChild1, *pChild2, *pChild3;
1857    TiXmlHandle hRoot(0);
1858    //printf("ServiceManagementLayer:: Loading Configuration.\n");
1859    TiXmlDocument doc(".");
1860    doc.LoadFile(SML_Config);
1861    bool loadOkay = doc.LoadFile();
1862    if(!loadOkay)
1863        printf("Loading SML configuration failed: %s\n", SML_Config);
1864
1865    TiXmlHandle hDoc(&doc);
1866   
1867    pMission = hDoc.FirstChildElement().Element();
1868
1869    if(!pMission)
1870        printf("No valid root!");
1871
1872    hRoot = TiXmlHandle(pMission);
1873    pService = pMission->FirstChildElement();
1874    int32_t mission_num = 0;
1875    //Iterate through the missions
1876    for(pChild0 = pMission->FirstChildElement(); pChild0 ; \
1877        pChild0 = pChild0->NextSiblingElement())
1878    {
1879        int32_t service_num = 0;
1880        uint16_t cond_array[] = {0, 0};
1881        //printf("mission_num = %d\n", mission_num);
1882        memset(cond_array, 0, 2);
1883       
1884        for(pChild1  = pChild0->FirstChildElement(); pChild1; \
1885            pChild1  = pChild1->NextSiblingElement())
1886        {
1887            int32_t conditional_0 = service_num;
1888            for(pChild2 = pChild1->FirstChildElement(); \
1889                pChild2; pChild2 = pChild2->NextSiblingElement())
1890            {
1891                service_num++;
1892                int32_t conditional_1 = service_num;
1893                for(pChild3 = pChild2->FirstChildElement(); \
1894                    pChild3; pChild3 = pChild3 ->NextSiblingElement())
1895                {
1896                    service_num++;
1897                    mList[mission_num].services[service_num].name = pChild3->Attribute("name");
1898                    if(pChild3->Attribute("input1"))
1899                        mList[mission_num].services[service_num].input[0] = pChild3->Attribute("input1");
1900                    if(pChild3->Attribute("input2"))
1901                        mList[mission_num].services[service_num].input[1] = pChild3->Attribute("input2");
1902                    if(pChild3->Attribute("input3"))
1903                        mList[mission_num].services[service_num].input[2] = pChild3->Attribute("input3");
1904                    if(pChild3->Attribute("output1"))
1905                        mList[mission_num].services[service_num].output[0] = pChild3->Attribute("output1");
1906                    if(pChild3->Attribute("output2"))
1907                        mList[mission_num].services[service_num].output[1] = pChild3->Attribute("output2");
1908                    if(pChild3->Attribute("output3"))
1909                        mList[mission_num].services[service_num].output[2] = pChild3->Attribute("output3");
1910                    cond_array[1]++;
1911                }
1912
1913                if(conditional_1 != service_num){
1914                    mList[mission_num].services[conditional_1].name = pChild2->Value();
1915                    if(pChild2->Attribute("input_t"))
1916                        mList[mission_num].services[conditional_1].input[0] = pChild2->Attribute("input_t");
1917                    if(pChild2->Attribute("input_f"))
1918                        mList[mission_num].services[conditional_1].input[1] = pChild2->Attribute("input_f");
1919                }
1920                else{
1921                    mList[mission_num].services[service_num].name = pChild2->Attribute("name");
1922                    if(pChild2->Attribute("input1"))
1923                        mList[mission_num].services[service_num].input[0] = pChild2->Attribute("input1");
1924                    if(pChild2->Attribute("input2"))
1925                        mList[mission_num].services[service_num].input[1] = pChild2->Attribute("input2");
1926                    if(pChild2->Attribute("input3"))
1927                        mList[mission_num].services[service_num].input[2] = pChild2->Attribute("input3");
1928                    if(pChild2->Attribute("output1"))
1929                        mList[mission_num].services[service_num].output[0] = pChild2->Attribute("output1");
1930                    if(pChild2->Attribute("output2"))
1931                        mList[mission_num].services[service_num].output[1] = pChild2->Attribute("output2");
1932                    if(pChild2->Attribute("output3"))
1933                        mList[mission_num].services[service_num].output[2] = pChild2->Attribute("output3");
1934                }
1935
1936                mList[mission_num].services[conditional_1].num_conds = cond_array[1];
1937                cond_array[1] = 0;
1938                cond_array[0]++;
1939            }
1940            if(conditional_0 != service_num){
1941                mList[mission_num].services[conditional_0].name = pChild1->Value();
1942                if(pChild1->Attribute("input_t"))
1943                    mList[mission_num].services[conditional_0].input[0] = pChild1->Attribute("input_t");
1944                if(pChild1->Attribute("input_f"))
1945                    mList[mission_num].services[conditional_0].input[1] = pChild1->Attribute("input_f");
1946                printf("if detected %s, %s\n", pChild1->Attribute("input_f"), pChild1->Attribute("input_t"));
1947            }
1948            else{
1949                mList[mission_num].services[service_num].name = pChild1->Attribute("name");
1950                if(pChild1->Attribute("input1"))
1951                    mList[mission_num].services[service_num].input[0] = pChild1->Attribute("input1");
1952                if(pChild1->Attribute("input2"))
1953                    mList[mission_num].services[service_num].input[1] = pChild1->Attribute("input2");
1954                if(pChild1->Attribute("input3"))
1955                    mList[mission_num].services[service_num].input[2] = pChild1->Attribute("input3");
1956                if(pChild1->Attribute("output1"))
1957                    mList[mission_num].services[service_num].output[0] = pChild1->Attribute("output1");
1958                if(pChild1->Attribute("output2"))
1959                    mList[mission_num].services[service_num].output[1] = pChild1->Attribute("output2");
1960                if(pChild1->Attribute("output3"))
1961                    mList[mission_num].services[service_num].output[2] = pChild1->Attribute("output3");
1962            }
1963
1964            mList[mission_num].services[conditional_0].num_conds = cond_array[0];
1965            //printf("hello\n");
1966           
1967            cond_array[0] = 0;
1968            service_num++;
1969        }
1970        for(int i = 0; i < service_num; i++)
1971                printf("input1=%s, output1=%s\n", mList[mission_num].services[i].input[0].c_str(), mList[mission_num].services[service_num].output[0].c_str());
1972
1973        mList[mission_num].numServices = service_num;
1974        mList[mission_num].name = pChild0->Attribute("name");
1975        mList[mission_num].missionID = atoi(pChild0->Attribute("id"));
1976        if(pChild0->Attribute("input1"))
1977            mList[mission_num].input[0] = pChild0->Attribute("input1");
1978        if(pChild0->Attribute("input2"))
1979            mList[mission_num].input[1] = pChild0->Attribute("input2");
1980        if(pChild0->Attribute("input3"))
1981            mList[mission_num].input[2] = pChild0->Attribute("input3");
1982        if(pChild0->Attribute("output1"))
1983            mList[mission_num].output[0] = pChild0->Attribute("output1");
1984        if(pChild0->Attribute("output2"))
1985            mList[mission_num].output[1] = pChild0->Attribute("output2");
1986        if(pChild0->Attribute("output3"))
1987            mList[mission_num].output[2] = pChild0->Attribute("output3");
1988        printf("input1=%s, outpu1=%s\n", mList[mission_num].input[0].c_str(), mList[mission_num].output[0].c_str());
1989        mission_num++;
1990    }*/
Note: See TracBrowser for help on using the browser.