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

Revision 521, 25.1 KB (checked in by bhilburn, 15 years ago)

Added some more doxygen docs at the top of files.

Line 
1/*
2 Copyright 2009 Virginia Polytechnic Institute and State University 
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/*! This file provides the default implementation of the Cognitive Radio Shell.
18 *
19 * The CRS acts as the central control component in a CROSS radio system.  It
20 * handles component registration and message passing.
21 */
22
23
24#include <cstdlib>
25#include <cstring>
26#include <stdint.h>
27#include <string>
28
29#include <arpa/inet.h>
30#include <iostream>
31#include <netinet/in.h>
32#include <netdb.h>
33#include <fcntl.h>
34#include <sys/ioctl.h>
35#include <sys/mman.h>
36#include <sys/socket.h>
37#include <sys/types.h>
38#include <sys/wait.h>
39
40#include "tinyxml/tinyxml.h"
41#include "tinyxml/tinystr.h"
42
43#include "vtcross/common.h"
44#include "vtcross/containers.h"
45#include "vtcross/cross_shell.h"
46#include "vtcross/debug.h"
47#include "vtcross/error.h"
48#include "vtcross/socketcomm.h"
49
50
51CognitiveRadioShell::CognitiveRadioShell()
52{
53    LOG("Creating Cognitive Radio Shell.\n");
54
55    SML_present = false;
56    PE_present = false;
57    CE_present = false;
58
59    params = new Parameter[10];
60    observables = new Observable[10];
61    utils = new Utility[10];
62    radio_info = new Radio_Info;
63}
64
65
66CognitiveRadioShell::~CognitiveRadioShell()
67{
68    delete [] params;
69    delete [] observables;
70    delete [] utils;
71    delete radio_info;
72}
73
74
75CognitiveRadioShell::CognitiveRadioShell(const char* radioConfig, int16_t p1, \
76        int16_t p2, int16_t p3)
77{
78    LOG("Creating Cognitive Radio Shell.\n");
79
80    SML_present = false;
81    PE_present = false;
82    CE_present = false;
83
84    params = new Parameter[10];
85    observables = new Observable[10];
86    utils = new Utility[10];
87    radio_info = new Radio_Info;
88
89    LoadRadioConfiguration(radioConfig, params, utils, observables, radio_info);
90
91    primaryPort = p1;
92    policyPort = p2;
93    commandPort = p3;
94}
95
96
97void
98CognitiveRadioShell::SendComponentType(int32_t socketFD)
99{
100    SendMessage(socketFD, "response_shell");
101    LOG("Cognitive Radio Shell responded to GetRemoteComponentType query.\n");
102}
103
104
105std::string
106CognitiveRadioShell::GetRemoteComponentType(int32_t socketFD)
107{
108    SendMessage(socketFD, "request_component_type");
109
110    char buffer[256];
111    memset(buffer, 0, 256);
112    ReadMessage(socketFD, buffer);
113
114    return std::string(buffer);
115}
116
117
118void
119CognitiveRadioShell::Shutdown()
120{
121    LOG("Shutting down Cognitive Radio Shell.\n");
122}
123
124
125void
126CognitiveRadioShell::Reset()
127{
128    LOG("Resetting Cognitive Radio Shell.\n");
129}
130
131
132bool
133CognitiveRadioShell::SendRadioConfiguration(int32_t socketFD)
134{
135    LOG("Cognitive Radio Shell:: Sending radio configuration to Cognitive Engine.\n");
136
137    char counter[55];
138    char var[50];
139
140    /* Send utilities */
141    sprintf(counter, "%d", radio_info->numUtilities);
142    SendMessage(socketFD, counter);
143    for(size_t i = 0; i < radio_info->numUtilities; i++) {
144        SendMessage(socketFD, utils[i].name.c_str());
145        SendMessage(socketFD, utils[i].units.c_str());
146        SendMessage(socketFD, utils[i].goal.c_str());
147        sprintf(var,"%f", utils[i].target);
148        SendMessage(socketFD, var);
149    }
150
151    /* Send parameters */
152    sprintf(counter,"%i",radio_info->numParameters);
153    SendMessage(socketFD,counter);
154    for(size_t i = 0; i < radio_info->numParameters; i++) {
155        SendMessage(socketFD, params[i].name.c_str());
156        SendMessage(socketFD, params[i].units.c_str());
157        sprintf(var, "%f", params[i].min);
158        SendMessage(socketFD,var);
159        sprintf(var, "%f", params[i].max);
160        SendMessage(socketFD, var);
161        sprintf(var, "%f", params[i].step);
162        SendMessage(socketFD, var);
163
164        sprintf(counter, "%i", params[i].numAffects);
165        SendMessage(socketFD, counter);
166        for(size_t j = 0; j < params[i].numAffects; j++) {
167            SendMessage(socketFD, params[i].affection_list[j].u->name.c_str());
168            SendMessage(socketFD, params[i].affection_list[j].relation.c_str());
169        }
170    }
171
172    /* Send observables */
173    sprintf(counter,"%i",radio_info->numObservables);
174    SendMessage(socketFD, counter);
175    for(size_t i = 0; i < radio_info->numObservables; i++) {
176        SendMessage(socketFD, observables[i].name.c_str());
177       
178        sprintf(counter, "%i", observables[i].numAffects);
179        SendMessage(socketFD, counter);
180        for(size_t j = 0; j < observables[i].numAffects; j++) {
181            SendMessage(socketFD, observables[i].affection_list[j].u->name.c_str());
182            SendMessage(socketFD, observables[i].affection_list[j].relation.c_str());
183        }
184    }
185   
186    /* Receive ACK for radio configuration */
187    char buffer[256];
188    memset(buffer, 0, 256);
189    ReadMessage(socketFD, buffer);
190
191    if(strcmp(buffer, "receive_config_ack") != 0) {
192        LOG("Cognitive Radio Shell:: Unexpected response: %s\n", buffer);
193        return false;
194    }
195
196    return true;
197}
198
199bool
200CognitiveRadioShell::SendRadioExperience(int32_t socketFD)
201{
202
203    LOG("Cognitive Radio Shell:: Sending radio experience to Cognitive Engine.\n");
204    int32_t numberExp = 4;
205    char numberExpString[50];
206
207    sprintf(numberExpString, "%d", numberExp);
208    SendMessage(socketFD, "test");
209
210    char buffer[256];
211    memset(buffer, 0, 256);
212    ReadMessage(socketFD, buffer);
213    if(strcmp(buffer, "receive_exp_ack") != 0) {
214        WARNING("Cognitive Radio Shell:: Unexpected response: %s\n", buffer);
215        return false;
216    }
217    return true;
218}
219
220
221void
222CognitiveRadioShell::RegisterCognitiveEngine(int32_t socketFD)
223{
224    LOG("Cognitive Radio Shell:: Received registration from Cognitive Engine on socket %d.\n", \
225            socketFD);
226   
227    SendMessage(socketFD, "register_ack");
228    SendRadioConfiguration(socketFD);
229    SendRadioExperience(socketFD);
230
231    numberOfCognitiveEngines++;
232   
233    /* More efficient to always set to true than add a conditional branch to the
234     * code. */
235    CE_present = true;
236}
237
238
239void
240CognitiveRadioShell::DeregisterCognitiveEngine(int32_t socketFD)
241{
242    LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n");
243
244    numberOfCognitiveEngines--;
245    if(numberOfCognitiveEngines == 0)
246        CE_present = false;
247
248    SendMessage(socketFD, "deregister_ack");
249    shutdown(socketFD, 2);
250    close(socketFD);
251    LOG("Cognitive Radio Shell:: Socket %d closed.\n", socketFD);
252}
253
254
255void
256CognitiveRadioShell::RegisterPolicyEngine(int32_t socketFD)
257{
258    LOG("Cognitive Radio Shell:: Received registration from Policy Engine on socket %d.\n", \
259            socketFD);
260
261    PE_present = true;
262}
263
264
265void
266CognitiveRadioShell::DeregisterPolicyEngine(int32_t socketFD)
267{
268    LOG("Cognitive Radio Shell:: Received deregistration message from Policy Engine.\n");
269
270    PE_present = false;
271   
272    SendMessage(socketFD, "deregister_ack");
273    shutdown(socketFD, 2);
274    close(socketFD);
275    LOG("Cognitive Radio Shell:: Socket %d closed.\n", socketFD);
276}
277
278
279void
280CognitiveRadioShell::RegisterSML(int32_t socketFD)
281{
282    LOG("Cognitive Radio Shell:: Received registration from SML on socket %d.\n", \
283            socketFD);
284
285    SML_present = true;
286}
287
288
289void
290CognitiveRadioShell::DeregisterSML(int32_t socketFD)
291{
292    LOG("Cognitive Radio Shell:: Received deregistration message from SML.\n");
293
294    SML_present = false;
295
296    SendMessage(socketFD, "deregister_ack");
297    shutdown(socketFD, 2);
298    close(socketFD);
299    LOG("Cognitive Radio Shell:: Socket %d closed.\n", socketFD);
300}
301
302void
303CognitiveRadioShell::SetActiveMission(int32_t socketFD)
304{
305    char buffer[256];
306
307    LOG("Cognitive Radio Shell:: Received Set Active Mission command from host.\n");
308   
309    /* Read the name of the active mission to be set from the host. */
310    memset(buffer, 0, 256);
311    ReadMessage(commandSocketFD, buffer);
312
313    /* Send command to SML. */
314    SendMessage(ceSocketFD, "set_active_mission");
315    SendMessage(ceSocketFD, buffer);
316
317    /* Get ack from SML saying the mission was set properly */
318    memset(buffer, 0, 256);
319    ReadMessage(ceSocketFD, buffer);
320
321    /* Forward ack to host */
322    SendMessage(commandSocketFD, buffer);
323}
324
325int32_t
326CognitiveRadioShell::LoadRadioConfiguration(const char* radioConfig, \
327        Parameter* &pList, Utility* &uList, Observable* &oList, \
328        Radio_Info* radioInfo)
329{
330    TiXmlElement *pElem;
331    TiXmlElement *pChild;
332    TiXmlElement *pChild1;
333    TiXmlElement *pSecondChild;
334    TiXmlHandle hRoot(0);
335
336    int32_t count = 0;
337    size_t item_count = 0;
338    size_t affect_count = 0;
339    uint32_t attribute_count = 0;
340    bool match_found = false;
341
342    LOG("Cognitive Radio Shell:: Loading radio configuration.\n");
343
344    TiXmlDocument doc( radioConfig );
345    bool loadOkay = doc.LoadFile();
346    if(!loadOkay)
347        ERROR(1, "Loading radio configuration failed: %s\n", radioConfig);
348
349    TiXmlHandle hDoc(&doc);
350   
351    pElem = hDoc.FirstChildElement().Element();
352
353    if(!pElem)
354        ERROR(1, "No valid root!");
355
356    hRoot = TiXmlHandle(pElem);
357
358    pElem = hRoot.FirstChild("utilities").Element();
359    pChild1 = hRoot.Child("utilities", count).Element();
360
361    for(pChild = pChild1->FirstChildElement("utility"); pChild; \
362        pChild = pChild->NextSiblingElement()) {
363
364        const char *uName = pChild->Attribute("name");
365        if(uName)
366            uList[item_count].name = uName;   
367
368        const char *uUnits = pChild->Attribute("units");
369        if(uUnits)
370            uList[item_count].units = uUnits;
371
372        const char *uGoal = pChild->Attribute("goal");
373        if(uGoal)
374            uList[item_count].goal = uGoal;
375
376        if(pChild->QueryFloatAttribute("target", &uList[item_count].target) != TIXML_SUCCESS)
377            uList[item_count].target = -1;
378
379        item_count++;
380    }
381
382    radio_info->numUtilities = item_count;   
383    LOG("Cognitive Radio Shell:: Parsed %d utilities.\n", radioInfo->numUtilities);
384
385    item_count = 0;
386    pElem = hRoot.FirstChild("observables").Element();
387    pChild1 = hRoot.Child("observables", count).Element();
388
389    for(pChild = pChild1->FirstChildElement("observable"); pChild; \
390        pChild = pChild->NextSiblingElement()) {
391
392        const char *oName = pChild->Attribute("name");
393        if(oName)
394            oList[item_count].name = oName;
395       
396        affect_count = 0;
397        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
398            pSecondChild = pSecondChild->NextSiblingElement()) {
399
400            const char *oUtilName = pSecondChild->Attribute("utility");
401            if(oUtilName) {
402                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++ ) {
403                    if(uList[attribute_count].name == oUtilName) {
404
405                        oList[item_count].affection_list[affect_count].u = &uList[attribute_count];
406                        const char *oRelate = pSecondChild->Attribute("relationship");
407                        if(oRelate)
408                            oList[item_count].affection_list[affect_count].relation = oRelate;
409
410                        affect_count++;
411                        match_found = true;
412                        break;
413                    }
414                }
415            }
416
417            if(!match_found) {
418                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
419                    oList[item_count].name.c_str(), oUtilName);
420            }
421            else
422                match_found = false;   
423        }
424        oList[item_count].numAffects = affect_count;
425        item_count++;
426    }
427
428    radioInfo->numObservables = item_count;   
429    LOG("Cognitive Radio Shell:: Parsed %d observables.\n", radioInfo->numObservables);
430
431    pElem = hRoot.FirstChild("parameters").Element();
432    pChild1 = hRoot.Child("parameters", count).Element();
433   
434    item_count = 0;
435    for(pChild = pChild1->FirstChildElement("parameter"); pChild; \
436        pChild = pChild->NextSiblingElement()) {
437
438        const char *pName = pChild->Attribute("name");
439        if(pName)
440            pList[item_count].name = pName;   
441
442        const char *pUnits = pChild->Attribute("units");
443        if(pUnits)
444            pList[item_count].units = pUnits;
445
446        if(pChild->QueryFloatAttribute("min", &pList[item_count].min) != TIXML_SUCCESS)
447            pList[item_count].min = -1;
448
449        if(pChild->QueryFloatAttribute("max", &pList[item_count].max) != TIXML_SUCCESS)
450            pList[item_count].max = -1;
451
452        if(pChild->QueryFloatAttribute("step", &pList[item_count].step) != TIXML_SUCCESS)
453            pList[item_count].step = -1;
454       
455        affect_count = 0;
456        for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \
457
458            pSecondChild = pSecondChild->NextSiblingElement()) {
459            const char *pUtilName = pSecondChild->Attribute("utility");
460            if(pUtilName) {
461                for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++) {
462                    if(uList[attribute_count].name == pUtilName) {
463                        pList[item_count].affection_list[affect_count].u = &uList[attribute_count];   
464
465                        const char *pRelate = pSecondChild->Attribute("relationship");
466                        if(pRelate)
467                            pList[item_count].affection_list[affect_count].relation = pRelate;
468                        else
469                            LOG("Error: No relation found.\n");
470
471                        match_found = true;
472                        affect_count++;
473                        break;
474                    }
475                }
476            }
477
478            if(!match_found) {
479                ERROR(1, "Error: %s: %s is not a valid utility.\n", \
480                    pList[item_count].name.c_str(), pUtilName);
481            }
482
483            match_found = false;   
484        }
485
486        pList[item_count].numAffects = affect_count;
487        item_count++;
488    }
489
490    radioInfo->numParameters = item_count;
491    LOG("Cognitive Radio Shell:: Parsed %d parameters.\n", radioInfo->numParameters);
492
493    /* TODO always returning one seems useless? */
494    return 1;
495}
496
497
498void
499CognitiveRadioShell::GetOptimalParameters(int32_t socketFD)
500{
501    char buffer[256];
502    char counter[55];
503    char var[50];
504
505    /* Receive Set of Observables */
506    LOG("Cognitive Radio Shell:: Got request for optimization.\n");
507    memset(buffer, 0, 256);
508    ReadMessage(commandSocketFD, buffer);
509    uint32_t numObservables = atoi(buffer);
510 
511    LOG("Cognitive Radio Shell:: Attempting to get %i observables.\n", numObservables);
512    Observable *o = new Observable[numObservables];
513 
514    for(size_t i = 0; i < numObservables; i++) {
515        memset(buffer, 0, 256);
516        ReadMessage(commandSocketFD, buffer);
517        o[i].name = std::string(buffer);
518   
519        memset(buffer, 0, 256);
520        ReadMessage(commandSocketFD, buffer);
521        o[i].value = atof(buffer);
522    }
523
524    /* Receive Set of Current Parameters */
525    memset(buffer, 0, 256);
526    ReadMessage(commandSocketFD,buffer);
527    uint32_t numCurrentParameters = atoi(buffer);
528 
529    LOG("Cognitive Radio Shell:: Attempting to get %i parameters.\n",numCurrentParameters);
530    Parameter *cp = new Parameter[numCurrentParameters];
531
532    for (size_t i = 0; i < numCurrentParameters; i++){
533        memset(buffer, 0, 256);
534        ReadMessage(commandSocketFD,buffer);
535        cp[i].name = std::string(buffer);
536
537        memset(buffer, 0, 256);
538        ReadMessage(commandSocketFD,buffer);
539        cp[i].value = atof(buffer);
540    }
541
542    /* Send to Cognitive Engine
543     * TODO: With multiple CEs we need to make a decision about where
544     * to send this information
545     */
546    LOG("Cognitive Radio Shell:: Passing on observables.\n");
547    SendMessage(ceSocketFD,"request_optimization");
548    sprintf(counter,"%i",numObservables);
549    SendMessage(ceSocketFD,counter);
550    for(size_t i = 0; i < numObservables; i++) {
551        SendMessage(ceSocketFD,o[i].name.c_str());
552        sprintf(var,"%f",o[i].value);
553        SendMessage(ceSocketFD,var);
554    }
555       
556    LOG("Cognitive Radio Shell:: Passing on current parameters.\n");
557    sprintf(counter,"%i",numCurrentParameters);
558    SendMessage(ceSocketFD,counter);
559    for(size_t i = 0; i < numCurrentParameters; i++) {
560        SendMessage(ceSocketFD,cp[i].name.c_str());
561        sprintf(var,"%f",cp[i].value);
562        SendMessage(ceSocketFD,var);
563    }
564
565    /* Receive Set of Parameters */
566    LOG("Cognitive Radio Shell:: Receiving optimized parameters.\n");
567    memset(buffer, 0, 256);
568    ReadMessage(ceSocketFD, buffer);
569    uint32_t numParameters = atoi(buffer);
570   
571    Parameter *p = new Parameter[numParameters];
572 
573    for(size_t i = 0; i < numParameters; i++) {
574        memset(buffer, 0, 256);
575        ReadMessage(ceSocketFD, buffer);
576        p[i].name = std::string(buffer);
577   
578        memset(buffer, 0, 256);
579        ReadMessage(ceSocketFD, buffer);
580        p[i].value = atof(buffer);
581    }
582
583    /* Send to Application
584     */
585    LOG("Cognitive Radio Shell:: Sending optimized parameters to Application.\n");
586    memset(counter, 0, 55);
587    sprintf(counter, "%i", numParameters);
588    SendMessage(commandSocketFD, counter);
589    for(size_t i = 0; i < numParameters; i++) {
590        SendMessage(commandSocketFD, p[i].name.c_str());
591        sprintf(var, "%f", p[i].value);
592        SendMessage(commandSocketFD, var);
593    }
594
595    delete [] o;
596    delete [] p;
597}
598
599// TODO point of always returning 1?
600bool
601CognitiveRadioShell::UpdateParameterPerformance(int32_t socketFD)
602{
603    char counter[55];
604    char var[50];
605    char buffer[256];
606
607    /* Receive Set of Parameters */
608    memset(buffer, 0, 256);
609    ReadMessage(commandSocketFD,buffer);
610    uint32_t numParameters = atoi(buffer);
611 
612    Parameter *p = new Parameter[numParameters];
613
614    for (size_t i = 0; i < numParameters; i++){
615        memset(buffer, 0, 256);
616        ReadMessage(commandSocketFD,buffer);
617        p[i].name = std::string(buffer);
618
619        memset(buffer, 0, 256);
620        ReadMessage(commandSocketFD,buffer);
621        p[i].value = atof(buffer);
622    }
623
624    /* Receive Set of Observables */
625    memset(buffer, 0, 256);
626    ReadMessage(commandSocketFD, buffer);
627    uint32_t numObservables = atoi(buffer);
628 
629    Observable *o = new Observable[numObservables];
630 
631    for(size_t i = 0; i < numObservables; i++) {
632        memset(buffer, 0, 256);
633        ReadMessage(commandSocketFD, buffer);
634        o[i].name = std::string(buffer);
635   
636        memset(buffer, 0, 256);
637        ReadMessage(commandSocketFD, buffer);
638        o[i].value = atof(buffer);
639    }
640
641    SendMessage(ceSocketFD, "update_performance");
642   
643    /* Send Parameters */
644    memset(counter, 0, 55);
645    sprintf(counter, "%i", numParameters);
646    SendMessage(ceSocketFD, counter);
647   
648    for(size_t i = 0; i < numParameters; i++) {
649        SendMessage(ceSocketFD,p[i].name.c_str());
650        sprintf(var,"%f",p[i].value);
651        SendMessage(ceSocketFD,var); 
652    }   
653   
654    /* Send Observables */
655    sprintf(counter, "%i", numObservables);
656    SendMessage(ceSocketFD, counter);
657    for(size_t i = 0; i < numObservables; i++) {
658        SendMessage(ceSocketFD, o[i].name.c_str());
659        sprintf(var, "%f", o[i].value);
660        SendMessage(ceSocketFD, var);
661    }   
662
663    delete [] p;
664    delete [] o;
665   
666    return true;
667}
668
669
670int32_t
671CognitiveRadioShell::HandleMessage(int32_t socketFD)
672{
673    char buffer[256];
674    int ret = 0;
675   
676    ret = ReadMessage(socketFD, buffer);
677    if(ret == -1)
678        return ret;
679
680    // TODO trying to read this code block makes my eyes bleed
681    if(strcmp(buffer, "register_engine_cognitive") == 0) {
682        RegisterCognitiveEngine(socketFD);
683    } else if(strcmp(buffer, "deregister_engine_cognitive") == 0) {
684        DeregisterCognitiveEngine(socketFD);
685    } else if(strcmp(buffer, "register_engine_policy") == 0) {
686        RegisterPolicyEngine(socketFD);
687    } else if(strcmp(buffer, "deregister_engine_policy") == 0) {
688        DeregisterPolicyEngine(socketFD);
689    } else if(strcmp(buffer, "register_sml") == 0) {
690        RegisterSML(socketFD);
691    } else if(strcmp(buffer, "deregister_sml") == 0) {
692        DeregisterSML(socketFD);
693    } else if(strcmp(buffer, "update_performance") == 0) {
694        UpdateParameterPerformance(socketFD);
695    } else if(strcmp(buffer, "get_number_utilities") == 0) {
696        char numUtilities[20];
697        sprintf(numUtilities, "%i", radio_info->numUtilities);
698        SendMessage(commandSocketFD, numUtilities);
699    } else if(strcmp(buffer, "get_number_observables") == 0) {
700        char numObservables[20];
701        sprintf(numObservables, "%i", radio_info->numObservables);
702        SendMessage(commandSocketFD, numObservables);
703    } else if(strcmp(buffer, "get_number_parameters") == 0) {
704        char numParameters[20];
705        sprintf(numParameters, "%i", radio_info->numParameters);
706        SendMessage(commandSocketFD, numParameters);
707    } else if(strcmp(buffer, "request_optimization") == 0) {
708        /* Receive optimization request and current environment */
709        GetOptimalParameters(socketFD); 
710    } else if(strcmp(buffer, "set_active_mission") == 0) {
711        SetActiveMission(socketFD); 
712    } else if(strcmp(buffer, "request_optimization_service") == 0) {
713        /* Receive optimization request and current environment */
714        //GetOptimalParametersService(socketFD); 
715    }
716
717    return ret;
718}
719
720
721void
722CognitiveRadioShell::StartShellServer()
723{
724    struct timeval selTimeout;
725    int32_t primary = 0;
726    int32_t policy = 1;
727    int32_t command = 2;
728    int32_t running = 1;
729    int32_t port, rc, new_sd = 1;
730    int32_t desc_ready = 1;
731    int32_t timeout = 50;
732    int32_t ret = 0;;
733    fd_set sockSet;
734   
735    int32_t *servSock = new int32_t[3];
736
737    servSock[primary] = CreateTCPServerSocket(primaryPort);
738    servSock[policy] = CreateTCPServerSocket(policyPort);
739    servSock[command] = CreateTCPServerSocket(commandPort);
740
741    int32_t maxDescriptor;
742
743    if(servSock[primary] > servSock[policy])
744        maxDescriptor = servSock[primary];
745    else
746        maxDescriptor = servSock[policy];
747
748    if(servSock[command] > maxDescriptor)
749        maxDescriptor = servSock[command];
750
751    if(InitializeTCPServerPort(servSock[primary]) == -1)
752        ERROR(1,"Error initializing primary port\n");
753 
754    if(InitializeTCPServerPort(servSock[policy]) == -1)
755        ERROR(1,"Error initializing policy port\n");
756
757    if(InitializeTCPServerPort(servSock[command]) == -1)
758        ERROR(1,"Error initializing command port\n");
759
760    FD_ZERO(&sockSet);
761   
762    while(running) {
763        /* Zero socket descriptor vector and set for server sockets */
764        /* This must be reset every time select() is called */
765        FD_SET(servSock[primary], &sockSet);
766        FD_SET(servSock[policy], &sockSet);
767        FD_SET(servSock[command], &sockSet);
768
769        /* Timeout specification */
770        /* This must be reset every time select() is called */
771        selTimeout.tv_sec = timeout;       /* timeout (secs.) */
772        selTimeout.tv_usec = 0;            /* 0 microseconds */
773
774        /* Suspend program until descriptor is ready or timeout */
775        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
776        if(rc == 0)
777            LOG("No echo requests for %i secs...Server still alive\n", timeout);
778        else {
779            desc_ready = rc;
780
781            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
782                if(FD_ISSET(port, &sockSet)) {
783                    desc_ready -= 1;
784                    /* Check if request is new or on an existing open descriptor */
785                    if((port == servSock[primary]) || \
786                            (port == servSock[policy]) || \
787                            (port == servSock[command])) {
788                        do {
789                            new_sd = AcceptTCPConnection(port);
790                            if(new_sd < 0)
791                                break;
792                            if(port == servSock[primary])
793                                ceSocketFD = new_sd;
794                            if(port == servSock[command])
795                                commandSocketFD = new_sd;
796                            if(port == servSock[policy])
797                                policySocketFD = new_sd;
798
799                            ret = HandleMessage(new_sd);
800
801                            if(ret == -1) {
802                                FD_CLR(new_sd,&sockSet);
803                                close(new_sd);
804                                break;
805                            }
806
807                            FD_SET(new_sd,&sockSet);
808                            if(new_sd > maxDescriptor)
809                                maxDescriptor = new_sd;
810
811                        } while(new_sd != -1);
812                    }
813                    else {
814                        ret = HandleMessage(port);
815                        if(ret == -1) {
816                            FD_CLR(port,&sockSet);
817                            close(port);
818                        }
819                    }
820                }
821            }
822        }
823    }
824
825    LOG("Closing it all.\n\n");
826
827    /* Close sockets */
828    close(servSock[primary]);
829    close(servSock[policy]);
830    close(servSock[command]);
831
832    /* Free list of sockets */
833    delete servSock;
834
835    return;
836}
837
Note: See TracBrowser for help on using the browser.