root/vtcross/trunk/src/shell/CognitiveRadioShell.cpp @ 213

Revision 213, 14.1 KB (checked in by bhilburn, 15 years ago)

Making field names more descriptive and easier to read. Also, added a
bug not about a possible segfault.

RevLine 
[207]1/* Virginia Tech Cognitive Radio Open Source Systems
2 * Virginia Tech, 2009
3 *
4 * LICENSE INFORMATION GOES HERE
5 */
6
7/* DESCRIPTION OF FILE.
8 */
9
10
11#include <cstdlib>
12#include <cstring>
13#include <stdint.h>
[212]14#include <string>
[207]15
16#include <arpa/inet.h>
17#include <iostream>
18#include <netinet/in.h>
19#include <netdb.h>
20#include <fcntl.h>
21#include <sys/ioctl.h>
22#include <sys/mman.h>
23#include <sys/socket.h>
24#include <sys/types.h>
25#include <sys/wait.h>
26
27#include "tinyxml/tinyxml.h"
28#include "tinyxml/tinystr.h"
29
30#include "vtcross/common.h"
31#include "vtcross/components.h"
32#include "vtcross/containers.h"
33#include "vtcross/debug.h"
34#include "vtcross/error.h"
35#include "vtcross/socketcomm.h"
36
37
38CognitiveRadioShell::CognitiveRadioShell()
39{
40    LOG("Creating Cognitive Radio Shell.\n");
41    SML_present = false;
42    PE_present = false;
43    CE_present = false;
[213]44
45    // TODO =BUG= The params, observables, and utils arrays are not being
46    // allocated here. If an shell object is constructed, and then immediately
47    // destructed, there will be no allocated memory, and the delete operater
48    // will receive a null pointer, which will segfault.
[207]49}
50
51
52CognitiveRadioShell::~CognitiveRadioShell()
53{
[213]54    delete [] params;
55    delete [] observables;
56    delete [] utils;
[207]57}
58
59
60CognitiveRadioShell::CognitiveRadioShell(const char* radioConfig, int16_t p1, \
61        int16_t p2, int16_t p3)
62{
63    LOG("Creating Cognitive Radio Shell.\n");
64
[213]65    params = new Parameter[10];
66    observables = new Observable[10];
67    utils = new Utility[10];
[207]68    radio_info = new Radio_Info;
69
[213]70    LoadRadioConfiguration(radioConfig, params, utils, observables, radio_info);
[207]71
72    primaryPort = p1;
73    policyPort = p2;
74    commandPort = p3;
75}
76
77
78void
79CognitiveRadioShell::SendComponentType(int32_t socketFD)
80{
81    SendMessage(socketFD, "response_shell");
82    LOG("Cognitive Radio Shell responded to GetRemoteComponentType query.\n");
83}
84
[209]85
[212]86std::string
87CognitiveRadioShell::GetRemoteComponentType(int32_t socketFD)
88{
89    SendMessage(socketFD, "request_component_type");
90
91    char buffer[256];
92    memset(buffer, 0, 256);
93    ReadMessage(socketFD, buffer);
94
95    return std::string(buffer);
96}
97
98
[207]99void
100CognitiveRadioShell::Shutdown()
101{
102    // TODO should something else be happening here?
103}
104
105
106void
107CognitiveRadioShell::Reset()
108{
109    LOG("Resetting Cognitive Radio Shell.\n");
110}
111
112
113void
114CognitiveRadioShell::SendRadioConfiguration(int32_t socketFD)
115{
116    LOG("Cognitive Radio Shell:: Sending radio configuration to Cognitive Engine.\n");
117}
118
[209]119
[207]120void
121CognitiveRadioShell::SendRadioExperience(int32_t socketFD)
122{
123
124    LOG("Cognitive Radio Shell:: Sending radio experience to Cognitive Engine.\n");
125}
126
[209]127
[207]128void
129CognitiveRadioShell::RegisterCognitiveEngine(int32_t socketFD)
130{
131    LOG("Cognitive Radio Shell:: Received registration message from Cognitive Engine.\n");
132   
133    SendRadioConfiguration(socketFD);
134    SendRadioExperience(socketFD);
135
136    numberOfCognitiveEngines++;
137    CE_present = true;
138}
139
[209]140
[207]141void
142CognitiveRadioShell::DeregisterCognitiveEngine(int32_t socketFD)
143{
144    LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n");
145
146    numberOfCognitiveEngines--;
147    if(numberOfCognitiveEngines == 0)
[209]148        CE_present = false;
[207]149
150    SendMessage(socketFD, "deregister_ack");
151    shutdown(socketFD, 2);
152    close(socketFD);
153    LOG("Cognitive Radio Shell:: Socket closed.\n");
154}
155
[209]156
[207]157void
158CognitiveRadioShell::RegisterPolicyEngine(int32_t socketFD)
159{
160    LOG("Cognitive Radio Shell:: Received registration message from Policy Engine.\n");
161    PE_present = true;
162}
163
[209]164
[207]165void
166CognitiveRadioShell::DeregisterPolicyEngine(int32_t socketFD)
167{
168    LOG("Cognitive Radio Shell:: Received deregistration message from Policy Engine.\n");
169
170    PE_present = false;
171   
172    SendMessage(socketFD, "deregister_ack");
173    shutdown(socketFD, 2);
174    close(socketFD);
175    LOG("Cognitive Radio Shell:: Socket closed.\n");
176}
177
[209]178
[207]179void
180CognitiveRadioShell::RegisterSML(int32_t socketFD)
181{
182    LOG("Cognitive Radio Shell:: Received registration message from SML.\n");
183
184    SML_present = true;
185}
186
[209]187
[207]188void
189CognitiveRadioShell::DeregisterSML(int32_t socketFD)
190{
191    LOG("Cognitive Radio Shell:: Received deregistration message from SML.\n");
192
193    SML_present = false;
194
195    SendMessage(socketFD, "deregister_ack");
196    shutdown(socketFD, 2);
197    close(socketFD);
198    LOG("Cognitive Radio Shell:: Socket closed.\n");
199}
200
[209]201
[207]202int32_t
[209]203CognitiveRadioShell::LoadRadioConfiguration(const char* radioConfig, \
204        Parameter* &pList, Utility* &uList, Observable* &oList, \
205        Radio_Info* radioInfo)
[207]206{
207    TiXmlElement *pElem;
208    TiXmlElement *pChild;
209    TiXmlElement *pChild1;
210    TiXmlElement *pSecondChild;
211    TiXmlHandle hRoot(0);
212
213    int32_t count = 0;
214    size_t item_count = 0;
215    size_t affect_count = 0;
216    int32_t attribute_count = 0;
217    bool match_found = false;
218
219    LOG("Cognitive Radio Shell:: Loading radio configuration.\n");
220
221    TiXmlDocument doc( radioConfig );
222    bool loadOkay = doc.LoadFile();
[209]223    if(!loadOkay) {
[207]224        ERROR(1,"Loading radio configuration failed: %s\n", radioConfig);
225        return -1;
226    }
227
228    TiXmlHandle hDoc(&doc);
229   
230    pElem = hDoc.FirstChildElement().Element();
231
232    if(!pElem)
233        ERROR(1, "No valid root!");
234
235    hRoot = TiXmlHandle(pElem);
236
237    pElem = hRoot.FirstChild("utilities").Element();
238    pChild1 = hRoot.Child("utilities", count).Element();
239
240    for(pChild = pChild1->FirstChildElement("utility"); pChild; \
[209]241        pChild = pChild->NextSiblingElement()) {
242
[207]243        const char *uName = pChild->Attribute("name");
244        if(uName)
[208]245            uList[item_count].name = uName;   
[207]246
247        const char *uUnits = pChild->Attribute("units");
248        if(uUnits)
249            uList[item_count].units = uUnits;
250
251        const char *uGoal = pChild->Attribute("goal");
252        if(uGoal)
253            uList[item_count].goal = uGoal;
254
255        if(pChild->QueryFloatAttribute("target", &uList[item_count].target) != TIXML_SUCCESS)
256            uList[item_count].target = -1;
257
258        item_count++;
259    }
260
[208]261    radio_info->numUtilities = item_count;   
[207]262    LOG("Cognitive Radio Shell:: Parsed %d utilities.\n", radioInfo->numUtilities);
263
264    item_count = 0;
265    pElem = hRoot.FirstChild("observables").Element();
266    pChild1 = hRoot.Child("observables", count).Element();
267
268    for(pChild = pChild1->FirstChildElement("observable"); pChild; \
[209]269        pChild = pChild->NextSiblingElement()) {
270
[207]271        const char *oName = pChild->Attribute("name");
272        if(oName)
273            oList[item_count].name = oName;
[208]274       
[207]275        affect_count = 0;
276        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
[209]277            pSecondChild = pSecondChild->NextSiblingElement()) {
278
[207]279            const char *oUtilName = pSecondChild->Attribute("utility");
[209]280            if(oUtilName) {
281                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++ ) {
282                    if(uList[attribute_count].name == oUtilName) {
283
[207]284                        oList[item_count].affection_list[affect_count].u = &uList[attribute_count];
285                        const char *oRelate = pSecondChild->Attribute("relationship");
286                        if(oRelate)
287                            oList[item_count].affection_list[affect_count].relation = oRelate;
[209]288
[207]289                        affect_count++;
290                        match_found = true;
291                        break;
292                    }
293                }
294            }
295
296            if(!match_found) {
297                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
298                    oList[item_count].name.c_str(), oUtilName);
299            }
300            else
[208]301                match_found = false;   
[207]302        }
303        oList[item_count].numAffects = affect_count;
304        item_count++;
305    }
306
[208]307    radioInfo->numObservables = item_count;   
[207]308    LOG("Cognitive Radio Shell:: Parsed %d observables.\n", radioInfo->numObservables);
309
310    pElem = hRoot.FirstChild("parameters").Element();
311    pChild1 = hRoot.Child("parameters", count).Element();
[208]312   
[207]313    item_count = 0;
314    for(pChild = pChild1->FirstChildElement("parameter"); pChild; \
[209]315        pChild = pChild->NextSiblingElement()) {
316
[207]317        const char *pName = pChild->Attribute("name");
318        if(pName)
[208]319            pList[item_count].name = pName;   
[207]320
321        const char *pUnits = pChild->Attribute("units");
322        if(pUnits)
323            pList[item_count].units = pUnits;
324
325        if(pChild->QueryFloatAttribute("min", &pList[item_count].min) != TIXML_SUCCESS)
326            pList[item_count].min = -1;
327
328        if(pChild->QueryFloatAttribute("max", &pList[item_count].max) != TIXML_SUCCESS)
329            pList[item_count].max = -1;
330
331        if(pChild->QueryFloatAttribute("step", &pList[item_count].step) != TIXML_SUCCESS)
332            pList[item_count].step = -1;
[208]333       
[207]334        affect_count = 0;
335        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
[209]336
337            pSecondChild = pSecondChild->NextSiblingElement()) {
[207]338            const char *pUtilName = pSecondChild->Attribute("utility");
[209]339            if(pUtilName) {
340                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++) {
341                    if(uList[attribute_count].name == pUtilName) {
[208]342                        pList[item_count].affection_list[affect_count].u = &uList[attribute_count];   
[207]343
344                        const char *pRelate = pSecondChild->Attribute("relationship");
345                        if(pRelate)
346                            pList[item_count].affection_list[affect_count].relation = pRelate;
347                        else
348                            LOG("Error: No relation found.\n");
349
350                        match_found = true;
351                        affect_count++;
352                        break;
353                    }
354                }
355            }
356
[209]357            if(!match_found) {
[207]358                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
359                    pList[item_count].name.c_str(), pUtilName);
360            }
361
[208]362            match_found = false;   
[207]363        }
364
365        pList[item_count].numAffects = affect_count;
366        item_count++;
367    }
368
369    radioInfo->numParameters = item_count;
370    LOG("Cognitive Radio Shell:: Parsed %d parameters.\n", radioInfo->numParameters);
371
372    return 1;
373
374}
375
[209]376
[207]377void
378CognitiveRadioShell::GetOptimalParameters(int32_t socketFD)
379{
380}
381
[209]382
[207]383void
384CognitiveRadioShell::HandleMessage(int32_t socketFD)
385{
386    char buffer[256];
387
388    ReadMessage(socketFD, buffer);
389
390    if(strcmp(buffer,"register_engine_cognitive") == 0) {
[208]391        RegisterCognitiveEngine(socketFD);
[207]392    } else if(strcmp(buffer,"deregister_engine_cognitive") == 0) {
[208]393        DeregisterCognitiveEngine(socketFD);
[207]394    } else if(strcmp(buffer,"register_engine_policy") == 0) {
[208]395        RegisterPolicyEngine(socketFD);
[207]396    } else if(strcmp(buffer,"deregister_engine_policy") == 0) {
[208]397        DeregisterPolicyEngine(socketFD);
[207]398    } else if(strcmp(buffer,"register_sml") == 0) {
[208]399        RegisterSML(socketFD);
[207]400    } else if(strcmp(buffer,"deregister_sml") == 0) {
[208]401        DeregisterSML(socketFD);
[207]402    } else if(strcmp(buffer,"optimize") == 0) {
[208]403        /* Receive optimization request and current environment */
404        GetOptimalParameters(socketFD); 
[207]405    }
406}
407
[209]408
[207]409void
410CognitiveRadioShell::StartShellServer()
411{
412    struct timeval selTimeout;
413    int32_t primary = 0;
414    int32_t policy = 1;
415    int32_t command = 2;
416    int32_t running = 1;
417    int32_t port, rc, new_sd = 1;
418    int32_t desc_ready = 1;
419    int32_t timeout = 10;
420    fd_set sockSet;
421
[210]422    int32_t *servSock = new int32_t[3];
[207]423
424    servSock[primary] = CreateTCPServerSocket(primaryPort);
425    servSock[policy] = CreateTCPServerSocket(policyPort);
426    servSock[command] = CreateTCPServerSocket(commandPort);
427
428    int32_t maxDescriptor = servSock[command];
429
430    if(InitializeTCPServerPort(servSock[primary]) == -1) {
[208]431    ERROR(1,"Error initializing primary port\n");
432           return;
[207]433    }
434 
435    if(InitializeTCPServerPort(servSock[policy]) == -1) {
[208]436    ERROR(1,"Error initializing policy port\n");
437           return;
[207]438    }
439
440    if(InitializeTCPServerPort(servSock[command]) == -1) {
[208]441    ERROR(1,"Error initializing command port\n");
442           return;
[207]443    }
444
[209]445    while (running) {
[207]446        /* Zero socket descriptor vector and set for server sockets */
447        /* This must be reset every time select() is called */
448        FD_ZERO(&sockSet);
449        FD_SET(servSock[primary], &sockSet);
450        FD_SET(servSock[policy], &sockSet);
451        FD_SET(servSock[command], &sockSet);
452
453        /* Timeout specification */
454        /* This must be reset every time select() is called */
455        selTimeout.tv_sec = timeout;       /* timeout (secs.) */
456        selTimeout.tv_usec = 0;            /* 0 microseconds */
457
458        /* Suspend program until descriptor is ready or timeout */
459        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
[209]460        if(rc == 0)
[207]461            LOG("No echo requests for %i secs...Server still alive\n", timeout);
[209]462        else {
[207]463            desc_ready = rc;
464
[209]465            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
466                if(FD_ISSET(port, &sockSet)) {
467                    desc_ready -= 1;
[207]468
469                    /* Check if request is new or on an existing open descriptor */
[209]470                    if((port == servSock[primary]) || (port == servSock[policy]) || (port == servSock[command])) {
471                        do {
[207]472                            new_sd = AcceptTCPConnection(port);
473                            if(new_sd < 0)
474                                break;
475                           
476                            HandleMessage(new_sd);
477                            FD_SET(new_sd,&sockSet);
478                            if(new_sd > maxDescriptor)
479                                maxDescriptor = new_sd;
480                            //LOG("New incoming connection - %i\n\n",new_sd);
481                        } while(new_sd != -1);
[209]482                    }
483                    else {
[207]484                        //LOG("Request on already open descriptor.\n\n");
485                        HandleMessage(port);
486                    }
487                }
488            }
489        }
490    }
491
492
493    /* Close sockets */
494    close(servSock[primary]);
495    close(servSock[policy]);
496    close(servSock[command]);
497
498    /* Free list of sockets */
[210]499    delete servSock;
[207]500
501    return;
502}
Note: See TracBrowser for help on using the browser.