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

Revision 294, 72.6 KB (checked in by wrodgers, 15 years ago)

Added nested conditionals, service paramaters, more dynamic conditional checking, and some minor reworks of the data storage backend

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