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

Revision 223, 19.2 KB (checked in by trnewman, 15 years ago)

Removed some debug statements.

Line 
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>
14#include <string>
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;
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.
49}
50
51
52CognitiveRadioShell::~CognitiveRadioShell()
53{
54    delete [] params;
55    delete [] observables;
56    delete [] utils;
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
65    params = new Parameter[10];
66    observables = new Observable[10];
67    utils = new Utility[10];
68    radio_info = new Radio_Info;
69
70    LoadRadioConfiguration(radioConfig, params, utils, observables, radio_info);
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
85
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
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
113bool
114CognitiveRadioShell::SendRadioConfiguration(int32_t socketfd)
115{
116    LOG("Cognitive Radio Shell:: Sending radio configuration to Cognitive Engine.\n");
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, utils[i].name.c_str());
128        SendMessage(socketfd, utils[i].units.c_str());
129        SendMessage(socketfd, utils[i].goal.c_str());
130        sprintf(var,"%f", utils[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,params[i].name.c_str());
139        SendMessage(socketfd,params[i].units.c_str());
140        sprintf(var,"%f",params[i].min);
141        SendMessage(socketfd,var);
142        sprintf(var,"%f",params[i].max);
143        SendMessage(socketfd,var);
144        sprintf(var,"%f",params[i].step);
145        SendMessage(socketfd,var);
146
147        sprintf(counter,"%i",params[i].numAffects);
148        SendMessage(socketfd,counter);
149        for(j = 0; j < params[i].numAffects; j++) {
150            SendMessage(socketfd,params[i].affection_list[j].u->name.c_str());
151            SendMessage(socketfd,params[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,observables[i].name.c_str());
160               
161        sprintf(counter,"%i",observables[i].numAffects);
162        SendMessage(socketfd,counter);
163        for(j = 0; j < observables[i].numAffects; j++) {
164            SendMessage(socketfd,observables[i].affection_list[j].u->name.c_str());
165            SendMessage(socketfd,observables[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
180}
181
182bool
183CognitiveRadioShell::SendRadioExperience(int32_t socketFD)
184{
185
186    LOG("Cognitive Radio Shell:: Sending radio experience to Cognitive Engine.\n");
187    int32_t numberExp = 4;
188        char numberExpString[50];
189
190    sprintf(numberExpString,"%i",numberExp);
191    SendMessage(socketFD, numberExpString);
192
193    char buffer[256];
194    memset(buffer, 0, 256);
195    ReadMessage(socketFD, buffer);
196    if(strcmp(buffer, "receive_exp_ack") != 0) {
197        LOG("Cognitive Radio Shell:: Unexpected response: %s\n",buffer);
198        return 0;
199    }
200    return 1;
201}
202
203
204void
205CognitiveRadioShell::RegisterCognitiveEngine(int32_t socketFD)
206{
207    LOG("Cognitive Radio Shell:: Received registration message from Cognitive Engine.\n");
208   
209    SendRadioConfiguration(socketFD);
210    SendRadioExperience(socketFD);
211
212    numberOfCognitiveEngines++;
213    CE_present = true;
214}
215
216
217void
218CognitiveRadioShell::DeregisterCognitiveEngine(int32_t socketFD)
219{
220    LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n");
221
222    numberOfCognitiveEngines--;
223    if(numberOfCognitiveEngines == 0)
224        CE_present = false;
225
226    SendMessage(socketFD, "deregister_ack");
227    shutdown(socketFD, 2);
228    close(socketFD);
229    LOG("Cognitive Radio Shell:: Socket closed.\n");
230}
231
232
233void
234CognitiveRadioShell::RegisterPolicyEngine(int32_t socketFD)
235{
236    LOG("Cognitive Radio Shell:: Received registration message from Policy Engine.\n");
237    PE_present = true;
238}
239
240
241void
242CognitiveRadioShell::DeregisterPolicyEngine(int32_t socketFD)
243{
244    LOG("Cognitive Radio Shell:: Received deregistration message from Policy Engine.\n");
245
246    PE_present = false;
247   
248    SendMessage(socketFD, "deregister_ack");
249    shutdown(socketFD, 2);
250    close(socketFD);
251    LOG("Cognitive Radio Shell:: Socket closed.\n");
252}
253
254
255void
256CognitiveRadioShell::RegisterSML(int32_t socketFD)
257{
258    LOG("Cognitive Radio Shell:: Received registration message from SML.\n");
259
260    SML_present = true;
261}
262
263
264void
265CognitiveRadioShell::DeregisterSML(int32_t socketFD)
266{
267    LOG("Cognitive Radio Shell:: Received deregistration message from SML.\n");
268
269    SML_present = false;
270
271    SendMessage(socketFD, "deregister_ack");
272    shutdown(socketFD, 2);
273    close(socketFD);
274    LOG("Cognitive Radio Shell:: Socket closed.\n");
275}
276
277
278int32_t
279CognitiveRadioShell::LoadRadioConfiguration(const char* radioConfig, \
280        Parameter* &pList, Utility* &uList, Observable* &oList, \
281        Radio_Info* radioInfo)
282{
283    TiXmlElement *pElem;
284    TiXmlElement *pChild;
285    TiXmlElement *pChild1;
286    TiXmlElement *pSecondChild;
287    TiXmlHandle hRoot(0);
288
289    int32_t count = 0;
290    size_t item_count = 0;
291    size_t affect_count = 0;
292    uint32_t attribute_count = 0;
293    bool match_found = false;
294
295    LOG("Cognitive Radio Shell:: Loading radio configuration.\n");
296
297    TiXmlDocument doc( radioConfig );
298    bool loadOkay = doc.LoadFile();
299    if(!loadOkay)
300        ERROR(1,"Loading radio configuration failed: %s\n", radioConfig);
301
302    TiXmlHandle hDoc(&doc);
303   
304    pElem = hDoc.FirstChildElement().Element();
305
306    if(!pElem)
307        ERROR(1, "No valid root!");
308
309    hRoot = TiXmlHandle(pElem);
310
311    pElem = hRoot.FirstChild("utilities").Element();
312    pChild1 = hRoot.Child("utilities", count).Element();
313
314    for(pChild = pChild1->FirstChildElement("utility"); pChild; \
315        pChild = pChild->NextSiblingElement()) {
316
317        const char *uName = pChild->Attribute("name");
318        if(uName)
319            uList[item_count].name = uName;   
320
321        const char *uUnits = pChild->Attribute("units");
322        if(uUnits)
323            uList[item_count].units = uUnits;
324
325        const char *uGoal = pChild->Attribute("goal");
326        if(uGoal)
327            uList[item_count].goal = uGoal;
328
329        if(pChild->QueryFloatAttribute("target", &uList[item_count].target) != TIXML_SUCCESS)
330            uList[item_count].target = -1;
331
332        item_count++;
333    }
334
335    radio_info->numUtilities = item_count;   
336    LOG("Cognitive Radio Shell:: Parsed %d utilities.\n", radioInfo->numUtilities);
337
338    item_count = 0;
339    pElem = hRoot.FirstChild("observables").Element();
340    pChild1 = hRoot.Child("observables", count).Element();
341
342    for(pChild = pChild1->FirstChildElement("observable"); pChild; \
343        pChild = pChild->NextSiblingElement()) {
344
345        const char *oName = pChild->Attribute("name");
346        if(oName)
347            oList[item_count].name = oName;
348       
349        affect_count = 0;
350        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
351            pSecondChild = pSecondChild->NextSiblingElement()) {
352
353            const char *oUtilName = pSecondChild->Attribute("utility");
354            if(oUtilName) {
355                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++ ) {
356                    if(uList[attribute_count].name == oUtilName) {
357
358                        oList[item_count].affection_list[affect_count].u = &uList[attribute_count];
359                        const char *oRelate = pSecondChild->Attribute("relationship");
360                        if(oRelate)
361                            oList[item_count].affection_list[affect_count].relation = oRelate;
362
363                        affect_count++;
364                        match_found = true;
365                        break;
366                    }
367                }
368            }
369
370            if(!match_found) {
371                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
372                    oList[item_count].name.c_str(), oUtilName);
373            }
374            else
375                match_found = false;   
376        }
377        oList[item_count].numAffects = affect_count;
378        item_count++;
379    }
380
381    radioInfo->numObservables = item_count;   
382    LOG("Cognitive Radio Shell:: Parsed %d observables.\n", radioInfo->numObservables);
383
384    pElem = hRoot.FirstChild("parameters").Element();
385    pChild1 = hRoot.Child("parameters", count).Element();
386   
387    item_count = 0;
388    for(pChild = pChild1->FirstChildElement("parameter"); pChild; \
389        pChild = pChild->NextSiblingElement()) {
390
391        const char *pName = pChild->Attribute("name");
392        if(pName)
393            pList[item_count].name = pName;   
394
395        const char *pUnits = pChild->Attribute("units");
396        if(pUnits)
397            pList[item_count].units = pUnits;
398
399        if(pChild->QueryFloatAttribute("min", &pList[item_count].min) != TIXML_SUCCESS)
400            pList[item_count].min = -1;
401
402        if(pChild->QueryFloatAttribute("max", &pList[item_count].max) != TIXML_SUCCESS)
403            pList[item_count].max = -1;
404
405        if(pChild->QueryFloatAttribute("step", &pList[item_count].step) != TIXML_SUCCESS)
406            pList[item_count].step = -1;
407       
408        affect_count = 0;
409        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
410
411            pSecondChild = pSecondChild->NextSiblingElement()) {
412            const char *pUtilName = pSecondChild->Attribute("utility");
413            if(pUtilName) {
414                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++) {
415                    if(uList[attribute_count].name == pUtilName) {
416                        pList[item_count].affection_list[affect_count].u = &uList[attribute_count];   
417
418                        const char *pRelate = pSecondChild->Attribute("relationship");
419                        if(pRelate)
420                            pList[item_count].affection_list[affect_count].relation = pRelate;
421                        else
422                            LOG("Error: No relation found.\n");
423
424                        match_found = true;
425                        affect_count++;
426                        break;
427                    }
428                }
429            }
430
431            if(!match_found) {
432                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
433                    pList[item_count].name.c_str(), pUtilName);
434            }
435
436            match_found = false;   
437        }
438
439        pList[item_count].numAffects = affect_count;
440        item_count++;
441    }
442
443    radioInfo->numParameters = item_count;
444    LOG("Cognitive Radio Shell:: Parsed %d parameters.\n", radioInfo->numParameters);
445
446    return 1;
447
448}
449
450
451void
452CognitiveRadioShell::GetOptimalParameters(int32_t socketFD)
453{
454    char buffer[256];
455    uint32_t numObservables,numParameters;
456    char counter[55];
457    uint16_t i;
458    char var[50];
459
460    /* Receive Set of Observables */
461    LOG("Cognitive Radio Shell:: Got request for optimization.\n");
462    memset(buffer, 0, 256);
463    ReadMessage(commandSocketFD,buffer);
464    numObservables = atoi(buffer);
465 
466        LOG("Cognitive Radio Shell:: Attempting to get %i observables.\n",numObservables);
467    Observable * o = new Observable[numObservables];
468 
469    for (i = 0; i < numObservables; i++){
470        memset(buffer, 0, 256);
471        ReadMessage(commandSocketFD,buffer);
472        o[i].name = std::string(buffer);
473   
474        memset(buffer, 0, 256);
475        ReadMessage(commandSocketFD,buffer);
476        o[i].value = atof(buffer);
477    }
478
479    /* Send to Cognitive Engine
480         * TODO: With multiple CEs we need to make a decision about where
481         * to send this information
482         */
483
484        LOG("Cognitive Radio Shell:: Passing on observables to Cognitive Engine\n");
485    SendMessage(ceSocketFD,"get_solution");
486    sprintf(counter,"%i",numObservables);
487    SendMessage(ceSocketFD,counter);
488    for(i = 0; i < numObservables; i++) {
489        SendMessage(ceSocketFD,o[i].name.c_str());
490        sprintf(var,"%f",o[i].value);
491            SendMessage(ceSocketFD,var);
492    }
493
494
495        LOG("Cognitive Radio Shell:: Receiving optimized parameters from Cognitive Engine.\n");
496    /* Receive Set of Parameters */
497    memset(buffer, 0, 256);
498    ReadMessage(ceSocketFD,buffer);
499    numParameters = atoi(buffer);
500   
501    Parameter * p = new Parameter[numParameters];
502 
503    for (i = 0; i < numParameters; i++){
504        memset(buffer, 0, 256);
505        ReadMessage(ceSocketFD,buffer);
506        p[i].name = std::string(buffer);
507   
508        memset(buffer, 0, 256);
509        ReadMessage(ceSocketFD,buffer);
510        p[i].value = atof(buffer);
511    }
512
513    /* Send to Application
514         */
515        LOG("Cognitive Radio Shell:: Sending optimized parameters to Application.\n");
516    memset(counter, 0, 55);
517    sprintf(counter,"%i",numParameters);
518    SendMessage(commandSocketFD,counter);
519    for(i = 0; i < numParameters; i++) {
520        SendMessage(commandSocketFD,p[i].name.c_str());
521        sprintf(var,"%f",p[i].value);
522            SendMessage(commandSocketFD,var);
523    }
524}
525
526
527void
528CognitiveRadioShell::HandleMessage(int32_t socketFD)
529{
530    char buffer[256];
531
532    ReadMessage(socketFD, buffer);
533
534    if(strcmp(buffer,"register_engine_cognitive") == 0) {
535        RegisterCognitiveEngine(socketFD);
536    } else if(strcmp(buffer,"deregister_engine_cognitive") == 0) {
537        DeregisterCognitiveEngine(socketFD);
538    } else if(strcmp(buffer,"register_engine_policy") == 0) {
539        RegisterPolicyEngine(socketFD);
540    } else if(strcmp(buffer,"deregister_engine_policy") == 0) {
541        DeregisterPolicyEngine(socketFD);
542    } else if(strcmp(buffer,"register_sml") == 0) {
543        RegisterSML(socketFD);
544    } else if(strcmp(buffer,"deregister_sml") == 0) {
545        DeregisterSML(socketFD);
546    } else if(strcmp(buffer,"request_optimization") == 0) {
547        /* Receive optimization request and current environment */
548        GetOptimalParameters(socketFD); 
549    }
550}
551
552
553void
554CognitiveRadioShell::StartShellServer()
555{
556    struct timeval selTimeout;
557    int32_t primary = 0;
558    int32_t policy = 1;
559    int32_t command = 2;
560    int32_t running = 1;
561    int32_t port, rc, new_sd = 1;
562    int32_t desc_ready = 1;
563    int32_t timeout = 10;
564    fd_set sockSet;
565
566    int32_t *servSock = new int32_t[3];
567
568    servSock[primary] = CreateTCPServerSocket(primaryPort);
569    servSock[policy] = CreateTCPServerSocket(policyPort);
570    servSock[command] = CreateTCPServerSocket(commandPort);
571
572    int32_t maxDescriptor;
573
574        if(servSock[primary] > servSock[policy])
575                maxDescriptor = servSock[primary];
576    else
577                maxDescriptor = servSock[policy];
578
579        if(servSock[command] > maxDescriptor)
580                maxDescriptor = servSock[command];
581
582    if(InitializeTCPServerPort(servSock[primary]) == -1)
583        ERROR(1,"Error initializing primary port\n");
584 
585    if(InitializeTCPServerPort(servSock[policy]) == -1)
586        ERROR(1,"Error initializing policy port\n");
587
588    if(InitializeTCPServerPort(servSock[command]) == -1)
589        ERROR(1,"Error initializing command port\n");
590
591    while (running) {
592        /* Zero socket descriptor vector and set for server sockets */
593        /* This must be reset every time select() is called */
594        FD_ZERO(&sockSet);
595        FD_SET(servSock[primary], &sockSet);
596        FD_SET(servSock[policy], &sockSet);
597        FD_SET(servSock[command], &sockSet);
598
599        /* Timeout specification */
600        /* This must be reset every time select() is called */
601        selTimeout.tv_sec = timeout;       /* timeout (secs.) */
602        selTimeout.tv_usec = 0;            /* 0 microseconds */
603
604        /* Suspend program until descriptor is ready or timeout */
605        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
606        if(rc == 0)
607            LOG("No echo requests for %i secs...Server still alive\n", timeout);
608        else {
609            desc_ready = rc;
610
611            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
612                if(FD_ISSET(port, &sockSet)) {
613                    desc_ready -= 1;
614
615                    /* Check if request is new or on an existing open descriptor */
616                    if((port == servSock[primary]) || (port == servSock[policy]) || (port == servSock[command])) {
617                        do {
618                            new_sd = AcceptTCPConnection(port);
619                            if(new_sd < 0)
620                                break;
621                           
622                            if(port == servSock[primary])
623                                ceSocketFD = new_sd;
624                            if(port == servSock[command])
625                                commandSocketFD = new_sd;
626                            if(port == servSock[policy])
627                                policySocketFD = new_sd;
628
629                            HandleMessage(new_sd);
630                            FD_SET(new_sd,&sockSet);
631                            if(new_sd > maxDescriptor)
632                                maxDescriptor = new_sd;
633                            //LOG("New incoming connection - %i\n\n",new_sd);
634                        } while(new_sd != -1);
635                    }
636                    else {
637                        //LOG("Request on already open descriptor.\n\n");
638                        HandleMessage(port);
639                    }
640                }
641            }
642        }
643    }
644
645
646    /* Close sockets */
647    close(servSock[primary]);
648    close(servSock[policy]);
649    close(servSock[command]);
650
651    /* Free list of sockets */
652    delete servSock;
653
654    return;
655}
Note: See TracBrowser for help on using the browser.