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

Revision 218, 16.3 KB (checked in by trnewman, 15 years ago)

Addec CE c++ report.

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
[218]113bool
114CognitiveRadioShell::SendRadioConfiguration(int32_t socketfd)
[207]115{
116    LOG("Cognitive Radio Shell:: Sending radio configuration to Cognitive Engine.\n");
[218]117    uint32_t i,j;
118    char counter[55];
119    char var[50];
120
121    // utilities
122    // Send number of utilities
123    sprintf(counter,"%d",radio_info->numUtilities);
124    SendMessage(socketfd,counter);
125    // send utility     
126    for(i = 0; i < radio_info->numUtilities; i++) {
127        SendMessage(socketfd, u[i].name.c_str());
128        SendMessage(socketfd, u[i].units.c_str());
129        SendMessage(socketfd, u[i].goal.c_str());
130        sprintf(var,"%f", u[i].target);
131        SendMessage(socketfd,var);
132    }
133
134    // parameters
135    sprintf(counter,"%i",radio_info->numParameters);
136    SendMessage(socketfd,counter);
137    for(i = 0; i < radio_info->numParameters; i++) {
138        SendMessage(socketfd,p[i].name.c_str());
139        SendMessage(socketfd,p[i].units.c_str());
140        sprintf(var,"%f",p[i].min);
141        SendMessage(socketfd,var);
142        sprintf(var,"%f",p[i].max);
143        SendMessage(socketfd,var);
144        sprintf(var,"%f",p[i].step);
145        SendMessage(socketfd,var);
146
147        sprintf(counter,"%i",p[i].numAffects);
148        SendMessage(socketfd,counter);
149        for(j = 0; j < p[i].numAffects; j++) {
150            SendMessage(socketfd,p[i].affection_list[j].u->name.c_str());
151            SendMessage(socketfd,p[i].affection_list[j].relation.c_str());
152        }
153    }
154
155    // observables
156    sprintf(counter,"%i",radio_info->numObservables);
157    SendMessage(socketfd,counter);
158    for(i = 0; i < radio_info->numObservables; i++) {
159        SendMessage(socketfd,o[i].name.c_str());
160               
161        sprintf(counter,"%i",o[i].numAffects);
162        SendMessage(socketfd,counter);
163        for(j = 0; j < o[i].numAffects; j++) {
164            SendMessage(socketfd,o[i].affection_list[j].u->name.c_str());
165            SendMessage(socketfd,o[i].affection_list[j].relation.c_str());
166        }
167    }
168       
169    // Receive ACK for utils
170    char buffer[256];
171    memset(buffer, 0, 256);
172    ReadMessage(socketfd, buffer);
173
174    if(strcmp(buffer, "receive_config_ack") != 0) {
175        LOG("Cognitive Radio Shell:: Unexpected response: %s\n",buffer);
176        return 0;
177    }
178    return 1;
179
[207]180}
181
[218]182bool
[207]183CognitiveRadioShell::SendRadioExperience(int32_t socketFD)
184{
185
186    LOG("Cognitive Radio Shell:: Sending radio experience to Cognitive Engine.\n");
[218]187    int32_t numberExp = 4;
188   
189    std::string numberExpString = numberExp;
190    SendMessage(socketFD, numberExp);
191
192    char buffer[256];
193    memset(buffer, 0, 256);
194    ReadMessage(socketFD, buffer);
195    if(strcmp(buffer, "receive_exp_ack") != 0) {
196        LOG("Cognitive Radio Shell:: Unexpected response: %s\n",buffer);
197        return 0;
198    }
199    return 1;
[207]200}
201
[209]202
[207]203void
204CognitiveRadioShell::RegisterCognitiveEngine(int32_t socketFD)
205{
206    LOG("Cognitive Radio Shell:: Received registration message from Cognitive Engine.\n");
207   
208    SendRadioConfiguration(socketFD);
209    SendRadioExperience(socketFD);
210
211    numberOfCognitiveEngines++;
212    CE_present = true;
213}
214
[209]215
[207]216void
217CognitiveRadioShell::DeregisterCognitiveEngine(int32_t socketFD)
218{
219    LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n");
220
221    numberOfCognitiveEngines--;
222    if(numberOfCognitiveEngines == 0)
[209]223        CE_present = false;
[207]224
225    SendMessage(socketFD, "deregister_ack");
226    shutdown(socketFD, 2);
227    close(socketFD);
228    LOG("Cognitive Radio Shell:: Socket closed.\n");
229}
230
[209]231
[207]232void
233CognitiveRadioShell::RegisterPolicyEngine(int32_t socketFD)
234{
235    LOG("Cognitive Radio Shell:: Received registration message from Policy Engine.\n");
236    PE_present = true;
237}
238
[209]239
[207]240void
241CognitiveRadioShell::DeregisterPolicyEngine(int32_t socketFD)
242{
243    LOG("Cognitive Radio Shell:: Received deregistration message from Policy Engine.\n");
244
245    PE_present = false;
246   
247    SendMessage(socketFD, "deregister_ack");
248    shutdown(socketFD, 2);
249    close(socketFD);
250    LOG("Cognitive Radio Shell:: Socket closed.\n");
251}
252
[209]253
[207]254void
255CognitiveRadioShell::RegisterSML(int32_t socketFD)
256{
257    LOG("Cognitive Radio Shell:: Received registration message from SML.\n");
258
259    SML_present = true;
260}
261
[209]262
[207]263void
264CognitiveRadioShell::DeregisterSML(int32_t socketFD)
265{
266    LOG("Cognitive Radio Shell:: Received deregistration message from SML.\n");
267
268    SML_present = false;
269
270    SendMessage(socketFD, "deregister_ack");
271    shutdown(socketFD, 2);
272    close(socketFD);
273    LOG("Cognitive Radio Shell:: Socket closed.\n");
274}
275
[209]276
[207]277int32_t
[209]278CognitiveRadioShell::LoadRadioConfiguration(const char* radioConfig, \
279        Parameter* &pList, Utility* &uList, Observable* &oList, \
280        Radio_Info* radioInfo)
[207]281{
282    TiXmlElement *pElem;
283    TiXmlElement *pChild;
284    TiXmlElement *pChild1;
285    TiXmlElement *pSecondChild;
286    TiXmlHandle hRoot(0);
287
288    int32_t count = 0;
289    size_t item_count = 0;
290    size_t affect_count = 0;
[218]291    uint32_t attribute_count = 0;
[207]292    bool match_found = false;
293
294    LOG("Cognitive Radio Shell:: Loading radio configuration.\n");
295
296    TiXmlDocument doc( radioConfig );
297    bool loadOkay = doc.LoadFile();
[215]298    if(!loadOkay)
[207]299        ERROR(1,"Loading radio configuration failed: %s\n", radioConfig);
300
301    TiXmlHandle hDoc(&doc);
302   
303    pElem = hDoc.FirstChildElement().Element();
304
305    if(!pElem)
306        ERROR(1, "No valid root!");
307
308    hRoot = TiXmlHandle(pElem);
309
310    pElem = hRoot.FirstChild("utilities").Element();
311    pChild1 = hRoot.Child("utilities", count).Element();
312
313    for(pChild = pChild1->FirstChildElement("utility"); pChild; \
[209]314        pChild = pChild->NextSiblingElement()) {
315
[207]316        const char *uName = pChild->Attribute("name");
317        if(uName)
[208]318            uList[item_count].name = uName;   
[207]319
320        const char *uUnits = pChild->Attribute("units");
321        if(uUnits)
322            uList[item_count].units = uUnits;
323
324        const char *uGoal = pChild->Attribute("goal");
325        if(uGoal)
326            uList[item_count].goal = uGoal;
327
328        if(pChild->QueryFloatAttribute("target", &uList[item_count].target) != TIXML_SUCCESS)
329            uList[item_count].target = -1;
330
331        item_count++;
332    }
333
[208]334    radio_info->numUtilities = item_count;   
[207]335    LOG("Cognitive Radio Shell:: Parsed %d utilities.\n", radioInfo->numUtilities);
336
337    item_count = 0;
338    pElem = hRoot.FirstChild("observables").Element();
339    pChild1 = hRoot.Child("observables", count).Element();
340
341    for(pChild = pChild1->FirstChildElement("observable"); pChild; \
[209]342        pChild = pChild->NextSiblingElement()) {
343
[207]344        const char *oName = pChild->Attribute("name");
345        if(oName)
346            oList[item_count].name = oName;
[208]347       
[207]348        affect_count = 0;
349        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
[209]350            pSecondChild = pSecondChild->NextSiblingElement()) {
351
[207]352            const char *oUtilName = pSecondChild->Attribute("utility");
[209]353            if(oUtilName) {
354                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++ ) {
355                    if(uList[attribute_count].name == oUtilName) {
356
[207]357                        oList[item_count].affection_list[affect_count].u = &uList[attribute_count];
358                        const char *oRelate = pSecondChild->Attribute("relationship");
359                        if(oRelate)
360                            oList[item_count].affection_list[affect_count].relation = oRelate;
[209]361
[207]362                        affect_count++;
363                        match_found = true;
364                        break;
365                    }
366                }
367            }
368
369            if(!match_found) {
370                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
371                    oList[item_count].name.c_str(), oUtilName);
372            }
373            else
[208]374                match_found = false;   
[207]375        }
376        oList[item_count].numAffects = affect_count;
377        item_count++;
378    }
379
[208]380    radioInfo->numObservables = item_count;   
[207]381    LOG("Cognitive Radio Shell:: Parsed %d observables.\n", radioInfo->numObservables);
382
383    pElem = hRoot.FirstChild("parameters").Element();
384    pChild1 = hRoot.Child("parameters", count).Element();
[208]385   
[207]386    item_count = 0;
387    for(pChild = pChild1->FirstChildElement("parameter"); pChild; \
[209]388        pChild = pChild->NextSiblingElement()) {
389
[207]390        const char *pName = pChild->Attribute("name");
391        if(pName)
[208]392            pList[item_count].name = pName;   
[207]393
394        const char *pUnits = pChild->Attribute("units");
395        if(pUnits)
396            pList[item_count].units = pUnits;
397
398        if(pChild->QueryFloatAttribute("min", &pList[item_count].min) != TIXML_SUCCESS)
399            pList[item_count].min = -1;
400
401        if(pChild->QueryFloatAttribute("max", &pList[item_count].max) != TIXML_SUCCESS)
402            pList[item_count].max = -1;
403
404        if(pChild->QueryFloatAttribute("step", &pList[item_count].step) != TIXML_SUCCESS)
405            pList[item_count].step = -1;
[208]406       
[207]407        affect_count = 0;
408        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
[209]409
410            pSecondChild = pSecondChild->NextSiblingElement()) {
[207]411            const char *pUtilName = pSecondChild->Attribute("utility");
[209]412            if(pUtilName) {
413                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++) {
414                    if(uList[attribute_count].name == pUtilName) {
[208]415                        pList[item_count].affection_list[affect_count].u = &uList[attribute_count];   
[207]416
417                        const char *pRelate = pSecondChild->Attribute("relationship");
418                        if(pRelate)
419                            pList[item_count].affection_list[affect_count].relation = pRelate;
420                        else
421                            LOG("Error: No relation found.\n");
422
423                        match_found = true;
424                        affect_count++;
425                        break;
426                    }
427                }
428            }
429
[209]430            if(!match_found) {
[207]431                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
432                    pList[item_count].name.c_str(), pUtilName);
433            }
434
[208]435            match_found = false;   
[207]436        }
437
438        pList[item_count].numAffects = affect_count;
439        item_count++;
440    }
441
442    radioInfo->numParameters = item_count;
443    LOG("Cognitive Radio Shell:: Parsed %d parameters.\n", radioInfo->numParameters);
444
445    return 1;
446
447}
448
[209]449
[207]450void
451CognitiveRadioShell::GetOptimalParameters(int32_t socketFD)
452{
453}
454
[209]455
[207]456void
457CognitiveRadioShell::HandleMessage(int32_t socketFD)
458{
459    char buffer[256];
460
461    ReadMessage(socketFD, buffer);
462
463    if(strcmp(buffer,"register_engine_cognitive") == 0) {
[208]464        RegisterCognitiveEngine(socketFD);
[207]465    } else if(strcmp(buffer,"deregister_engine_cognitive") == 0) {
[208]466        DeregisterCognitiveEngine(socketFD);
[207]467    } else if(strcmp(buffer,"register_engine_policy") == 0) {
[208]468        RegisterPolicyEngine(socketFD);
[207]469    } else if(strcmp(buffer,"deregister_engine_policy") == 0) {
[208]470        DeregisterPolicyEngine(socketFD);
[207]471    } else if(strcmp(buffer,"register_sml") == 0) {
[208]472        RegisterSML(socketFD);
[207]473    } else if(strcmp(buffer,"deregister_sml") == 0) {
[208]474        DeregisterSML(socketFD);
[207]475    } else if(strcmp(buffer,"optimize") == 0) {
[208]476        /* Receive optimization request and current environment */
477        GetOptimalParameters(socketFD); 
[207]478    }
479}
480
[209]481
[207]482void
483CognitiveRadioShell::StartShellServer()
484{
485    struct timeval selTimeout;
486    int32_t primary = 0;
487    int32_t policy = 1;
488    int32_t command = 2;
489    int32_t running = 1;
490    int32_t port, rc, new_sd = 1;
491    int32_t desc_ready = 1;
492    int32_t timeout = 10;
493    fd_set sockSet;
494
[210]495    int32_t *servSock = new int32_t[3];
[207]496
497    servSock[primary] = CreateTCPServerSocket(primaryPort);
498    servSock[policy] = CreateTCPServerSocket(policyPort);
499    servSock[command] = CreateTCPServerSocket(commandPort);
500
501    int32_t maxDescriptor = servSock[command];
502
[215]503    if(InitializeTCPServerPort(servSock[primary]) == -1)
504        ERROR(1,"Error initializing primary port\n");
[207]505 
[215]506    if(InitializeTCPServerPort(servSock[policy]) == -1)
507        ERROR(1,"Error initializing policy port\n");
[207]508
[215]509    if(InitializeTCPServerPort(servSock[command]) == -1)
510        ERROR(1,"Error initializing command port\n");
[207]511
[209]512    while (running) {
[207]513        /* Zero socket descriptor vector and set for server sockets */
514        /* This must be reset every time select() is called */
515        FD_ZERO(&sockSet);
516        FD_SET(servSock[primary], &sockSet);
517        FD_SET(servSock[policy], &sockSet);
518        FD_SET(servSock[command], &sockSet);
519
520        /* Timeout specification */
521        /* This must be reset every time select() is called */
522        selTimeout.tv_sec = timeout;       /* timeout (secs.) */
523        selTimeout.tv_usec = 0;            /* 0 microseconds */
524
525        /* Suspend program until descriptor is ready or timeout */
526        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
[209]527        if(rc == 0)
[207]528            LOG("No echo requests for %i secs...Server still alive\n", timeout);
[209]529        else {
[207]530            desc_ready = rc;
531
[209]532            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
533                if(FD_ISSET(port, &sockSet)) {
534                    desc_ready -= 1;
[207]535
536                    /* Check if request is new or on an existing open descriptor */
[209]537                    if((port == servSock[primary]) || (port == servSock[policy]) || (port == servSock[command])) {
538                        do {
[207]539                            new_sd = AcceptTCPConnection(port);
540                            if(new_sd < 0)
541                                break;
542                           
543                            HandleMessage(new_sd);
544                            FD_SET(new_sd,&sockSet);
545                            if(new_sd > maxDescriptor)
546                                maxDescriptor = new_sd;
547                            //LOG("New incoming connection - %i\n\n",new_sd);
548                        } while(new_sd != -1);
[209]549                    }
550                    else {
[207]551                        //LOG("Request on already open descriptor.\n\n");
552                        HandleMessage(port);
553                    }
554                }
555            }
556        }
557    }
558
559
560    /* Close sockets */
561    close(servSock[primary]);
562    close(servSock[policy]);
563    close(servSock[command]);
564
565    /* Free list of sockets */
[210]566    delete servSock;
[207]567
568    return;
569}
Note: See TracBrowser for help on using the browser.