2 * Copyright (C) 2011, BMW AG
4 * GeniviAudioMananger AudioManagerDaemon
6 * \file RoutingReceiverAsyncShadow.cpp
8 * \date 20-Oct-2011 3:42:04 PM
9 * \author Christian Mueller (christian.ei.mueller@bmw.de)
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
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.
25 #include "RoutingReceiverAsyncShadow.h"
26 #include "DltContext.h"
28 #include <sys/socket.h>
29 #include <sys/ioctl.h>
38 pthread_mutex_t RoutingReceiverAsyncShadow::mMutex = PTHREAD_MUTEX_INITIALIZER;
41 RoutingReceiverAsyncShadow::RoutingReceiverAsyncShadow()
42 :asyncMsgReceive(this, &RoutingReceiverAsyncShadow::asyncMsgReceiver),
43 asyncDispatch(this, &RoutingReceiverAsyncShadow::asyncDispatcher),
44 asyncCheck(this, &RoutingReceiverAsyncShadow::asyncChecker),
46 mRoutingReceiveInterface(),
53 RoutingReceiverAsyncShadow::~RoutingReceiverAsyncShadow()
57 void RoutingReceiverAsyncShadow::ackConnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
60 //put the data in the queue:
63 temp.connectionID = connectionID;
65 //then we make a message out of it:
67 msg.msgID = MSG_ACKCONNECT;
68 msg.parameters.connect = temp;
69 //here we share data !
70 pthread_mutex_lock(&mMutex);
72 pthread_mutex_unlock(&mMutex);
74 //ok, fire the signal that data needs to be received !
75 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
77 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackConnect write failed, error code:"),DLT_STRING(strerror(errno)));
81 void RoutingReceiverAsyncShadow::ackDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
84 //put the data in the queue:
87 temp.connectionID = connectionID;
89 //then we make a message out of it:
91 msg.msgID = MSG_ACKDISCONNECT;
92 msg.parameters.connect = temp;
93 //here we share data !
94 pthread_mutex_lock(&mMutex);
96 pthread_mutex_unlock(&mMutex);
98 //ok, fire the signal that data needs to be received !
99 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
101 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackDisconnect write failed, error code:"),DLT_STRING(strerror(errno)));
105 void RoutingReceiverAsyncShadow::ackSetSinkVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
108 //put the data in the queue:
110 temp.handle = handle;
111 temp.volume = volume;
113 //then we make a message out of it:
115 msg.msgID = MSG_ACKSETSINKVOLUMECHANGE;
116 msg.parameters.volume = temp;
117 //here we share data !
118 pthread_mutex_lock(&mMutex);
120 pthread_mutex_unlock(&mMutex);
122 //ok, fire the signal that data needs to be received !
123 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
125 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSinkVolumeChange write failed, error code:"),DLT_STRING(strerror(errno)));
129 void RoutingReceiverAsyncShadow::ackSetSourceVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
132 //put the data in the queue:
134 temp.handle = handle;
135 temp.volume = volume;
137 //then we make a message out of it:
139 msg.msgID = MSG_ACKSETSOURCEVOLUMECHANGE;
140 msg.parameters.volume = temp;
141 //here we share data !
142 pthread_mutex_lock(&mMutex);
144 pthread_mutex_unlock(&mMutex);
146 //ok, fire the signal that data needs to be received !
147 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
149 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceVolumeChange write failed, error code:"),DLT_STRING(strerror(errno)));
153 void RoutingReceiverAsyncShadow::ackSetSourceState(const am_Handle_s handle, const am_Error_e error)
156 //put the data in the queue:
158 temp.handle = handle;
160 //then we make a message out of it:
162 msg.msgID = MSG_ACKSETSOURCESTATE;
163 msg.parameters.handle = temp;
164 //here we share data !
165 pthread_mutex_lock(&mMutex);
167 pthread_mutex_unlock(&mMutex);
169 //ok, fire the signal that data needs to be received !
170 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
172 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceState write failed, error code:"),DLT_STRING(strerror(errno)));
176 void RoutingReceiverAsyncShadow::ackSetSinkSoundProperty(const am_Handle_s handle, const am_Error_e error)
179 //put the data in the queue:
181 temp.handle = handle;
183 //then we make a message out of it:
185 msg.msgID = MSG_ACKSETSINKSOUNDPROPERTY;
186 msg.parameters.handle = temp;
187 //here we share data !
188 pthread_mutex_lock(&mMutex);
190 pthread_mutex_unlock(&mMutex);
192 //ok, fire the signal that data needs to be received !
193 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
195 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSinkSoundProperty write failed, error code:"),DLT_STRING(strerror(errno)));
199 void RoutingReceiverAsyncShadow::ackSetSourceSoundProperty(const am_Handle_s handle, const am_Error_e error)
202 //put the data in the queue:
204 temp.handle = handle;
206 //then we make a message out of it:
208 msg.msgID = MSG_ACKSETSOURCESOUNDPROPERTY;
209 msg.parameters.handle = temp;
210 //here we share data !
211 pthread_mutex_lock(&mMutex);
213 pthread_mutex_unlock(&mMutex);
215 //ok, fire the signal that data needs to be received !
216 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
218 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceSoundProperty write failed, error code:"),DLT_STRING(strerror(errno)));
222 void RoutingReceiverAsyncShadow::ackCrossFading(const am_Handle_s handle, const am_HotSink_e hotSink, const am_Error_e error)
225 //put the data in the queue:
226 a_crossfading_s temp;
227 temp.handle = handle;
228 temp.hotSink=hotSink;
230 //then we make a message out of it:
232 msg.msgID = MSG_ACKCROSSFADING;
233 msg.parameters.crossfading = temp;
234 //here we share data !
235 pthread_mutex_lock(&mMutex);
237 pthread_mutex_unlock(&mMutex);
239 //ok, fire the signal that data needs to be received !
240 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
242 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackCrossFading write failed, error code:"),DLT_STRING(strerror(errno)));
246 void RoutingReceiverAsyncShadow::ackSourceVolumeTick(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume)
249 //put the data in the queue:
250 a_sourceVolumeTick_s temp;
251 temp.sourceID=sourceID;
252 temp.handle = handle;
253 temp.volume = volume;
254 //then we make a message out of it:
256 msg.msgID = MSG_ACKSOURCEVOLUMETICK;
257 msg.parameters.sourceVolumeTick = temp;
258 //here we share data !
259 pthread_mutex_lock(&mMutex);
261 pthread_mutex_unlock(&mMutex);
263 //ok, fire the signal that data needs to be received !
264 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
266 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSourceVolumeTick write failed, error code:"),DLT_STRING(strerror(errno)));
270 void RoutingReceiverAsyncShadow::ackSinkVolumeTick(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume)
273 //put the data in the queue:
274 a_sinkVolumeTick_s temp;
276 temp.handle = handle;
277 temp.volume = volume;
278 //then we make a message out of it:
280 msg.msgID = MSG_ACKSINKVOLUMETICK;
281 msg.parameters.sinkVolumeTick = temp;
282 //here we share data !
283 pthread_mutex_lock(&mMutex);
285 pthread_mutex_unlock(&mMutex);
287 //ok, fire the signal that data needs to be received !
288 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
290 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSinkVolumeTick write failed, error code:"),DLT_STRING(strerror(errno)));
294 void RoutingReceiverAsyncShadow::hookInterruptStatusChange(const am_sourceID_t sourceID, const am_InterruptState_e interruptState)
297 //put the data in the queue:
298 a_interruptStatusChange_s temp;
299 temp.sourceID=sourceID;
300 temp.interruptState = interruptState;
302 //then we make a message out of it:
304 msg.msgID = MSG_HOOKINTERRUPTSTATUSCHANGE;
305 msg.parameters.interruptStatusChange = temp;
306 //here we share data !
307 pthread_mutex_lock(&mMutex);
309 pthread_mutex_unlock(&mMutex);
311 //ok, fire the signal that data needs to be received !
312 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
314 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookInterruptStatusChange write failed, error code:"),DLT_STRING(strerror(errno)));
318 void RoutingReceiverAsyncShadow::hookSinkAvailablityStatusChange(const am_sinkID_t sinkID, const am_Availability_s & availability)
321 //put the data in the queue:
322 a_sinkAvailability_s temp;
324 temp.availability = availability;
326 //then we make a message out of it:
328 msg.msgID = MSG_HOOKSINKAVAILABLITYSTATUSCHANGE;
329 msg.parameters.sinkAvailability = temp;
330 //here we share data !
331 pthread_mutex_lock(&mMutex);
333 pthread_mutex_unlock(&mMutex);
335 //ok, fire the signal that data needs to be received !
336 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
338 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookSinkAvailablityStatusChange write failed, error code:"),DLT_STRING(strerror(errno)));
342 void RoutingReceiverAsyncShadow::hookSourceAvailablityStatusChange(const am_sourceID_t sourceID, const am_Availability_s & availability)
345 //put the data in the queue:
346 a_sourceAvailability_s temp;
347 temp.sourceID=sourceID;
348 temp.availability = availability;
350 //then we make a message out of it:
352 msg.msgID = MSG_HOOKSOURCEAVAILABLITYSTATUSCHANGE;
353 msg.parameters.sourceAvailability = temp;
354 //here we share data !
355 pthread_mutex_lock(&mMutex);
357 pthread_mutex_unlock(&mMutex);
359 //ok, fire the signal that data needs to be received !
360 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
362 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookSourceAvailablityStatusChange write failed, error code:"),DLT_STRING(strerror(errno)));
366 void RoutingReceiverAsyncShadow::hookDomainStateChange(const am_domainID_t domainID, const am_DomainState_e domainState)
369 //put the data in the queue:
370 a_hookDomainStateChange_s temp;
371 temp.domainID=domainID;
372 temp.state = domainState;
374 //then we make a message out of it:
376 msg.msgID = MSG_HOOKDOMAINSTATECHANGE;
377 msg.parameters.domainStateChange = temp;
378 //here we share data !
379 pthread_mutex_lock(&mMutex);
381 pthread_mutex_unlock(&mMutex);
383 //ok, fire the signal that data needs to be received !
384 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
386 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookDomainStateChange write failed, error code:"),DLT_STRING(strerror(errno)));
390 void RoutingReceiverAsyncShadow::hookTimingInformationChanged(const am_connectionID_t connectionID, const am_timeSync_t delay)
393 //put the data in the queue:
394 a_timingInfoChanged_s temp;
395 temp.connectionID=connectionID;
398 //then we make a message out of it:
400 msg.msgID = MSG_HOOKTIMINGINFORMATIONCHANGED;
401 msg.parameters.timingInfoChange = temp;
402 //here we share data !
403 pthread_mutex_lock(&mMutex);
405 pthread_mutex_unlock(&mMutex);
407 //ok, fire the signal that data needs to be received !
408 if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
410 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookTimingInformationChanged write failed, error code:"),DLT_STRING(strerror(errno)));
414 void RoutingReceiverAsyncShadow::asyncMsgReceiver(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
418 //it is no really important what to read here, we will read the queue later...
420 if(read(pollfd.fd, buffer, 10)==-1)
422 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::asyncMsgReceiver could not read!"));
426 bool RoutingReceiverAsyncShadow::asyncDispatcher(const sh_pollHandle_t handle, void *userData)
432 //ok, let's receive, first lock
433 pthread_mutex_lock(&mMutex);
434 msg = mQueue.front();
436 pthread_mutex_unlock(&mMutex);
438 //check for the message:
441 mRoutingReceiveInterface->ackConnect(msg.parameters.connect.handle, msg.parameters.connect.connectionID, msg.parameters.connect.error);
443 case MSG_ACKDISCONNECT:
444 mRoutingReceiveInterface->ackDisconnect(msg.parameters.connect.handle, msg.parameters.connect.connectionID, msg.parameters.connect.error);
446 case MSG_ACKSETSINKVOLUMECHANGE:
447 mRoutingReceiveInterface->ackSetSinkVolumeChange(msg.parameters.volume.handle, msg.parameters.volume.volume,msg.parameters.volume.error);
449 case MSG_ACKSETSOURCEVOLUMECHANGE:
450 mRoutingReceiveInterface->ackSetSourceVolumeChange(msg.parameters.volume.handle,msg.parameters.volume.volume,msg.parameters.volume.error);
452 case MSG_ACKSETSOURCESTATE:
453 mRoutingReceiveInterface->ackSetSourceState(msg.parameters.handle.handle,msg.parameters.handle.error);
455 case MSG_ACKSETSINKSOUNDPROPERTY:
456 mRoutingReceiveInterface->ackSetSinkSoundProperty(msg.parameters.handle.handle,msg.parameters.handle.error);
458 case MSG_ACKSETSOURCESOUNDPROPERTY:
459 mRoutingReceiveInterface->ackSetSourceSoundProperty(msg.parameters.handle.handle,msg.parameters.handle.error);
461 case MSG_ACKCROSSFADING:
462 mRoutingReceiveInterface->ackCrossFading(msg.parameters.crossfading.handle,msg.parameters.crossfading.hotSink,msg.parameters.crossfading.error);
464 case MSG_ACKSOURCEVOLUMETICK:
465 mRoutingReceiveInterface->ackSourceVolumeTick(msg.parameters.sourceVolumeTick.handle,msg.parameters.sourceVolumeTick.sourceID,msg.parameters.sourceVolumeTick.volume);
467 case MSG_ACKSINKVOLUMETICK:
468 mRoutingReceiveInterface->ackSinkVolumeTick(msg.parameters.sinkVolumeTick.handle,msg.parameters.sinkVolumeTick.sinkID,msg.parameters.sinkVolumeTick.volume);
470 case MSG_HOOKINTERRUPTSTATUSCHANGE:
471 mRoutingReceiveInterface->hookInterruptStatusChange(msg.parameters.interruptStatusChange.sourceID,msg.parameters.interruptStatusChange.interruptState);
473 case MSG_HOOKSINKAVAILABLITYSTATUSCHANGE:
474 mRoutingReceiveInterface->hookSinkAvailablityStatusChange(msg.parameters.sinkAvailability.sinkID,msg.parameters.sinkAvailability.availability);
476 case MSG_HOOKSOURCEAVAILABLITYSTATUSCHANGE:
477 mRoutingReceiveInterface->hookSourceAvailablityStatusChange(msg.parameters.sourceAvailability.sourceID,msg.parameters.sourceAvailability.availability);
479 case MSG_HOOKDOMAINSTATECHANGE:
480 mRoutingReceiveInterface->hookDomainStateChange(msg.parameters.domainStateChange.domainID,msg.parameters.domainStateChange.state);
482 case MSG_HOOKTIMINGINFORMATIONCHANGED:
483 mRoutingReceiveInterface->hookTimingInformationChanged(msg.parameters.timingInfoChange.connectionID,msg.parameters.timingInfoChange.delay);
486 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::asyncDispatcher unknown message was received:"),DLT_INT(msg.msgID));
491 pthread_mutex_lock(&mMutex);
492 if(mQueue.size() > 0) retVal=true;
493 pthread_mutex_unlock(&mMutex);
498 bool RoutingReceiverAsyncShadow::asyncChecker(const sh_pollHandle_t handle, void *userData)
502 bool returnVal=false;
503 pthread_mutex_lock(&mMutex);
504 if(mQueue.size() > 0) returnVal=true;
505 pthread_mutex_unlock(&mMutex);
509 am_Error_e RoutingReceiverAsyncShadow::setRoutingInterface(RoutingReceiveInterface *receiveInterface)
511 assert(receiveInterface!=0);
512 mRoutingReceiveInterface=receiveInterface;
513 mRoutingReceiveInterface->getSocketHandler(mSocketHandler);
516 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::setRoutingInterface could not create pipe!:"));
522 mSocketHandler->addFDPoll(mPipe[0],event,NULL,&asyncMsgReceive,&asyncCheck,&asyncDispatch,NULL,mHandle);