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

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

Fixed minor errors/compressed XML read operation

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