root/vtcross/trunk/CR_shell/src/main_cognitive_radio.cpp @ 95

Revision 95, 15.3 KB (checked in by trnewman, 15 years ago)

Cleaned up the code and put in the hooks for optimization request messages

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