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

Revision 308, 68.5 KB (checked in by wrodgers, 15 years ago)

slight modification to SML

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;
843    int rc;
844    char *errorMsg;
845    char* cols[] = {(char *)"Tag", (char *)"Data"};
846    //Get the inputs
847    memset(buffer, 0, 256);
848    ReadMessage(shellSocketFD, buffer);
849    LOG("ServiceManagementLayer:: Received PerformActiveMission command.\n");
850    //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
851    int32_t t = atoi(buffer);
852    /* Receive Set of Observables */
853    for(int32_t m = 0; m < t; m++) {
854        //printf("data=%s\n", data_obsv.c_str());
855        memset(buffer1, 0, 256);
856        ReadMessage(shellSocketFD, buffer1);
857        strcpy(_data_DB->command, "insert into ");
858        strcat(_data_DB->command, _data_DB->tablename);
859        strcat(_data_DB->command, " (");
860        strcat(_data_DB->command, cols[0]);
861        strcat(_data_DB->command, ", ");
862        strcat(_data_DB->command, cols[1]);
863        strcat(_data_DB->command, ") ");
864        memset(buffer, 0, 256);
865        ReadMessage(shellSocketFD, buffer);
866        sprintf(_data_DB->command, "%s values('%s', '1@%s@%s", _data_DB->command, buffer1, buffer1, buffer);
867        strcat(_data_DB->command, "');");
868        rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
869        if( rc!=SQLITE_OK && rc!=101 )
870            fprintf(stderr, "SQL error: %s\n", errorMsg);
871    }
872
873    /* Receive Set of Parameters */
874    memset(buffer, 0, 256);
875    ReadMessage(shellSocketFD, buffer);
876    t=atoi(buffer);
877    for(int m = 0; m < t; m++) {
878        //printf("data=%s\n", data_obsv.c_str());
879        memset(buffer1, 0, 256);
880        ReadMessage(shellSocketFD, buffer1);
881        strcpy(_data_DB->command, "insert into ");
882        strcat(_data_DB->command, _data_DB->tablename);
883        strcat(_data_DB->command, " (");
884        strcat(_data_DB->command, cols[0]);
885        strcat(_data_DB->command, ", ");
886        strcat(_data_DB->command, cols[1]);
887        strcat(_data_DB->command, ") ");
888        memset(buffer, 0, 256);
889        ReadMessage(shellSocketFD, buffer);
890        sprintf(_data_DB->command, "%s values('%s', '1@%s@%s');", _data_DB->command, buffer1, buffer1, buffer);
891        rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
892        if( rc!=SQLITE_OK && rc!=101 )
893            fprintf(stderr, "SQL error: %s\n", errorMsg);
894    }
895
896
897
898
899    //Receive any other defined inputs
900    /*while(i < 10 && !miss[activeMission].input[i].empty()){
901            //New data being added to DB
902        //printf("inserting data from shell\n");
903        memset(buffer1, 0, 256);
904        ReadMessage(shellSocketFD, buffer1);
905        t=atoi(buffer1);
906        //printf("t=%d\n", t);
907        for(int m = 0; m < t; m++) {
908            data.append("@");
909            memset(buffer, 0, 256);
910            ReadMessage(shellSocketFD, buffer);
911            data.append(buffer);
912            data.append("@");
913            memset(buffer, 0, 256);
914            ReadMessage(shellSocketFD, buffer);
915            data.append(buffer);
916        }
917        //printf("here %s\n", data.c_str());
918        strcpy(_data_DB->command, "insert into ");
919        strcat(_data_DB->command, _data_DB->tablename);
920        strcat(_data_DB->command, " (");
921        strcat(_data_DB->command, cols[0]);
922        strcat(_data_DB->command, ", ");
923        strcat(_data_DB->command, cols[1]);
924        strcat(_data_DB->command, ") ");
925        strcat(_data_DB->command, " values('");
926        strcat(_data_DB->command, miss[activeMission].input[i].c_str());
927        sprintf(_data_DB->command, "%s', '%s%s');", _data_DB->command, buffer1, data.c_str());
928        char *errorMsg;
929        rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
930        if( rc!=SQLITE_OK && rc!=101 )
931            fprintf(stderr, "SQL error: %s\n", errorMsg);
932        //printf("SML: finished adding data from shell on input %d\n", i);
933        i++;
934        data.clear();
935    }*/
936
937
938    //Useful for spotchecking what's in the database
939    /*printf("\n\n\n");
940    // generate commandi
941    strcpy(_data_DB->command, "select ");
942    strcat(_data_DB->command, _data_DB->tablename);
943    strcat(_data_DB->command, ".* from ");
944    strcat(_data_DB->command, _data_DB->tablename);
945    strcat(_data_DB->command, ";");
946
947    // execute print (select all)  command 
948    rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
949    if( rc!=SQLITE_OK && rc!=101 )
950        fprintf(stderr, "SQL error: %s\n", errorMsg);
951    printf("database %s, table %s:\n", _data_DB->filename, _data_DB->tablename);
952    printf("\n\n\n");*/
953
954
955
956
957   // printf("done\n");
958    i=0;
959    int32_t numstatements[3] = {0,0,0};
960    while(i < miss[activeMission].numServices)
961    {
962        if(miss[activeMission].services[i].name.compare("if")==0)
963        {
964           //printf("L0:if detected\n");
965            input.clear();
966            check.clear();
967            int t;
968            for(t = 0; t < 5; t++){
969                if(!miss[activeMission].services[i].output[t].empty()){
970                    //printf("i-numstmts-1 = %d\n", i-numstatements[0]-1);
971                    input=miss[activeMission].services[i-numstatements[0]-1].output[t];
972                    strcpy(_data_DB->command, "SELECT ");
973                    strcat(_data_DB->command, _data_DB->tablename);
974                    strcat(_data_DB->command, ".* from ");
975                    strcat(_data_DB->command, _data_DB->tablename);
976                    strcat(_data_DB->command, " where Tag==");
977                    sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
978                    sqlite3_stmt * pStatement;
979                    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
980                    if (rc == SQLITE_OK){
981                        if (sqlite3_step(pStatement) == SQLITE_ROW)
982                             data = (const char *) sqlite3_column_text(pStatement, 1);
983                        else {
984                                printf("1 data_DB:: Data not yet in DB.\n");
985                                rc=31337;
986                        }
987                    } else {
988                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
989                    }
990                    sqlite3_finalize(pStatement);
991                    //printf("data=%s\n", data.c_str());
992                    token = strtok((char *)data.c_str(), "@");
993                    token = strtok(NULL, "@");
994                    token = strtok(NULL, "@");
995                    //printf("data=%s\n", token);
996                data.clear();
997                    break;
998                }
999            }
1000            //printf("L0:--- %s  %s---\n", miss[activeMission].services[i].output[t].c_str(), token);
1001            bool doit = false;
1002            if(miss[activeMission].services[i].output[t].find(">") != string::npos){
1003                //printf("foundit!\n");
1004                    strcpy(_data_DB->command, "SELECT ");
1005                    strcat(_data_DB->command, _data_DB->tablename);
1006                    strcat(_data_DB->command, ".* from ");
1007                    strcat(_data_DB->command, _data_DB->tablename);
1008                strcat(_data_DB->command, " where Tag==");
1009                    miss[activeMission].services[i].output[t].erase(0, 1);
1010            //printf("here! %s\n", miss[activeMission].services[i].output[t].c_str());
1011                    sprintf(_data_DB->command, "%s'%s';", _data_DB->command, miss[activeMission].services[i].output[t].c_str());
1012                    sqlite3_stmt * pStatement;
1013                    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1014                    if (rc == SQLITE_OK){
1015                        if (sqlite3_step(pStatement) == SQLITE_ROW)
1016                             data = (const char *) sqlite3_column_text(pStatement, 1);
1017                        else {
1018                                printf("1 data_DB:: Data not yet in DB.\n");
1019                                rc=31337;
1020                        }
1021                    } else {
1022                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1023                    }
1024                            sqlite3_finalize(pStatement);
1025                    token = strtok((char *)data.c_str(), "@");
1026                    token = strtok(NULL, "@");
1027                    token = strtok(NULL, "@");
1028                    if(atof(buffer) > atof(token))
1029                        doit=true;
1030                    //printf("%s %s\n", buffer, token);
1031                data.clear();
1032            }
1033            else if (strstr(miss[activeMission].services[i].output[t].c_str(), token))
1034                doit=true;
1035            if(doit){
1036            //if(strstr(miss[activeMission].services[i].output[t].c_str(), token)){
1037                //printf("L0:if taken\n");
1038                for(uint16_t k = i+1; k <= i+miss[activeMission].services[i].num_conds; k++){
1039                        //printf("transacting data for k=%d\n", k);
1040                    //printf("%s---%d\n", miss[activeMission].services[k].name.c_str(), k);
1041                    if(miss[activeMission].services[k].name.compare("if")==0){
1042                        //printf("L1:if detected\n");
1043                            input.clear();
1044                            check.clear();
1045                            for(t = 0; t < 5; t++){
1046                                if(!miss[activeMission].services[k].output[t].empty()){
1047                                    //printf("i-numstmts = %d\n", i-numstatements-1);
1048                                    input=miss[activeMission].services[k-numstatements[1]-1].output[t];
1049                                    strcpy(_data_DB->command, "SELECT ");
1050                                    strcat(_data_DB->command, _data_DB->tablename);
1051                                    strcat(_data_DB->command, ".* from ");
1052                                    strcat(_data_DB->command, _data_DB->tablename);
1053                                    strcat(_data_DB->command, " where Tag==");
1054                                    sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1055                                    sqlite3_stmt * pStatement;
1056                                    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1057                                    if (rc == SQLITE_OK){
1058                                        if (sqlite3_step(pStatement) == SQLITE_ROW)
1059                                             data = (const char *) sqlite3_column_text(pStatement, 1);
1060                                        else {
1061                                                printf("1 data_DB:: Data not yet in DB.\n");
1062                                                rc=31337;
1063                                        }
1064                                    } else {
1065                                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1066                                    }
1067                                    sqlite3_finalize(pStatement);
1068                                    //printf("data=%s\n", data.c_str());
1069                                    token = strtok((char *)data.c_str(), "@");
1070                                    token = strtok(NULL, "@");
1071                                    token = strtok(NULL, "@");
1072                                    //printf("data=%s\n", token);
1073                                    data.clear();
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                                    strcpy(_data_DB->command, "SELECT ");
1083                                    strcat(_data_DB->command, _data_DB->tablename);
1084                                    strcat(_data_DB->command, ".* from ");
1085                                    strcat(_data_DB->command, _data_DB->tablename);
1086                                    strcat(_data_DB->command, " where Tag==");
1087                                    miss[activeMission].services[k].output[t].erase(0, 1);
1088                                    sprintf(_data_DB->command, "%s'%s';", _data_DB->command, miss[activeMission].services[k].output[t].c_str());
1089                                    sqlite3_stmt * pStatement;
1090                                    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1091                                    if (rc == SQLITE_OK){
1092                                        if (sqlite3_step(pStatement) == SQLITE_ROW)
1093                                             data = (const char *) sqlite3_column_text(pStatement, 1);
1094                                        else {
1095                                                printf("1 data_DB:: Data not yet in DB.\n");
1096                                                rc=31337;
1097                                        }
1098                                    } else {
1099                                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1100                                    }
1101                                    sqlite3_finalize(pStatement);
1102                                    token = strtok((char *)data.c_str(), "@");
1103                                    token = strtok(NULL, "@");
1104                                    token = strtok(NULL, "@");
1105                                if(atof(buffer) > atof(token))
1106                                    doit=true;
1107                                data.clear();
1108                            }
1109                            else if (strstr(miss[activeMission].services[k].output[t].c_str(), token))
1110                                doit=true;
1111                            if(doit){
1112                                //printf("L1:if taken\n");
1113                                for(uint16_t j = k+1; j <= k+miss[activeMission].services[k].num_conds; j++){
1114                                    //printf("transacting data for k=%d\n", k);
1115                                    //printf("%s---%d\n", miss[activeMission].services[j].name.c_str(), j);
1116                                    if(miss[activeMission].services[j].name.compare("if")==0){
1117                                        //printf("L2:if detected\n");
1118                                            input.clear();
1119                                            check.clear();
1120                                            for(t = 0; t < 5; t++){
1121                                                if(!miss[activeMission].services[j].output[t].empty()){
1122                                                    //printf("i-numstmts = %d\n", i-numstatements-1);
1123                                                    input=miss[activeMission].services[j-numstatements[2]-1].output[t];
1124                                                    strcpy(_data_DB->command, "SELECT ");
1125                                                    strcat(_data_DB->command, _data_DB->tablename);
1126                                                    strcat(_data_DB->command, ".* from ");
1127                                                    strcat(_data_DB->command, _data_DB->tablename);
1128                                                    strcat(_data_DB->command, " where Tag==");
1129                                                    sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1130                                                    sqlite3_stmt * pStatement;
1131                                                    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1132                                                    if (rc == SQLITE_OK){
1133                                                        if (sqlite3_step(pStatement) == SQLITE_ROW)
1134                                                             data = (const char *) sqlite3_column_text(pStatement, 1);
1135                                                        else {
1136                                                                printf("1 data_DB:: Data not yet in DB.\n");
1137                                                                rc=31337;
1138                                                        }
1139                                                    } else {
1140                                                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1141                                                    }
1142                                                    sqlite3_finalize(pStatement);
1143                                                    //printf("data=%s\n", data.c_str());
1144                                                    token = strtok((char *)data.c_str(), "@");
1145                                                    token = strtok(NULL, "@");
1146                                                    token = strtok(NULL, "@");
1147                                                    //printf("data=%s\n", token);
1148                                                    data.clear();
1149                                                    break;
1150                                                }
1151                                            }
1152                                            //printf("L2:---%s||%s---\n", miss[activeMission].services[j].output[t].c_str(), token);
1153                                            //TODO change to strstr
1154                                            bool doit = false;
1155                                                //printf("here! %s\n", miss[activeMission].services[j].output[t].c_str());
1156                                            if(miss[activeMission].services[j].output[t].find(">") != string::npos){
1157                                                    strcpy(_data_DB->command, "SELECT ");
1158                                                    strcat(_data_DB->command, _data_DB->tablename);
1159                                                    strcat(_data_DB->command, ".* from ");
1160                                                    strcat(_data_DB->command, _data_DB->tablename);
1161                                                    strcat(_data_DB->command, " where Tag==");
1162                                                    miss[activeMission].services[k].output[t].erase(0, 1);
1163                                        sprintf(_data_DB->command, "%s'%s';", _data_DB->command, miss[activeMission].services[j].output[t].c_str());
1164                                                    sqlite3_stmt * pStatement;
1165                                                    rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1166                                                    if (rc == SQLITE_OK){
1167                                                        if (sqlite3_step(pStatement) == SQLITE_ROW)
1168                                                             data = (const char *) sqlite3_column_text(pStatement, 1);
1169                                                        else {
1170                                                                printf("1 data_DB:: Data not yet in DB.\n");
1171                                                                rc=31337;
1172                                                        }
1173                                                    } else {
1174                                                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1175                                                    }
1176                                                    sqlite3_finalize(pStatement);
1177                                                    token = strtok((char *)data.c_str(), "@");
1178                                                    token = strtok(NULL, "@");
1179                                                    token = strtok(NULL, "@");
1180                                                if(atof(buffer) > atof(token))
1181                                                    doit=true;
1182                                                data.clear();
1183                                            }
1184                                            else if (strstr(miss[activeMission].services[j].output[t].c_str(), token))
1185                                                doit=true;
1186                                            if(doit){
1187                                                //printf("L1:if taken\n");
1188                                                for(uint16_t l = j+1; l <= j+miss[activeMission].services[j].num_conds; l++){
1189                                                    //printf("transacting data for k=%d\n", k);
1190                                                    TransactData(l);
1191                                                }
1192                                            }
1193                                            else
1194                                                //printf("L2: if not taken\n");
1195                                                numstatements[2] +=miss[activeMission].services[j].num_conds+1;
1196                                                j+=miss[activeMission].services[j].num_conds;
1197                                            //printf("doneif %d, %d, %d\n", numstatements, miss[activeMission].services[i].num_conds, i);
1198                                        }else if(miss[activeMission].services[j].name.compare("dowhile")==0){
1199                                            numstatements[0]=0;
1200                                            //printf("L2 while detected\n");
1201                                            while(true){
1202                                                uint16_t l;
1203                                                    for(l = j+1; l <= j+miss[activeMission].services[j].num_conds; l++){
1204                                                        TransactData(l);
1205                                                        //printf("l=%d\n", l);
1206                                                    }
1207                                                    data.clear();
1208                                                    //printf("L0:while detected %d, %d\n", k, miss[activeMission].services[i].num_conds);
1209                                                    input.clear();
1210                                                    check.clear();
1211                                                    int t;
1212                                                    for(t = 0; t < 5; t++){
1213                                                        if(!miss[activeMission].services[j].output[t].empty()){
1214                                                            input=miss[activeMission].services[l-2].output[t];
1215                                                            //printf("input=%s\n", input.c_str());
1216                                                            strcpy(_data_DB->command, "SELECT ");
1217                                                            strcat(_data_DB->command, _data_DB->tablename);
1218                                                            strcat(_data_DB->command, ".* from ");
1219                                                            strcat(_data_DB->command, _data_DB->tablename);
1220                                                            strcat(_data_DB->command, " where Tag==");
1221                                                            sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1222                                                            sqlite3_stmt * pStatement;
1223                                                            rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1224                                                            if (rc == SQLITE_OK){
1225                                                                if (sqlite3_step(pStatement) == SQLITE_ROW)
1226                                                                     data = (const char *) sqlite3_column_text(pStatement, 1);
1227                                                                else {
1228                                                                        printf("1 data_DB:: Data not yet in DB.\n");
1229                                                                        rc=31337;
1230                                                                }
1231                                                            } else {
1232                                                                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1233                                                            }
1234                                                            sqlite3_finalize(pStatement);
1235                                                            //printf("data=%s\n", data.c_str());
1236                                                            token = strtok((char *)data.c_str(), "@");
1237                                                            token = strtok(NULL, "@");
1238                                                            token = strtok(NULL, "@");
1239                                                            //printf("data=%s\n", token);
1240                                                            break;
1241                                                        }
1242                                                    }
1243                                                    //printf("L2:--- %s  %s---\n", miss[activeMission].services[j].output[t].c_str(), token);
1244                                                    if(strstr(miss[activeMission].services[j].output[t].c_str(), token)){
1245                                                        //printf("L2:while taken again!\n");
1246                                                    }
1247                                                    else {
1248                                                        //printf("no more while\n");
1249                                                        break;}
1250                                            }
1251                                            j+=miss[activeMission].services[j].num_conds;
1252                                            //printf("doneif\n");
1253                                        }
1254                                        else{
1255                                            //printf("NO L2 COND!\n");
1256                                            numstatements[2]=0;
1257                                            TransactData(j);
1258                                        }
1259                                }
1260                            }
1261                            else{
1262                                //printf("L1: if not taken\n");
1263                            }
1264                                numstatements[1] +=miss[activeMission].services[k].num_conds+1;
1265                                k+=miss[activeMission].services[k].num_conds;
1266                            //printf("doneif %d, %d, %d\n", numstatements, miss[activeMission].services[i].num_conds, i);
1267                        }else if(miss[activeMission].services[k].name.compare("dowhile")==0){
1268                            numstatements[0]=0;
1269                            //printf("L1 while detected\n");
1270                            while(true){
1271                                uint16_t j;
1272                                    for(j = k+1; j <= k+miss[activeMission].services[k].num_conds; j++){
1273                                        TransactData(j);
1274                                    }
1275                                    data.clear();
1276                                    //printf("L0:while detected %d, %d\n", k, miss[activeMission].services[i].num_conds);
1277                                    input.clear();
1278                                    check.clear();
1279                                    int t;
1280                                    for(t = 0; t < 5; t++){
1281                                        if(!miss[activeMission].services[k].output[t].empty()){
1282                                            input=miss[activeMission].services[j-2].output[t];
1283                                            //printf("input=%s\n", input.c_str());
1284                                            strcpy(_data_DB->command, "SELECT ");
1285                                            strcat(_data_DB->command, _data_DB->tablename);
1286                                            strcat(_data_DB->command, ".* from ");
1287                                            strcat(_data_DB->command, _data_DB->tablename);
1288                                            strcat(_data_DB->command, " where Tag==");
1289                                            sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1290                                            sqlite3_stmt * pStatement;
1291                                            rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1292                                            if (rc == SQLITE_OK){
1293                                                if (sqlite3_step(pStatement) == SQLITE_ROW)
1294                                                     data = (const char *) sqlite3_column_text(pStatement, 1);
1295                                                else {
1296                                                        printf("1 data_DB:: Data not yet in DB.\n");
1297                                                        rc=31337;
1298                                                }
1299                                            } else {
1300                                                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1301                                            }
1302                                            sqlite3_finalize(pStatement);
1303                                           // printf("data=%s\n", data.c_str());
1304                                            token = strtok((char *)data.c_str(), "@");
1305                                            token = strtok(NULL, "@");
1306                                            token = strtok(NULL, "@");
1307                                            //printf("data=%s\n", token);
1308                                            break;
1309                                        }
1310                                    }
1311                                    //printf("L1:--- %s  %s---\n", miss[activeMission].services[k].output[t].c_str(), token);
1312                                    if(strstr(miss[activeMission].services[k].output[t].c_str(), token)){
1313                                        //printf("L1:while taken again!\n");
1314                                    }
1315                                    else {
1316                                        //printf("no more while\n");
1317                                        break;}
1318                            }
1319                            k+=miss[activeMission].services[k].num_conds;
1320                            //printf("doneif\n");
1321                        }
1322                        else{
1323                            //printf("NO L1 COND!\n");
1324                            numstatements[1]=0;
1325                            TransactData(k);
1326                        }
1327               
1328                        //numstatements[0] +=miss[activeMission].services[i].num_conds+1;
1329                        //i+=miss[activeMission].services[i].num_conds;
1330            //printf("doneif %d, %d, %d\n", numstatements, miss[activeMission].services[i].num_conds, i);
1331                }
1332            }
1333           // else
1334                //printf("LO if not taken\n");
1335            numstatements[0] +=miss[activeMission].services[i].num_conds+1;
1336            i+=miss[activeMission].services[i].num_conds;
1337            //printf("doneif %d, %d, %d\n", numstatements, miss[activeMission].services[i].num_conds, i);
1338        }
1339        else if(miss[activeMission].services[i].name.compare("dowhile")==0)
1340        {
1341            numstatements[0]=0;
1342            //printf("L0 while detected\n");
1343            while(true){
1344                uint16_t k;
1345                    for(k = i+1; k <= i+miss[activeMission].services[i].num_conds; k++){
1346                        TransactData(k);
1347                    }
1348                    data.clear();
1349                    input.clear();
1350                    check.clear();
1351                    int t;
1352                    for(t = 0; t < 5; t++){
1353                        if(!miss[activeMission].services[i].output[t].empty()){
1354                            input=miss[activeMission].services[k-2].output[t];
1355                            //printf("input=%s\n", input.c_str());
1356                            strcpy(_data_DB->command, "SELECT ");
1357                            strcat(_data_DB->command, _data_DB->tablename);
1358                            strcat(_data_DB->command, ".* from ");
1359                            strcat(_data_DB->command, _data_DB->tablename);
1360                            strcat(_data_DB->command, " where Tag==");
1361                            sprintf(_data_DB->command, "%s'%s';", _data_DB->command, input.c_str());
1362                            sqlite3_stmt * pStatement;
1363                            rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1364                            if (rc == SQLITE_OK){
1365                                if (sqlite3_step(pStatement) == SQLITE_ROW)
1366                                     data = (const char *) sqlite3_column_text(pStatement, 1);
1367                                else {
1368                                        printf("1 data_DB:: Data not yet in DB.\n");
1369                                        rc=31337;
1370                                }
1371                            } else {
1372                                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1373                            }
1374                            sqlite3_finalize(pStatement);
1375                            token = strtok((char *)data.c_str(), "@");
1376                            token = strtok(NULL, "@");
1377                            token = strtok(NULL, "@");
1378                            break;
1379                        }
1380                    }
1381                    //printf("L0:--- %s  %s---\n", miss[activeMission].services[i].output[t].c_str(), token);
1382                    if(strstr(miss[activeMission].services[i].output[t].c_str(), token)){
1383                        //printf("L0:while taken again!\n");
1384                    }
1385                    else {
1386                        //printf("no more while\n");
1387                        break;}
1388            }
1389            i+=miss[activeMission].services[i].num_conds;
1390            //printf("doneif\n");
1391        }
1392        else{
1393            numstatements[0]=0;
1394            //printf("L0 Neither if nor while\n");
1395            TransactData(i);}
1396        i++;
1397    }
1398    i=0;
1399    data.clear();
1400    //get the ouptuts
1401    while(i < 10 && !miss[activeMission].output[i].empty()){
1402        //printf("sending output data to shell\n");
1403        strcpy(_data_DB->command, "select ");
1404        strcat(_data_DB->command, _data_DB->tablename);
1405        strcat(_data_DB->command, ".* from ");
1406        strcat(_data_DB->command, _data_DB->tablename);
1407        strcat(_data_DB->command, " where Tag==");
1408        sprintf(_data_DB->command, "%s'%s';", _data_DB->command, miss[activeMission].output[i].c_str());
1409        sqlite3_stmt * pStatement;
1410        int rc = sqlite3_prepare_v2(_data_DB->db, _data_DB->command, -1, &pStatement, NULL);
1411        if (rc == SQLITE_OK){
1412            if (sqlite3_step(pStatement) == SQLITE_ROW)
1413                 data.append((const char*) sqlite3_column_text(pStatement, 1));
1414            else {
1415                    printf("1data_DB:: Data not yet in DB.\n");
1416                    rc=31337;
1417            }
1418        }
1419        else {
1420            printf("services_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command);
1421        }
1422        //printf("here %s\n", data.c_str());
1423        sqlite3_finalize(pStatement);
1424        char *data_ch = (char *) data.c_str();
1425        char *token = strtok(data_ch, "@");
1426        SendMessage(shellSocketFD, token);
1427        token = strtok(NULL, "@");
1428        while(token){
1429            SendMessage(shellSocketFD, token);
1430            //printf("token1 = %s\n", token);
1431            token = strtok(NULL, "@");
1432            SendMessage(shellSocketFD, token);
1433            //printf("token2 = %s\n", token);
1434            token = strtok(NULL, "@");
1435        }
1436        i++;
1437        data.clear();
1438    }
1439
1440
1441    LOG("ServiceManagementLayer:: Done performing active mission.\n");
1442    /*LOG("ServiceManagementLayer:: Done sending output data to shell from PerformActiveMission.\n");
1443    strcpy(_data_DB->command, "select ");
1444    strcat(_data_DB->command, _data_DB->tablename);
1445    strcat(_data_DB->command, ".* from ");
1446    strcat(_data_DB->command, _data_DB->tablename);
1447    strcat(_data_DB->command, ";");
1448
1449    // execute print (select all)  command 
1450    rc = sqlite3_exec(_data_DB->db, _data_DB->command, callback, 0, &errorMsg);
1451    if( rc!=SQLITE_OK && rc!=101 )
1452        fprintf(stderr, "SQL error: %s\n", errorMsg);
1453    printf("database %s, table %s:\n", _data_DB->filename, _data_DB->tablename);
1454    printf("\n\n\n");*/
1455}
1456
1457
1458/* CALLED BY: MessageHandler
1459 * INPUTS: <none>
1460 * OUTPUTS: <none>
1461 *
1462 * DESCRIPTION: Print a list of the services currently registered and the ID's of the components that registered them
1463 */
1464void
1465ServiceManagementLayer::ListServices()
1466{
1467    // generate commandi
1468    strcpy(_services_DB->command, "select ");
1469    strcat(_services_DB->command, _services_DB->tablename);
1470    strcat(_services_DB->command, ".* from ");
1471    strcat(_services_DB->command, _services_DB->tablename);
1472    strcat(_services_DB->command, ";");
1473
1474    // execute print (select all)  command   
1475    char *errorMsg;
1476    int rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
1477    if( rc!=SQLITE_OK && rc!=101 )
1478        fprintf(stderr, "SQL error: %s\n", errorMsg);
1479    printf("database %s, table %s:\n", _services_DB->filename, _services_DB->tablename);
1480}
1481
1482/* CALLED BY: Reset
1483 * INPUTS: <none>
1484 * OUTPUTS: <none>
1485 *
1486 * DESCRIPTION: Clear and reinitialize the mission array, then reload the configuration file
1487 */
1488void
1489ServiceManagementLayer::ReloadConfiguration()
1490{
1491    LOG("ServiceManagementLayer:: Reloading Configuration.\n");
1492    free(miss);
1493    miss = new Mission[10];
1494    for(int i = 0; i < 10; i++)
1495        miss[i].services = new Service[30];
1496    LoadConfiguration(_SML_Config, miss);
1497}
1498
1499/* CALLED BY: constructor
1500 * INPUTS: |SML_Config| Address (either relitive or full) of the XML file containing mission data
1501 *         |mList| Mission array to be modified
1502 * OUTPUTS: <none>
1503 *
1504 * DESCRIPTION: IMPORTANT - See formatting instructions for correct parsing of data
1505 * Can currently handle 10 inputs and 10 outputs per service, but easily expandable
1506 * Also, can handle two layer of nested conditional statements, but could
1507 * be expanded to meet additional needs.
1508 *
1509 * Components assigned to mission during "set active mission" stage so that
1510 * components can still continue to register after the configuration is loaded
1511 */
1512void
1513ServiceManagementLayer::LoadConfiguration(const char *SML_Config, Mission* &mList)
1514{
1515    TiXmlElement *pMission;
1516    TiXmlElement *pService;
1517    TiXmlElement *pChild0, *pChild1, *pChild2, *pChild3, *pChild4;
1518    TiXmlHandle hRoot(0);
1519    printf("ServiceManagementLayer:: Loading Configuration.\n");
1520    TiXmlDocument doc(".");
1521    doc.LoadFile(SML_Config);
1522    bool loadOkay = doc.LoadFile();
1523    if(!loadOkay)
1524        printf("Loading SML configuration failed: %s\n", SML_Config);
1525
1526    TiXmlHandle hDoc(&doc);
1527   
1528    pMission = hDoc.FirstChildElement().Element();
1529
1530    if(!pMission)
1531        printf("No valid root!");
1532
1533    hRoot = TiXmlHandle(pMission);
1534    pService = pMission->FirstChildElement();
1535    int32_t mission_num = 0;
1536    //Iterate through the missions
1537    for(pChild0 = pMission->FirstChildElement(); pChild0 ; \
1538        pChild0 = pChild0->NextSiblingElement())
1539    {
1540        int32_t service_num = 0;
1541        uint16_t cond_array[] = {0, 0, 0};
1542        //printf("mission_num = %d\n", mission_num);
1543        //memset(cond_array, 0, 2);
1544       
1545        for(pChild1  = (pChild0->FirstChildElement())->FirstChildElement(); pChild1; \
1546            pChild1  = pChild1->NextSiblingElement())
1547        {
1548            //printf("here1\n");
1549            int32_t conditional_0 = service_num;
1550            for(pChild2 = pChild1->FirstChildElement(); \
1551                pChild2; pChild2 = pChild2->NextSiblingElement())
1552            {
1553                service_num++;
1554                int32_t conditional_1 = service_num;
1555                for(pChild3 = pChild2->FirstChildElement(); \
1556                    pChild3; pChild3 = pChild3->NextSiblingElement())
1557                {
1558                    service_num++;
1559                    int32_t conditional_2 = service_num;
1560                        for(pChild4 = pChild3->FirstChildElement(); \
1561                            pChild4; pChild4 = pChild4->NextSiblingElement())
1562                        {
1563                            service_num++;
1564                            if(pChild4->Attribute("name"))
1565                                mList[mission_num].services[service_num].name = pChild4->Attribute("name");
1566                            else
1567                                mList[mission_num].services[service_num].name = pChild4->Value();
1568                            for(int i = 1; i <= 10; i++) {
1569                                char buffer[9]="input";
1570                                sprintf(buffer, "%s%d", buffer, i);
1571                                //printf("buffer=%s\n", buffer);
1572                                if(pChild4->Attribute(buffer))
1573                                    mList[mission_num].services[service_num].input[i-1] = pChild4->Attribute(buffer);
1574                                char buffer2[9]="output";
1575                                sprintf(buffer2, "%s%d", buffer2, i);
1576                                if(pChild4->Attribute(buffer2))
1577                                    mList[mission_num].services[service_num].output[i-1] = pChild4->Attribute(buffer2);
1578                                //printf("i1=%s\n", mList[mission_num].services[conditional_0].input[i].c_str());
1579                            }
1580                            if(pChild4->Attribute("parameter"))
1581                                mList[mission_num].services[service_num].parameter = pChild4->Attribute("parameter");
1582                            cond_array[2]++;
1583                        }
1584                        if(!strcmp(pChild3->Value(), "shell") || conditional_2 != service_num) {
1585                            mList[mission_num].services[conditional_2].name = pChild3->Value();
1586                        }
1587                        else{
1588                            mList[mission_num].services[service_num].name = pChild3->Attribute("name");
1589                        }
1590                        for(int i = 1; i <= 10; i++) {
1591                            char buffer[9]="input";
1592                            sprintf(buffer, "%s%d", buffer, i);
1593                            if(pChild3->Attribute(buffer))
1594                                mList[mission_num].services[conditional_2].input[i-1] = pChild3->Attribute(buffer);
1595                            char buffer2[9]="output";
1596                            sprintf(buffer2, "%s%d", buffer2, i);
1597                            if(pChild3->Attribute(buffer2))
1598                                mList[mission_num].services[conditional_2].output[i-1] = pChild3->Attribute(buffer2);
1599                        }
1600                            if(pChild3->Attribute("parameter"))
1601                                mList[mission_num].services[conditional_2].parameter = pChild3->Attribute("parameter");
1602                        mList[mission_num].services[conditional_2].num_conds = cond_array[2];
1603                        cond_array[1]+=cond_array[2]+1;
1604                        cond_array[2] = 0;
1605
1606
1607                }
1608                if(!strcmp(pChild2->Value(), "shell") || conditional_1 != service_num) {
1609                    mList[mission_num].services[conditional_1].name = pChild2->Value();
1610                }
1611                else{
1612                    mList[mission_num].services[service_num].name = pChild2->Attribute("name");
1613                }
1614                for(int i = 1; i <= 10; i++) {
1615                    char buffer[9]="input";
1616                    sprintf(buffer, "%s%d", buffer, i);
1617                    if(pChild2->Attribute(buffer))
1618                        mList[mission_num].services[conditional_1].input[i-1] = pChild2->Attribute(buffer);
1619                    char buffer2[9]="output";
1620                    sprintf(buffer2, "%s%d", buffer2, i);
1621                    if(pChild2->Attribute(buffer2))
1622                        mList[mission_num].services[conditional_1].output[i-1] = pChild2->Attribute(buffer2);
1623                }
1624                    if(pChild2->Attribute("parameter"))
1625                        mList[mission_num].services[conditional_1].parameter = pChild2->Attribute("parameter");
1626
1627                mList[mission_num].services[conditional_1].num_conds = cond_array[1];
1628                cond_array[0]+=cond_array[1]+1;
1629                cond_array[1] = 0;
1630            }
1631           
1632            if(!strcmp(pChild1->Value(), "shell") || conditional_0 != service_num) {
1633                mList[mission_num].services[conditional_0].name = pChild1->Value();
1634            }
1635            else{
1636                mList[mission_num].services[conditional_0].name = pChild1->Attribute("name");
1637            }
1638                for(int i = 1; i <= 10; i++) {
1639                    char buffer[9]="input";
1640                    sprintf(buffer, "%s%d", buffer, i);
1641                    if(pChild1->Attribute(buffer))
1642                        mList[mission_num].services[conditional_0].input[i-1] = pChild1->Attribute(buffer);
1643                    char buffer2[9]="output";
1644                    sprintf(buffer2, "%s%d", buffer2, i);
1645                    if(pChild1->Attribute(buffer2))
1646                        mList[mission_num].services[conditional_0].output[i-1] = pChild1->Attribute(buffer2);
1647                }
1648                   // printf("i1=%s\n", mList[mission_num].services[conditional_0].input[0].c_str());
1649                if(pChild1->Attribute("parameter"))
1650                    mList[mission_num].services[conditional_0].parameter = pChild1->Attribute("parameter");
1651            mList[mission_num].services[conditional_0].num_conds = cond_array[0];
1652            cond_array[0] = 0;
1653            service_num++;
1654        }
1655        //for(int i = 0; i < service_num; i++)
1656         //printf("ttt%s\n",mList[mission_num].services[i].input[0].c_str());
1657       
1658        mList[mission_num].numServices = service_num;
1659        mList[mission_num].name = pChild0->Attribute("name");
1660        mList[mission_num].missionID = atoi(pChild0->Attribute("id"));
1661        for(int i = 1; i <= 10; i++) {
1662            char buffer[9]="input";
1663            sprintf(buffer, "%s%d", buffer, i);
1664            if(pChild0->Attribute(buffer))
1665                mList[mission_num].input[i-1] = pChild0->Attribute(buffer);
1666            char buffer2[9]="output";
1667            sprintf(buffer2, "%s%d", buffer2, i);
1668            if(pChild0->Attribute(buffer2))
1669                mList[mission_num].output[i-1] = pChild0->Attribute(buffer2);
1670        }
1671        //printf("mis, input1=%s, output1=%s\n", mList[mission_num].input[0].c_str(), mList[mission_num].output[0].c_str());
1672        //printf("NUMSERVICES = %d\n", mList[mission_num].numServices);
1673        mission_num++;
1674        //printf("here\n");
1675    }
1676    //LOG("ServiceManagementLayer:: Done Loading Configuration");
1677}
1678
1679/* CALLED BY: MessageHandler
1680 * INPUTS: |ID| The ID number of the engine to be registered
1681 * OUTPUTS: <none>
1682 *
1683 * DESCRIPTION: Sends a registration message onto the shell and sends the ACK back to the component
1684 */
1685void
1686ServiceManagementLayer::RegisterCognitiveEngine(int32_t ID)
1687{
1688    //LOG("SML::regcogeng");
1689    SendMessage(shellSocketFD, "register_engine_cognitive");
1690
1691   // printf("SSFD = %d\n", shellSocketFD);
1692    LOG("ServiceManagementLayer:: CE registration message forwarded to shell.\n");
1693    char buffer[256];
1694    memset(buffer, 0, 256);
1695    ReadMessage(shellSocketFD, buffer);
1696    //printf("ServiceManagementLayer::buffer = %s\n", buffer);
1697    SendMessage(CE_List[ID].FD, buffer);
1698
1699    TransferRadioConfiguration(ID);
1700    memset(buffer, 0, 256);
1701    //printf("start trans exp\n");
1702    TransferExperience(ID);
1703    memset(buffer, 0, 256);
1704    numberOfCognitiveEngines++;
1705    CE_Present = true;
1706    //printf("done registering CE!\n");
1707}
1708
1709/* CALLED BY: MessageHandler
1710 * INPUTS: |ID| The ID number of the engine to have it's services deregistered
1711 * OUTPUTS: <none>
1712 *
1713 * DESCRIPTION: Deletes individual services from the DB
1714 * NOTE THAT this function only needs to be called if service deregistration is going
1715 * to be done at a different time than component deregistration; it is handled
1716 * more efficiently and directly during that deregistration process.
1717 */
1718void
1719ServiceManagementLayer::DeregisterServices(int32_t ID)
1720{
1721    char buffer[256];
1722    memset(buffer, 0, 256);
1723    ReadMessage(CE_List[ID].FD, buffer);
1724    strcpy(_services_DB->command, "DELETE FROM ");
1725    strcat(_services_DB->command, _services_DB->tablename);
1726    strcat(_services_DB->command, " WHERE ID_Num IN (SELECT");
1727    sprintf(_services_DB->command, " %s %d",_services_DB->command, ID);
1728    strcat(_services_DB->command, " FROM ");
1729    strcat(_services_DB->command, _services_DB->tablename);
1730    strcat(_services_DB->command, " WHERE Service_Name");
1731    strcat(_services_DB->command, "==");
1732    sprintf(_services_DB->command, "%s'%s');", _services_DB->command, buffer);
1733    char *errorMsg;
1734    int rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
1735    if( rc!=SQLITE_OK && rc!=101 )
1736        fprintf(stderr, "SQL error: %s\n", errorMsg);
1737}
1738
1739/* CALLED BY: MessageHandler
1740 * INPUTS: |ID| The ID number of the engine to have it's services deregistered
1741 * OUTPUTS: <none>
1742 *
1743 * DESCRIPTION: Deletes the contact info for the cognitive engine, forwards a deregistration message to the shell
1744 * Also, deletes the services from the DB
1745 */
1746void
1747ServiceManagementLayer::DeregisterCognitiveEngine(int32_t ID)
1748{
1749    LOG("ServiceManagementLayer:: CE deregistration message forwarded to shell.\n");
1750
1751    numberOfCognitiveEngines--;
1752    if(numberOfCognitiveEngines == 0)
1753        CE_Present = false;
1754
1755    SendMessage(shellSocketFD, "deregister_engine_cognitive");
1756    char buffer[256];
1757    memset(buffer, 0, 256);
1758    ReadMessage(shellSocketFD, buffer);
1759    SendMessage(CE_List[ID].FD, buffer);
1760    if(strcmp("deregister_ack", buffer) != 0) {
1761        ERROR(1, "SML:: Failed to close CE socket\n");
1762    }
1763
1764    //Deregister the services
1765    strcpy(_services_DB->command, "DELETE FROM ");
1766    strcat(_services_DB->command, _services_DB->tablename);
1767    strcat(_services_DB->command, " WHERE ");
1768    strcat(_services_DB->command, "ID_Num");
1769    strcat(_services_DB->command, "==");
1770    sprintf(_services_DB->command, "%s%d;", _services_DB->command, ID);
1771    char *errorMsg;
1772    int rc = sqlite3_exec(_services_DB->db, _services_DB->command, callback, 0, &errorMsg);
1773    if( rc!=SQLITE_OK && rc!=101 )
1774        fprintf(stderr, "SQL error: %s\n", errorMsg);
1775
1776
1777    CE_List[ID].FD = -1;
1778    CE_List[ID].ID_num = -1;
1779
1780    LOG("Cognitive Radio Shell:: CE Socket closed for engine #%d.\n", ID);
1781}
1782
1783
1784/* CALLED BY: test class
1785 * INPUTS: <none>
1786 * OUTPUTS: <none>
1787 *
1788 * DESCRIPTION: Sets up a server socket and listens for communication on either that or the shell socket
1789 */
1790void
1791ServiceManagementLayer::StartSMLServer()
1792{
1793    //printf("Ready for CE Signal! (registration done)\n");
1794    struct timeval selTimeout;
1795    int32_t running = 1;
1796    int32_t port, rc, new_sd = 1;
1797    int32_t desc_ready = 1;
1798                //If there is, call the MessageHandler with the Shell_Msg code of -1
1799    fd_set sockSet, shellSet;
1800
1801    cogEngSrv = CreateTCPServerSocket(SMLport);
1802    int32_t maxDescriptor = cogEngSrv;
1803
1804    if(InitializeTCPServerPort(cogEngSrv) == -1)
1805        ERROR(1,"Error initializing primary port\n");
1806
1807    int i = 10000000;  //TODO change to "running" if endpoint can be reached
1808    while (running) {
1809        i--;
1810        /* Zero socket descriptor vector and set for server sockets */
1811        /* This must be reset every time select() is called */
1812        FD_ZERO(&sockSet);
1813        FD_SET(cogEngSrv, &sockSet);
1814        for(uint16_t k = 0; k < Current_ID; k++){
1815            if(CE_List[k].ID_num != -1)
1816                FD_SET(CE_List[k].FD, &sockSet);
1817        }
1818            //printf("k=%d, CID=%d\n", k, CE_List[k].FD);
1819
1820        /* Timeout specification */
1821        /* This must be reset every time select() is called */
1822        selTimeout.tv_sec = 0;       /* timeout (secs.) */
1823        selTimeout.tv_usec = 0;            /* 0 microseconds */
1824        //Changed both to zero so that select will check messages from the shell instead of blocking
1825        //when there is no command from the CE's to be processed
1826
1827        //Check if there is a message on the socket waiting to be read
1828        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
1829        //printf("rc=%d\n", rc);
1830        if(rc == 0){
1831            //LOG("No echo requests for %i secs...Server still alive\n", timeout);
1832       
1833            FD_ZERO(&shellSet);
1834            FD_SET(shellSocketFD, &shellSet);
1835            selTimeout.tv_sec = 0;
1836            selTimeout.tv_usec = 0;
1837            //Check if there is a message on the shell socket ready to be processed
1838            select(shellSocketFD + 1, &shellSet, NULL, NULL, &selTimeout);
1839            //printf("rc2=%d\n", rc2);
1840                //If there is, call the MessageHandler with the Shell_Msg code of -1
1841            if(FD_ISSET(shellSocketFD, &shellSet)){
1842                //printf("shell_msg, %d\n", rc2);
1843                MessageHandler(-1);}
1844        }
1845        else {
1846            desc_ready = rc;
1847            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
1848                if(FD_ISSET(port, &sockSet)) {
1849                    desc_ready -= 1;
1850
1851                    //Check if request is new or on an existing open descriptor
1852                    if(port == cogEngSrv) {
1853                        //If new, assign it a descriptor and give it an ID
1854                        new_sd = AcceptTCPConnection(port);
1855                         
1856                        if(new_sd < 0)
1857                            break;
1858
1859                        CE_List[Current_ID].FD = new_sd;
1860                        CE_List[Current_ID].ID_num = Current_ID;
1861                        MessageHandler(Current_ID);
1862                        Current_ID++;
1863       
1864                        FD_SET(new_sd,&sockSet);
1865                        if(new_sd > maxDescriptor)
1866                           maxDescriptor = new_sd;
1867                    }
1868                    else {
1869                        //If old, figure out which ID it coresponds to and handle it accordingly
1870                        for(uint16_t z = 0; z < Current_ID; z++)
1871                        {
1872                                if(CE_List[z].FD == port){
1873                                        MessageHandler(z);}
1874                        }
1875                    }
1876                }
1877            }
1878        }
1879    }       
1880
1881    /* Close sockets */
1882    close(cogEngSrv);
1883
1884    //delete &cogEngSrv;
1885    return;
1886}
Note: See TracBrowser for help on using the browser.