/* Virginia Tech Cognitive Radio Open Source Systems * Virginia Tech, 2009 * * LICENSE INFORMATION GOES HERE */ /* DESCRIPTION OF FILE. */ #include #include #include #include "vtcross/common.h" #include "vtcross/components.h" #include "vtcross/containers.h" #include "vtcross/debug.h" #include "vtcross/error.h" #include "vtcross/socketcomm.h" PolicyEngine::PolicyEngine() { LOG("Creating Policy Engine.\n"); SML_present = false; LoadPolicies(); } PolicyEngine::~PolicyEngine() { } PolicyEngine::PolicyEngine(const char* serverName, const char* serverPort, \ const bool SML) { LOG("Creating Policy Engine.\n"); SML_present = SML; ConnectToRemoteComponent(serverName, serverPort); LoadPolicies(); } void PolicyEngine::SendComponentType() { SendMessage(commandSocketFD, "response_engine_policy"); LOG("Policy Engine responded to GetRemoteComponentType query.\n"); } void PolicyEngine::ConnectToRemoteComponent(const char* serverName, \ const char* serverPort) { commandSocketFD = ClientSocket(serverName, serverPort); if(SML_present) { RegisterServices(); LOG("Policy Engine connected to SML at %s.\n", serverName); } else { RegisterComponent(); LOG("Policy Engine connected to shell at %s.\n", serverName); } } void PolicyEngine::WaitForSignal() { char buffer[256]; while(true) { memset(buffer, 0, 256); ReadMessage(commandSocketFD, buffer); // TODO this is ugly... is there a better way? Doesn't strcmp compare the // whole string? We only need to compare until we find a single different // byte... // // 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, "validate_parameters") == 0) { ValidateParameters(); } else if(strcmp(buffer, "query_component_type") == 0) { SendComponentType(); } else if(strcmp(buffer, "connect_sml") == 0) { /* 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); SML_present = true; ConnectToRemoteComponent(serverName, serverPort); } } else if(strcmp(buffer, "disconnect_sml") == 0) { /* 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); SML_present = false; ConnectToRemoteComponent(serverName, serverPort); } } else if(strcmp(buffer, "reload_engine_configs") == 0) { ReloadPolicies(); } else if(strcmp(buffer, "reset_engine_policy") == 0) { Reset(); } else if(strcmp(buffer, "shutdown_engine_policy") == 0) { Shutdown(); } } } void PolicyEngine::Shutdown() { if(SML_present) DeregisterServices(); else DeregisterComponent(); // TODO should something else be happening here? } void PolicyEngine::Reset() { LOG("Resetting Policy Engine.\n"); SML_present = false; commandSocketFD = -1; LoadPolicies(); } void PolicyEngine::RegisterComponent() { SendMessage(commandSocketFD, "register_engine_policy"); LOG("Policy Engine:: Registration message sent to shell.\n"); } void PolicyEngine::DeregisterComponent() { SendMessage(commandSocketFD, "deregister_engine_policy"); LOG("Policy Engine:: Deregistration message sent to shell.\n"); shutdown(commandSocketFD, 2); close(commandSocketFD); LOG("Policy Engine:: Shell socket closed.\n"); } void PolicyEngine::RegisterServices() { LOG("Policy Engine:: Registering services.\n"); SendMessage(commandSocketFD, "register_service_pe_geo"); SendMessage(commandSocketFD, "register_service_pe_time"); SendMessage(commandSocketFD, "register_service_pe_spectrum"); SendMessage(commandSocketFD, "register_service_pe_spacial"); } void PolicyEngine::DeregisterServices() { LOG("Policy Engine:: Deregistering services.\n"); SendMessage(commandSocketFD, "deregister_service_pe_geo"); SendMessage(commandSocketFD, "deregister_service_pe_time"); SendMessage(commandSocketFD, "deregister_service_pe_spectrum"); SendMessage(commandSocketFD, "deregister_service_pe_spacial"); shutdown(commandSocketFD, 2); close(commandSocketFD); LOG("Policy Engine:: SML socket closed.\n"); } void PolicyEngine::LoadPolicies() { LOG("PolicyEngine:: Loading policies.\n"); } void PolicyEngine::ReloadPolicies() { LOG("PolicyEngine:: Reloading policies.\n"); } void PolicyEngine::SendPEDecision(struct Parameter pList[], \ struct Radio_Info *radio_info, int32_t decision_array[]) { char var[50]; for (size_t i = 0; i < radio_info->numParameters; i++) { sprintf(var, "%i", decision_array[i]); SendMessage(commandSocketFD, var); } } void PolicyEngine::ValidateParameters() { LOG("Policy Engine:: Preparing to receive parameters for validation....\n"); int32_t decision_array[10]; struct Parameter pList[10]; struct Radio_Info radio_info; if(GetRequest(commandSocketFD, pList, &radio_info)) { LOG("Policy Engine:: Validating Transmission Parameters.\n"); for (size_t i = 0; i < radio_info.numParameters; i++) decision_array[i] = 1; LOG("Policy Engine:: Sending Policy decision to Server.\n"); SendPEDecision(pList, &radio_info, decision_array); LOG("Policy Engine:: Policies Validated.\n"); } else ERROR(1, "Call to GetRequest in ValidateParameters failed.\n"); }