root/vtcross/trunk/src/shell/cr_shell.cpp @ 166

Revision 166, 21.8 KB (checked in by bhilburn, 15 years ago)

Starting converting the shell code to our new design and good code style.

RevLine 
[166]1/* Virginia Tech Cognitive Radio Open Source Systems
2 * Virginia Tech, 2009
3 *
4 * TODO LICENSE INFORMATION GOES HERE
5 */
6
7/* TODO DESCRIPTION OF FILE.
8 */
9
10
11#include <arpa/inet.h>
[35]12#include <iostream>
[96]13#include <netinet/in.h>
14#include <netdb.h>
[97]15#include <fcntl.h>
16#include <sys/ioctl.h>
[166]17#include <sys/mman.h>
18#include <sys/socket.h>
19#include <sys/types.h>
20#include <sys/wait.h>
[97]21
[161]22#include "tinyxml/tinyxml.h"
23#include "tinyxml/tinystr.h"
24
[166]25#include "vtcross/common.h"
26#include "vtcross/components.h"
27#include "vtcross/containers.h"
28#include "vtcross/debug.h"
29#include "vtcross/error.h"
30#include "vtcross/socketcomm.h"
31
32
[35]33using namespace std;
34
[166]35
[97]36#define CE_SERVER_PORT 30001
[166]37#define PE_SERVER_PORT 30003
[35]38
[166]39
40void
41print_current_config(Utility* uList[], Parameter* pList[], \
42        Observable* oList[], CE_Info* ce_info)
[97]43{
[166]44        for(size_t i = 0; i < ce_info->numUtilities ; i++) {
45        LOG("Shell:: Utility: %s\n\tUnits: %s\n\tGoal: %s\n\tTarget: %s\n", \
46                uList[i]->name, uList[i]->units, uList[i]->goal, \
47                uList[i]->target);
48        }
[97]49
[166]50        for(size_t i = 0; i < ce_info->numParameters; i++) {
51            LOG("Shell:: Radio Operation Profile has been sucessfully sent.\n");
52        LOG("Shell:: Parameter: %s\n\tUnits: %s\n\tMin: %s\n\t", \
53                pList[i]->name, pList[i]->units, pList[i]->min);
54        LOG("\tMax: %s\n\tStep: %s\n", pList[i]->max, pList[i]->step);
[35]55
[166]56                for(size_t j = 0; j < pList[i]->numAffects; j++) {
57                        LOG("\t\tAffect %s -> %s\n", pList[i]->affection_list[j].u->name, \
58                    pList[i]->affection_list[j].relation);
[35]59                }
60        }
[80]61       
[166]62    for(size_t i = 0; i < ce_info->numObservables; i++) {
63                LOG("Observable: %s\n", oList[i]->name);
64                for(size_t j = 0; j < oList[i]->numAffects; j++) {
65                        LOG("\t\tAffect %s -> %s ", oList[i]->affection_list[j].u->name, \
66                    oList[i]->affection_list[j].relation);
[35]67                }
68        }
69}
70
71
[166]72int32_t
73parse_ce_config(TiXmlDocument* doc, Utility* u[], Parameter* p[], \
74        Observable* o[], CE_Info* ce_info)
75{
[35]76
77        TiXmlElement* pElem;    //!current element
78        TiXmlElement* pChild;   //!current child of pElem
79        TiXmlElement* pChild1;  //!current child of pElem
80        TiXmlElement* pSecondChild;     //!current child of pElem
81        TiXmlHandle hDoc(doc);  //!handle to xml document
82        TiXmlHandle hRoot(0); //! handle to root element
83
[166]84        int32_t count = 0;
85        int32_t i = 0;
86        int32_t j = 0;
87        int32_t k = 0;
88        int32_t match_found = 0;
[35]89
90        pElem = hDoc.FirstChildElement().Element();
91        if(!pElem) { cout << "no valid root! quit-ing function!" << endl; return 0; }
92        hRoot = TiXmlHandle(pElem);
93
94        // Pull utility information from XML file.
95
96        pElem = hRoot.FirstChild("utilities").Element();
97        pChild1 = hRoot.Child("utilities",count).Element();
98
99
100        for(pChild = pChild1->FirstChildElement("utility"); pChild; pChild = pChild->NextSiblingElement())
101        {
102                u[i] = new Utility;
103                const char *uName = pChild->Attribute("name");
104                if(uName) u[i]->name = uName;   
105                const char *uUnits = pChild->Attribute("units");
106                if(uUnits) u[i]->units = uUnits;
107                const char *uGoal = pChild->Attribute("goal");
108                if(uGoal) u[i]->goal = uGoal;
109                if(pChild->QueryFloatAttribute("target",&u[i]->target) != TIXML_SUCCESS) u[i]->target = -1;
110                i++;
111        }
112        ce_info->numUtilities = i;     
[95]113        cout << "Initialize:: Parsed " << ce_info->numUtilities << " utilities." << endl;
[35]114
115        // Pull observable information from XML file.
116        i = 0;
117        pElem = hRoot.FirstChild("observables").Element();
118        pChild1 = hRoot.Child("observables",count).Element();
119       
120        for(pChild = pChild1->FirstChildElement("observable"); pChild; pChild = pChild->NextSiblingElement())
121        {
122
123                const char *oName = pChild->Attribute("name");
124                o[i] = new Observable;
125
126                if(oName) o[i]->name = oName;
127               
128                j = 0;
129                for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; pSecondChild = pSecondChild->NextSiblingElement())
130                {
131                        const char *oUtilName = pSecondChild->Attribute("utility");
132
133                        // If a utility affects this parameter find the utility object and assign it
134                        if(oUtilName) {
135                                // Search for correct utility
[86]136                                for( k=0 ; u[k]!=NULL ; k++ ){
[35]137                                        if(u[k]->name == oUtilName) {
138                                                o[i]->affection_list[j].u = u[k];
[86]139                                                // Set relationship
140                                                const char *oRelate = pSecondChild->Attribute("relationship");
141                                                if(oRelate) o[i]->affection_list[j].relation = oRelate;
142                                                j++;
143                                                match_found = 1;
[35]144                                                break;
145                                        }
146                                }
147                        }
[86]148                        if(!match_found) cout << "Error: " << o[i]->name << ": " << oUtilName << " not a valid utility: Affect not added." << endl;     
149                        match_found = 0;       
[35]150                }
151                o[i]->numAffects = j;
152                i++;
153        }
154        ce_info->numObservables = i;   
[95]155        cout << "Initialize:: Parsed " << ce_info->numObservables << " observables." << endl;
[35]156       
157
158        // Pull parameter information from XML file.
159        pElem = hRoot.FirstChild("parameters").Element();
160        pChild1 = hRoot.Child("parameters",count).Element();
161       
162        i = 0;
163        for(pChild = pChild1->FirstChildElement("parameter"); pChild; pChild = pChild->NextSiblingElement())
164        {
165                p[i] = new Parameter;
166
167                const char *pName = pChild->Attribute("name");
168                if(pName) p[i]->name = pName;   
169                const char *pUnits = pChild->Attribute("units");
170                if(pUnits) p[i]->units = pUnits;
171
172                if(pChild->QueryFloatAttribute("min",&p[i]->min) != TIXML_SUCCESS) p[i]->min = -1;
173                if(pChild->QueryFloatAttribute("max",&p[i]->max) != TIXML_SUCCESS) p[i]->max = -1;
174                if(pChild->QueryFloatAttribute("step",&p[i]->step) != TIXML_SUCCESS) p[i]->step = -1;
175               
176                j = 0;
177                for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; pSecondChild = pSecondChild->NextSiblingElement())
178                {
179                        const char *pUtilName = pSecondChild->Attribute("utility");
180                       
181                        // If a utility affects this parameter find the utility object and assign it
182                        if(pUtilName) {
183                                // Search for correct utility
184                                for( k=0 ; u[k]!=NULL ; k++ ){
185                                        if(u[k]->name == pUtilName) {
[86]186                                                // If match found, assign it to this index
[35]187                                                p[i]->affection_list[j].u = u[k];       
[86]188                                                const char *pRelate = pSecondChild->Attribute("relationship");
189                                                if(pRelate) {
190                                                        p[i]->affection_list[j].relation = pRelate;
191                                                } else {
192                                                        cout << "Error: No relation found." << endl;
193                                                }
194                                                match_found = 1;
195                                                j++;
[35]196                                                break;
197                                        }
198                                }
199                        }
[86]200                        if(!match_found) cout << "Error: " << p[i]->name << ": " << pUtilName << " not a valid utility: Affect not added." << endl;     
201                        match_found = 0;       
[35]202                }
203                p[i]->numAffects = j;
204                i++;
205
206        }
207        ce_info->numParameters = i;     
[95]208        cout << "Initialize:: Parsed " << ce_info->numParameters << " parameters." << endl;
[35]209        return 1;
210}
211
212
[166]213int32_t
214ReceiveMessage(int32_t socket, char* buffer)
[63]215{
[166]216    int32_t i,n;
[97]217   
218    n = recv(socket,buffer,256,MSG_PEEK);
[65]219   
[81]220    for(i=0;i<256;i++){
221        if(strcmp(&buffer[i],"\0") == 0) break;
222    }
223    n = recv(socket,buffer,i+1,0);
224    if (n < 0)
225        error("ERROR reading from socket");
[166]226    //    print32_tf("ReadMessage:%s %d\n",buffer,n);
[81]227
228    return n;
[65]229}
230
[81]231
[166]232int32_t
233SendMessage(int32_t socketfd, string message)
234{
235        int32_t n;
[65]236
[85]237        message.append("\0");   
[65]238        // Write message back to client
[97]239    n = send(socketfd,message.c_str(),(message.size()+1),0);
[90]240    if (n<0)
241        error("Error sending to client\n");
242    if(n == 0)
[166]243        print32_tf("Client closed the socket.\n");
[85]244
[166]245        //print32_tf("SendMessage:%s %d\n",message.c_str(),n); 
[90]246    return n;
[65]247}
248
[72]249
[166]250void
251LoadCEConfiguration(int32_t socketfd,Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info){
252        int32_t n,i,j;
[65]253        char counter[55];
254        char var[50];
[166]255        //int32_t total_bytes;   
[72]256
[166]257        print32_tf("Cognitive Radio:: Sending Radio Operating Profile to Cognitive Engine.\n\n");
[72]258 
[80]259        // utilities
[72]260        // Send number of utilities
[166]261        sprint32_tf(counter,"%d",ce_info->numUtilities);
[72]262        SendMessage(socketfd,counter);
[80]263        // send utility
264    for(i = 0; i < ce_info->numUtilities; i++) {
[72]265                SendMessage(socketfd,uList[i]->name);
266                SendMessage(socketfd,uList[i]->units);
267                SendMessage(socketfd,uList[i]->goal);
[166]268                sprint32_tf(var,"%f",uList[i]->target);
[72]269                SendMessage(socketfd,var);
270        }
[66]271
[72]272        // parameters
[166]273    sprint32_tf(counter,"%i",ce_info->numParameters);
[72]274        SendMessage(socketfd,counter);
275        for(i = 0; i < ce_info->numParameters; i++) {
276                SendMessage(socketfd,pList[i]->name);
277                SendMessage(socketfd,pList[i]->units);
[166]278                sprint32_tf(var,"%f",pList[i]->min);
[72]279                SendMessage(socketfd,var);
[166]280                sprint32_tf(var,"%f",pList[i]->max);
[72]281                SendMessage(socketfd,var);
[166]282                sprint32_tf(var,"%f",pList[i]->step);
[72]283                SendMessage(socketfd,var);
284               
[166]285                sprint32_tf(counter,"%i",pList[i]->numAffects);
[65]286                SendMessage(socketfd,counter);
[72]287                for(j = 0; j < pList[i]->numAffects; j++) {
288                        SendMessage(socketfd,pList[i]->affection_list[j].u->name);
289                        SendMessage(socketfd,pList[i]->affection_list[j].relation);
[65]290                }
[72]291        }
[66]292
[80]293    // observables
[166]294        sprint32_tf(counter,"%i",ce_info->numObservables);
[72]295        SendMessage(socketfd,counter);
296        for(i = 0; i < ce_info->numObservables; i++) {
297                SendMessage(socketfd,oList[i]->name);
298               
[166]299                sprint32_tf(counter,"%i",oList[i]->numAffects);
[65]300                SendMessage(socketfd,counter);
[72]301                for(j = 0; j < oList[i]->numAffects; j++) {
302                        SendMessage(socketfd,oList[i]->affection_list[j].u->name);
303                        SendMessage(socketfd,oList[i]->affection_list[j].relation);
[71]304                }
[72]305        }
[66]306       
[72]307        // Receive ACK for utils
[81]308    char buffer[256];
[66]309        string message;
[81]310        n = ReceiveMessage(socketfd, buffer);
[166]311    //print32_tf("%s\n", buffer);
[81]312        //cout << message << endl;
[166]313        //print32_tf("ACK received.\n");
[66]314
[72]315}
[66]316
[72]317void UpdateCEConfiguration() {
318
319}
320
321void ResetCEConfiguration(){
322
323}
324
[166]325void UpdateCEExperience(int32_t socketfd, int32_t num_rows, int32_t num_cols,
[87]326        float * past_exp[])
327{
[166]328    int32_t i, j;
[87]329        char counter[55];
330        char var[50];
[72]331
[87]332    for (i = 0; i < num_rows; i++){
333        for (j = 0; j< num_cols; j++){
[166]334                sprint32_tf(var,"%f",past_exp[i][j]);
335        //print32_tf("%f, \n", past_exp[i][j]);
336        //print32_tf("%s, \n", var);
[87]337        }
338    }
339   
340    // send the number of rows to the ce first
[166]341        sprint32_tf(counter,"%d",num_rows);
[87]342        SendMessage(socketfd,counter);
343    // send the number of columns to the ce
[166]344        sprint32_tf(counter,"%d",num_cols);
[87]345        SendMessage(socketfd,counter);
346    // update ce with experience
347    for (i = 0; i < num_rows; i++){
348        for (j = 0; j< num_cols; j++){
[166]349                sprint32_tf(var,"%f",past_exp[i][j]);
[87]350                SendMessage(socketfd,var);
351        }
352    }
[90]353
[72]354}
355
356void ResetCEExperience() {
357
358}
359
[82]360// Update operating settings
[166]361// This function will int32_teract with the hardware "drivers"
[87]362void UpdateRadioSettings()
363{
[72]364}
365
[97]366
[166]367int32_t RequestPolicyValidation(Parameter * pList[], CE_Info *ce_info)
[97]368{
369        char counter[55];
370        char var[50];
[166]371    int32_t i;
[97]372    string control_msg;
373   
[166]374    int32_t socketfd = ce_info->policy_socket;
[97]375
376    // Control message that validation request is coming
377    control_msg = "val";
378        SendMessage(socketfd,control_msg);
379
[166]380    print32_tf("Cognitive Radio:: Here. %i\n\n", socketfd);
[97]381
382        // Send parameter information
[166]383    sprint32_tf(counter,"%i",ce_info->numParameters);
[97]384        SendMessage(socketfd,counter);
385        for(i = 0; i < ce_info->numParameters; i++) {
386                SendMessage(socketfd,pList[i]->name);
387                SendMessage(socketfd,pList[i]->units);
[166]388                sprint32_tf(var,"%f",pList[i]->min);
[97]389                SendMessage(socketfd,var);
[166]390                sprint32_tf(var,"%f",pList[i]->max);
[97]391                SendMessage(socketfd,var);
[166]392                sprint32_tf(var,"%f",pList[i]->step);
[97]393                SendMessage(socketfd,var);
[166]394                sprint32_tf(var,"%f",pList[i]->value);
[97]395                SendMessage(socketfd,var);
396               
397        }
398    return 1;
399
400}
401
402
[166]403int32_t RequestCEOptimization(int32_t sockfd, Utility *uList[],
[80]404        Parameter *pList[], Observable *oList[],
405        CE_Info *ce_info)
406{
[81]407    char buffer[256];
[166]408    int32_t i;
[80]409    float var;
[72]410
[95]411    // Send request optimization message followed by the current environment parameters.
412    /*
413    SendMessage(sockfd,"request");
414    for (i = 0; i < ce_info->numObservables; i++){
415        SendMessage(sockfd,..);
416    }
417    */
418
419    // Receive optimized values from the Cognitive Engine
[80]420    for (i = 0; i < ce_info->numParameters; i++){
[81]421        bzero(buffer,256);
422        ReceiveMessage(sockfd,buffer);
423        var = atof(buffer);
[80]424        pList[i]->value = var;
425    }
426
[82]427
[97]428    // If policy engine is connect, validate new values
429    if(ce_info->policy_engine == 1) {
430
[166]431        print32_tf("Cognitive Radio:: Found Policy Engine!\n");
432        print32_tf("Cognitive Radio:: Validating parameters with Policy Engine\n\n");
[97]433        RequestPolicyValidation(pList,ce_info);
[166]434        print32_tf("Cognitive Radio:: Done\n\n");
[97]435
436    }
437
438
[81]439    return 1;
[80]440}
441
[166]442void RunSimulator(int32_t socketfd, Utility * uList[],
[80]443        Parameter * pList[], Observable * oList[],
444        CE_Info * ce_info) {
[85]445       
446        float **past_exp;
[166]447    int32_t num_rows, num_cols;
[80]448
[78]449        // Set fake current environment params = current environment
[82]450        RequestCEOptimization(socketfd, uList, pList, oList, ce_info);
[72]451
452        // Act like we are updating the hardware tranmission settings
[82]453        UpdateRadioSettings();
[72]454
455        // Send back fake utility values
[87]456    // need to initialize
457        //UpdateCEExperience(socketfd, num_rows, num_cols, past_exp);   
[63]458}
[35]459
[166]460void InitializePE(int32_t socket, CE_Info * ce_info)
[87]461{
[97]462    // Policy Engine is connected
463    // Set global policy engine value to 1
464    ce_info->policy_engine = 1;
465    ce_info->policy_socket = socket;
466
467    return;
468}
469
[166]470void InitializeCE(int32_t socketfd, Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info)
[97]471{
[80]472        LoadCEConfiguration(socketfd, uList, pList, oList, ce_info);
[85]473       
[87]474    // cr experience
475    float **past_exp;
[166]476        int32_t num_cols;
[87]477    // get number of columns
478    num_cols = ce_info->numUtilities + ce_info->numParameters;
479    num_cols = num_cols + ce_info->numObservables;
480    num_cols = num_cols + 1;    // overall utility
[166]481    int32_t num_rows = 2;
[87]482    past_exp = (float **)malloc(sizeof(float)*num_rows);
[166]483    int32_t i;
[87]484    for (i=0; i<num_rows; i++){
485        past_exp[i] = (float*)malloc(sizeof(float)*num_cols);
486    }
487    // sample experience #1
488    past_exp[0][0] = 1e3f;  // throughput
489    past_exp[0][1] = 1;     // spectral_efficiency
490    past_exp[0][2] = -3.5;  // log10_ber
491    past_exp[0][3] = 1;     // mod_scheme
[90]492    past_exp[0][4] = -10;   // tx_power
[87]493    past_exp[0][5] = 10.0;  // SNR
[90]494    past_exp[0][6] = 0.762; // overall utility*/
495    // sample experience #2
[87]496    past_exp[1][0] = 1e2f;  // throughput
497    past_exp[1][1] = 1;     // spectral_efficiency
498    past_exp[1][2] = -3.5;  // log10_ber
499    past_exp[1][3] = 1;     // mod_scheme
[90]500    past_exp[1][4] = -14;   // tx_power
501    past_exp[1][5] = 3.0;   // SNR
502    past_exp[1][6] = 0.462; // overall utility
[72]503
[87]504        // update ce with experience
[166]505    print32_tf("Cognitive Radio:: Sending Previous Experience to New Cognitive Engine.\n\n");
[87]506    UpdateCEExperience(socketfd, num_rows, num_cols, past_exp);
507
[80]508        RunSimulator(socketfd, uList, pList, oList, ce_info);
[72]509}
510
[166]511int32_t AcceptTCPConnection(int32_t servSock)
[97]512{
[166]513    int32_t clntSock;                    /* Socket descriptor for client */
[97]514    struct sockaddr_in echoClntAddr;
[166]515    unsigned int32_t clntLen;
[35]516
[97]517    /* Set the size of the in-out parameter */
518    clntLen = sizeof(echoClntAddr);
[35]519
[97]520    /* Wait for a client to connect */
521    //if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr, &clntLen)) < 0) {
522    if ((clntSock = accept(servSock, NULL, NULL)) < 0) {
523        return -1;
524    }
525   
526    /* clntSock is connected to a client! */
527   
[166]528    print32_tf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));
[63]529
[97]530    return clntSock;
531}
[95]532
[166]533int32_t CreateTCPServerSocket(unsigned short port)
[97]534{
[166]535    int32_t sock;                        /* socket to create */
[97]536    struct sockaddr_in echoServAddr; /* Local address */
537
538    /* Create socket for incoming connections */
539    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
540        DieWithError("socket() failed");
541     
542    /* Construct local address structure */
543    memset(&echoServAddr, 0, sizeof(echoServAddr));   /* Zero out structure */
[166]544    echoServAddr.sin_family = AF_INET;                /* int32_ternet address family */
545    echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming int32_terface */
[97]546    echoServAddr.sin_port = htons(port);              /* Local port */
547
548    /* Bind to the local address */
549    if (bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
550        DieWithError("bind() failed");
551
552    /* Mark the socket so it will listen for incoming connections */
553    if (listen(sock, 5) < 0) {
[166]554        print32_tf("listen() failed\n");
[97]555        return 0;
556    }
557
558    return sock;
559}
560
[166]561void HandleTCPClient(int32_t socketfd, Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info)
[97]562{
563    char buffer[256];        /* Buffer for echo string */
564
565    /* Receive message from client */
566    bzero(buffer,256);
567    ReceiveMessage(socketfd,buffer);
568
[166]569    print32_tf("Cognitive Radio:: Message Received - %s.\n\n", buffer);
[97]570
571    if(strcmp(buffer,"c_register") == 0)
572            InitializeCE(socketfd, uList, pList, oList, ce_info);
573
574    if(strcmp(buffer,"p_register") == 0)
575            InitializePE(socketfd, ce_info);
576
577    if(strcmp(buffer,"optimize") == 0)
578            RunSimulator(socketfd, uList, pList, oList, ce_info);
579       
580    //close(socketfd);    /* Close client socket */
581}
582
[166]583int32_t StartServers(Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info) {
584    int32_t * servSock;
585    int32_t running = 1;
[97]586    struct timeval selTimeout;
[166]587    int32_t timeout = 10;
588    int32_t cognitive_engine = 0;
589    int32_t policy_engine = 1;
590    int32_t port, rc, on = 1;
591    int32_t new_sd;
592    int32_t desc_ready = 0;
[97]593    fd_set sockSet;
594   
[166]595    servSock = (int32_t *) malloc(2 * sizeof(int32_t));
[97]596
597    servSock[cognitive_engine] = CreateTCPServerSocket(CE_SERVER_PORT);
[166]598    servSock[policy_engine] = CreateTCPServerSocket(PE_SERVER_PORT);
[97]599
600
[166]601    int32_t maxDescriptor = servSock[cognitive_engine];
[97]602
603    if(servSock[cognitive_engine] < servSock[policy_engine])
604        maxDescriptor = servSock[policy_engine];
605
606    rc = setsockopt(servSock[cognitive_engine], SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
607    if(rc < 0)
608    {
609        perror("setsockopt() failed");
610        close(servSock[cognitive_engine]);
611        exit(-1);
612    }
613   
614    rc = setsockopt(servSock[policy_engine], SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
615    if(rc < 0)
616    {
617        perror("setsockopt() failed");
618        close(servSock[policy_engine]);
619        exit(-1);
620    }
621   
622    rc = ioctl(servSock[cognitive_engine], FIONBIO, (char*)&on);
623    if(rc < 0)
624    {
625        perror("ioctl() failed");
626        close(servSock[cognitive_engine]);
627        exit(-1);
628    }
629   
630    rc = ioctl(servSock[policy_engine], FIONBIO, (char*)&on);
631    if(rc < 0)
632    {
633        perror("ioctl() failed");
634        close(servSock[policy_engine]);
635        exit(-1);
636    }
637   
[166]638    print32_tf("Starting server:  Hit return to shutdown\n");
[97]639    while (running)
640    {
641        /* Zero socket descriptor vector and set for server sockets */
642        /* This must be reset every time select() is called */
643        FD_ZERO(&sockSet);
644        /* Add keyboard to descriptor vector */
645        FD_SET(STDIN_FILENO, &sockSet);
646        FD_SET(servSock[cognitive_engine], &sockSet);
647        FD_SET(servSock[policy_engine], &sockSet);
648
649        /* Timeout specification */
650        /* This must be reset every time select() is called */
651        selTimeout.tv_sec = timeout;       /* timeout (secs.) */
652        selTimeout.tv_usec = 0;            /* 0 microseconds */
653
654        /* Suspend program until descriptor is ready or timeout */
655        rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout);
656        if (rc == 0)
[166]657            print32_tf("No echo requests for %i secs...Server still alive\n", timeout);
[97]658        else
659        {
660            if (FD_ISSET(0, &sockSet)) /* Check keyboard */
661            {
[166]662                print32_tf("Shutting down server\n");
[97]663                getchar();
664                running = 0;
665            }
666
667            desc_ready = rc;
668
669            for (port = 0; port <= maxDescriptor && desc_ready > 0; port++) {
670                if (FD_ISSET(port, &sockSet))
671                {
[166]672                    print32_tf("Request on port %d:  ", port);
[97]673                        desc_ready -= 1;
674
675
676                    if( (port == servSock[cognitive_engine]) || (port == servSock[policy_engine])) {
677                       
678                        do
679                        {
680                            new_sd = AcceptTCPConnection(port);
681                            if(new_sd < 0)
682                            {
683                                break;
684                            }
685                           
686                            HandleTCPClient(new_sd, uList, pList, oList, ce_info);
687                            FD_SET(new_sd,&sockSet);
688                            if(new_sd > maxDescriptor)
689                                maxDescriptor = new_sd;
[166]690                            print32_tf("New incoming connection - %i\n\n",new_sd);
[97]691                        } while(new_sd != -1);
692                    } else {
693                       
[166]694                        print32_tf("Request on already open descriptor.\n\n");
[97]695                        HandleTCPClient(port, uList, pList, oList, ce_info);
696
697                    }
698
699                }
700            }
701        }
702    }
703
704    /* Close sockets */
705    for (port = 0; port < 2; port++)
706        close(servSock[port]);
707
708    /* Free list of sockets */
709    free(servSock);       
710       
[63]711        return 0;
[35]712}
713
[166]714int32_t
715main(int32_t argc, char* argv[])
716{
[35]717        // CognitiveEngine CE;
718        // CognitiveEngineShell Shell;
719        string pFilename;
[166]720    int32_t fd;
[35]721
722        Utility * uList[10];
723        Parameter * pList[10];
724        Observable * oList[10];
[97]725        struct CE_Info *ce_info;
[35]726
[97]727    if((fd = open("/dev/zero", O_RDWR)) == -1)
728            return 1;
729
730    ce_info = (struct CE_Info *)mmap(0,sizeof(CE_Info),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
731
732    close(fd);
733
[35]734        if(argc < 2) {
735                cout << "Warning no XML file specific using default: example.xml" << endl;
736                pFilename = "example.xml";
737        } else { 
738                pFilename = argv[1];
739        }
740
741        TiXmlDocument doc( pFilename.c_str() );
742        bool loadOkay = doc.LoadFile();
743        if (!loadOkay)
744        {
745                cout << "Loading " << pFilename << " failed." << endl;
746                return 0;
747        }
748
[95]749        cout << "\n\nInitialize:: Attemping to parse " << pFilename << "." << endl;
[97]750        parse_ce_config( &doc , uList, pList, oList, ce_info);
[95]751        cout << "Initialize:: Configuration file parsing completed.\n" << endl;
[35]752
[166]753    //print32_t_current_config(uList, pList, oList, &ce_info);
[69]754       
[97]755   StartServers(uList, pList, oList, ce_info);
[35]756   return 1;
[71]757}
Note: See TracBrowser for help on using the browser.