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

Revision 441, 69.2 KB (checked in by bhilburn, 15 years ago)

Mostly style fixes. Changing over some fprintf's to use the proper
MACRO.

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