root/vtcross/branches/trnewman/CR_shell/src/main_cognitive_radio.cpp @ 90

Revision 90, 15.2 KB (checked in by ahe, 16 years ago)

fixed the bug, experience transmission works

RevLine 
[35]1#include <iostream>
[63]2#include <sys/types.h>
3#include <sys/wait.h>
[35]4#include "tinyxml.h"
5#include "tinystr.h"
6#include "socket/ServerSocket.h"
7#include "socket/SocketException.h"
8
9using namespace std;
10
11#define SERVER_PORT 30000
12
13struct CE_Info {
14        int numUtilities;
15        int numParameters;
16        int numObservables;
17};
18
19struct Utility {
20        string name;
21        string units;
22        string goal;
23        float target;
[80]24    float value;
[35]25};
26struct Affect {
27        Utility * u;
28        string relation;
29};
30struct Parameter {
31        string name;
32        string units;
33        float min;
34        int numAffects;
35        Affect affection_list[10];
36        float max;
37        float step;
[80]38    float value;
[35]39};
40
41struct Observable {
42        string name;
43        Affect affection_list[10];
44        int numAffects;
[80]45    float value;
[35]46};
47
[65]48void print_current_config(Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info) {
[35]49        int i = 0;
50        int j = 0;
51
52        for(i = 0; i < ce_info->numUtilities ; i++) {
53                cout << "Utility:  " << uList[i]->name << endl;
54                cout << "     Units:  " << uList[i]->units << endl;
55                cout << "     Goal:   " << uList[i]->goal << endl;
56                cout << "     Target: " << uList[i]->target << endl;
57        }
58
59        for(i = 0; i < ce_info->numParameters; i++) {
60                cout << "Parameter:  " << pList[i]->name << endl;
61                cout << "       Units:   " << pList[i]->units << endl;
62                cout << "       Min:     " << pList[i]->min << endl;
63                cout << "       Max:     " << pList[i]->max << endl;
64                cout << "       Step:    " << pList[i]->step << endl;
65                for(j = 0; j < pList[i]->numAffects; j++) {
66                        cout << "       Affect: " << pList[i]->affection_list[j].u->name << " -> " << pList[i]->affection_list[j].relation << endl;
67                }
68        }
[80]69       
70    for(i = 0; i < ce_info->numObservables; i++) {
[35]71                cout << "Observable:  " << oList[i]->name << endl;
72                for(j = 0; j < oList[i]->numAffects; j++) {
73                        cout << "       Affect: " << oList[i]->affection_list[j].u->name << " -> " << oList[i]->affection_list[j].relation << endl;
74                }
75        }
76}
77
78
79int parse_ce_config( TiXmlDocument * doc , Utility * u[], Parameter * p[], Observable * o[], CE_Info * ce_info) {
80
81        TiXmlElement* pElem;    //!current element
82        TiXmlElement* pChild;   //!current child of pElem
83        TiXmlElement* pChild1;  //!current child of pElem
84        TiXmlElement* pSecondChild;     //!current child of pElem
85        TiXmlHandle hDoc(doc);  //!handle to xml document
86        TiXmlHandle hRoot(0); //! handle to root element
87
88        int count = 0;
89        int i = 0;
90        int j = 0;
91        int k = 0;
[86]92        int match_found = 0;
[35]93
94        pElem = hDoc.FirstChildElement().Element();
95        if(!pElem) { cout << "no valid root! quit-ing function!" << endl; return 0; }
96        hRoot = TiXmlHandle(pElem);
97
98        // Pull utility information from XML file.
99
100        pElem = hRoot.FirstChild("utilities").Element();
101        pChild1 = hRoot.Child("utilities",count).Element();
102
103
104        for(pChild = pChild1->FirstChildElement("utility"); pChild; pChild = pChild->NextSiblingElement())
105        {
106                u[i] = new Utility;
107                const char *uName = pChild->Attribute("name");
108                if(uName) u[i]->name = uName;   
109                const char *uUnits = pChild->Attribute("units");
110                if(uUnits) u[i]->units = uUnits;
111                const char *uGoal = pChild->Attribute("goal");
112                if(uGoal) u[i]->goal = uGoal;
113                if(pChild->QueryFloatAttribute("target",&u[i]->target) != TIXML_SUCCESS) u[i]->target = -1;
114                i++;
115        }
116        ce_info->numUtilities = i;     
117        cout << "Parsed " << ce_info->numUtilities << " utilities." << endl;
118
119        // Pull observable information from XML file.
120        i = 0;
121        pElem = hRoot.FirstChild("observables").Element();
122        pChild1 = hRoot.Child("observables",count).Element();
123       
124        for(pChild = pChild1->FirstChildElement("observable"); pChild; pChild = pChild->NextSiblingElement())
125        {
126
127                const char *oName = pChild->Attribute("name");
128                o[i] = new Observable;
129
130                if(oName) o[i]->name = oName;
131               
132                j = 0;
133                for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; pSecondChild = pSecondChild->NextSiblingElement())
134                {
135                        const char *oUtilName = pSecondChild->Attribute("utility");
136
137                        // If a utility affects this parameter find the utility object and assign it
138                        if(oUtilName) {
139                                // Search for correct utility
[86]140                                for( k=0 ; u[k]!=NULL ; k++ ){
[35]141                                        if(u[k]->name == oUtilName) {
142                                                o[i]->affection_list[j].u = u[k];
[86]143                                                // Set relationship
144                                                const char *oRelate = pSecondChild->Attribute("relationship");
145                                                if(oRelate) o[i]->affection_list[j].relation = oRelate;
146                                                j++;
147                                                match_found = 1;
[35]148                                                break;
149                                        }
150                                }
151                        }
[86]152                        if(!match_found) cout << "Error: " << o[i]->name << ": " << oUtilName << " not a valid utility: Affect not added." << endl;     
153                        match_found = 0;       
[35]154                }
155                o[i]->numAffects = j;
156                i++;
157        }
158        ce_info->numObservables = i;   
159        cout << "Parsed " << ce_info->numObservables << " observables." << endl;
160       
161
162        // Pull parameter information from XML file.
163        pElem = hRoot.FirstChild("parameters").Element();
164        pChild1 = hRoot.Child("parameters",count).Element();
165       
166        i = 0;
167        for(pChild = pChild1->FirstChildElement("parameter"); pChild; pChild = pChild->NextSiblingElement())
168        {
169                p[i] = new Parameter;
170
171                const char *pName = pChild->Attribute("name");
172                if(pName) p[i]->name = pName;   
173                const char *pUnits = pChild->Attribute("units");
174                if(pUnits) p[i]->units = pUnits;
175
176                if(pChild->QueryFloatAttribute("min",&p[i]->min) != TIXML_SUCCESS) p[i]->min = -1;
177                if(pChild->QueryFloatAttribute("max",&p[i]->max) != TIXML_SUCCESS) p[i]->max = -1;
178                if(pChild->QueryFloatAttribute("step",&p[i]->step) != TIXML_SUCCESS) p[i]->step = -1;
179               
180                j = 0;
181                for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; pSecondChild = pSecondChild->NextSiblingElement())
182                {
183                        const char *pUtilName = pSecondChild->Attribute("utility");
184                       
185                        // If a utility affects this parameter find the utility object and assign it
186                        if(pUtilName) {
187                                // Search for correct utility
188                                for( k=0 ; u[k]!=NULL ; k++ ){
189                                        if(u[k]->name == pUtilName) {
[86]190                                                // If match found, assign it to this index
[35]191                                                p[i]->affection_list[j].u = u[k];       
[86]192                                                const char *pRelate = pSecondChild->Attribute("relationship");
193                                                if(pRelate) {
194                                                        p[i]->affection_list[j].relation = pRelate;
195                                                } else {
196                                                        cout << "Error: No relation found." << endl;
197                                                }
198                                                match_found = 1;
199                                                j++;
[35]200                                                break;
201                                        }
202                                }
203                        }
[86]204                        if(!match_found) cout << "Error: " << p[i]->name << ": " << pUtilName << " not a valid utility: Affect not added." << endl;     
205                        match_found = 0;       
[35]206                }
207                p[i]->numAffects = j;
208                i++;
209
210        }
211        ce_info->numParameters = i;     
212        cout << "Parsed " << ce_info->numParameters << " parameters." << endl;
213        return 1;
214}
215
216
[63]217void error(char *msg)
218{
219    perror(msg);
220    exit(1);
221}
[35]222
223
[81]224int ReceiveMessage(int socket,char * buffer)
225{
226    int i,n;
[65]227   
[81]228    n = recv(socket,buffer,256,MSG_PEEK);
229    for(i=0;i<256;i++){
230        if(strcmp(&buffer[i],"\0") == 0) break;
231    }
232    n = recv(socket,buffer,i+1,0);
233    if (n < 0)
234        error("ERROR reading from socket");
235    //    printf("ReadMessage:%s %d\n",buffer,n);
236
237    return n;
[65]238}
239
[81]240
[65]241int SendMessage(int socketfd, string message) {
242        int n;
243
[85]244        message.append("\0");   
[65]245        // Write message back to client
[90]246    n = write(socketfd,message.c_str(),(message.size()+1));
247    if (n<0)
248        error("Error sending to client\n");
249    if(n == 0)
250        printf("Client closed the socket.\n");
[85]251
[90]252        //printf("SendMessage:%s %d\n",message.c_str(),n);     
253    return n;
[65]254}
255
[72]256void GetEnvironment() {
257
258}
259
260void Policy_ValidateSettings() {
261
262}
263
264
265void LoadCEConfiguration(int socketfd,Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info){
[65]266        int n,i,j;
267        char counter[55];
268        char var[50];
[82]269        //int total_bytes;   
[72]270
271        printf("Sending configuration to CE.\n");
272 
[80]273        // utilities
[72]274        // Send number of utilities
275        sprintf(counter,"%d",ce_info->numUtilities);
276        SendMessage(socketfd,counter);
[80]277        // send utility
278    for(i = 0; i < ce_info->numUtilities; i++) {
[72]279                SendMessage(socketfd,uList[i]->name);
280                SendMessage(socketfd,uList[i]->units);
281                SendMessage(socketfd,uList[i]->goal);
282                sprintf(var,"%f",uList[i]->target);
283                SendMessage(socketfd,var);
284        }
[66]285
[72]286        // parameters
[80]287    sprintf(counter,"%i",ce_info->numParameters);
[72]288        SendMessage(socketfd,counter);
289        for(i = 0; i < ce_info->numParameters; i++) {
290                SendMessage(socketfd,pList[i]->name);
291                SendMessage(socketfd,pList[i]->units);
292                sprintf(var,"%f",pList[i]->min);
293                SendMessage(socketfd,var);
294                sprintf(var,"%f",pList[i]->max);
295                SendMessage(socketfd,var);
296                sprintf(var,"%f",pList[i]->step);
297                SendMessage(socketfd,var);
298               
299                sprintf(counter,"%i",pList[i]->numAffects);
[65]300                SendMessage(socketfd,counter);
[72]301                for(j = 0; j < pList[i]->numAffects; j++) {
302                        SendMessage(socketfd,pList[i]->affection_list[j].u->name);
303                        SendMessage(socketfd,pList[i]->affection_list[j].relation);
[65]304                }
[72]305        }
[66]306
[80]307    // observables
[72]308        sprintf(counter,"%i",ce_info->numObservables);
309        SendMessage(socketfd,counter);
310        for(i = 0; i < ce_info->numObservables; i++) {
311                SendMessage(socketfd,oList[i]->name);
312               
313                sprintf(counter,"%i",oList[i]->numAffects);
[65]314                SendMessage(socketfd,counter);
[72]315                for(j = 0; j < oList[i]->numAffects; j++) {
316                        SendMessage(socketfd,oList[i]->affection_list[j].u->name);
317                        SendMessage(socketfd,oList[i]->affection_list[j].relation);
[71]318                }
[72]319        }
[66]320       
[72]321        printf("Configuration sent, waiting for ACK...\n");
322        // Receive ACK for utils
[81]323    char buffer[256];
[66]324        string message;
[81]325        n = ReceiveMessage(socketfd, buffer);
326    printf("%s\n", buffer);
327        //cout << message << endl;
[72]328        printf("ACK received.\n");
[66]329
[72]330}
[66]331
[72]332void UpdateCEConfiguration() {
333
334}
335
336void ResetCEConfiguration(){
337
338}
339
[87]340void UpdateCEExperience(int socketfd, int num_rows, int num_cols,
341        float * past_exp[])
342{
343    char buffer[256];
344    int i, j;
345        char counter[55];
346        char var[50];
[72]347
[87]348    for (i = 0; i < num_rows; i++){
349        for (j = 0; j< num_cols; j++){
350                sprintf(var,"%f",past_exp[i][j]);
[90]351        //printf("%f, \n", past_exp[i][j]);
352        //printf("%s, \n", var);
[87]353        }
354    }
355   
356    // send the number of rows to the ce first
357        sprintf(counter,"%d",num_rows);
358        SendMessage(socketfd,counter);
359    // send the number of columns to the ce
360        sprintf(counter,"%d",num_cols);
361        SendMessage(socketfd,counter);
362    // update ce with experience
363    for (i = 0; i < num_rows; i++){
364        for (j = 0; j< num_cols; j++){
365                sprintf(var,"%f",past_exp[i][j]);
366                SendMessage(socketfd,var);
367        }
368    }
[90]369
370    printf("experience sent\n");
[72]371}
372
373void ResetCEExperience() {
374
375}
376
[82]377// Update operating settings
378// This function will interact with the hardware "drivers"
[87]379void UpdateRadioSettings()
380{
[72]381}
382
[82]383int RequestCEOptimization(int sockfd, Utility *uList[],
[80]384        Parameter *pList[], Observable *oList[],
385        CE_Info *ce_info)
386{
[81]387    char buffer[256];
[80]388    int i;
389    float var;
[72]390
[82]391    /*// utility
[80]392    for (i = 0; i < ce_info->numUtilities; i++){
393        bzero(buffer,256);
[81]394        ReceiveMessage(sockfd,buffer);
395        var = atof(buffer);
[80]396        uList[i]->value = var;
[81]397        printf("utility %s, value %f\n"
398                , uList[i]->name.c_str(), uList[i]->value);
[82]399    }*/
[80]400   
401    // paramter
402    for (i = 0; i < ce_info->numParameters; i++){
[81]403        bzero(buffer,256);
404        ReceiveMessage(sockfd,buffer);
405        var = atof(buffer);
[80]406        pList[i]->value = var;
[81]407        printf("parameter %s, value %f\n"
408                , pList[i]->name.c_str(), pList[i]->value);
[80]409    }
410
[82]411    /*// observable
[80]412    for (i = 0; i < ce_info->numObservables; i++){
[81]413        bzero(buffer,256);
414        ReceiveMessage(sockfd,buffer);
415        var = atof(buffer);
[80]416        oList[i]->value = var;
[81]417        printf("observable %s, value %f\n"
418                , oList[i]->name.c_str(), oList[i]->value);
[82]419    }*/
420
[81]421    return 1;
[80]422}
423
424void RunSimulator(int socketfd, Utility * uList[],
425        Parameter * pList[], Observable * oList[],
426        CE_Info * ce_info) {
[85]427       
428        float **past_exp;
[87]429    int num_rows, num_cols;
[80]430
[78]431        // Set fake current environment params = current environment
[82]432        RequestCEOptimization(socketfd, uList, pList, oList, ce_info);
[72]433
434        // Act like we are updating the hardware tranmission settings
[82]435        UpdateRadioSettings();
[72]436
437        // Send back fake utility values
[87]438    // need to initialize
439        //UpdateCEExperience(socketfd, num_rows, num_cols, past_exp);   
[63]440}
[35]441
[87]442void StartMessaging(int socketfd, Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info)
443{
[80]444        LoadCEConfiguration(socketfd, uList, pList, oList, ce_info);
[85]445       
[87]446    // cr experience
447    float **past_exp;
448        int num_cols;
449    // get number of columns
450    num_cols = ce_info->numUtilities + ce_info->numParameters;
451    num_cols = num_cols + ce_info->numObservables;
452    num_cols = num_cols + 1;    // overall utility
[90]453    int num_rows = 2;
[87]454    past_exp = (float **)malloc(sizeof(float)*num_rows);
455    int i;
456    for (i=0; i<num_rows; i++){
457        past_exp[i] = (float*)malloc(sizeof(float)*num_cols);
458    }
459    // sample experience #1
460    past_exp[0][0] = 1e3f;  // throughput
461    past_exp[0][1] = 1;     // spectral_efficiency
462    past_exp[0][2] = -3.5;  // log10_ber
463    past_exp[0][3] = 1;     // mod_scheme
[90]464    past_exp[0][4] = -10;   // tx_power
[87]465    past_exp[0][5] = 10.0;  // SNR
[90]466    past_exp[0][6] = 0.762; // overall utility*/
467    // sample experience #2
[87]468    past_exp[1][0] = 1e2f;  // throughput
469    past_exp[1][1] = 1;     // spectral_efficiency
470    past_exp[1][2] = -3.5;  // log10_ber
471    past_exp[1][3] = 1;     // mod_scheme
[90]472    past_exp[1][4] = -14;   // tx_power
473    past_exp[1][5] = 3.0;   // SNR
474    past_exp[1][6] = 0.462; // overall utility
[72]475
[87]476
477        // update ce with experience
478    UpdateCEExperience(socketfd, num_rows, num_cols, past_exp);
479
[80]480        RunSimulator(socketfd, uList, pList, oList, ce_info);
[72]481}
482
[65]483int StartShell(int port,Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info) {
[63]484        // Start socket server
485        int sockfd, newsockfd, clilen;
486        struct sockaddr_in serv_addr, cli_addr;
[35]487
[73]488        // Setup server socket connection
489        sockfd = socket(AF_INET, SOCK_STREAM, 0);
[63]490        if (sockfd < 0)
491                error("ERROR opening socket");
492        bzero((char *) &serv_addr, sizeof(serv_addr));
493        serv_addr.sin_family = AF_INET;
494        serv_addr.sin_port = htons(port);
[73]495        serv_addr.sin_addr.s_addr = INADDR_ANY;
[63]496        if (bind(sockfd, (struct sockaddr *) &serv_addr,
497                sizeof(serv_addr)) < 0)
498                error("ERROR on binding");
499        listen(sockfd,5);
500        clilen = sizeof(cli_addr);
[35]501
[66]502        //while(1) {
[64]503                newsockfd = accept(sockfd,
504                        (struct sockaddr *) &cli_addr,
505                        (socklen_t*)&clilen);
506                if (newsockfd < 0)
507                        error("ERROR on accept");
[63]508
[64]509                // Begin parsing the messages
[80]510                StartMessaging(newsockfd, uList, pList, oList, ce_info);
[66]511        //}
[63]512        return 0;
[35]513}
514
515int main(int argc, char* argv[]) {
516
517
518        // CognitiveEngine CE;
519        // CognitiveEngineShell Shell;
520        string pFilename;
[64]521        int pid;
[35]522
523        Utility * uList[10];
524        Parameter * pList[10];
525        Observable * oList[10];
526        CE_Info ce_info;
527
528        if(argc < 2) {
529                cout << "Warning no XML file specific using default: example.xml" << endl;
530                pFilename = "example.xml";
531        } else { 
532                pFilename = argv[1];
533        }
534
535        TiXmlDocument doc( pFilename.c_str() );
536        bool loadOkay = doc.LoadFile();
537        if (!loadOkay)
538        {
539                cout << "Loading " << pFilename << " failed." << endl;
540                return 0;
541        }
542
543        cout << "Attemping to parse " << pFilename << "." << endl;
544        parse_ce_config( &doc , uList, pList, oList, &ce_info);
545        cout << "Configuration file parsing completed." << endl;
546
[72]547    //print_current_config(uList, pList, oList, &ce_info);
[69]548       
549    pid = fork();
[64]550        if(pid == 0) {
551                // In child process - open policy engine port.
[71]552        //      StartShell(30000,uList, pList, oList, &ce_info);
[64]553        } else {
554                // In parent process - open cognitive engine port.
[82]555                StartShell(30001,uList, pList, oList, &ce_info);
[64]556        }
557       
[35]558
559   return 1;
[71]560}
Note: See TracBrowser for help on using the browser.