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