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

Revision 411, 64.0 KB (checked in by trnewman, 15 years ago)

Adding Apache license information.

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