* recreated the header files out of the model. Added versioning support in the header...
[profile/ivi/genivi/genivi-audio-manager.git] / PluginRoutingInterfaceAsync / include / RoutingSenderAsyn.h
1 /**
2 * Copyright (C) 2011, BMW AG
3 *
4 * GeniviAudioMananger DbusPlugin
5 *
6 * \file RoutingSender.h
7 *
8 * \date 20-Oct-2011 3:42:04 PM
9 * \author Christian Mueller (christian.ei.mueller@bmw.de)
10 *
11 * \section License
12 * GNU Lesser General Public License, version 2.1, with special exception (GENIVI clause)
13 * Copyright (C) 2011, BMW AG Christian Mueller  Christian.ei.mueller@bmw.de
14 *
15 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
16 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License, version 2.1, for more details.
17 * You should have received a copy of the GNU Lesser General Public License, version 2.1, along with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
18 * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may also be applicable to programs even in cases in which the program is not a library in the technical sense.
19 * Linking AudioManager statically or dynamically with other modules is making a combined work based on AudioManager. You may license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to license your linked modules under the GNU Lesser General Public License, version 2.1, you may use the program under the following exception.
20 * As a special exception, the copyright holders of AudioManager give you permission to combine AudioManager with software programs or libraries that are released under any license unless such a combination is not permitted by the license of such a software program or library. You may copy and distribute such a system following the terms of the GNU Lesser General Public License, version 2.1, including this special exception, for AudioManager and the licenses of the other code concerned.
21 * Note that people who make modified versions of AudioManager are not obligated to grant this special exception for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License, version 2.1, gives permission to release a modified version without this exception; this exception also makes it possible to release a modified version which carries forward this exception.
22 *
23 * THIS CODE HAS BEEN GENERATED BY ENTERPRISE ARCHITECT GENIVI MODEL. PLEASE CHANGE ONLY IN ENTERPRISE ARCHITECT AND GENERATE AGAIN
24 */
25
26 #ifndef ROUTINGSENDER_H_
27 #define ROUTINGSENDER_H_
28
29 #include <routing/RoutingSendInterface.h>
30 #include "RoutingReceiverAsyncShadow.h"
31 #include <semaphore.h>
32
33 namespace am {
34
35 class WorkerThreadPool;
36
37 /**
38  * Base class for workers implements everything that is needed to implement a workerthread
39  * inherit from this class when adding new workers
40  */
41 class Worker
42 {
43 public:
44         Worker(WorkerThreadPool* pool);
45         virtual ~Worker(){};
46         /**
47          * needs to be overwritten, this function is called when the worker should start to work
48          */
49         void virtual start2work()=0;
50
51         /**
52          * needs to be overwritten, this function is called when the worker thread is canceled. Should be used for
53          * clean up and sending important messages
54          */
55         void virtual cancelWork()=0;
56         /**
57          * waits for a semaphore with a timeout. This leaves the Threadpool the chance to interrupt the processing
58          * You should call whenever waiting on some event, even with time=0 in order to make sure that cancel events are
59          * received
60          * @param time time until timeout in timespec format
61          * @return true if thread is canceled. Then just return start2work function so that the thread is given back to the pool
62          */
63         bool timedWait(timespec time);
64
65         /**
66          * the semaphore for cancellation is set by the thread automatically...
67          * @param cancel
68          */
69         void setCancelSempaphore(sem_t* cancel);
70         WorkerThreadPool* pPool;
71 private:
72         sem_t* mCancelSem; //<! semaphore for cancellation
73 };
74
75
76 /**
77  * This class handles the threadpool
78  */
79 class WorkerThreadPool
80 {
81 public:
82         /**
83          * creates the pool. Give the max number of threads as argument
84          * @param numThreads max number of threads
85          */
86         WorkerThreadPool(int numThreads);
87         virtual ~WorkerThreadPool();
88
89         /**
90          * assigns a thread to a worker class and starts working.
91          * @param worker
92          * @return the actual assigned workerID or -1 in case no thread is free
93          */
94         int16_t startWork(Worker* worker);
95         /**
96          * cancels a thread
97          * @param workerID thread to be canceled
98          * @return true if thread was found, false if not
99          */
100         bool cancelWork(int workerID);
101
102         /**
103          * the workers call this function upon completion of their task
104          * @param threadID
105          */
106         void finishedWork(pthread_t threadID);
107
108
109 private:
110         static void* WorkerThread (void* data);
111         int mNumThreads;
112         struct threadInfo_s
113         {
114                 uint16_t workerID;
115                 pthread_t threadID;
116                 bool busy;
117                 sem_t block;
118                 sem_t cancel;
119                 Worker *worker;
120         };
121         std::vector<threadInfo_s> mListWorkers; //<! list of all workers
122         static pthread_mutex_t mBlockingMutex;  //<! mutex to block the acces of the list
123 };
124
125 class AsyncRoutingSender: public RoutingSendInterface {
126 public:
127         AsyncRoutingSender();
128         virtual ~AsyncRoutingSender();
129         void startupRoutingInterface(RoutingReceiveInterface* routingreceiveinterface) ;
130         void routingInterfacesReady() ;
131         void routingInterfacesRundown() ;
132         am_Error_e asyncAbort(const am_Handle_s handle) ;
133         am_Error_e asyncConnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_ConnectionFormat_e connectionFormat) ;
134         am_Error_e asyncDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID) ;
135         am_Error_e asyncSetSinkVolume(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume, const am_RampType_e ramp, const am_time_t time) ;
136         am_Error_e asyncSetSourceVolume(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume, const am_RampType_e ramp, const am_time_t time) ;
137         am_Error_e asyncSetSourceState(const am_Handle_s handle, const am_sourceID_t sourceID, const am_SourceState_e state) ;
138         am_Error_e asyncSetSinkSoundProperty(const am_Handle_s handle, const am_SoundProperty_s& soundProperty, const am_sinkID_t sinkID) ;
139         am_Error_e asyncSetSinkSoundProperties(const am_Handle_s handle, const std::vector<am_SoundProperty_s>& listSoundProperties, const am_sinkID_t sinkID) ;
140         am_Error_e asyncSetSourceSoundProperty(const am_Handle_s handle, const am_SoundProperty_s& soundProperty, const am_sourceID_t sourceID) ;
141         am_Error_e asyncSetSourceSoundProperties(const am_Handle_s handle, const std::vector<am_SoundProperty_s>& listSoundProperties, const am_sourceID_t sourceID) ;
142         am_Error_e asyncCrossFade(const am_Handle_s handle, const am_crossfaderID_t crossfaderID, const am_HotSink_e hotSink, const am_RampType_e rampType, const am_time_t time) ;
143         am_Error_e setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState) ;
144         am_Error_e returnBusName(std::string& BusName) const ;
145         uint16_t getInterfaceVersion() const;
146
147         /**
148          * threadafe insert of route and connectionID
149          * @param connectionID
150          * @param route
151          */
152         void insertConnectionSafe(am_connectionID_t connectionID,am_RoutingElement_s route);
153
154         /**
155          * threadsafe removal of a connection
156          * @param
157          */
158         void removeConnectionSafe(am_connectionID_t);
159
160         /**
161          * threadsafe remove of a handle
162          * @param handle
163          */
164         void removeHandleSafe(uint16_t handle);
165
166         /**
167          * threadsafe update of Sinkvolume
168          * @param sinkID
169          * @param volume
170          */
171         void updateSinkVolumeSafe(am_sinkID_t sinkID,am_volume_t volume);
172
173         /**
174          * threadsafe update of SourceVolume
175          * @param sourceID
176          * @param volume
177          */
178         void updateSourceVolumeSafe(am_sourceID_t sourceID,am_volume_t volume);
179
180         /**
181          * threadsafe update of sourceState
182          * @param sourceID
183          * @param state
184          */
185         void updateSourceStateSafe(am_sourceID_t sourceID,am_SourceState_e state);
186
187         /**
188          * threadsafe update of sinkSoundProperty
189          * @param sinkID
190          * @param soundProperty
191          */
192         void updateSinkSoundPropertySafe(am_sinkID_t sinkID, am_SoundProperty_s soundProperty);
193
194         /**
195          * threadsafe update of sourceSoundProperty
196          * @param sourceID
197          * @param soundProperty
198          */
199         void updateSourceSoundPropertySafe(am_sourceID_t sourceID, am_SoundProperty_s soundProperty);
200
201         /**
202          * threadsafe update of domainstate
203          * @param domainID
204          * @param domainState
205          */
206         void updateDomainstateSafe(am_domainID_t domainID,am_DomainState_e domainState);
207
208 private:
209         /**
210          * Extra thread that handles dbus stimulation for interrupt tests
211          * @param data
212          */
213         static void* InterruptEvents (void* data);
214         std::vector<am_Domain_s> createDomainTable();
215         std::vector<am_Sink_s> createSinkTable();
216         std::vector<am_Source_s> createSourceTable();
217         std::vector<am_Gateway_s> createGatewayTable();
218         RoutingReceiverAsyncShadow mShadow;
219         RoutingReceiveInterface* mReceiveInterface;
220         SocketHandler *mSocketHandler;
221         std::vector<am_Domain_s> mDomains;
222         std::vector<am_Sink_s> mSinks;
223         std::vector<am_Source_s> mSources;
224         std::vector<am_Gateway_s> mGateways;
225         std::map<uint16_t,int16_t> mMapHandleWorker;
226         std::map<am_connectionID_t,am_RoutingElement_s> mMapConnectionIDRoute;
227         WorkerThreadPool mPool;
228         pthread_t mInterruptThread;
229         static pthread_mutex_t mMapConnectionMutex;
230         static pthread_mutex_t mMapHandleWorkerMutex;
231         static pthread_mutex_t mSinksMutex;
232         static pthread_mutex_t mSourcesMutex;
233         static pthread_mutex_t mDomainsMutex;
234 };
235
236
237 /**
238  * worker to for connection
239  */
240 class asycConnectWorker : public Worker
241 {
242 public:
243         asycConnectWorker(AsyncRoutingSender * asyncSender,WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_connectionID_t connectionID, const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_ConnectionFormat_e connectionFormat);
244         void start2work();
245         void cancelWork();
246 private:
247         AsyncRoutingSender * mAsyncSender;
248         RoutingReceiverAsyncShadow *mShadow;
249         am_Handle_s mHandle;
250         am_connectionID_t mConnectionID;
251         am_sourceID_t mSourceID;
252         am_sinkID_t mSinkID;
253         am_ConnectionFormat_e mConnectionFormat;
254 };
255
256 /**
257  * worker for disconnecting
258  */
259 class asycDisConnectWorker : public Worker
260 {
261 public:
262         asycDisConnectWorker(AsyncRoutingSender * asyncSender,WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_connectionID_t connectionID);
263         void start2work();
264         void cancelWork();
265 private:
266         AsyncRoutingSender * mAsyncSender;
267         RoutingReceiverAsyncShadow *mShadow;
268         am_Handle_s mHandle;
269         am_connectionID_t mConnectionID;
270         am_ConnectionFormat_e mConnectionFormat;
271 };
272
273 /**
274  * worker to for connection
275  */
276
277 #include <semaphore.h>
278 #include <sys/signalfd.h>
279 #include <signal.h>
280
281 class asyncSetSinkVolumeWorker : public Worker
282 {
283 public:
284         asyncSetSinkVolumeWorker(AsyncRoutingSender * asyncSender,WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_volume_t currentVolume,const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume, const am_RampType_e ramp, const am_time_t time);
285         void start2work();
286         void cancelWork();
287 private:
288         AsyncRoutingSender * mAsyncSender;
289         RoutingReceiverAsyncShadow *mShadow;
290         am_volume_t mCurrentVolume;
291         am_Handle_s mHandle;
292         am_sinkID_t mSinkID;
293         am_volume_t mVolume;
294         am_RampType_e mRamp;
295         am_time_t mTime;
296 };
297
298 class asyncSetSourceVolumeWorker : public Worker
299 {
300 public:
301         asyncSetSourceVolumeWorker(AsyncRoutingSender * asyncSender,WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_volume_t currentVolume,const am_Handle_s handle, const am_sourceID_t SourceID, const am_volume_t volume, const am_RampType_e ramp, const am_time_t time);
302         void start2work();
303         void cancelWork();
304 private:
305         AsyncRoutingSender * mAsyncSender;
306         RoutingReceiverAsyncShadow *mShadow;
307         am_volume_t mCurrentVolume;
308         am_Handle_s mHandle;
309         am_sourceID_t mSourceID;
310         am_volume_t mVolume;
311         am_RampType_e mRamp;
312         am_time_t mTime;
313 };
314
315 class asyncSetSourceStateWorker : public Worker
316 {
317 public:
318         asyncSetSourceStateWorker(AsyncRoutingSender * asyncSender,WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_sourceID_t sourceID, const am_SourceState_e state);
319         void start2work();
320         void cancelWork();
321 private:
322         AsyncRoutingSender * mAsyncSender;
323         RoutingReceiverAsyncShadow *mShadow;
324         am_Handle_s mHandle;
325         am_sourceID_t mSourceID;
326     am_SourceState_e mSourcestate;
327 };
328
329 class asyncSetSinkSoundPropertyWorker : public Worker
330 {
331 public:
332         asyncSetSinkSoundPropertyWorker(AsyncRoutingSender * asyncSender,WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_SoundProperty_s soundProperty, const am_sinkID_t sinkID);
333         void start2work();
334         void cancelWork();
335 private:
336         AsyncRoutingSender * mAsyncSender;
337         RoutingReceiverAsyncShadow *mShadow;
338         am_Handle_s mHandle;
339         am_sinkID_t mSinkID;
340     am_SoundProperty_s mSoundProperty;
341 };
342
343 class asyncSetSourceSoundPropertyWorker : public Worker
344 {
345 public:
346         asyncSetSourceSoundPropertyWorker(AsyncRoutingSender * asyncSender,WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_SoundProperty_s soundProperty, const am_sourceID_t sourceID);
347         void start2work();
348         void cancelWork();
349 private:
350         AsyncRoutingSender * mAsyncSender;
351         RoutingReceiverAsyncShadow *mShadow;
352         am_Handle_s mHandle;
353         am_sourceID_t mSourceID;
354     am_SoundProperty_s mSoundProperty;
355 };
356
357 class asyncDomainStateChangeWorker : public Worker
358 {
359 public:
360         asyncDomainStateChangeWorker(AsyncRoutingSender * asyncSender,WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_domainID_t domainID, const am_DomainState_e domainState);
361         void start2work();
362         void cancelWork();
363 private:
364         AsyncRoutingSender * mAsyncSender;
365         RoutingReceiverAsyncShadow *mShadow;
366         am_domainID_t mDomainID;
367         am_DomainState_e mDomainState;
368 };
369
370 }
371
372 #endif /* ROUTINGSENDER_H_ */