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

Revision 228, 20.7 KB (checked in by trnewman, 15 years ago)

Added sending current parameters in the libvt request optimization function.

Added guts to the CBR so it actually creates an sql db and searches it.

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