* formatting all the source code with eclipse source code style
[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     void startupRoutingInterface(RoutingReceiveInterface* routingreceiveinterface);
133     void routingInterfacesReady();
134     void routingInterfacesRundown();
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 asyncSetSinkSoundProperty(const am_Handle_s handle, const am_SoundProperty_s& soundProperty, const am_sinkID_t sinkID);
142     am_Error_e asyncSetSinkSoundProperties(const am_Handle_s handle, const std::vector<am_SoundProperty_s>& listSoundProperties, const am_sinkID_t sinkID);
143     am_Error_e asyncSetSourceSoundProperty(const am_Handle_s handle, const am_SoundProperty_s& soundProperty, const am_sourceID_t sourceID);
144     am_Error_e asyncSetSourceSoundProperties(const am_Handle_s handle, const std::vector<am_SoundProperty_s>& listSoundProperties, const am_sourceID_t sourceID);
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     uint16_t getInterfaceVersion() 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      * @param data
215      */
216     static void* InterruptEvents(void* data);
217     std::vector<am_Domain_s> createDomainTable();
218     std::vector<am_Sink_s> createSinkTable();
219     std::vector<am_Source_s> createSourceTable();
220     std::vector<am_Gateway_s> createGatewayTable();
221     RoutingReceiverAsyncShadow mShadow;
222     RoutingReceiveInterface* mReceiveInterface;
223     SocketHandler *mSocketHandler;
224     std::vector<am_Domain_s> mDomains;
225     std::vector<am_Sink_s> mSinks;
226     std::vector<am_Source_s> mSources;
227     std::vector<am_Gateway_s> mGateways;
228     std::map<uint16_t, int16_t> mMapHandleWorker;
229     std::map<am_connectionID_t, am_RoutingElement_s> mMapConnectionIDRoute;
230     WorkerThreadPool mPool;
231     pthread_t mInterruptThread;
232     static pthread_mutex_t mMapConnectionMutex;
233     static pthread_mutex_t mMapHandleWorkerMutex;
234     static pthread_mutex_t mSinksMutex;
235     static pthread_mutex_t mSourcesMutex;
236     static pthread_mutex_t mDomainsMutex;
237 };
238
239 /**
240  * worker to for connection
241  */
242 class asycConnectWorker: public Worker
243 {
244 public:
245     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);
246     void start2work();
247     void cancelWork();
248 private:
249     AsyncRoutingSender * mAsyncSender;
250     RoutingReceiverAsyncShadow *mShadow;
251     am_Handle_s mHandle;
252     am_connectionID_t mConnectionID;
253     am_sourceID_t mSourceID;
254     am_sinkID_t mSinkID;
255     am_ConnectionFormat_e mConnectionFormat;
256 };
257
258 /**
259  * worker for disconnecting
260  */
261 class asycDisConnectWorker: public Worker
262 {
263 public:
264     asycDisConnectWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_connectionID_t connectionID);
265     void start2work();
266     void cancelWork();
267 private:
268     AsyncRoutingSender * mAsyncSender;
269     RoutingReceiverAsyncShadow *mShadow;
270     am_Handle_s mHandle;
271     am_connectionID_t mConnectionID;
272     am_ConnectionFormat_e mConnectionFormat;
273 };
274
275 /**
276  * worker to for connection
277  */
278
279 #include <semaphore.h>
280 #include <sys/signalfd.h>
281 #include <signal.h>
282
283 class asyncSetSinkVolumeWorker: public Worker
284 {
285 public:
286     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);
287     void start2work();
288     void cancelWork();
289 private:
290     AsyncRoutingSender * mAsyncSender;
291     RoutingReceiverAsyncShadow *mShadow;
292     am_volume_t mCurrentVolume;
293     am_Handle_s mHandle;
294     am_sinkID_t mSinkID;
295     am_volume_t mVolume;
296     am_RampType_e mRamp;
297     am_time_t mTime;
298 };
299
300 class asyncSetSourceVolumeWorker: public Worker
301 {
302 public:
303     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);
304     void start2work();
305     void cancelWork();
306 private:
307     AsyncRoutingSender * mAsyncSender;
308     RoutingReceiverAsyncShadow *mShadow;
309     am_volume_t mCurrentVolume;
310     am_Handle_s mHandle;
311     am_sourceID_t mSourceID;
312     am_volume_t mVolume;
313     am_RampType_e mRamp;
314     am_time_t mTime;
315 };
316
317 class asyncSetSourceStateWorker: public Worker
318 {
319 public:
320     asyncSetSourceStateWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_sourceID_t sourceID, const am_SourceState_e state);
321     void start2work();
322     void cancelWork();
323 private:
324     AsyncRoutingSender * mAsyncSender;
325     RoutingReceiverAsyncShadow *mShadow;
326     am_Handle_s mHandle;
327     am_sourceID_t mSourceID;
328     am_SourceState_e mSourcestate;
329 };
330
331 class asyncSetSinkSoundPropertyWorker: public Worker
332 {
333 public:
334     asyncSetSinkSoundPropertyWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_SoundProperty_s soundProperty, const am_sinkID_t sinkID);
335     void start2work();
336     void cancelWork();
337 private:
338     AsyncRoutingSender * mAsyncSender;
339     RoutingReceiverAsyncShadow *mShadow;
340     am_Handle_s mHandle;
341     am_sinkID_t mSinkID;
342     am_SoundProperty_s mSoundProperty;
343 };
344
345 class asyncSetSourceSoundPropertyWorker: public Worker
346 {
347 public:
348     asyncSetSourceSoundPropertyWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_Handle_s handle, const am_SoundProperty_s soundProperty, const am_sourceID_t sourceID);
349     void start2work();
350     void cancelWork();
351 private:
352     AsyncRoutingSender * mAsyncSender;
353     RoutingReceiverAsyncShadow *mShadow;
354     am_Handle_s mHandle;
355     am_sourceID_t mSourceID;
356     am_SoundProperty_s mSoundProperty;
357 };
358
359 class asyncDomainStateChangeWorker: public Worker
360 {
361 public:
362     asyncDomainStateChangeWorker(AsyncRoutingSender * asyncSender, WorkerThreadPool* pool, RoutingReceiverAsyncShadow* shadow, const am_domainID_t domainID, const am_DomainState_e domainState);
363     void start2work();
364     void cancelWork();
365 private:
366     AsyncRoutingSender * mAsyncSender;
367     RoutingReceiverAsyncShadow *mShadow;
368     am_domainID_t mDomainID;
369     am_DomainState_e mDomainState;
370 };
371
372 }
373
374 #endif /* ROUTINGSENDER_H_ */