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

Revision 212, 13.7 KB (checked in by bhilburn, 15 years ago)

Manually adding GetRemoteComponentType? to the shell since it doesn't
inherit from Component and therefore doesn't get the inherited function.

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