/* Virginia Tech Cognitive Radio Open Source Systems * Virginia Tech, 2009 * * LICENSE INFORMATION GOES HERE */ /* DESCRIPTION OF FILE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "tinyxml/tinyxml.h" #include "tinyxml/tinystr.h" #include "vtcross/common.h" #include "vtcross/components.h" #include "vtcross/containers.h" #include "vtcross/debug.h" #include "vtcross/error.h" #include "vtcross/socketcomm.h" CognitiveRadioShell::CognitiveRadioShell() { LOG("Creating Cognitive Radio Shell.\n"); SML_present = false; PE_present = false; CE_present = false; // TODO =BUG= The params, observables, and utils arrays are not being // allocated here. If an shell object is constructed, and then immediately // destructed, there will be no allocated memory, and the delete operater // will receive a null pointer, which will segfault. } CognitiveRadioShell::~CognitiveRadioShell() { delete [] params; delete [] observables; delete [] utils; } CognitiveRadioShell::CognitiveRadioShell(const char* radioConfig, int16_t p1, \ int16_t p2, int16_t p3) { LOG("Creating Cognitive Radio Shell.\n"); params = new Parameter[10]; observables = new Observable[10]; utils = new Utility[10]; radio_info = new Radio_Info; LoadRadioConfiguration(radioConfig, params, utils, observables, radio_info); primaryPort = p1; policyPort = p2; commandPort = p3; } void CognitiveRadioShell::SendComponentType(int32_t socketFD) { SendMessage(socketFD, "response_shell"); LOG("Cognitive Radio Shell responded to GetRemoteComponentType query.\n"); } std::string CognitiveRadioShell::GetRemoteComponentType(int32_t socketFD) { SendMessage(socketFD, "request_component_type"); char buffer[256]; memset(buffer, 0, 256); ReadMessage(socketFD, buffer); return std::string(buffer); } void CognitiveRadioShell::Shutdown() { // TODO should something else be happening here? } void CognitiveRadioShell::Reset() { LOG("Resetting Cognitive Radio Shell.\n"); } void CognitiveRadioShell::SendRadioConfiguration(int32_t socketFD) { LOG("Cognitive Radio Shell:: Sending radio configuration to Cognitive Engine.\n"); } void CognitiveRadioShell::SendRadioExperience(int32_t socketFD) { LOG("Cognitive Radio Shell:: Sending radio experience to Cognitive Engine.\n"); } void CognitiveRadioShell::RegisterCognitiveEngine(int32_t socketFD) { LOG("Cognitive Radio Shell:: Received registration message from Cognitive Engine.\n"); SendRadioConfiguration(socketFD); SendRadioExperience(socketFD); numberOfCognitiveEngines++; CE_present = true; } void CognitiveRadioShell::DeregisterCognitiveEngine(int32_t socketFD) { LOG("Cognitive Radio Shell:: Received deregistration message from Cognitive Engine.\n"); numberOfCognitiveEngines--; if(numberOfCognitiveEngines == 0) CE_present = false; SendMessage(socketFD, "deregister_ack"); shutdown(socketFD, 2); close(socketFD); LOG("Cognitive Radio Shell:: Socket closed.\n"); } void CognitiveRadioShell::RegisterPolicyEngine(int32_t socketFD) { LOG("Cognitive Radio Shell:: Received registration message from Policy Engine.\n"); PE_present = true; } void CognitiveRadioShell::DeregisterPolicyEngine(int32_t socketFD) { LOG("Cognitive Radio Shell:: Received deregistration message from Policy Engine.\n"); PE_present = false; SendMessage(socketFD, "deregister_ack"); shutdown(socketFD, 2); close(socketFD); LOG("Cognitive Radio Shell:: Socket closed.\n"); } void CognitiveRadioShell::RegisterSML(int32_t socketFD) { LOG("Cognitive Radio Shell:: Received registration message from SML.\n"); SML_present = true; } void CognitiveRadioShell::DeregisterSML(int32_t socketFD) { LOG("Cognitive Radio Shell:: Received deregistration message from SML.\n"); SML_present = false; SendMessage(socketFD, "deregister_ack"); shutdown(socketFD, 2); close(socketFD); LOG("Cognitive Radio Shell:: Socket closed.\n"); } int32_t CognitiveRadioShell::LoadRadioConfiguration(const char* radioConfig, \ Parameter* &pList, Utility* &uList, Observable* &oList, \ Radio_Info* radioInfo) { TiXmlElement *pElem; TiXmlElement *pChild; TiXmlElement *pChild1; TiXmlElement *pSecondChild; TiXmlHandle hRoot(0); int32_t count = 0; size_t item_count = 0; size_t affect_count = 0; int32_t attribute_count = 0; bool match_found = false; LOG("Cognitive Radio Shell:: Loading radio configuration.\n"); TiXmlDocument doc( radioConfig ); bool loadOkay = doc.LoadFile(); if(!loadOkay) ERROR(1,"Loading radio configuration failed: %s\n", radioConfig); TiXmlHandle hDoc(&doc); pElem = hDoc.FirstChildElement().Element(); if(!pElem) ERROR(1, "No valid root!"); hRoot = TiXmlHandle(pElem); pElem = hRoot.FirstChild("utilities").Element(); pChild1 = hRoot.Child("utilities", count).Element(); for(pChild = pChild1->FirstChildElement("utility"); pChild; \ pChild = pChild->NextSiblingElement()) { const char *uName = pChild->Attribute("name"); if(uName) uList[item_count].name = uName; const char *uUnits = pChild->Attribute("units"); if(uUnits) uList[item_count].units = uUnits; const char *uGoal = pChild->Attribute("goal"); if(uGoal) uList[item_count].goal = uGoal; if(pChild->QueryFloatAttribute("target", &uList[item_count].target) != TIXML_SUCCESS) uList[item_count].target = -1; item_count++; } radio_info->numUtilities = item_count; LOG("Cognitive Radio Shell:: Parsed %d utilities.\n", radioInfo->numUtilities); item_count = 0; pElem = hRoot.FirstChild("observables").Element(); pChild1 = hRoot.Child("observables", count).Element(); for(pChild = pChild1->FirstChildElement("observable"); pChild; \ pChild = pChild->NextSiblingElement()) { const char *oName = pChild->Attribute("name"); if(oName) oList[item_count].name = oName; affect_count = 0; for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \ pSecondChild = pSecondChild->NextSiblingElement()) { const char *oUtilName = pSecondChild->Attribute("utility"); if(oUtilName) { for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++ ) { if(uList[attribute_count].name == oUtilName) { oList[item_count].affection_list[affect_count].u = &uList[attribute_count]; const char *oRelate = pSecondChild->Attribute("relationship"); if(oRelate) oList[item_count].affection_list[affect_count].relation = oRelate; affect_count++; match_found = true; break; } } } if(!match_found) { ERROR(1, "Error: %s: %s is not a valid utility.\n", \ oList[item_count].name.c_str(), oUtilName); } else match_found = false; } oList[item_count].numAffects = affect_count; item_count++; } radioInfo->numObservables = item_count; LOG("Cognitive Radio Shell:: Parsed %d observables.\n", radioInfo->numObservables); pElem = hRoot.FirstChild("parameters").Element(); pChild1 = hRoot.Child("parameters", count).Element(); item_count = 0; for(pChild = pChild1->FirstChildElement("parameter"); pChild; \ pChild = pChild->NextSiblingElement()) { const char *pName = pChild->Attribute("name"); if(pName) pList[item_count].name = pName; const char *pUnits = pChild->Attribute("units"); if(pUnits) pList[item_count].units = pUnits; if(pChild->QueryFloatAttribute("min", &pList[item_count].min) != TIXML_SUCCESS) pList[item_count].min = -1; if(pChild->QueryFloatAttribute("max", &pList[item_count].max) != TIXML_SUCCESS) pList[item_count].max = -1; if(pChild->QueryFloatAttribute("step", &pList[item_count].step) != TIXML_SUCCESS) pList[item_count].step = -1; affect_count = 0; for(pSecondChild = pChild->FirstChildElement("affect"); pSecondChild; \ pSecondChild = pSecondChild->NextSiblingElement()) { const char *pUtilName = pSecondChild->Attribute("utility"); if(pUtilName) { for(attribute_count = 0; attribute_count < radio_info->numUtilities; attribute_count++) { if(uList[attribute_count].name == pUtilName) { pList[item_count].affection_list[affect_count].u = &uList[attribute_count]; const char *pRelate = pSecondChild->Attribute("relationship"); if(pRelate) pList[item_count].affection_list[affect_count].relation = pRelate; else LOG("Error: No relation found.\n"); match_found = true; affect_count++; break; } } } if(!match_found) { ERROR(1, "Error: %s: %s is not a valid utility.\n", \ pList[item_count].name.c_str(), pUtilName); } match_found = false; } pList[item_count].numAffects = affect_count; item_count++; } radioInfo->numParameters = item_count; LOG("Cognitive Radio Shell:: Parsed %d parameters.\n", radioInfo->numParameters); return 1; } void CognitiveRadioShell::GetOptimalParameters(int32_t socketFD) { } void CognitiveRadioShell::HandleMessage(int32_t socketFD) { char buffer[256]; ReadMessage(socketFD, buffer); if(strcmp(buffer,"register_engine_cognitive") == 0) { RegisterCognitiveEngine(socketFD); } else if(strcmp(buffer,"deregister_engine_cognitive") == 0) { DeregisterCognitiveEngine(socketFD); } else if(strcmp(buffer,"register_engine_policy") == 0) { RegisterPolicyEngine(socketFD); } else if(strcmp(buffer,"deregister_engine_policy") == 0) { DeregisterPolicyEngine(socketFD); } else if(strcmp(buffer,"register_sml") == 0) { RegisterSML(socketFD); } else if(strcmp(buffer,"deregister_sml") == 0) { DeregisterSML(socketFD); } else if(strcmp(buffer,"optimize") == 0) { /* Receive optimization request and current environment */ GetOptimalParameters(socketFD); } } void CognitiveRadioShell::StartShellServer() { struct timeval selTimeout; int32_t primary = 0; int32_t policy = 1; int32_t command = 2; int32_t running = 1; int32_t port, rc, new_sd = 1; int32_t desc_ready = 1; int32_t timeout = 10; fd_set sockSet; int32_t *servSock = new int32_t[3]; servSock[primary] = CreateTCPServerSocket(primaryPort); servSock[policy] = CreateTCPServerSocket(policyPort); servSock[command] = CreateTCPServerSocket(commandPort); int32_t maxDescriptor = servSock[command]; if(InitializeTCPServerPort(servSock[primary]) == -1) ERROR(1,"Error initializing primary port\n"); if(InitializeTCPServerPort(servSock[policy]) == -1) ERROR(1,"Error initializing policy port\n"); if(InitializeTCPServerPort(servSock[command]) == -1) ERROR(1,"Error initializing command port\n"); while (running) { /* Zero socket descriptor vector and set for server sockets */ /* This must be reset every time select() is called */ FD_ZERO(&sockSet); FD_SET(servSock[primary], &sockSet); FD_SET(servSock[policy], &sockSet); FD_SET(servSock[command], &sockSet); /* Timeout specification */ /* This must be reset every time select() is called */ selTimeout.tv_sec = timeout; /* timeout (secs.) */ selTimeout.tv_usec = 0; /* 0 microseconds */ /* Suspend program until descriptor is ready or timeout */ rc = select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimeout); if(rc == 0) LOG("No echo requests for %i secs...Server still alive\n", timeout); else { desc_ready = rc; for(port = 0; port <= maxDescriptor && desc_ready > 0; port++) { if(FD_ISSET(port, &sockSet)) { desc_ready -= 1; /* Check if request is new or on an existing open descriptor */ if((port == servSock[primary]) || (port == servSock[policy]) || (port == servSock[command])) { do { new_sd = AcceptTCPConnection(port); if(new_sd < 0) break; HandleMessage(new_sd); FD_SET(new_sd,&sockSet); if(new_sd > maxDescriptor) maxDescriptor = new_sd; //LOG("New incoming connection - %i\n\n",new_sd); } while(new_sd != -1); } else { //LOG("Request on already open descriptor.\n\n"); HandleMessage(port); } } } } } /* Close sockets */ close(servSock[primary]); close(servSock[policy]); close(servSock[command]); /* Free list of sockets */ delete servSock; return; }