* [GAM-11] Merge branch 'dlt_dependency'
[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
36 class WorkerThreadPool;
37
38 /**
39  * Base class for workers implements everything that is needed to implement a workerthread
40  * inherit from this class when adding new workers
41  */
42 class Worker
43 {
44 public:
45     Worker(WorkerThreadPool* pool);
46     virtual ~Worker()
47     {
48     }
49     ;
50     /**
51      * needs to be overwritten, this function is called when the worker should start to work
52      */
53     void virtual start2work()=0;
54
55     /**
56      * needs to be overwritten, this function is called when the worker thread is canceled. Should be used for
57      * clean up and sending important messages
58      */
59     void virtual cancelWork()=0;
60     /**
61      * waits for a semaphore with a timeout. This leaves the Threadpool the chance to interrupt the processing
62      * You should call whenever waiting on some event, even with time=0 in order to make sure that cancel events are
63      * received
64      * @param time time until timeout in timespec format
65      * @return true if thread is canceled. Then just return start2work function so that the thread is given back to the pool
66      */
67     bool timedWait(timespec time);
68
69     /**
70      * the semaphore for cancellation is set by the thread automatically...
71      * @param cancel
72      */
73     void setCancelSempaphore(sem_t* cancel);
74     WorkerThreadPool* pPool;
75 private:
76     sem_t* mCancelSem; //<! semaphore for cancellation
77 };
78
79 /**
80  * This class handles the threadpool
81  */
82 class WorkerThreadPool
83 {
84 public:
85     /**
86      * creates the pool. Give the max number of threads as argument
87      * @param numThreads max number of threads
88      */
89     WorkerThreadPool(int numThreads);
90     virtual ~WorkerThreadPool();
91
92     /**
93      * assigns a thread to a worker class and starts working.
94      * @param worker
95      * @return the actual assigned workerID or -1 in case no thread is free
96      */
97     int16_t startWork(Worker* worker);
98     /**
99      * cancels a thread
100      * @param workerID thread to be canceled
101      * @return true if thread was found, false if not
102      */
103     bool cancelWork(int workerID);
104
105     /**
106      * the workers call this function upon completion of their task
107      * @param threadID
108      */
109     void finishedWork(pthread_t threadID);
110
111 private:
112     static void* WorkerThread(void* data);
113     int mNumThreads;
114     struct threadInfo_s
115     {
116         uint16_t workerID;
117         pthread_t threadID;
118         bool busy;
119         sem_t block;
120         sem_t cancel;
121         Worker *worker;
122     };
123     std::vector<threadInfo_s> mListWorkers; //<! list of all workers
124     static pthread_mutex_t mBlockingMutex; //<! mutex to block the acces of the list
125 };
126
127 class AsyncRoutingSender: public RoutingSendInterface
128 {
129 public:
130     AsyncRoutingSender();
131     virtual ~AsyncRoutingSender();
132     am_Error_e startupInterface(RoutingReceiveInterface* routingreceiveinterface) ;
133     void setRoutingReady(const uint16_t handle) ;
134     void setRoutingRundown(const uint16_t handle) ;
135     am_Error_e asyncAbort(const am_Handle_s handle) ;
136     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) ;
137     am_Error_e asyncDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID) ;
138     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) ;
139     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) ;
140     am_Error_e asyncSetSourceState(const am_Handle_s handle, const am_sourceID_t sourceID, const am_SourceState_e state) ;
141     am_Error_e asyncSetSinkSoundProperties(const am_Handle_s handle, const am_sinkID_t sinkID, const std::vector<am_SoundProperty_s>& listSoundProperties) ;
142     am_Error_e asyncSetSinkSoundProperty(const am_Handle_s handle, const am_sinkID_t sinkID, const am_SoundProperty_s& soundProperty) ;
143     am_Error_e asyncSetSourceSoundProperties(const am_Handle_s handle, const am_sourceID_t sourceID, const std::vector<am_SoundProperty_s>& listSoundProperties) ;
144     am_Error_e asyncSetSourceSoundProperty(const am_Handle_s handle, const am_sourceID_t sourceID, const am_SoundProperty_s& soundProperty) ;
145     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) ;
146     am_Error_e setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState) ;
147     am_Error_e returnBusName(std::string& BusName) const ;
148     void getInterfaceVersion(std::string& version) const ;
149
150     /**
151      * threadafe insert of route and connectionID
152      * @param connectionID
153      * @param route
154      */
155     void insertConnectionSafe(am_connectionID_t connectionID, am_RoutingElement_s route);
156
157     /**
158      * threadsafe removal of a connection
159      * @param
160      */
161     void removeConnectionSafe(am_connectionID_t);
162
163     /**
164      * threadsafe remove of a handle
165      * @param handle
166      */
167     void removeHandleSafe(uint16_t handle);
168
169     /**
170      * threadsafe update of Sinkvolume
171      * @param sinkID
172      * @param volume
173      */
174     void updateSinkVolumeSafe(am_sinkID_t sinkID, am_volume_t volume);
175
176     /**
177      * threadsafe update of SourceVolume
178      * @param sourceID
179      * @param volume
180      */
181     void updateSourceVolumeSafe(am_sourceID_t sourceID, am_volume_t volume);
182
183     /**
184      * threadsafe update of sourceState
185      * @param sourceID
186      * @param state
187      */
188     void updateSourceStateSafe(am_sourceID_t sourceID, am_SourceState_e state);
189
190     /**
191      * threadsafe update of sinkSoundProperty
192      * @param sinkID
193      * @param soundProperty
194      */
195     void updateSinkSoundPropertySafe(am_sinkID_t sinkID, am_SoundProperty_s soundProperty);
196
197     /**
198      * threadsafe update of sourceSoundProperty
199      * @param sourceID
200      * @param soundProperty
201      */
202     void updateSourceSoundPropertySafe(am_sourceID_t sourceID, am_SoundProperty_s soundProperty);
203
204     /**
205      * threadsafe update of domainstate
206      * @param domainID
207      * @param domainState
208      */
209     void updateDomainstateSafe(am_domainID_t domainID, am_DomainState_e domainState);
210
211 private:
212     /**
213      * Extra thread that handles dbus stimulation for interrupt tests
214      * This is a very very very basic implementation of the dbus interface
215      * there is not failure handling, nothing.
216      * it is used just for testing, not intended to be used otherwise...
217      * @param data
218      */
219     static void* InterruptEvents(void* data);
220     std::vector<am_Domain_s> createDomainTable();
221     std::vector<am_Sink_s> createSinkTable();
222     std::vector<am_Source_s> createSourceTable();
223     std::vector<am_Gateway_s> createGatewayTable();
224     RoutingReceiverAsyncShadow mShadow;
225     RoutingReceiveInterface* mReceiveInterface;
226     SocketHandler *mSocketHandler;
227     std::vector<am_Domain_s> mDomains;
228     std::vector<am_Sink_s> mSinks;
229     std::vector<am_Source_s> mSources;
230     std::vector<am_Gateway_s> mGateways;
231     std::map<uint16_t, int16_t> mMapHandleWorker;
232     std::map<am_connectionID_t, am_RoutingElement_s> mMapConnectionIDRoute;
233     WorkerThreadPool mPool;
234     pthread_t mInterruptThread;
235     static pthread_mutex_t mMapConnectionMutex;
236     static pthread_mutex_t mMapHandleWorkerMutex;
237     static pthread_mutex_t mSinksMutex;
238     static pthread_mutex_t mSourcesMutex;
239     static pthread_mutex_t mDomainsMutex;
240 };
241
242 /**
243  * worker to for connection
244  */
245 class asycConnectWorker: public Worker
246 {
247 public:
248     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);
249     void start2work();
250     void cancelWork();
251 private:
252     AsyncRoutingSender * mAsyncSender;
253     RoutingReceiverAsyncShadow *mShadow;
254     am_Handle_s mHandle;
255     am_connectionID_t mConnectionID;
256     am_sourceID_t mSourceID;
257     am_sinkID_t mSinkID;
258     am_ConnectionFormat_e mConnectionFormat;
259 };
260
261 /**
262  * worker for disconnecting
263  */
264 class asycDisConnectWorker: public Worker
265 {
266 public:
267     asycDisConnectWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_connectionID_t connectionID);
268     void start2work();
269     void cancelWork();
270 private:
271     AsyncRoutingSender * mAsyncSender;
272     RoutingReceiverAsyncShadow *mShadow;
273     am_Handle_s mHandle;
274     am_connectionID_t mConnectionID;
275     am_ConnectionFormat_e mConnectionFormat;
276 };
277
278 /**
279  * worker to for connection
280  */
281
282 #include <semaphore.h>
283 #include <sys/signalfd.h>
284 #include <signal.h>
285
286 class asyncSetSinkVolumeWorker: public Worker
287 {
288 public:
289     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);
290     void start2work();
291     void cancelWork();
292 private:
293     AsyncRoutingSender * mAsyncSender;
294     RoutingReceiverAsyncShadow *mShadow;
295     am_volume_t mCurrentVolume;
296     am_Handle_s mHandle;
297     am_sinkID_t mSinkID;
298     am_volume_t mVolume;
299     am_RampType_e mRamp;
300     am_time_t mTime;
301 };
302
303 class asyncSetSourceVolumeWorker: public Worker
304 {
305 public:
306     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);
307     void start2work();
308     void cancelWork();
309 private:
310     AsyncRoutingSender * mAsyncSender;
311     RoutingReceiverAsyncShadow *mShadow;
312     am_volume_t mCurrentVolume;
313     am_Handle_s mHandle;
314     am_sourceID_t mSourceID;
315     am_volume_t mVolume;
316     am_RampType_e mRamp;
317     am_time_t mTime;
318 };
319
320 class asyncSetSourceStateWorker: public Worker
321 {
322 public:
323     asyncSetSourceStateWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_sourceID_t sourceID, const am_SourceState_e state);
324     void start2work();
325     void cancelWork();
326 private:
327     AsyncRoutingSender * mAsyncSender;
328     RoutingReceiverAsyncShadow *mShadow;
329     am_Handle_s mHandle;
330     am_sourceID_t mSourceID;
331     am_SourceState_e mSourcestate;
332 };
333
334 class asyncSetSinkSoundPropertyWorker: public Worker
335 {
336 public:
337     asyncSetSinkSoundPropertyWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_SoundProperty_s soundProperty, const am_sinkID_t sinkID);
338     void start2work();
339     void cancelWork();
340 private:
341     AsyncRoutingSender * mAsyncSender;
342     RoutingReceiverAsyncShadow *mShadow;
343     am_Handle_s mHandle;
344     am_sinkID_t mSinkID;
345     am_SoundProperty_s mSoundProperty;
346 };
347
348 class asyncSetSourceSoundPropertyWorker: public Worker
349 {
350 public:
351     asyncSetSourceSoundPropertyWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_SoundProperty_s soundProperty, const am_sourceID_t sourceID);
352     void start2work();
353     void cancelWork();
354 private:
355     AsyncRoutingSender * mAsyncSender;
356     RoutingReceiverAsyncShadow *mShadow;
357     am_Handle_s mHandle;
358     am_sourceID_t mSourceID;
359     am_SoundProperty_s mSoundProperty;
360 };
361
362 class asyncDomainStateChangeWorker: public Worker
363 {
364 public:
365     asyncDomainStateChangeWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_domainID_t domainID, const am_DomainState_e domainState);
366     void start2work();
367     void cancelWork();
368 private:
369     AsyncRoutingSender * mAsyncSender;
370     RoutingReceiverAsyncShadow *mShadow;
371     am_domainID_t mDomainID;
372     am_DomainState_e mDomainState;
373 };
374
375 }
376
377 #endif /* ROUTINGSENDER_H_ */