/*! * \file CPluginExecutor.h * \author S. Eisenhauer * \date 27.10.2011 * \brief Header of CPluginExecutor */ #ifndef CPLUGINEXECUTOR_H_ #define CPLUGINEXECUTOR_H_ #include #include #include #include #include "TcpServer.h" #include "IPluginExecutor.h" #include "XorayaConnector.h" #include "CInterfaceManager.h" #include "plugin_api.h" /// maximum number of can tx messages in all plugins #define nMAX_CAN_TX_MESSAGES 1024 /// maximum length of a shared object file name #define nMAX_FILENAME_LENGTH 256 #define nMAX_LINE_LENGTH nMAX_FILENAME_LENGTH+2 /// structure for target plugins struct tstPluginConfig : public boost::intrusive::list_base_hook<> { char acPluginFilename[nMAX_FILENAME_LENGTH]; //!< filename of the shared object void* pvPluginHandle; //!< Handle of the plugin tpfctCreatePlugin pfctPluginFactory; //!< function pointer for the factory of this plugin tpfctDestroyPlugin pfctPluginDestruction; //!< function pointer for the destruction function of this plugin IPlugin* pxPlugin; //!< interface pointer for the plugin implementation }; /// type definition for target plugin pointer typedef tstPluginConfig* tpstPluginConfig; /// type definition for target plugin container typedef boost::intrusive::list tPluginList; /// type definition for target plugin container iterator typedef tPluginList::iterator tPluginIter; /// wrapper for storing CAN-Tx-Messages in an intrusive set struct tstCanTxMsgWrapper : public boost::intrusive::set_base_hook<> { tpstCanTxMessage m_pstCanTxMsg; //!< pointer to the CAN TX message int32_t i32Interface; //!< interface for sending the message /// operator less, needed for sorting messages by id in the intrusive set friend bool operator< (const tstCanTxMsgWrapper& a, const tstCanTxMsgWrapper& b) { return a.m_pstCanTxMsg->u32CanId < b.m_pstCanTxMsg->u32CanId; } }; /// type definition for CAN TX message container typedef boost::intrusive::multiset tCanTxMessageSet; /// target main application class CPluginExecutor : IPluginExecutor { public: CPluginExecutor(); virtual ~CPluginExecutor(); /// add a plugin /// \param[in] pcSoFilename filename of the shared object to load as plugin /// \param[in] i32Interface interface for sending messages in the plugin /// \param[out] u8PluginId id of the plugin /// \return error code tenRetCodes enAddPlugin( const char* pcSoFilename, const int32_t i32Interface, uint8_t& u8PluginId ); /// remove a plugin /// \param[in] i32Interface interface from which to remove the according plugin /// \param[in] boLock lock the plugin container during removal, default yes /// \return error code tenRetCodes enRemovePlugin( const int32_t i32Interface, bool boLock = true ); /// cyclic function, this is the RT-prio task function void vRun(); /// deinitialize all plugins /// \return error code tenRetCodes enDeinitAllPlugins(); /// stop the application void vStop(); /// deinitialize the application void vDeinit(); /// get the number of loaded plugins /// \return number loaded plugins uint8_t u8GetPluginCount(); /// load all plugins with autoload flag active /// \return error code tenRetCodes enAutoLoadPlugins(); /// get a specified log file, rotates log file if current log is requested /// \param[in] pcRequestFilename requested file /// \param[out] pcResponseFilename name of the file that contains the requested log /// \param[out] u32Length Length of pcResponseFilename /// \return error code tenRetCodes enGetLog(const char* pcRequestFilename, char* pcResponseFilename, uint32_t& u32Length); /// get names of available logfiles /// \param[out] pcLogfiles available logfiles, separate by newline character /// \param[out] u32Length Length of pcLogfiles /// \return error code tenRetCodes enEnumerateLogs(char* pcLogfiles, uint32_t& u32Length); /// get hardware interfaces /// \param[out] pcResponse interfaces, separate by newline character /// \param[out] u32Length Length of pcResponse /// \return error code void vGetInterfaces(char* pcResponse, uint32_t& u32Length); /// start a plugin on given interface /// \param[in] i32Interface the interface /// \param[in] pcSoFilename file name of the shared object void vStartPlugin(const int32_t i32Interface, const char* pcSoFilename); /// stop the plugin running on given interface /// \param[in] i32Interface the interface void vStopPlugin(const int32_t i32Interface); /// change data of a can message /// \param[in] i32Interface the interface of the message /// \param[in] u32CanId identifier of the message /// \param[in] pu8Data pointer to new message data void vChangeMsgData(const int32_t i32Interface, const uint32_t u32CanId, const uint8_t* pu8Data); virtual void vUploadLogMessage(const tstLogMessage& stLogMsg); private: bool m_boDoStop; CInterfaceManager m_xInterfaceManager; tPluginList m_astPluginConfig; uint8_t m_u8PluginCounter; CTcpServer m_xTcpServer; CXorayaConnector m_xConnector; boost::thread m_xConnectorThread; tCanTxMessageSet m_xTxMsgList; x2e::Mutex m_xPluginListMutex; x2e::Mutex m_xStopFlagMutex; IPlugin* m_pxLogPlugin; tenRetCodes enLoadSoFile( const char* pcSoFilename, void** ppvSoHandle ); tenRetCodes enLoadSymbol( const char* pcSymbolName, void* pvSoHandle, void** ppvHandle ); tenRetCodes enInitPlugin( tpstPluginConfig& pstPluginConfig, const int32_t i32Interface); tenRetCodes enDeinitPlugin(tpstPluginConfig& pstPluginConfig); void vSendCanTxMessages(); tPluginIter findPluginByInterface(const int32_t i32Interface) { tPluginIter it = m_astPluginConfig.begin(); for(; it!= m_astPluginConfig.end(); ++it) { tpstPluginConfig pstPluginConfig = &(*it); if( pstPluginConfig && pstPluginConfig->pvPluginHandle ) { IPlugin* pxPlugin = pstPluginConfig->pxPlugin; if( pxPlugin ) { if( pxPlugin->i32GetCanInterfaceHandle() == i32Interface ) { DEBUG_PRINT("found memory for plugin on interface %d",i32Interface); return it; } } } } return it; } }; #endif /* CPLUGINEXECUTOR_H_ */