root/vtcross/trunk/src/cognitive_engines/CognitiveEngine.cpp @ 228

Revision 228, 15.9 KB (checked in by trnewman, 15 years ago)

Added sending current parameters in the libvt request optimization function.

Added guts to the CBR so it actually creates an sql db and searches it.

Line 
1/* Virginia Tech Cognitive Radio Open Source Systems
2 * Virginia Tech, 2009
3 *
4 * LICENSE INFORMATION GOES HERE
5 */
6
7/* DESCRIPTION OF FILE.
8 */
9
10
11#include <cstdlib>
12#include <cstring>
13#include <stdint.h>
14
15#include "vtcross/common.h"
16#include "vtcross/components.h"
17#include "vtcross/containers.h"
18#include "vtcross/debug.h"
19#include "vtcross/error.h"
20#include "vtcross/socketcomm.h"
21#include "vtcross/cbr.h"
22
23#include "cbr.c"
24
25#include <sqlite3.h>
26#include <sqlite3ext.h>
27
28
29
30static cbr myCBR;
31
32CognitiveEngine::CognitiveEngine()
33{
34    LOG("Creating Cognitive Engine.\n");
35    SML_present = false;
36    commandSocketFD = -1;
37}
38
39
40CognitiveEngine::~CognitiveEngine()
41{
42        cbr_free(myCBR);
43    delete [] pList;
44    delete [] oList;
45    delete [] uList;
46    delete [] radioInfo;
47}
48
49
50CognitiveEngine::CognitiveEngine(const char* serverName, const char* serverPort, \
51        const bool SML)
52{
53    LOG("Creating Cognitive Engine.\n");
54
55    pList = new Parameter[10];
56    oList = new Observable[10];
57    uList = new Utility[10];
58    radioInfo = new Radio_Info;
59
60    ConnectToRemoteComponent(serverName, serverPort, SML);
61}
62
63
64void
65CognitiveEngine::SendComponentType()
66{
67    SendMessage(commandSocketFD, "response_engine_cognitive");
68    LOG("Cognitive Engine responded to GetRemoteComponentType query.\n");
69}
70
71
72void
73CognitiveEngine::ConnectToRemoteComponent(const char* serverName, \
74        const char* serverPort, const bool SML)
75{
76    commandSocketFD = ClientSocket(serverName, serverPort);
77
78    SML_present = SML;
79
80    if(SML) {
81        RegisterComponent();
82        RegisterServices();
83        LOG("Cognitive Engine connected to SML at %s.\n", serverName);
84        ReceiveRadioConfiguration();
85        ReceiveExperience();
86    }
87    else {
88        RegisterComponent();
89        LOG("Cognitive Engine connected to shell at %s.\n", serverName);
90        ReceiveRadioConfiguration();
91        ReceiveExperience();
92    }
93}
94
95void
96CognitiveEngine::WaitForSignal()
97{
98    char buffer[256];
99
100    while(true) {
101        memset(buffer, 0, 256);
102       
103        ReadMessage(commandSocketFD, buffer);
104
105        // TODO this is ugly... is there a better way? Doesn't strcmp compare the
106        // whole string?  We only need to compare until we find a single different
107        // byte...
108        //
109        // If we send integer op codes rather than strings, this process will be
110        // MUCH faster since instead of donig string compares we can simply
111        // switch on the integer value...
112        if(strcmp(buffer, "request_optimization") == 0) {
113           
114            /* Receive Set of Observables */
115                        LOG("Cognitive Engine:: Receiving Observable Parameters\n");
116
117            memset(buffer, 0, 256);
118            ReadMessage(commandSocketFD,buffer);
119            uint32_t numObservables = atoi(buffer);
120   
121            Observable *o = new Observable[numObservables];
122 
123            for(size_t i = 0; i < numObservables; i++) {
124                memset(buffer, 0, 256);
125                ReadMessage(commandSocketFD, buffer);
126                o[i].name = std::string(buffer);
127   
128                memset(buffer, 0, 256);
129                ReadMessage(commandSocketFD, buffer);
130                o[i].value = atof(buffer);
131            } 
132
133            /* Receive Set of current Parameters */
134                        LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n");
135
136            memset(buffer, 0, 256);
137            ReadMessage(commandSocketFD,buffer);
138            uint32_t numCurrentParameters = atoi(buffer);
139   
140            Parameter *cp = new Parameter[numCurrentParameters];
141 
142            for(size_t i = 0; i < numCurrentParameters; i++) {
143                memset(buffer, 0, 256);
144                ReadMessage(commandSocketFD, buffer);
145                cp[i].name = std::string(buffer);
146   
147                memset(buffer, 0, 256);
148                ReadMessage(commandSocketFD, buffer);
149                cp[i].value = atof(buffer);
150            } 
151                        LOG("Cognitive Engine:: Processing parameters....\n");
152
153            Parameter *solutionSet;
154                       
155                        solutionSet = GetSolution(o,cp);
156
157            // TODO need to actually do something with the observables here
158           
159                        LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n");
160                        char numParametersChar[10];
161                        char solutionValue[50];
162                        sprintf(numParametersChar,"%i",radioInfo->numParameters);
163                        SendMessage(commandSocketFD,numParametersChar);
164            for(size_t i = 0; i < radioInfo->numParameters; i++) {
165                SendMessage(commandSocketFD,solutionSet[i].name.c_str());
166                memset(solutionValue, 0, 50);
167                            sprintf(solutionValue,"%f",solutionSet[i].value);
168                SendMessage(commandSocketFD,solutionValue);
169                        }
170
171            delete [] o;
172            delete [] cp;
173        }
174        else if(strcmp(buffer, "query_component_type") == 0) {
175            SendComponentType();
176        }
177        else if(strcmp(buffer, "connect_sml") == 0) {
178            /* This command implies that we are disconnecting from the shell and
179             * connecting to a SML component. */
180            char serverName[256];
181            char serverPort[256];
182            // TODO is this going to end up being too slow?
183            memset(serverName, 0, 256);
184            memset(serverPort, 0, 256);
185
186            ReadMessage(commandSocketFD, serverName);
187            ReadMessage(commandSocketFD, serverPort);
188
189            /* Only continue if we are currently connected to a shell. */
190            if(!SML_present) {
191                DeregisterComponent();
192
193                shutdown(commandSocketFD, 2);
194                close(commandSocketFD);
195
196                ConnectToRemoteComponent(serverName, serverPort, true);
197            }
198        }
199        else if(strcmp(buffer, "disconnect_sml") == 0) {
200            /* This command implies that we are disconnecting from the SML and
201             * connecting to a shell component. */
202            char serverName[256];
203            char serverPort[256];
204            // TODO is this going to end up being too slow?
205            memset(serverName, 0, 256);
206            memset(serverPort, 0, 256);
207
208            ReadMessage(commandSocketFD, serverName);
209            ReadMessage(commandSocketFD, serverPort);
210
211            /* We only want to do this if we are actually connected to an SML
212             * currently. */
213            if(SML_present) {
214                DeregisterServices();
215
216                shutdown(commandSocketFD, 2);
217                close(commandSocketFD);
218
219                ConnectToRemoteComponent(serverName, serverPort, false);
220            }
221        }
222        else if(strcmp(buffer, "reset_engine_cognitive") == 0) {
223            Reset();
224        }
225        else if(strcmp(buffer, "shutdown_engine_cognitive") == 0) {
226            Shutdown();
227        }
228    }
229}
230
231
232void
233CognitiveEngine::Shutdown()
234{
235    if(SML_present) {
236        DeregisterServices();
237        DeregisterComponent();
238    }
239    else {
240        DeregisterComponent();
241    }
242    // TODO should something else be happening here?
243}
244
245
246void
247CognitiveEngine::Reset()
248{
249    LOG("Resetting Cognitive Engine.\n");
250
251    if(SML_present) {
252        DeregisterServices();
253        DeregisterComponent();
254    }
255    else {
256        DeregisterComponent();
257    }
258}
259
260
261void
262CognitiveEngine::RegisterComponent()
263{
264    SendMessage(commandSocketFD, "register_engine_cognitive");
265    LOG("Cognitive Engine:: Registration message sent to shell.\n");
266}
267
268void
269CognitiveEngine::DeregisterComponent()
270{
271    SendMessage(commandSocketFD, "deregister_engine_cognitive");
272    LOG("Cognitive Engine:: Deregistration message sent.\n");
273
274    shutdown(commandSocketFD, 2);
275    close(commandSocketFD);
276    commandSocketFD = -1;
277    LOG("Cognitive Engine:: Shell socket closed.\n");
278}
279
280
281void
282CognitiveEngine::RegisterServices()
283{
284    LOG("Cognitive Engine:: Registering services.\n");
285
286    SendMessage(commandSocketFD, "register_service");
287    SendMessage(commandSocketFD, "jam_wifi");
288
289    SendMessage(commandSocketFD, "register_service");
290    SendMessage(commandSocketFD, "signal_detection");
291
292    SendMessage(commandSocketFD, "register_service");
293    SendMessage(commandSocketFD, "max_throughput");
294
295    SendMessage(commandSocketFD, "register_service");
296    SendMessage(commandSocketFD, "jam_bluetooth");
297}
298
299
300void
301CognitiveEngine::DeregisterServices()
302{
303    LOG("Cognitive Engine:: Deregistering services.\n");
304
305    SendMessage(commandSocketFD, "deregister_service");
306    SendMessage(commandSocketFD, "jam_wifi");
307
308    SendMessage(commandSocketFD, "deregister_service");
309    SendMessage(commandSocketFD, "signal_detection");
310
311    SendMessage(commandSocketFD, "deregister_service");
312    SendMessage(commandSocketFD, "max_throughput");
313
314    SendMessage(commandSocketFD, "deregister_service");
315    SendMessage(commandSocketFD, "jam_bluetooth");
316
317}
318
319void
320CognitiveEngine::ReceiveRadioConfiguration()
321{
322    LOG("Cognitive Engine:: Receiving Radio Configuration.\n");
323   
324    char buffer[256];
325 
326    /* Receive Set of Utilities */
327    memset(buffer, 0, 256);
328    ReadMessage(commandSocketFD,buffer);
329    radioInfo->numUtilities = atoi(buffer);
330   
331    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
332        memset(buffer, 0, 256);
333        ReadMessage(commandSocketFD,buffer);
334        uList[i].name = std::string(buffer);
335   
336        memset(buffer, 0, 256);
337        ReadMessage(commandSocketFD,buffer);
338        uList[i].units = std::string(buffer);
339
340        memset(buffer, 0, 256);
341        ReadMessage(commandSocketFD,buffer);
342        uList[i].goal = std::string(buffer);
343   
344        memset(buffer, 0, 256);
345        ReadMessage(commandSocketFD,buffer);
346        uList[i].target = atof(buffer);
347    }
348
349    /* Receive Set of Parameters */
350    memset(buffer, 0, 256);
351    ReadMessage(commandSocketFD, buffer);
352    radioInfo->numParameters = atoi(buffer);
353   
354    for(size_t i = 0; i < radioInfo->numParameters; i++) {
355        memset(buffer, 0, 256);
356        ReadMessage(commandSocketFD, buffer);
357        pList[i].name = std::string(buffer);
358   
359        memset(buffer, 0, 256);
360        ReadMessage(commandSocketFD, buffer);
361        pList[i].units = std::string(buffer);
362
363        memset(buffer, 0, 256);
364        ReadMessage(commandSocketFD, buffer);
365        pList[i].min = atof(buffer);
366   
367        memset(buffer, 0, 256);
368        ReadMessage(commandSocketFD, buffer);
369        pList[i].max = atof(buffer);
370   
371        memset(buffer, 0, 256);
372        ReadMessage(commandSocketFD, buffer);
373        pList[i].step = atof(buffer);
374   
375        memset(buffer, 0, 256);
376        ReadMessage(commandSocketFD,buffer);
377        pList[i].numAffects = atoi(buffer);
378   
379        for(size_t j = 0; j < pList[i].numAffects; j++) {
380            memset(buffer, 0, 256);
381            ReadMessage(commandSocketFD,buffer);
382            for(size_t k = 0; k < radioInfo->numUtilities; k++) {
383                if(uList[k].name == std::string(buffer)){   
384                    pList[i].affection_list[j].u = &uList[k];   
385                    break;
386                }
387            }
388
389            memset(buffer, 0, 256);
390            ReadMessage(commandSocketFD,buffer);
391            pList[i].affection_list[j].relation = std::string(buffer);   
392        }
393    }   
394
395    /* Receive Set of Observables */
396    memset(buffer, 0, 256);
397    ReadMessage(commandSocketFD,buffer);
398    radioInfo->numObservables = atoi(buffer);
399   
400    for(size_t i = 0; i < radioInfo->numObservables; i++) {
401        memset(buffer, 0, 256);
402        ReadMessage(commandSocketFD,buffer);
403        oList[i].name = std::string(buffer);
404   
405        memset(buffer, 0, 256);
406        ReadMessage(commandSocketFD,buffer);
407        oList[i].numAffects = atoi(buffer);
408   
409        for(size_t j = 0; j < oList[i].numAffects; j++) {
410            memset(buffer, 0, 256);
411            ReadMessage(commandSocketFD,buffer);
412            for(size_t k = 0; k < radioInfo->numUtilities; k++) {
413                if(uList[k].name == std::string(buffer)){   
414                    oList[i].affection_list[j].u = &uList[k];   
415                    break;
416                }
417            }
418 
419            memset(buffer, 0, 256);
420            ReadMessage(commandSocketFD,buffer);
421            oList[i].affection_list[j].relation = std::string(buffer);   
422        }
423    }
424
425    SendMessage(commandSocketFD, "receive_config_ack");
426
427        BuildCognitiveEngine();
428}
429
430void
431CognitiveEngine::ReceiveExperience()
432{
433    LOG("Cognitive Engine:: Receiving Experience Report.\n");
434    char buffer[256];
435    uint32_t numberExp;
436   
437    /* Receive number of experience entries */
438    memset(buffer, 0, 256);
439    ReadMessage(commandSocketFD,buffer);
440    numberExp = atoi(buffer);
441
442    LOG("Cognitive Engine:: Waiting for %i number of entries.\n",numberExp);
443 
444    SendMessage(commandSocketFD, "receive_exp_ack");
445}
446
447Parameter*
448CognitiveEngine::GetSolution(Observable *observables, Parameter *currentParameters)
449{
450    LOG("Cognitive Engine:: Generating solution.\n");
451
452    char *searchNames[radioInfo->numUtilities];
453
454    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
455        searchNames[i] = (char*)uList[i].name.c_str();
456        }
457
458    float searchVals[radioInfo->numUtilities];
459
460        for(size_t i = 0; i < radioInfo->numUtilities; i++) {
461                searchVals[i] = uList[i].target;
462    }
463
464    uint32_t numberColumns =
465                radioInfo->numUtilities +
466                radioInfo->numParameters +
467                radioInfo->numObservables + 1;
468       
469        float returnValues[numberColumns];
470       
471        int searchOps[radioInfo->numUtilities];
472    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
473
474        /* If the goal is to maximum, set the search operation to
475                 * return values greater than the target.
476                 *
477                 * If the goal is to minimize, set the search operation to
478                 * return values less than the target.
479                 */
480
481                if(strcmp(uList[i].goal.c_str(),"max") == 0) {
482                    searchOps[i] = GT;
483                } else if(strcmp(uList[i].goal.c_str(),"min") == 0) {
484                        searchOps[i] = LT;
485                }
486        }
487
488        /* CBR specific call */
489        uint32_t rc = cbr_search(myCBR, searchNames, searchOps, searchVals,
490                        radioInfo->numUtilities, returnValues);
491
492        if(rc == 0){
493        /* Adapt the returned parameters to meet the objective */
494
495    } else if(rc == 31337){
496                /* No rows in the CBR, pick default parameters */
497                // Currently this is hard coded and implementation specific!
498            //returnValues[2] = currentParameters[0].value + 5;
499            //returnValues[3] = currentParameters[1].value + 10;
500       
501        } else {
502        WARNING("Cognitive Engine:: Search return an invalid value.\n");
503        }
504
505        size_t returnValueIndex = 0;
506    for(size_t i = 0; i < radioInfo->numUtilities; i++) {
507                uList[i].value = returnValues[returnValueIndex];
508                returnValueIndex++;
509        }
510    for(size_t i = 0; i < radioInfo->numParameters; i++) {
511                pList[i].value = returnValues[returnValueIndex];
512                returnValueIndex++;
513        }
514    for(size_t i = 0; i < radioInfo->numObservables; i++) {
515                oList[i].value = returnValues[returnValueIndex];
516                returnValueIndex++;
517        }
518
519        // Add row to CBR.
520
521        return pList;
522
523}
524
525
526Parameter*
527CognitiveEngine::GetSolution(Observable *observables, Parameter *currentParameters, std::string service)
528{
529    LOG("Cognitive Engine:: Generating solution for %s service.\n",service.c_str());
530
531    return pList;
532}
533
534
535void
536CognitiveEngine::ReceiveFeedback(Observable *observables, Parameter *parameters, \
537    Utility *utilities)
538{
539    LOG("Cognitive Engine:: Receiving feedback.\n");
540}
541
542
543void
544CognitiveEngine::ReceiveFeedback(Observable *observables, Parameter *parameters, \
545    Utility *utilities, std::string service)
546{
547    LOG("Cognitive Engine:: Receiving feedback.\n");
548}
549
550
551void
552CognitiveEngine::BuildCognitiveEngine()
553{
554        char filename[] = {"ex1"};
555        char tablename[] = {"data"};
556
557    uint32_t numberColumns =
558                radioInfo->numUtilities +
559                radioInfo->numParameters +
560                radioInfo->numObservables + 1;
561
562    char *cols[numberColumns];
563
564    size_t columnIndex = 0;
565    for (size_t i = 0; i < radioInfo->numUtilities; i++){
566                cols[columnIndex] = (char*)uList[i].name.c_str();
567        columnIndex++;
568    }   
569    for (size_t i = 0; i < radioInfo->numParameters; i++){
570                cols[columnIndex] = (char*)pList[i].name.c_str();
571        columnIndex++;
572    }   
573    for (size_t i = 0; i < radioInfo->numObservables; i++){
574                cols[columnIndex] = (char*)oList[i].name.c_str();
575        columnIndex++;
576    }   
577    cols[columnIndex] = "utility";
578
579    myCBR = cbr_create(filename, tablename, cols, numberColumns);
580}
581
Note: See TracBrowser for help on using the browser.