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;
40 RoutingReceiverAsyncShadow::RoutingReceiverAsyncShadow():
41 asyncMsgReceive(this, &RoutingReceiverAsyncShadow::asyncMsgReceiver), //
42 asyncDispatch(this, &RoutingReceiverAsyncShadow::asyncDispatcher),//
43 asyncCheck(this, &RoutingReceiverAsyncShadow::asyncChecker), //
45 mRoutingReceiveInterface(),//
52 RoutingReceiverAsyncShadow::~RoutingReceiverAsyncShadow()
56 void RoutingReceiverAsyncShadow::ackConnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
59 //put the data in the queue:
62 temp.connectionID = connectionID;
64 //then we make a message out of it:
66 msg.msgID = MSG_ACKCONNECT;
67 msg.parameters.connect = temp;
68 //here we share data !
69 pthread_mutex_lock(&mMutex);
71 pthread_mutex_unlock(&mMutex);
73 //ok, fire the signal that data needs to be received !
74 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
76 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackConnect write failed, error code:"), DLT_STRING(strerror(errno)));
80 void RoutingReceiverAsyncShadow::ackDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
83 //put the data in the queue:
86 temp.connectionID = connectionID;
88 //then we make a message out of it:
90 msg.msgID = MSG_ACKDISCONNECT;
91 msg.parameters.connect = temp;
92 //here we share data !
93 pthread_mutex_lock(&mMutex);
95 pthread_mutex_unlock(&mMutex);
97 //ok, fire the signal that data needs to be received !
98 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
100 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackDisconnect write failed, error code:"), DLT_STRING(strerror(errno)));
104 void RoutingReceiverAsyncShadow::ackSetSinkVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
107 //put the data in the queue:
109 temp.handle = handle;
110 temp.volume = volume;
112 //then we make a message out of it:
114 msg.msgID = MSG_ACKSETSINKVOLUMECHANGE;
115 msg.parameters.volume = temp;
116 //here we share data !
117 pthread_mutex_lock(&mMutex);
119 pthread_mutex_unlock(&mMutex);
121 //ok, fire the signal that data needs to be received !
122 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
124 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSinkVolumeChange write failed, error code:"), DLT_STRING(strerror(errno)));
128 void RoutingReceiverAsyncShadow::ackSetSourceVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
131 //put the data in the queue:
133 temp.handle = handle;
134 temp.volume = volume;
136 //then we make a message out of it:
138 msg.msgID = MSG_ACKSETSOURCEVOLUMECHANGE;
139 msg.parameters.volume = temp;
140 //here we share data !
141 pthread_mutex_lock(&mMutex);
143 pthread_mutex_unlock(&mMutex);
145 //ok, fire the signal that data needs to be received !
146 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
148 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceVolumeChange write failed, error code:"), DLT_STRING(strerror(errno)));
152 void RoutingReceiverAsyncShadow::ackSetSourceState(const am_Handle_s handle, const am_Error_e error)
155 //put the data in the queue:
157 temp.handle = handle;
159 //then we make a message out of it:
161 msg.msgID = MSG_ACKSETSOURCESTATE;
162 msg.parameters.handle = temp;
163 //here we share data !
164 pthread_mutex_lock(&mMutex);
166 pthread_mutex_unlock(&mMutex);
168 //ok, fire the signal that data needs to be received !
169 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
171 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceState write failed, error code:"), DLT_STRING(strerror(errno)));
175 void RoutingReceiverAsyncShadow::ackSetSinkSoundProperty(const am_Handle_s handle, const am_Error_e error)
178 //put the data in the queue:
180 temp.handle = handle;
182 //then we make a message out of it:
184 msg.msgID = MSG_ACKSETSINKSOUNDPROPERTY;
185 msg.parameters.handle = temp;
186 //here we share data !
187 pthread_mutex_lock(&mMutex);
189 pthread_mutex_unlock(&mMutex);
191 //ok, fire the signal that data needs to be received !
192 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
194 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSinkSoundProperty write failed, error code:"), DLT_STRING(strerror(errno)));
198 void RoutingReceiverAsyncShadow::ackSetSourceSoundProperty(const am_Handle_s handle, const am_Error_e error)
201 //put the data in the queue:
203 temp.handle = handle;
205 //then we make a message out of it:
207 msg.msgID = MSG_ACKSETSOURCESOUNDPROPERTY;
208 msg.parameters.handle = temp;
209 //here we share data !
210 pthread_mutex_lock(&mMutex);
212 pthread_mutex_unlock(&mMutex);
214 //ok, fire the signal that data needs to be received !
215 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
217 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceSoundProperty write failed, error code:"), DLT_STRING(strerror(errno)));
221 void RoutingReceiverAsyncShadow::ackCrossFading(const am_Handle_s handle, const am_HotSink_e hotSink, const am_Error_e error)
224 //put the data in the queue:
225 a_crossfading_s temp;
226 temp.handle = handle;
227 temp.hotSink = hotSink;
229 //then we make a message out of it:
231 msg.msgID = MSG_ACKCROSSFADING;
232 msg.parameters.crossfading = temp;
233 //here we share data !
234 pthread_mutex_lock(&mMutex);
236 pthread_mutex_unlock(&mMutex);
238 //ok, fire the signal that data needs to be received !
239 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
241 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackCrossFading write failed, error code:"), DLT_STRING(strerror(errno)));
245 void RoutingReceiverAsyncShadow::ackSourceVolumeTick(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume)
248 //put the data in the queue:
249 a_sourceVolumeTick_s temp;
250 temp.sourceID = sourceID;
251 temp.handle = handle;
252 temp.volume = volume;
253 //then we make a message out of it:
255 msg.msgID = MSG_ACKSOURCEVOLUMETICK;
256 msg.parameters.sourceVolumeTick = temp;
257 //here we share data !
258 pthread_mutex_lock(&mMutex);
260 pthread_mutex_unlock(&mMutex);
262 //ok, fire the signal that data needs to be received !
263 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
265 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSourceVolumeTick write failed, error code:"), DLT_STRING(strerror(errno)));
269 void RoutingReceiverAsyncShadow::ackSinkVolumeTick(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume)
272 //put the data in the queue:
273 a_sinkVolumeTick_s temp;
274 temp.sinkID = sinkID;
275 temp.handle = handle;
276 temp.volume = volume;
277 //then we make a message out of it:
279 msg.msgID = MSG_ACKSINKVOLUMETICK;
280 msg.parameters.sinkVolumeTick = temp;
281 //here we share data !
282 pthread_mutex_lock(&mMutex);
284 pthread_mutex_unlock(&mMutex);
286 //ok, fire the signal that data needs to be received !
287 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
289 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSinkVolumeTick write failed, error code:"), DLT_STRING(strerror(errno)));
293 void RoutingReceiverAsyncShadow::hookInterruptStatusChange(const am_sourceID_t sourceID, const am_InterruptState_e interruptState)
296 //put the data in the queue:
297 a_interruptStatusChange_s temp;
298 temp.sourceID = sourceID;
299 temp.interruptState = interruptState;
301 //then we make a message out of it:
303 msg.msgID = MSG_HOOKINTERRUPTSTATUSCHANGE;
304 msg.parameters.interruptStatusChange = temp;
305 //here we share data !
306 pthread_mutex_lock(&mMutex);
308 pthread_mutex_unlock(&mMutex);
310 //ok, fire the signal that data needs to be received !
311 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
313 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookInterruptStatusChange write failed, error code:"), DLT_STRING(strerror(errno)));
317 void RoutingReceiverAsyncShadow::hookSinkAvailablityStatusChange(const am_sinkID_t sinkID, const am_Availability_s & availability)
320 //put the data in the queue:
321 a_sinkAvailability_s temp;
322 temp.sinkID = sinkID;
323 temp.availability = availability;
325 //then we make a message out of it:
327 msg.msgID = MSG_HOOKSINKAVAILABLITYSTATUSCHANGE;
328 msg.parameters.sinkAvailability = temp;
329 //here we share data !
330 pthread_mutex_lock(&mMutex);
332 pthread_mutex_unlock(&mMutex);
334 //ok, fire the signal that data needs to be received !
335 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
337 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookSinkAvailablityStatusChange write failed, error code:"), DLT_STRING(strerror(errno)));
341 void RoutingReceiverAsyncShadow::hookSourceAvailablityStatusChange(const am_sourceID_t sourceID, const am_Availability_s & availability)
344 //put the data in the queue:
345 a_sourceAvailability_s temp;
346 temp.sourceID = sourceID;
347 temp.availability = availability;
349 //then we make a message out of it:
351 msg.msgID = MSG_HOOKSOURCEAVAILABLITYSTATUSCHANGE;
352 msg.parameters.sourceAvailability = temp;
353 //here we share data !
354 pthread_mutex_lock(&mMutex);
356 pthread_mutex_unlock(&mMutex);
358 //ok, fire the signal that data needs to be received !
359 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
361 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookSourceAvailablityStatusChange write failed, error code:"), DLT_STRING(strerror(errno)));
365 void RoutingReceiverAsyncShadow::hookDomainStateChange(const am_domainID_t domainID, const am_DomainState_e domainState)
368 //put the data in the queue:
369 a_hookDomainStateChange_s temp;
370 temp.domainID = domainID;
371 temp.state = domainState;
373 //then we make a message out of it:
375 msg.msgID = MSG_HOOKDOMAINSTATECHANGE;
376 msg.parameters.domainStateChange = temp;
377 //here we share data !
378 pthread_mutex_lock(&mMutex);
380 pthread_mutex_unlock(&mMutex);
382 //ok, fire the signal that data needs to be received !
383 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
385 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookDomainStateChange write failed, error code:"), DLT_STRING(strerror(errno)));
389 void RoutingReceiverAsyncShadow::hookTimingInformationChanged(const am_connectionID_t connectionID, const am_timeSync_t delay)
392 //put the data in the queue:
393 a_timingInfoChanged_s temp;
394 temp.connectionID = connectionID;
397 //then we make a message out of it:
399 msg.msgID = MSG_HOOKTIMINGINFORMATIONCHANGED;
400 msg.parameters.timingInfoChange = temp;
401 //here we share data !
402 pthread_mutex_lock(&mMutex);
404 pthread_mutex_unlock(&mMutex);
406 //ok, fire the signal that data needs to be received !
407 if (write(mPipe[1], &msg.msgID, sizeof(msgID_e)) == -1)
409 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookTimingInformationChanged write failed, error code:"), DLT_STRING(strerror(errno)));
413 void RoutingReceiverAsyncShadow::asyncMsgReceiver(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
417 //it is no really important what to read here, we will read the queue later...
419 if (read(pollfd.fd, buffer, 10) == -1)
421 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::asyncMsgReceiver could not read!"));
425 bool RoutingReceiverAsyncShadow::asyncDispatcher(const sh_pollHandle_t handle, void *userData)
431 //ok, let's receive, first lock
432 pthread_mutex_lock(&mMutex);
433 msg = mQueue.front();
435 pthread_mutex_unlock(&mMutex);
437 //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);
514 if (pipe(mPipe) == -1)
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);