/* Virginia Tech Cognitive Radio Open Source Systems * Virginia Tech, 2009 * * LICENSE INFORMATION GOES HERE */ /* DESCRIPTION OF FILE. */ #include #include #include #include "../../trunk/src/include/vtcross/common.h" #include "../../trunk/src/include/vtcross/components.h" #include "../../trunk/src/include/vtcross/containers.h" #include "../../trunk/src/include/vtcross/debug.h" #include "../../trunk/src/include/vtcross/error.h" #include "../../trunk/src/include/vtcross/socketcomm.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../../trunk/src/include/tinyxml/tinyxml.h" #include "../../trunk/src/include/tinyxml/tinystr.h" ServiceManagementLayer::ServiceManagementLayer() { LOG("Creating Service Management Layer.\n"); shellSocketFD = -1; numberOfCognitiveEngines = 0; CE_Present = false; cogEngSrv = 1; Current_ID = 0; LoadConfiguration(); } ServiceManagementLayer::~ServiceManagementLayer() { } ServiceManagementLayer::ServiceManagementLayer(const char* serverName, \ const char* serverPort) { LOG("Creating Service Management Layer.\n"); ConnectToShell(serverName, serverPort); CE_List = new CE_Reg[10]; LoadConfiguration(); } void ServiceManagementLayer::SendComponentType() { SendMessage(shellSocketFD, "response_sml"); LOG("SML responded to GetRemoteComponentType query.\n"); } void ServiceManagementLayer::ConnectToShell(const char* serverName, \ const char* serverPort) { shellSocketFD = ClientSocket(serverName, serverPort); RegisterComponent(); } void ServiceManagementLayer::ShellSignalHandler() { char buffer[256]; memset(buffer, 0, 256); ReadMessage(shellSocketFD, buffer); // TODO // If we send integer op codes rather than strings, this process will be // MUCH faster since instead of donig string compares we can simply // switch on the integer value... if(strcmp(buffer, "register_service") == 0) { if(strcmp(buffer, "policy_geo") == 0) { } else if(strcmp(buffer, "policy_time") == 0) { } else if(strcmp(buffer, "policy_spectrum") == 0) { } else if(strcmp(buffer, "policy_spacial") == 0) { } } else if(strcmp(buffer, "deregister_service") == 0) { if(strcmp(buffer, "policy_geo") == 0) { } else if(strcmp(buffer, "policy_time") == 0) { } else if(strcmp(buffer, "policy_spectrum") == 0) { } else if(strcmp(buffer, "policy_spacial") == 0) { } } else if(strcmp(buffer, "query_component_type") == 0) { SendComponentType(); } else if(strcmp(buffer, "reset_sml") == 0) { Reset(); } else if(strcmp(buffer, "shutdown_sml") == 0) { Shutdown(); } } void ServiceManagementLayer::CESignalHandler(int32_t ID) { char buffer[256]; memset(buffer, 0, 256); // ReadMessage(cogEngSrv, buffer); if(strcmp(buffer, "register_engine_cognitive") == 0) { RegisterCognitiveEngine(ID); } } void ServiceManagementLayer::Shutdown() { DeregisterComponent(); } void ServiceManagementLayer::Reset() { DeregisterComponent(); LoadConfiguration(); } void ServiceManagementLayer::RegisterComponent() { SendMessage(shellSocketFD, "register_sml"); LOG("ServiceManagementLayer:: Registration message sent.\n"); } void ServiceManagementLayer::DeregisterComponent() { SendMessage(shellSocketFD, "deregister_sml"); LOG("ServiceManagementLayer:: Deregistration message sent.\n"); shutdown(shellSocketFD, 2); close(shellSocketFD); shellSocketFD = -1; LOG("ServiceManagementLayer:: Shell socket closed.\n"); } void ServiceManagementLayer::TransferRadioConfiguration(int32_t ID) { } void ServiceManagementLayer::TransferExperience(int32_t ID) { } void ServiceManagementLayer::ReceiveServices() { } void ServiceManagementLayer::SetActiveMission() { } void ServiceManagementLayer::ListServices() { } void ServiceManagementLayer::ReloadConfiguration() { LOG("ServiceManagementLayer:: Reloading Configuration.\n"); } void ServiceManagementLayer::LoadConfiguration() { LOG("ServiceManagementLayer:: Loading Configuration.\n"); } void ServiceManagementLayer::RegisterCognitiveEngine(int32_t socketFD) { SendMessage(shellSocketFD, "register_engine_cognitive"); LOG("Cognitive Engine:: Registration message sent to shell.\n"); TransferRadioConfiguration(socketFD); TransferExperience(socketFD); numberOfCognitiveEngines++; CE_Present = true; } void ServiceManagementLayer::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 ServiceManagementLayer::StartSMLServer() { struct timeval selTimeout; int32_t running = 1; int32_t port, rc, new_sd = 1; int32_t desc_ready = 1; int32_t timeout = 10; fd_set sockSet; cogEngSrv = CreateTCPServerSocket(CEPort); int32_t maxDescriptor = cogEngSrv; if(InitializeTCPServerPort(cogEngSrv) == -1) ERROR(1,"Error initializing primary 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(cogEngSrv, &sockSet); /* Timeout specification */ /* This must be reset every time select() is called */ selTimeout.tv_sec = timeout; /* timeout (secs.) */ selTimeout.tv_usec = 0; /* 0 microseconds */ //Check if there is a message on the socket waiting to be read rc = select(cogEngSrv + 1, &sockSet, NULL, NULL, &selTimeout); if(rc == 0){ //If not, log that fact and check instead for messages from the shell LOG("No echo requests for %i secs...Server still alive\n", timeout); ShellSignalHandler(); } else { //If so, process the address information and pass the component ID on to the handler char buffer[256]; memset(buffer, 0, 256); struct sockaddr_in sock_addr; memset((void *) &sock_addr, 0, sizeof(sock_addr)); //Peak at the next message on the socket to determine its address of orgin recvfrom(cogEngSrv, buffer, 256, MSG_PEEK, (struct sockaddr*) &sock_addr, NULL); bool found = false; //Is it from a previously logged address? for(int i = 0; i < Current_ID; i++){ if((*CE_List[i].sock_ptr).sin_addr.s_addr == sock_addr.sin_addr.s_addr){ //If so, pass the ID number of that component into the signal handler to process the message found=true; CESignalHandler(i); } } //If not, log the address and pass the ID number of that component into the signal handler if(!found){ CE_List[Current_ID].sock_ptr = &sock_addr; CE_List[Current_ID].ID_num = Current_ID; CESignalHandler(Current_ID); Current_ID++; } } } /* Close sockets */ close(cogEngSrv); return; } /* rc = select(cogEngSrv + 1, &sockSet, NULL, NULL, &selTimeout); if(rc == 0){ LOG("No echo requests for %i secs...Server still alive\n", timeout); ShellSignalHandler(); } 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 == cogEngSrv) { do { new_sd = AcceptTCPConnection(port); if(new_sd < 0) break; CE_List[Current_ID].FD = new_sd; CE_List[Current_ID].IDNum = Current_ID; HandleMessage(CE_List[Current_ID]); Current_ID++; 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"); for(int16_t i = 0; i < Current_ID; i++) { if(CE_List[i].FD == port) HandleMessage(CE_List[i]); } } } } } */