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

Revision 313, 68.7 KB (checked in by wrodgers, 15 years ago)

Minor changes to finalize LT/GT in IF statements

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