/* Copyright 2009 Virginia Polytechnic Institute and State University Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /*! This file provides an implemention of a CBR-based CE that works with the * provided test scripts and configuration filse. */ #include "DSA_CognitiveEngine.h" using namespace std; DSA_CE::DSA_CE() { LOG("Creating Cognitive Engine.\n"); SML_present = false; commandSocketFD = -1; srand(time(NULL)); } DSA_CE::~DSA_CE() { delete myCBR; delete [] pList; delete [] oList; delete [] uList; delete [] radioInfo; } DSA_CE::DSA_CE(const char* serverName, const char* serverPort, \ const int32_t numFields, const bool SML) \ : CognitiveEngine(serverName, serverPort, numFields, SML) { LOG("Creating Cognitive Engine.\n"); srand ( time(NULL) ); BuildCognitiveEngine(); } void DSA_CE::RegisterServices() { LOG("Cognitive Engine:: Registering services.\n"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "test_srv"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "test_srv1"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "test_srv2"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "test_srv3"); } //Combined with deregister component since those two things must happen togeather void DSA_CE::DeregisterServices() { LOG("Cognitive Engine:: Deregistering services.\n"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "test_srv"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "test_srv1"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "test_srv2"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "test_srv3"); } /* The core of the CE is this function */ Parameter* DSA_CE::GetSolution(Observable *observables, Parameter *currentParameters) { LOG("Cognitive Engine:: Generating solution.\n"); /* Put together the CBR search array */ uint32_t channel = 0; string searchNames[1]; string sumSearchName; float searchVals[1]; float utilArray[(int)pList[0].max]; int searchOps[1]; uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \ radioInfo->numObservables + 1; float returnValues[numberColumns]; float sumRetVals[numberColumns]; // Total sum of utilities in sumRetVals[0] string channel_name = "channel"; string utility_name = "utility"; for(int32_t i = 0 ; i < pList[0].max ; i++ ) { searchNames[0] = pList[0].name; searchOps[0] = 0; searchVals[0] = i+1; uint32_t rc = myCBR->Search(searchNames, searchOps, searchVals, 1, returnValues); if(rc == 31337) { // No entry - must add string rowNames[numberColumns]; size_t rowIndex = 0; for(size_t j = 0; j < radioInfo->numUtilities; j++) { rowNames[rowIndex] = uList[j].name; rowIndex++; } for(size_t j = 0; j < radioInfo->numParameters; j++) { rowNames[rowIndex] = pList[j].name; if(pList[j].name == "channel") returnValues[rowIndex] = i+1; rowIndex++; } for(size_t j = 0; j < radioInfo->numObservables; j++) { rowNames[rowIndex] = oList[j].name; rowIndex++; } rowNames[rowIndex] = utility_name; returnValues[rowIndex] = 500; /* Add the new optimized set to the CBR database */ myCBR->AddRow(rowNames, returnValues, numberColumns); } utilArray[i] = returnValues[UTILITY]; } printf("Current Channel Utility Scores\n"); printf("1: %f\t7: %f\t8: %f\t14: %f\n",utilArray[0],utilArray[1],utilArray[2],utilArray[3]); // Get sum of all the channel utilities. sumSearchName = utility_name; uint32_t rc = myCBR->SearchSum(sumSearchName, sumRetVals); // Psuedo random channel selection based upon utility. int k = rand() % (int)sumRetVals[0]; int cdf_total(0); for ( int i = 0; i < pList[0].max; i++ ) { cdf_total += utilArray[i]; if(k < cdf_total) { channel = i + 1; break; } } searchNames[0] = pList[0].name; searchOps[0] = 0; searchVals[0] = channel; rc = myCBR->Search(searchNames, searchOps, searchVals, 1, returnValues); //returnValues[CHANNEL] = rand() % (int)pList[0].max + (int)pList[0].min; returnValues[CHANNEL] = channel; printf("Cognitive Engine:: ..---===***### Channel %i has been selected ###***===---..\n",channel); /* Package up the new set of parameters in order to add the new entry into the CBR database. */ size_t returnValueIndex = 0; for(size_t i = 0; i < radioInfo->numUtilities; i++) { uList[i].value = returnValues[returnValueIndex]; returnValueIndex++; } for(size_t i = 0; i < radioInfo->numParameters; i++) { pList[i].value = returnValues[returnValueIndex]; returnValueIndex++; } for(size_t i = 0; i < radioInfo->numObservables; i++) { oList[i].value = returnValues[returnValueIndex]; returnValueIndex++; } //returnValues[returnValueIndex] = 0; string allNames[numberColumns]; size_t allNameIndex = 0; for(size_t i = 0; i < radioInfo->numUtilities; i++) { allNames[allNameIndex] = uList[i].name; returnValues[allNameIndex] = uList[i].target; allNameIndex++; } for(size_t i = 0; i < radioInfo->numParameters; i++) { allNames[allNameIndex] = pList[i].name; allNameIndex++; } for(size_t i = 0; i < radioInfo->numObservables; i++) { allNames[allNameIndex] = oList[i].name; // returnValues[allNameIndex] = 0; allNameIndex++; } allNames[allNameIndex] = utility_name; /* Add the new optimized set to the CBR database */ //myCBR->AddRow(allNames, returnValues, returnValueIndex+1); /* Return the set of new parameter values. */ return pList; } Parameter* DSA_CE::GetSolution(Observable *observables, \ Parameter *currentParameters, std::string service) { LOG("Cognitive Engine:: Generating solution for %s service.\n", service.c_str()); return pList; } void DSA_CE::ReceiveFeedback(Observable *observables, Parameter *parameters) { LOG("Cognitive Engine:: Receiving feedback.\n"); uint32_t numberColumns = radioInfo->numParameters; uint32_t obsColumns = radioInfo->numObservables + 1; uint32_t numberTotalColumns = radioInfo->numUtilities + radioInfo->numParameters + radioInfo->numObservables + 1; float valList[numberColumns]; float obsVals[numberColumns]; string nameList[numberColumns]; string obsList[obsColumns]; string searchNames[1]; float searchVals[1]; int searchOps[1]; float returnValues[numberTotalColumns]; size_t columnObsIndex = 0; for (size_t i = 0; i < radioInfo->numObservables; i++){ obsList[columnObsIndex] = observables[i].name; columnObsIndex++; } obsList[columnObsIndex] = "utility"; size_t columnIndex = 0; for (size_t i = 0; i < radioInfo->numParameters; i++){ nameList[columnIndex] = parameters[i].name; columnIndex++; } size_t obsValueIndex = 0; for(size_t i = 0; i < radioInfo->numObservables; i++) { obsVals[obsValueIndex] = observables[i].value; obsValueIndex++; } /* Make sure we do not return any entries for the current channel */ std::string channel_name = "channel"; searchNames[0] = channel_name; searchOps[0] = 0; searchVals[0] = parameters[0].value; /* Execute CBR search and put output into returnValues */ myCBR->Search(searchNames, searchOps, searchVals, 1, returnValues); /* Calculate Utility */ float oldUtilityValue = returnValues[UTILITY]; ////////////////////////////////////////////// // // BEGIN CORE DSA ALGORITHM UTILITY FUNCTION // ////////////////////////////////////////////// // Set DSA utility to take into account both the previously sensed // energy and the average communication time. float newUtilityValue = oldUtilityValue + observables[COMMUNICATION_TIME].value; // If communication time value is set, we know we need to change channels because of PU. // So we should lower the utility for this channel. int reward = 20; int punishment = -100; int Detection_Threshold = 10000000; if((observables[COMMUNICATION_TIME].value != 0) || (observables[ENERGY].value > Detection_Threshold)) { printf("Cognitive Engine:: Possible PU Detection - Decrementing Utility. %f %f",observables[COMMUNICATION_TIME].value,observables[ENERGY].value); newUtilityValue = newUtilityValue + punishment; } else { printf("Cognitive Engine:: Scan Mode:: No PU detected - Incrementing Utility."); newUtilityValue = newUtilityValue + reward; } if(newUtilityValue <= 100) newUtilityValue = 100; // Put limit on utility score to prevent a positive feedback loop if(newUtilityValue >= 800) newUtilityValue = 800; obsVals[obsValueIndex] = newUtilityValue; ////////////////////////////////////////////// // // END CORE DSA ALGORITHM UTILITY FUNCTION // ////////////////////////////////////////////// size_t returnValueIndex = 0; for(size_t i = 0; i < radioInfo->numParameters; i++) { valList[returnValueIndex] = parameters[i].value; returnValueIndex++; } myCBR->Update(nameList, obsList, valList, obsVals, numberColumns, obsColumns); } void DSA_CE::ReceiveFeedback(Observable *observables, Parameter *parameters, \ std::string service) { LOG("Cognitive Engine:: Receiving feedback.\n"); } void DSA_CE::BuildCognitiveEngine() { string filename = "ex1"; string tablename = "data"; uint32_t numberColumns = radioInfo->numUtilities + radioInfo->numParameters + \ radioInfo->numObservables + 1; string cols[numberColumns]; size_t columnIndex = 0; for (size_t i = 0; i < radioInfo->numUtilities; i++){ cols[columnIndex] = uList[i].name; columnIndex++; } string paramCols[radioInfo->numParameters]; size_t paramColumnIndex = 0; // Also need to make parameters the unique key for (size_t i = 0; i < radioInfo->numParameters; i++){ cols[columnIndex] = pList[i].name; paramCols[paramColumnIndex] = pList[i].name; columnIndex++; paramColumnIndex++; } for (size_t i = 0; i < radioInfo->numObservables; i++){ cols[columnIndex] = oList[i].name; columnIndex++; } std::string utility_name = "utility"; cols[columnIndex] = utility_name; myCBR = new CBR(filename, tablename, cols, paramCols, numberColumns, radioInfo->numParameters); } void DSA_CE::PerformUpdatePerformance() { /* Receive Set of current Parameters */ char buffer[256]; memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); uint32_t numParameters = atoi(buffer); Parameter *p = new Parameter[numParameters]; for(size_t i = 0; i < numParameters; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); p[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); p[i].value = atof(buffer); } /* Receive Set of Observables */ memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); uint32_t numObservables = atoi(buffer); Observable *o = new Observable[numObservables]; for(size_t i = 0; i < numObservables; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].value = atof(buffer); } ReceiveFeedback(o,p); delete [] o; delete [] p; } void DSA_CE::PerformRequestOptimizationService() { // THIS IS CURRENTLY IN DEMO MODE /* Receive Set of Observables */ LOG("\nCognitive Engine:: Receiving service name\n"); char buffer[256]; memset(buffer, 0, 256); ReadMessage(commandSocketFD,buffer); LOG("\nCognitive Engine:: Got service name, %s\n", buffer); /* Receive Set of Observables */ LOG("\nCognitive Engine:: Receiving Observable Parameters\n"); memset(buffer, 0, 256); ReadMessage(commandSocketFD,buffer); uint32_t numObservables = atoi(buffer); Observable *o = new Observable[numObservables]; for(size_t i = 0; i < numObservables; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].value = atof(buffer); } /* Receive Set of current Parameters */ LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n"); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); uint32_t numCurrentParameters = atoi(buffer); Parameter *cp = new Parameter[numCurrentParameters]; for(size_t i = 0; i < numCurrentParameters; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); cp[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); cp[i].value = atof(buffer); } LOG("Cognitive Engine:: Processing parameters....\n"); // TODO need to actually do something with the observables here LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n"); char numParametersChar[10]; sprintf(numParametersChar, "%i", radioInfo->numParameters); SendMessage(commandSocketFD, numParametersChar); for(size_t i = 0; i < radioInfo->numParameters; i++) { SendMessage(commandSocketFD, "test"); SendMessage(commandSocketFD, "00"); } delete [] o; delete [] cp; } void DSA_CE::PerformRequestOptimization() { /* Receive Set of Observables */ LOG("\nCognitive Engine:: Receiving Observable Parameters\n"); char buffer[256]; memset(buffer, 0, 256); ReadMessage(commandSocketFD,buffer); uint32_t numObservables = atoi(buffer); Observable *o = new Observable[numObservables]; for(size_t i = 0; i < numObservables; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); o[i].value = atof(buffer); } /* Receive Set of current Parameters */ LOG("Cognitive Engine:: Receiving Current Transmission Parameters\n"); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); uint32_t numCurrentParameters = atoi(buffer); Parameter *cp = new Parameter[numCurrentParameters]; for(size_t i = 0; i < numCurrentParameters; i++) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); cp[i].name = std::string(buffer); memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); cp[i].value = atof(buffer); } LOG("Cognitive Engine:: Processing parameters....\n"); Parameter *solutionSet; solutionSet = GetSolution(o,cp); // TODO need to actually do something with the observables here LOG("Cognitive Engine:: Sending Optimal Parameters to Application.\n"); char numParametersChar[10]; char solutionValue[50]; sprintf(numParametersChar, "%i", radioInfo->numParameters); SendMessage(commandSocketFD, numParametersChar); for(size_t i = 0; i < radioInfo->numParameters; i++) { SendMessage(commandSocketFD, solutionSet[i].name.c_str()); memset(solutionValue, 0, 50); sprintf(solutionValue, "%f", solutionSet[i].value); SendMessage(commandSocketFD, solutionValue); } delete [] o; delete [] cp; } void DSA_CE::PerformQueryComponentType() { SendComponentType(); } void DSA_CE::PerformConnectSML() { /* This command implies that we are disconnecting from the shell and * connecting to a SML component. */ char serverName[256]; char serverPort[256]; // TODO is this going to end up being too slow? memset(serverName, 0, 256); memset(serverPort, 0, 256); ReadMessage(commandSocketFD, serverName); ReadMessage(commandSocketFD, serverPort); /* Only continue if we are currently connected to a shell. */ if(!SML_present) { DeregisterComponent(); shutdown(commandSocketFD, 2); close(commandSocketFD); ConnectToRemoteComponent(serverName, serverPort, true); } } void DSA_CE::PerformDisconnectSML() { /* This command implies that we are disconnecting from the SML and * connecting to a shell component. */ char serverName[256]; char serverPort[256]; // TODO is this going to end up being too slow? memset(serverName, 0, 256); memset(serverPort, 0, 256); ReadMessage(commandSocketFD, serverName); ReadMessage(commandSocketFD, serverPort); /* We only want to do this if we are actually connected to an SML * currently. */ if(SML_present) { DeregisterServices(); shutdown(commandSocketFD, 2); close(commandSocketFD); ConnectToRemoteComponent(serverName, serverPort, false); } } void DSA_CE::PerformResetEngineCognitive() { Reset(); } void DSA_CE::PerformShutdownEngineCognitive() { Shutdown(); }