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

Revision 316, 63.5 KB (checked in by wrodgers, 15 years ago)

Updated SML and Shell for new I/O model, minor bug fixes

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