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

Revision 537, 25.0 KB (checked in by bhilburn, 14 years ago)

Removing useless return types from CRS functions
'LoadRadioConfiguration?' and 'UpdateParameterPerformance?'.

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
325void
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
494
495void
496CognitiveRadioShell::GetOptimalParameters(int32_t socketFD)
497{
498    char buffer[256];
499    char counter[55];
500    char var[50];
501
502    /* Receive Set of Observables */
503    LOG("Cognitive Radio Shell:: Got request for optimization.\n");
504    memset(buffer, 0, 256);
505    ReadMessage(commandSocketFD, buffer);
506    uint32_t numObservables = atoi(buffer);
507 
508    LOG("Cognitive Radio Shell:: Attempting to get %i observables.\n", numObservables);
509    Observable *o = new Observable[numObservables];
510 
511    for(size_t i = 0; i < numObservables; i++) {
512        memset(buffer, 0, 256);
513        ReadMessage(commandSocketFD, buffer);
514        o[i].name = std::string(buffer);
515   
516        memset(buffer, 0, 256);
517        ReadMessage(commandSocketFD, buffer);
518        o[i].value = atof(buffer);
519    }
520
521    /* Receive Set of Current Parameters */
522    memset(buffer, 0, 256);
523    ReadMessage(commandSocketFD,buffer);
524    uint32_t numCurrentParameters = atoi(buffer);
525 
526    LOG("Cognitive Radio Shell:: Attempting to get %i parameters.\n",numCurrentParameters);
527    Parameter *cp = new Parameter[numCurrentParameters];
528
529    for (size_t i = 0; i < numCurrentParameters; i++){
530        memset(buffer, 0, 256);
531        ReadMessage(commandSocketFD,buffer);
532        cp[i].name = std::string(buffer);
533
534        memset(buffer, 0, 256);
535        ReadMessage(commandSocketFD,buffer);
536        cp[i].value = atof(buffer);
537    }
538
539    /* Send to Cognitive Engine
540     * TODO: With multiple CEs we need to make a decision about where
541     * to send this information
542     */
543    LOG("Cognitive Radio Shell:: Passing on observables.\n");
544    SendMessage(ceSocketFD,"request_optimization");
545    sprintf(counter,"%i",numObservables);
546    SendMessage(ceSocketFD,counter);
547    for(size_t i = 0; i < numObservables; i++) {
548        SendMessage(ceSocketFD,o[i].name.c_str());
549        sprintf(var,"%f",o[i].value);
550        SendMessage(ceSocketFD,var);
551    }
552       
553    LOG("Cognitive Radio Shell:: Passing on current parameters.\n");
554    sprintf(counter,"%i",numCurrentParameters);
555    SendMessage(ceSocketFD,counter);
556    for(size_t i = 0; i < numCurrentParameters; i++) {
557        SendMessage(ceSocketFD,cp[i].name.c_str());
558        sprintf(var,"%f",cp[i].value);
559        SendMessage(ceSocketFD,var);
560    }
561
562    /* Receive Set of Parameters */
563    LOG("Cognitive Radio Shell:: Receiving optimized parameters.\n");
564    memset(buffer, 0, 256);
565    ReadMessage(ceSocketFD, buffer);
566    uint32_t numParameters = atoi(buffer);
567   
568    Parameter *p = new Parameter[numParameters];
569 
570    for(size_t i = 0; i < numParameters; i++) {
571        memset(buffer, 0, 256);
572        ReadMessage(ceSocketFD, buffer);
573        p[i].name = std::string(buffer);
574   
575        memset(buffer, 0, 256);
576        ReadMessage(ceSocketFD, buffer);
577        p[i].value = atof(buffer);
578    }
579
580    /* Send to Application
581     */
582    LOG("Cognitive Radio Shell:: Sending optimized parameters to Application.\n");
583    memset(counter, 0, 55);
584    sprintf(counter, "%i", numParameters);
585    SendMessage(commandSocketFD, counter);
586    for(size_t i = 0; i < numParameters; i++) {
587        SendMessage(commandSocketFD, p[i].name.c_str());
588        sprintf(var, "%f", p[i].value);
589        SendMessage(commandSocketFD, var);
590    }
591
592    delete [] o;
593    delete [] p;
594}
595
596
597void
598CognitiveRadioShell::UpdateParameterPerformance(int32_t socketFD)
599{
600    char counter[55];
601    char var[50];
602    char buffer[256];
603
604    /* Receive Set of Parameters */
605    memset(buffer, 0, 256);
606    ReadMessage(commandSocketFD,buffer);
607    uint32_t numParameters = atoi(buffer);
608 
609    Parameter *p = new Parameter[numParameters];
610
611    for (size_t i = 0; i < numParameters; i++){
612        memset(buffer, 0, 256);
613        ReadMessage(commandSocketFD,buffer);
614        p[i].name = std::string(buffer);
615
616        memset(buffer, 0, 256);
617        ReadMessage(commandSocketFD,buffer);
618        p[i].value = atof(buffer);
619    }
620
621    /* Receive Set of Observables */
622    memset(buffer, 0, 256);
623    ReadMessage(commandSocketFD, buffer);
624    uint32_t numObservables = atoi(buffer);
625 
626    Observable *o = new Observable[numObservables];
627 
628    for(size_t i = 0; i < numObservables; i++) {
629        memset(buffer, 0, 256);
630        ReadMessage(commandSocketFD, buffer);
631        o[i].name = std::string(buffer);
632   
633        memset(buffer, 0, 256);
634        ReadMessage(commandSocketFD, buffer);
635        o[i].value = atof(buffer);
636    }
637
638    SendMessage(ceSocketFD, "update_performance");
639   
640    /* Send Parameters */
641    memset(counter, 0, 55);
642    sprintf(counter, "%i", numParameters);
643    SendMessage(ceSocketFD, counter);
644   
645    for(size_t i = 0; i < numParameters; i++) {
646        SendMessage(ceSocketFD,p[i].name.c_str());
647        sprintf(var,"%f",p[i].value);
648        SendMessage(ceSocketFD,var); 
649    }   
650   
651    /* Send Observables */
652    sprintf(counter, "%i", numObservables);
653    SendMessage(ceSocketFD, counter);
654    for(size_t i = 0; i < numObservables; i++) {
655        SendMessage(ceSocketFD, o[i].name.c_str());
656        sprintf(var, "%f", o[i].value);
657        SendMessage(ceSocketFD, var);
658    }   
659
660    delete [] p;
661    delete [] o;
662}
663
664
665int32_t
666CognitiveRadioShell::HandleMessage(int32_t socketFD)
667{
668    char buffer[256];
669    int ret = 0;
670   
671    ret = ReadMessage(socketFD, buffer);
672    if(ret == -1)
673        return ret;
674
675    // TODO trying to read this code block makes my eyes bleed
676    if(strcmp(buffer, "register_engine_cognitive") == 0) {
677        RegisterCognitiveEngine(socketFD);
678    } else if(strcmp(buffer, "deregister_engine_cognitive") == 0) {
679        DeregisterCognitiveEngine(socketFD);
680    } else if(strcmp(buffer, "register_engine_policy") == 0) {
681        RegisterPolicyEngine(socketFD);
682    } else if(strcmp(buffer, "deregister_engine_policy") == 0) {
683        DeregisterPolicyEngine(socketFD);
684    } else if(strcmp(buffer, "register_sml") == 0) {
685        RegisterSML(socketFD);
686    } else if(strcmp(buffer, "deregister_sml") == 0) {
687        DeregisterSML(socketFD);
688    } else if(strcmp(buffer, "update_performance") == 0) {
689        UpdateParameterPerformance(socketFD);
690    } else if(strcmp(buffer, "get_number_utilities") == 0) {
691        char numUtilities[20];
692        sprintf(numUtilities, "%i", radio_info->numUtilities);
693        SendMessage(commandSocketFD, numUtilities);
694    } else if(strcmp(buffer, "get_number_observables") == 0) {
695        char numObservables[20];
696        sprintf(numObservables, "%i", radio_info->numObservables);
697        SendMessage(commandSocketFD, numObservables);
698    } else if(strcmp(buffer, "get_number_parameters") == 0) {
699        char numParameters[20];
700        sprintf(numParameters, "%i", radio_info->numParameters);
701        SendMessage(commandSocketFD, numParameters);
702    } else if(strcmp(buffer, "request_optimization") == 0) {
703        /* Receive optimization request and current environment */
704        GetOptimalParameters(socketFD); 
705    } else if(strcmp(buffer, "set_active_mission") == 0) {
706        SetActiveMission(socketFD); 
707    } else if(strcmp(buffer, "request_optimization_service") == 0) {
708        /* Receive optimization request and current environment */
709        //GetOptimalParametersService(socketFD); 
710    }
711
712    return ret;
713}
714
715
716void
717CognitiveRadioShell::StartShellServer()
718{
719    struct timeval selTimeout;
720    int32_t primary = 0;
721    int32_t policy = 1;
722    int32_t command = 2;
723    int32_t running = 1;
724    int32_t port, rc, new_sd = 1;
725    int32_t desc_ready = 1;
726    int32_t timeout = 50;
727    int32_t ret = 0;;
728    fd_set sockSet;
729   
730    int32_t *servSock = new int32_t[3];
731
732    servSock[primary] = CreateTCPServerSocket(primaryPort);
733    servSock[policy] = CreateTCPServerSocket(policyPort);
734    servSock[command] = CreateTCPServerSocket(commandPort);
735
736    int32_t maxDescriptor;
737
738    if(servSock[primary] > servSock[policy])
739        maxDescriptor = servSock[primary];
740    else
741        maxDescriptor = servSock[policy];
742
743    if(servSock[command] > maxDescriptor)
744        maxDescriptor = servSock[command];
745
746    if(InitializeTCPServerPort(servSock[primary]) == -1)
747        ERROR(1,"Error initializing primary port\n");
748 
749    if(InitializeTCPServerPort(servSock[policy]) == -1)
750        ERROR(1,"Error initializing policy port\n");
751
752    if(InitializeTCPServerPort(servSock[command]) == -1)
753        ERROR(1,"Error initializing command port\n");
754
755    FD_ZERO(&sockSet);
756   
757    while(running) {
758        /* Zero socket descriptor vector and set for server sockets */
759        /* This must be reset every time select() is called */
760        FD_SET(servSock[primary], &sockSet);
761        FD_SET(servSock[policy], &sockSet);
762        FD_SET(servSock[command], &sockSet);
763
764        /* Timeout specification */
765        /* This must be reset every time select() is called */
766        selTimeout.tv_sec = timeout;       /* timeout (secs.) */
767        selTimeout.tv_usec = 0;            /* 0 microseconds */
768
769        /* Suspend program until descriptor is ready or timeout */
770        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
771        if(rc == 0)
772            LOG("No echo requests for %i secs...Server still alive\n", timeout);
773        else {
774            desc_ready = rc;
775
776            for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
777                if(FD_ISSET(port, &sockSet)) {
778                    desc_ready -= 1;
779                    /* Check if request is new or on an existing open descriptor */
780                    if((port == servSock[primary]) || \
781                            (port == servSock[policy]) || \
782                            (port == servSock[command])) {
783                        do {
784                            new_sd = AcceptTCPConnection(port);
785                            if(new_sd < 0)
786                                break;
787                            if(port == servSock[primary])
788                                ceSocketFD = new_sd;
789                            if(port == servSock[command])
790                                commandSocketFD = new_sd;
791                            if(port == servSock[policy])
792                                policySocketFD = new_sd;
793
794                            ret = HandleMessage(new_sd);
795
796                            if(ret == -1) {
797                                FD_CLR(new_sd,&sockSet);
798                                close(new_sd);
799                                break;
800                            }
801
802                            FD_SET(new_sd,&sockSet);
803                            if(new_sd > maxDescriptor)
804                                maxDescriptor = new_sd;
805
806                        } while(new_sd != -1);
807                    }
808                    else {
809                        ret = HandleMessage(port);
810                        if(ret == -1) {
811                            FD_CLR(port,&sockSet);
812                            close(port);
813                        }
814                    }
815                }
816            }
817        }
818    }
819
820    LOG("Closing it all.\n\n");
821
822    /* Close sockets */
823    close(servSock[primary]);
824    close(servSock[policy]);
825    close(servSock[command]);
826
827    /* Free list of sockets */
828    delete servSock;
829
830    return;
831}
832
Note: See TracBrowser for help on using the browser.