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

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

Fixed local includes. In order for autofoo installs to work, the
install breaks.

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