diff --git a/cpp/common/include/IpcMessage.h b/cpp/common/include/IpcMessage.h index 686b2b37a..715a53340 100644 --- a/cpp/common/include/IpcMessage.h +++ b/cpp/common/include/IpcMessage.h @@ -90,6 +90,8 @@ class IpcMessage MsgValCmdStatus, //!< Status command message MsgValCmdConfigure, //!< Configure command message MsgValCmdRequestConfiguration, //!< Request configuration command message + MsgValCmdCommand, //!< Submit a command message + MsgValCmdRequestCommands, //!< Request available commands message MsgValCmdRequestVersion, //!< Request version information message MsgValCmdBufferConfigRequest, //!< Buffer configuration request MsgValCmdBufferPrechargeRequest, //!< Buffer precharge request diff --git a/cpp/frameProcessor/include/FrameProcessorController.h b/cpp/frameProcessor/include/FrameProcessorController.h index d2944bdd6..ea014fc5f 100644 --- a/cpp/frameProcessor/include/FrameProcessorController.h +++ b/cpp/frameProcessor/include/FrameProcessorController.h @@ -45,6 +45,8 @@ class FrameProcessorController : public IFrameCallback, void provideVersion(OdinData::IpcMessage& reply); void configure(OdinData::IpcMessage& config, OdinData::IpcMessage& reply); void requestConfiguration(OdinData::IpcMessage& reply); + void command(OdinData::IpcMessage& config, OdinData::IpcMessage& reply); + void requestCommands(OdinData::IpcMessage& reply); void resetStatistics(OdinData::IpcMessage& reply); void configurePlugin(OdinData::IpcMessage& config, OdinData::IpcMessage& reply); void loadPlugin(const std::string& index, const std::string& name, const std::string& library); diff --git a/cpp/frameProcessor/include/FrameProcessorPlugin.h b/cpp/frameProcessor/include/FrameProcessorPlugin.h index 17921c511..b9f28b8e0 100644 --- a/cpp/frameProcessor/include/FrameProcessorPlugin.h +++ b/cpp/frameProcessor/include/FrameProcessorPlugin.h @@ -45,6 +45,8 @@ class FrameProcessorPlugin : public IFrameCallback, public OdinData::IVersionedO std::vector get_warnings(); virtual void configure(OdinData::IpcMessage& config, OdinData::IpcMessage& reply); virtual void requestConfiguration(OdinData::IpcMessage& reply); + virtual void command(OdinData::IpcMessage& config, OdinData::IpcMessage& reply); + virtual void requestCommands(OdinData::IpcMessage& reply); virtual void status(OdinData::IpcMessage& status); void add_performance_stats(OdinData::IpcMessage& status); void reset_performance_stats(); diff --git a/cpp/frameProcessor/src/FrameProcessorController.cpp b/cpp/frameProcessor/src/FrameProcessorController.cpp index 627b7f458..f12e28bb4 100644 --- a/cpp/frameProcessor/src/FrameProcessorController.cpp +++ b/cpp/frameProcessor/src/FrameProcessorController.cpp @@ -135,6 +135,20 @@ void FrameProcessorController::handleCtrlChannel() LOG4CXX_DEBUG_LEVEL(3, logger_, "Control thread reply message (request configuration): " << replyMsg.encode()); } + else if ((ctrlMsg.get_msg_type() == OdinData::IpcMessage::MsgTypeCmd) && + (ctrlMsg.get_msg_val() == OdinData::IpcMessage::MsgValCmdCommand)) { + replyMsg.set_msg_type(OdinData::IpcMessage::MsgTypeAck); + this->command(ctrlMsg, replyMsg); + LOG4CXX_DEBUG_LEVEL(3, logger_, "Control thread reply message (command): " + << replyMsg.encode()); + } + else if ((ctrlMsg.get_msg_type() == OdinData::IpcMessage::MsgTypeCmd) && + (ctrlMsg.get_msg_val() == OdinData::IpcMessage::MsgValCmdRequestCommands)) { + replyMsg.set_msg_type(OdinData::IpcMessage::MsgTypeAck); + this->requestCommands(replyMsg); + LOG4CXX_DEBUG_LEVEL(3, logger_, "Control thread reply message (request commands): " + << replyMsg.encode()); + } else if ((ctrlMsg.get_msg_type() == OdinData::IpcMessage::MsgTypeCmd) && (ctrlMsg.get_msg_val() == OdinData::IpcMessage::MsgValCmdStatus)) { replyMsg.set_msg_type(OdinData::IpcMessage::MsgTypeAck); @@ -507,6 +521,56 @@ void FrameProcessorController::requestConfiguration(OdinData::IpcMessage& reply) } } +/** + * Submit commands to the FrameProcessor plugins. + * + * Submits command(s) to execute on individual plugins if they + * support commands. The IpcMessage should contain the command + * name and a structure of any parameters required by the command. + * + * This method searches for command objects that have the same + * index as loaded plugins. If any of these are found then the + * commands are passed down to the plugin for execution. + * + * \param[in] config - IpcMessage containing command and any parameter data. + * \param[out] reply - Response IpcMessage. + */ +void FrameProcessorController::command(OdinData::IpcMessage& config, OdinData::IpcMessage& reply) +{ + LOG4CXX_DEBUG_LEVEL(1, logger_, "Command submitted: " << config.encode()); + + // Loop over plugins, checking for command messages + std::map >::iterator iter; + for (iter = plugins_.begin(); iter != plugins_.end(); ++iter) { + if (config.has_param(iter->first)) { + OdinData::IpcMessage subConfig(config.get_param(iter->first), + config.get_msg_type(), + config.get_msg_val()); + iter->second->command(subConfig, reply); + } + } +} + +/** + * Request the command set supported by this FrameProcessorController and + * its loaded plugins. + * + * The method searches through all loaded plugins. Each plugin is + * also sent a request for its supported commands. + * + * \param[out] reply - Response IpcMessage with the current supported command set. + */ +void FrameProcessorController::requestCommands(OdinData::IpcMessage& reply) +{ + LOG4CXX_DEBUG_LEVEL(3, logger_, "Request for supported commands made"); + + // Loop over plugins and request current supported commands from each + std::map >::iterator iter; + for (iter = plugins_.begin(); iter != plugins_.end(); ++iter) { + iter->second->requestCommands(reply); + } +} + /** * Reset statistics on all of the loaded plugins. * diff --git a/cpp/frameProcessor/src/FrameProcessorPlugin.cpp b/cpp/frameProcessor/src/FrameProcessorPlugin.cpp index 837e699f9..77c7db5c8 100644 --- a/cpp/frameProcessor/src/FrameProcessorPlugin.cpp +++ b/cpp/frameProcessor/src/FrameProcessorPlugin.cpp @@ -143,7 +143,7 @@ std::vector FrameProcessorPlugin::get_warnings() return warning_messages_; } - /** Configure the plugin. +/** Configure the plugin. * * In this abstract class the configure method does perform any * actions, this should be overridden by subclasses. @@ -168,6 +168,31 @@ void FrameProcessorPlugin::requestConfiguration(OdinData::IpcMessage& reply) // Default method simply does nothing } +/** Execute a command within the plugin. + * + * In this abstract class the command method does perform any + * actions, this should be overridden by subclasses. + * + * \param[in] config - IpcMessage containing command data. + * \param[out] reply - Response IpcMessage. + */ +void FrameProcessorPlugin::command(OdinData::IpcMessage& config, OdinData::IpcMessage& reply) +{ + // Default method simply does nothing +} + +/** Request the plugin's supported commands. + * + * In this abstract class the request method does perform any + * actions, this should be overridden by subclasses. + * + * \param[out] reply - Response IpcMessage with current supported commands. + */ +void FrameProcessorPlugin::requestCommands(OdinData::IpcMessage& reply) +{ + // Default method simply does nothing +} + /** * Collate status information for the plugin. *