/* Virginia Tech Cognitive Radio Open Source Systems * Virginia Tech, 2009 * * TODO LICENSE INFORMATION GOES HERE */ /* TODO DESCRIPTION OF FILE. */ #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" using namespace std; #define CE_SERVER_PORT 30001 #define PE_SERVER_PORT 30003 void print_current_config(Utility* uList[], Parameter* pList[], \ Observable* oList[], CE_Info* ce_info) { for(size_t i = 0; i < ce_info->numUtilities ; i++) { LOG("Shell:: Utility: %s\n\tUnits: %s\n\tGoal: %s\n\tTarget: %s\n", \ uList[i]->name, uList[i]->units, uList[i]->goal, \ uList[i]->target); } for(size_t i = 0; i < ce_info->numParameters; i++) { LOG("Shell:: Radio Operation Profile has been sucessfully sent.\n"); LOG("Shell:: Parameter: %s\n\tUnits: %s\n\tMin: %s\n\t", \ pList[i]->name, pList[i]->units, pList[i]->min); LOG("\tMax: %s\n\tStep: %s\n", pList[i]->max, pList[i]->step); for(size_t j = 0; j < pList[i]->numAffects; j++) { LOG("\t\tAffect %s -> %s\n", pList[i]->affection_list[j].u->name, \ pList[i]->affection_list[j].relation); } } for(size_t i = 0; i < ce_info->numObservables; i++) { LOG("Observable: %s\n", oList[i]->name); for(size_t j = 0; j < oList[i]->numAffects; j++) { LOG("\t\tAffect %s -> %s ", oList[i]->affection_list[j].u->name, \ oList[i]->affection_list[j].relation); } } } int32_t parse_ce_config(TiXmlDocument* doc, Utility* u[], Parameter* p[], \ Observable* o[], CE_Info* ce_info) { TiXmlElement *pElem; TiXmlElement *pChild; TiXmlElement *pChild1; TiXmlElement *pSecondChild; TiXmlHandle hDoc(doc); 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; 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()) { u[item_count] = new Utility; const char *uName = pChild->Attribute("name"); if(uName) u[item_count]->name = uName; const char *uUnits = pChild->Attribute("units"); if(uUnits) u[item_count]->units = uUnits; const char *uGoal = pChild->Attribute("goal"); if(uGoal) u[item_count]->goal = uGoal; if(pChild->QueryFloatAttribute("target", &u[i]->target) != TIXML_SUCCESS) u[i]->target = -1; item_count++; } ce_info->numUtilities = item_count; LOG("Initialize:: Parsed %d utilities.\n", ce_info->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"); o[item_count] = new Observable; if(oName) o[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; u[attribute_count]! = NULL; attribute_count++ ) { if(u[attribute_count]->name == oUtilName) { o[i]->affection_list[affect_count].u = u[attribute_count]; const char *oRelate = pSecondChild->Attribute("relationship"); if(oRelate) o[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", \ o[i]->name, oUtilName); else match_found = false; } o[item_count]->numAffects = affect_count; item_count++; } ce_info->numObservables = item_count; LOG("Initialize:: Parsed %d observables.\n", ce_info->numObservables); pElem = hRoot.FirstChild("parameters").Element(); pChild1 = hRoot.Child("parameters", count).Element(); item_count = 0; for(pChild = pChild1->FirstChildElement("parameter"); pChild; \ pChild = pChild->NextSiblingElement()) { p[item_count] = new Parameter; const char *pName = pChild->Attribute("name"); if(pName) p[item_count]->name = pName; const char *pUnits = pChild->Attribute("units"); if(pUnits) p[item_count]->units = pUnits; if(pChild->QueryFloatAttribute("min", &p[i]->min) != TIXML_SUCCESS) p[item_count]->min = -1; if(pChild->QueryFloatAttribute("max", &p[i]->max) != TIXML_SUCCESS) p[item_count]->max = -1; if(pChild->QueryFloatAttribute("step", &p[i]->step) != TIXML_SUCCESS) p[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; u[attribute_count] != NULL; attribute_count++) { if(u[attribute_count]->name == pUtilName) { p[item_count]->affection_list[affect_count].u = u[attribute_count]; const char *pRelate = pSecondChild->Attribute("relationship"); if(pRelate) p[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", \ p[item_count]->name, pUtilName); } match_found = false; } p[item_count]->numAffects = affect_count; item_count++; } ce_info->numParameters = item_count; LOG("Initialize:: Parsed %d parameters.\n", ce_info->numParameters); return 1; } int32_t ReceiveMessage(int32_t socket, char* buffer) { int32_t i,n; n = recv(socket,buffer,256,MSG_PEEK); for(i=0;i<256;i++){ if(strcmp(&buffer[i],"\0") == 0) break; } n = recv(socket,buffer,i+1,0); if (n < 0) ERROR(1, "Error reading from socket!\n"); // printf("ReadMessage:%s %d\n",buffer,n); return n; } int32_t SendMessage(int32_t socketfd, string message) { int32_t n; message.append("\0"); // Write message back to client n = send(socketfd,message.c_str(),(message.size()+1),0); if (n<0) ERROR(1, "Error sending to client\n"); if(n == 0) printf("Client closed the socket.\n"); //printf("SendMessage:%s %d\n",message.c_str(),n); return n; } void LoadCEConfiguration(int32_t socketfd,Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info){ int32_t n,i,j; char counter[55]; char var[50]; //int32_t total_bytes; printf("Cognitive Radio:: Sending Radio Operating Profile to Cognitive Engine.\n\n"); // utilities // Send number of utilities sprintf(counter,"%d",ce_info->numUtilities); SendMessage(socketfd,counter); // send utility for(i = 0; i < ce_info->numUtilities; i++) { SendMessage(socketfd,uList[i]->name); SendMessage(socketfd,uList[i]->units); SendMessage(socketfd,uList[i]->goal); sprintf(var,"%f",uList[i]->target); SendMessage(socketfd,var); } // parameters sprintf(counter,"%i",ce_info->numParameters); SendMessage(socketfd,counter); for(i = 0; i < ce_info->numParameters; i++) { SendMessage(socketfd,pList[i]->name); SendMessage(socketfd,pList[i]->units); sprintf(var,"%f",pList[i]->min); SendMessage(socketfd,var); sprintf(var,"%f",pList[i]->max); SendMessage(socketfd,var); sprintf(var,"%f",pList[i]->step); SendMessage(socketfd,var); sprintf(counter,"%i",pList[i]->numAffects); SendMessage(socketfd,counter); for(j = 0; j < pList[i]->numAffects; j++) { SendMessage(socketfd,pList[i]->affection_list[j].u->name); SendMessage(socketfd,pList[i]->affection_list[j].relation); } } // observables sprintf(counter,"%i",ce_info->numObservables); SendMessage(socketfd,counter); for(i = 0; i < ce_info->numObservables; i++) { SendMessage(socketfd,oList[i]->name); sprintf(counter,"%i",oList[i]->numAffects); SendMessage(socketfd,counter); for(j = 0; j < oList[i]->numAffects; j++) { SendMessage(socketfd,oList[i]->affection_list[j].u->name); SendMessage(socketfd,oList[i]->affection_list[j].relation); } } // Receive ACK for utils char buffer[256]; string message; n = ReceiveMessage(socketfd, buffer); //printf("%s\n", buffer); //cout << message << endl; //printf("ACK received.\n"); } void UpdateCEConfiguration() { } void ResetCEConfiguration(){ } void UpdateCEExperience(int32_t socketfd, int32_t num_rows, int32_t num_cols, float * past_exp[]) { int32_t i, j; char counter[55]; char var[50]; for (i = 0; i < num_rows; i++){ for (j = 0; j< num_cols; j++){ sprintf(var,"%f",past_exp[i][j]); //printf("%f, \n", past_exp[i][j]); //printf("%s, \n", var); } } // send the number of rows to the ce first sprintf(counter,"%d",num_rows); SendMessage(socketfd,counter); // send the number of columns to the ce sprintf(counter,"%d",num_cols); SendMessage(socketfd,counter); // update ce with experience for (i = 0; i < num_rows; i++){ for (j = 0; j< num_cols; j++){ sprintf(var,"%f",past_exp[i][j]); SendMessage(socketfd,var); } } } void ResetCEExperience() { } // Update operating settings // This function will int32_teract with the hardware "drivers" void UpdateRadioSettings() { } int32_t RequestPolicyValidation(Parameter * pList[], CE_Info *ce_info) { char counter[55]; char var[50]; int32_t i; string control_msg; int32_t socketfd = ce_info->policy_socket; // Control message that validation request is coming control_msg = "val"; SendMessage(socketfd,control_msg); printf("Cognitive Radio:: Here. %i\n\n", socketfd); // Send parameter information sprintf(counter,"%i",ce_info->numParameters); SendMessage(socketfd,counter); for(i = 0; i < ce_info->numParameters; i++) { SendMessage(socketfd,pList[i]->name); SendMessage(socketfd,pList[i]->units); sprintf(var,"%f",pList[i]->min); SendMessage(socketfd,var); sprintf(var,"%f",pList[i]->max); SendMessage(socketfd,var); sprintf(var,"%f",pList[i]->step); SendMessage(socketfd,var); sprintf(var,"%f",pList[i]->value); SendMessage(socketfd,var); } return 1; } int32_t RequestCEOptimization(int32_t sockfd, Utility *uList[], Parameter *pList[], Observable *oList[], CE_Info *ce_info) { char buffer[256]; int32_t i; float var; // Send request optimization message followed by the current environment parameters. /* SendMessage(sockfd,"request"); for (i = 0; i < ce_info->numObservables; i++){ SendMessage(sockfd,..); } */ // Receive optimized values from the Cognitive Engine for (i = 0; i < ce_info->numParameters; i++){ bzero(buffer,256); ReceiveMessage(sockfd,buffer); var = atof(buffer); pList[i]->value = var; } // If policy engine is connect, validate new values if(ce_info->policy_engine == 1) { printf("Cognitive Radio:: Found Policy Engine!\n"); printf("Cognitive Radio:: Validating parameters with Policy Engine\n\n"); RequestPolicyValidation(pList,ce_info); printf("Cognitive Radio:: Done\n\n"); } return 1; } void RunSimulator(int32_t socketfd, Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info) { float **past_exp; int32_t num_rows, num_cols; // Set fake current environment params = current environment RequestCEOptimization(socketfd, uList, pList, oList, ce_info); // Act like we are updating the hardware tranmission settings UpdateRadioSettings(); // Send back fake utility values // need to initialize //UpdateCEExperience(socketfd, num_rows, num_cols, past_exp); } void InitializePE(int32_t socket, CE_Info * ce_info) { // Policy Engine is connected // Set global policy engine value to 1 ce_info->policy_engine = 1; ce_info->policy_socket = socket; return; } void InitializeCE(int32_t socketfd, Utility * uList[], Parameter * pList[], Observable * oList[], CE_Info * ce_info) { LoadCEConfiguration(socketfd, uList, pList, oList, ce_info); // cr experience float **past_exp; int32_t num_cols; // get number of columns num_cols = ce_info->numUtilities + ce_info->numParameters; num_cols = num_cols + ce_info->numObservables; num_cols = num_cols + 1; // overall utility int32_t num_rows = 2; past_exp = (float **)malloc(sizeof(float)*num_rows); int32_t i; for (i=0; i 0; port++) { if (FD_ISSET(port, &sockSet)) { printf("Request on port %d: ", port); desc_ready -= 1; if( (port == servSock[cognitive_engine]) || (port == servSock[policy_engine])) { do { new_sd = AcceptTCPConnection(port); if(new_sd < 0) { break; } HandleTCPClient(new_sd, uList, pList, oList, ce_info); FD_SET(new_sd,&sockSet); if(new_sd > maxDescriptor) maxDescriptor = new_sd; printf("New incoming connection - %i\n\n",new_sd); } while(new_sd != -1); } else { printf("Request on already open descriptor.\n\n"); HandleTCPClient(port, uList, pList, oList, ce_info); } } } } } /* Close sockets */ for (port = 0; port < 2; port++) close(servSock[port]); /* Free list of sockets */ free(servSock); return 0; } int32_t main(int32_t argc, char* argv[]) { // CognitiveEngine CE; // CognitiveEngineShell Shell; string pFilename; int32_t fd; Utility * uList[10]; Parameter * pList[10]; Observable * oList[10]; struct CE_Info *ce_info; if((fd = open("/dev/zero", O_RDWR)) == -1) return 1; ce_info = (struct CE_Info *)mmap(0,sizeof(CE_Info),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); close(fd); if(argc < 2) { cout << "Warning no XML file specific using default: example.xml" << endl; pFilename = "example.xml"; } else { pFilename = argv[1]; } TiXmlDocument doc( pFilename.c_str() ); bool loadOkay = doc.LoadFile(); if (!loadOkay) { cout << "Loading " << pFilename << " failed." << endl; return 0; } cout << "\n\nInitialize:: Attemping to parse " << pFilename << "." << endl; parse_ce_config( &doc , uList, pList, oList, ce_info); cout << "Initialize:: Configuration file parsing completed.\n" << endl; //print_current_config(uList, pList, oList, &ce_info); StartServers(uList, pList, oList, ce_info); return 1; }