/* 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 is a reference implementation for the CROSS Policy Engine. * * Note that this implementation is NOT complete. */ #include #include #include #include "vtcross/common.h" #include "vtcross/containers.h" #include "vtcross/debug.h" #include "vtcross/error.h" #include "vtcross/policy_engine.h" #include "vtcross/socketcomm.h" PolicyEngine::PolicyEngine() { LOG("Creating Policy Engine.\n"); SML_present = false; commandSocketFD = -1; LoadPolicies(); } PolicyEngine::~PolicyEngine() { } PolicyEngine::PolicyEngine(const char* serverName, const char* serverPort, \ const bool SML) { LOG("Creating Policy Engine.\n"); ConnectToRemoteComponent(serverName, serverPort, SML); 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, const bool SML) { commandSocketFD = ClientSocket(serverName, serverPort); SML_present = SML; if(SML) { 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); ConnectToRemoteComponent(serverName, serverPort, true); } } 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); ConnectToRemoteComponent(serverName, serverPort, false); } } 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"); if(SML_present) DeregisterServices(); else DeregisterComponent(); } 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); commandSocketFD = -1; LOG("Policy Engine:: Shell socket closed.\n"); } void PolicyEngine::RegisterServices() { LOG("Policy Engine:: Registering services.\n"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "policy_geo"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "policy_time"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "policy_spectrum"); SendMessage(commandSocketFD, "register_service"); SendMessage(commandSocketFD, "policy_spacial"); } void PolicyEngine::DeregisterServices() { LOG("Policy Engine:: Deregistering services.\n"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "policy_geo"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "policy_time"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "policy_spectrum"); SendMessage(commandSocketFD, "deregister_service"); SendMessage(commandSocketFD, "policy_spacial"); shutdown(commandSocketFD, 2); close(commandSocketFD); commandSocketFD = -1; 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"); }