summaryrefslogtreecommitdiffstats
path: root/Master/Masterarbeit/src/XorayaPluginExecutor/CPluginExecutor.h
blob: 1fd5790699a5439c44f4db123e513fbaf891dd4a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*!
 * \file CPluginExecutor.h
 * \author S. Eisenhauer
 * \date 27.10.2011
 * \brief Header of CPluginExecutor
 */
#ifndef CPLUGINEXECUTOR_H_
#define CPLUGINEXECUTOR_H_

#include <boost/thread.hpp>
#include <x2e/sys/Mutex.hpp>
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/list.hpp>
#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<tstPluginConfig> 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<tstCanTxMsgWrapper> 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_ */