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

Revision 419, 62.6 KB (checked in by wrodgers, 15 years ago)

Updated c-string operations to c++

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("1 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("1 data_DB:: Data not yet in DB.\n");
1006                                                rc=31337;
1007                                        }
1008                                    } else {
1009                                        printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command.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("1 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("1 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("1 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-1].output[t];
1149                                                            _data_DB->command="SELECT ";
1150                                                            _data_DB->command.append(_data_DB->tablename);
1151                                                            _data_DB->command.append(".* from ");
1152                                                            _data_DB->command.append(_data_DB->tablename);
1153                                                            _data_DB->command.append(" where Tag=='");
1154                                                            _data_DB->command.append(input);
1155                                                            _data_DB->command.append("';");
1156                                                            sqlite3_stmt * pStatement;
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("1 data_DB:: Data not yet in DB.\n");
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("1 data_DB:: Data not yet in DB.\n");
1229                                                        rc=31337;
1230                                                }
1231                                            } else {
1232                                                printf("data_DB:: Error executing SQL statement. rc = %i\n%s\n",rc,_data_DB->command.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("1 data_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    while (running) {
1695        /* Zero socket descriptor vector and set for server sockets */
1696        /* This must be reset every time select() is called */
1697        FD_ZERO(&sockSet);
1698        FD_SET(cogEngSrv, &sockSet);
1699        for(uint16_t k = 0; k < Current_ID; k++){
1700            if(CE_List[k].ID_num != -1)
1701                FD_SET(CE_List[k].FD, &sockSet);
1702        }
1703            //printf("k=%d, CID=%d\n", k, CE_List[k].FD);
1704
1705        /* Timeout specification */
1706        /* This must be reset every time select() is called */
1707        selTimeout.tv_sec = 0;       /* timeout (secs.) */
1708        selTimeout.tv_usec = 0;            /* 0 microseconds */
1709        //Changed both to zero so that select will check messages from the shell instead of blocking
1710        //when there is no command from the CE's to be processed
1711
1712        //Check if there is a message on the socket waiting to be read
1713        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
1714        //printf("rc=%d\n", rc);
1715        if(rc == 0){
1716            //LOG("No echo requests for %i secs...Server still alive\n", timeout);
1717       
1718            FD_ZERO(&shellSet);
1719            FD_SET(shellSocketFD, &shellSet);
1720            selTimeout.tv_sec = 0;
1721            selTimeout.tv_usec = 0;
1722            //Check if there is a message on the shell socket ready to be processed
1723            select(shellSocketFD + 1, &shellSet, NULL, NULL, &selTimeout);
1724            //printf("rc2=%d\n", rc2);
1725                //If there is, call the MessageHandler with the Shell_Msg code of -1
1726            if(FD_ISSET(shellSocketFD, &shellSet)){
1727                //printf("shell_msg, %d\n", rc2);
1728                MessageHandler(-1);}
1729        }
1730        else {
1731            desc_ready = rc;
1732            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
1733                if(FD_ISSET(port, &sockSet)) {
1734                    desc_ready -= 1;
1735
1736                    //Check if request is new or on an existing open descriptor
1737                    if(port == cogEngSrv) {
1738                        //If new, assign it a descriptor and give it an ID
1739                        new_sd = AcceptTCPConnection(port);
1740                         
1741                        if(new_sd < 0)
1742                            break;
1743
1744                        CE_List[Current_ID].FD = new_sd;
1745                        CE_List[Current_ID].ID_num = Current_ID;
1746                        MessageHandler(Current_ID);
1747                        Current_ID++;
1748       
1749                        FD_SET(new_sd,&sockSet);
1750                        if(new_sd > maxDescriptor)
1751                           maxDescriptor = new_sd;
1752                    }
1753                    else {
1754                        //If old, figure out which ID it coresponds to and handle it accordingly
1755                        for(uint16_t z = 0; z < Current_ID; z++)
1756                        {
1757                                if(CE_List[z].FD == port){
1758                                        MessageHandler(z);}
1759                        }
1760                    }
1761                }
1762            }
1763        }
1764    }       
1765
1766    /* Close sockets */
1767    close(cogEngSrv);
1768
1769    //delete &cogEngSrv;
1770    return;
1771}
Note: See TracBrowser for help on using the browser.