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

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

Made 2221 substitions (tabs to spaces) on nearly 800 lines.

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