* assert on empty busname (routinginterface)
[profile/ivi/audiomanager.git] / PluginRoutingInterfaceAsync / src / RoutingReceiverAsyncShadow.cpp
1 /*
2  * RoutingReceiverAsyncShadow.cpp
3  *
4  *  Created on: Dec 23, 2011
5  *      Author: christian
6  */
7
8 #include "RoutingReceiverAsyncShadow.h"
9 #include "DltContext.h"
10 #include <assert.h>
11 #include <sys/socket.h>
12 #include <sys/ioctl.h>
13 #include <string.h>
14 #include <netdb.h>
15 #include <fcntl.h>
16 #include <sys/un.h>
17 #include <errno.h>
18
19 using namespace am;
20
21 pthread_mutex_t RoutingReceiverAsyncShadow::mMutex = PTHREAD_MUTEX_INITIALIZER;
22
23
24 RoutingReceiverAsyncShadow::RoutingReceiverAsyncShadow()
25         :asyncMsgReceive(this, &RoutingReceiverAsyncShadow::asyncMsgReceiver),
26          asyncDispatch(this, &RoutingReceiverAsyncShadow::asyncDispatcher),
27          asyncCheck(this, &RoutingReceiverAsyncShadow::asyncChecker),
28          mSocketHandler(),
29          mRoutingReceiveInterface(),
30          mHandle(),
31          mPipe()
32 {
33
34 }
35
36 RoutingReceiverAsyncShadow::~RoutingReceiverAsyncShadow()
37 {
38 }
39
40 void RoutingReceiverAsyncShadow::ackConnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
41 {
42         assert(mPipe[0]!=0);
43         //put the data in the queue:
44         a_connect_s temp;
45         temp.handle = handle;
46         temp.connectionID = connectionID;
47         temp.error = error;
48         //then we make a message out of it:
49         msg_s msg;
50         msg.msgID = MSG_ACKCONNECT;
51         msg.parameters.connect = temp;
52         //here we share data !
53         pthread_mutex_lock(&mMutex);
54         mQueue.push(msg);
55         pthread_mutex_unlock(&mMutex);
56
57         //ok, fire the signal that data needs to be received !
58         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
59         {
60                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackConnect write failed, error code:"),DLT_STRING(strerror(errno)));
61         }
62 }
63
64 void RoutingReceiverAsyncShadow::ackDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_Error_e error)
65 {
66         assert(mPipe[0]!=0);
67         //put the data in the queue:
68         a_connect_s temp;
69         temp.handle = handle;
70         temp.connectionID = connectionID;
71         temp.error = error;
72         //then we make a message out of it:
73         msg_s msg;
74         msg.msgID = MSG_ACKDISCONNECT;
75         msg.parameters.connect = temp;
76         //here we share data !
77         pthread_mutex_lock(&mMutex);
78         mQueue.push(msg);
79         pthread_mutex_unlock(&mMutex);
80
81         //ok, fire the signal that data needs to be received !
82         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
83         {
84                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackDisconnect write failed, error code:"),DLT_STRING(strerror(errno)));
85         }
86 }
87
88 void RoutingReceiverAsyncShadow::ackSetSinkVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
89 {
90         assert(mPipe[0]!=0);
91         //put the data in the queue:
92         a_volume_s temp;
93         temp.handle = handle;
94         temp.volume = volume;
95         temp.error = error;
96         //then we make a message out of it:
97         msg_s msg;
98         msg.msgID = MSG_ACKSETSINKVOLUMECHANGE;
99         msg.parameters.volume = temp;
100         //here we share data !
101         pthread_mutex_lock(&mMutex);
102         mQueue.push(msg);
103         pthread_mutex_unlock(&mMutex);
104
105         //ok, fire the signal that data needs to be received !
106         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
107         {
108                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSinkVolumeChange write failed, error code:"),DLT_STRING(strerror(errno)));
109         }
110 }
111
112 void RoutingReceiverAsyncShadow::ackSetSourceVolumeChange(const am_Handle_s handle, const am_volume_t volume, const am_Error_e error)
113 {
114         assert(mPipe[0]!=0);
115         //put the data in the queue:
116         a_volume_s temp;
117         temp.handle = handle;
118         temp.volume = volume;
119         temp.error = error;
120         //then we make a message out of it:
121         msg_s msg;
122         msg.msgID = MSG_ACKSETSOURCEVOLUMECHANGE;
123         msg.parameters.volume = temp;
124         //here we share data !
125         pthread_mutex_lock(&mMutex);
126         mQueue.push(msg);
127         pthread_mutex_unlock(&mMutex);
128
129         //ok, fire the signal that data needs to be received !
130         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
131         {
132                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceVolumeChange write failed, error code:"),DLT_STRING(strerror(errno)));
133         }
134 }
135
136 void RoutingReceiverAsyncShadow::ackSetSourceState(const am_Handle_s handle, const am_Error_e error)
137 {
138         assert(mPipe[0]!=0);
139         //put the data in the queue:
140         a_handle_s temp;
141         temp.handle = handle;
142         temp.error = error;
143         //then we make a message out of it:
144         msg_s msg;
145         msg.msgID = MSG_ACKSETSOURCESTATE;
146         msg.parameters.handle = temp;
147         //here we share data !
148         pthread_mutex_lock(&mMutex);
149         mQueue.push(msg);
150         pthread_mutex_unlock(&mMutex);
151
152         //ok, fire the signal that data needs to be received !
153         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
154         {
155                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceState write failed, error code:"),DLT_STRING(strerror(errno)));
156         }
157 }
158
159 void RoutingReceiverAsyncShadow::ackSetSinkSoundProperty(const am_Handle_s handle, const am_Error_e error)
160 {
161         assert(mPipe[0]!=0);
162         //put the data in the queue:
163         a_handle_s temp;
164         temp.handle = handle;
165         temp.error = error;
166         //then we make a message out of it:
167         msg_s msg;
168         msg.msgID = MSG_ACKSETSINKSOUNDPROPERTY;
169         msg.parameters.handle = temp;
170         //here we share data !
171         pthread_mutex_lock(&mMutex);
172         mQueue.push(msg);
173         pthread_mutex_unlock(&mMutex);
174
175         //ok, fire the signal that data needs to be received !
176         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
177         {
178                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSinkSoundProperty write failed, error code:"),DLT_STRING(strerror(errno)));
179         }
180 }
181
182 void RoutingReceiverAsyncShadow::ackSetSourceSoundProperty(const am_Handle_s handle, const am_Error_e error)
183 {
184         assert(mPipe[0]!=0);
185         //put the data in the queue:
186         a_handle_s temp;
187         temp.handle = handle;
188         temp.error = error;
189         //then we make a message out of it:
190         msg_s msg;
191         msg.msgID = MSG_ACKSETSOURCESOUNDPROPERTY;
192         msg.parameters.handle = temp;
193         //here we share data !
194         pthread_mutex_lock(&mMutex);
195         mQueue.push(msg);
196         pthread_mutex_unlock(&mMutex);
197
198         //ok, fire the signal that data needs to be received !
199         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
200         {
201                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSetSourceSoundProperty write failed, error code:"),DLT_STRING(strerror(errno)));
202         }
203 }
204
205 void RoutingReceiverAsyncShadow::ackCrossFading(const am_Handle_s handle, const am_HotSink_e hotSink, const am_Error_e error)
206 {
207         assert(mPipe[0]!=0);
208         //put the data in the queue:
209         a_crossfading_s temp;
210         temp.handle = handle;
211         temp.hotSink=hotSink;
212         temp.error = error;
213         //then we make a message out of it:
214         msg_s msg;
215         msg.msgID = MSG_ACKCROSSFADING;
216         msg.parameters.crossfading = temp;
217         //here we share data !
218         pthread_mutex_lock(&mMutex);
219         mQueue.push(msg);
220         pthread_mutex_unlock(&mMutex);
221
222         //ok, fire the signal that data needs to be received !
223         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
224         {
225                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackCrossFading write failed, error code:"),DLT_STRING(strerror(errno)));
226         }
227 }
228
229 void RoutingReceiverAsyncShadow::ackSourceVolumeTick(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume)
230 {
231         assert(mPipe[0]!=0);
232         //put the data in the queue:
233         a_sourceVolumeTick_s temp;
234         temp.sourceID=sourceID;
235         temp.handle = handle;
236         temp.volume = volume;
237         //then we make a message out of it:
238         msg_s msg;
239         msg.msgID = MSG_ACKSOURCEVOLUMETICK;
240         msg.parameters.sourceVolumeTick = temp;
241         //here we share data !
242         pthread_mutex_lock(&mMutex);
243         mQueue.push(msg);
244         pthread_mutex_unlock(&mMutex);
245
246         //ok, fire the signal that data needs to be received !
247         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
248         {
249                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSourceVolumeTick write failed, error code:"),DLT_STRING(strerror(errno)));
250         }
251 }
252
253 void RoutingReceiverAsyncShadow::ackSinkVolumeTick(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume)
254 {
255         assert(mPipe[0]!=0);
256         //put the data in the queue:
257         a_sinkVolumeTick_s temp;
258         temp.sinkID=sinkID;
259         temp.handle = handle;
260         temp.volume = volume;
261         //then we make a message out of it:
262         msg_s msg;
263         msg.msgID = MSG_ACKSINKVOLUMETICK;
264         msg.parameters.sinkVolumeTick = temp;
265         //here we share data !
266         pthread_mutex_lock(&mMutex);
267         mQueue.push(msg);
268         pthread_mutex_unlock(&mMutex);
269
270         //ok, fire the signal that data needs to be received !
271         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
272         {
273                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::ackSinkVolumeTick write failed, error code:"),DLT_STRING(strerror(errno)));
274         }
275 }
276
277 void RoutingReceiverAsyncShadow::hookInterruptStatusChange(const am_sourceID_t sourceID, const am_InterruptState_e interruptState)
278 {
279         assert(mPipe[0]!=0);
280         //put the data in the queue:
281         a_interruptStatusChange_s temp;
282         temp.sourceID=sourceID;
283         temp.interruptState = interruptState;
284
285         //then we make a message out of it:
286         msg_s msg;
287         msg.msgID = MSG_HOOKINTERRUPTSTATUSCHANGE;
288         msg.parameters.interruptStatusChange = temp;
289         //here we share data !
290         pthread_mutex_lock(&mMutex);
291         mQueue.push(msg);
292         pthread_mutex_unlock(&mMutex);
293
294         //ok, fire the signal that data needs to be received !
295         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
296         {
297                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookInterruptStatusChange write failed, error code:"),DLT_STRING(strerror(errno)));
298         }
299 }
300
301 void RoutingReceiverAsyncShadow::hookSinkAvailablityStatusChange(const am_sinkID_t sinkID, const am_Availability_s & availability)
302 {
303         assert(mPipe[0]!=0);
304         //put the data in the queue:
305         a_sinkAvailability_s temp;
306         temp.sinkID=sinkID;
307         temp.availability = availability;
308
309         //then we make a message out of it:
310         msg_s msg;
311         msg.msgID = MSG_HOOKSINKAVAILABLITYSTATUSCHANGE;
312         msg.parameters.sinkAvailability = temp;
313         //here we share data !
314         pthread_mutex_lock(&mMutex);
315         mQueue.push(msg);
316         pthread_mutex_unlock(&mMutex);
317
318         //ok, fire the signal that data needs to be received !
319         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
320         {
321                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookSinkAvailablityStatusChange write failed, error code:"),DLT_STRING(strerror(errno)));
322         }
323 }
324
325 void RoutingReceiverAsyncShadow::hookSourceAvailablityStatusChange(const am_sourceID_t sourceID, const am_Availability_s & availability)
326 {
327         assert(mPipe[0]!=0);
328         //put the data in the queue:
329         a_sourceAvailability_s temp;
330         temp.sourceID=sourceID;
331         temp.availability = availability;
332
333         //then we make a message out of it:
334         msg_s msg;
335         msg.msgID = MSG_HOOKSOURCEAVAILABLITYSTATUSCHANGE;
336         msg.parameters.sourceAvailability = temp;
337         //here we share data !
338         pthread_mutex_lock(&mMutex);
339         mQueue.push(msg);
340         pthread_mutex_unlock(&mMutex);
341
342         //ok, fire the signal that data needs to be received !
343         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
344         {
345                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookSourceAvailablityStatusChange write failed, error code:"),DLT_STRING(strerror(errno)));
346         }
347 }
348
349 void RoutingReceiverAsyncShadow::hookDomainStateChange(const am_domainID_t domainID, const am_DomainState_e domainState)
350 {
351         assert(mPipe[0]!=0);
352         //put the data in the queue:
353         a_hookDomainStateChange_s temp;
354         temp.domainID=domainID;
355         temp.state = domainState;
356
357         //then we make a message out of it:
358         msg_s msg;
359         msg.msgID = MSG_HOOKDOMAINSTATECHANGE;
360         msg.parameters.domainStateChange = temp;
361         //here we share data !
362         pthread_mutex_lock(&mMutex);
363         mQueue.push(msg);
364         pthread_mutex_unlock(&mMutex);
365
366         //ok, fire the signal that data needs to be received !
367         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
368         {
369                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookDomainStateChange write failed, error code:"),DLT_STRING(strerror(errno)));
370         }
371 }
372
373 void RoutingReceiverAsyncShadow::hookTimingInformationChanged(const am_connectionID_t connectionID, const am_timeSync_t delay)
374 {
375         assert(mPipe[0]!=0);
376         //put the data in the queue:
377         a_timingInfoChanged_s temp;
378         temp.connectionID=connectionID;
379         temp.delay = delay;
380
381         //then we make a message out of it:
382         msg_s msg;
383         msg.msgID = MSG_HOOKTIMINGINFORMATIONCHANGED;
384         msg.parameters.timingInfoChange = temp;
385         //here we share data !
386         pthread_mutex_lock(&mMutex);
387         mQueue.push(msg);
388         pthread_mutex_unlock(&mMutex);
389
390         //ok, fire the signal that data needs to be received !
391         if (write(mPipe[1], &msg.msgID, sizeof (msgID_e))==-1)
392         {
393                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::hookTimingInformationChanged write failed, error code:"),DLT_STRING(strerror(errno)));
394         }
395 }
396
397 void RoutingReceiverAsyncShadow::asyncMsgReceiver(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
398 {
399         (void)handle;
400         (void)userData;
401         //it is no really important what to read here, we will read the queue later...
402         char buffer[10];
403         if(read(pollfd.fd, buffer, 10)==-1)
404         {
405                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::asyncMsgReceiver could not read!"));
406         }
407 }
408
409 bool RoutingReceiverAsyncShadow::asyncDispatcher(const sh_pollHandle_t handle, void *userData)
410 {
411         (void)handle;
412         (void)userData;
413         msg_s msg;
414
415         //ok, let's receive, first lock
416         pthread_mutex_lock(&mMutex);
417         msg = mQueue.front();
418         mQueue.pop();
419         pthread_mutex_unlock(&mMutex);
420
421         //check for the message:
422         switch (msg.msgID){
423                 case MSG_ACKCONNECT:
424                         mRoutingReceiveInterface->ackConnect(msg.parameters.connect.handle, msg.parameters.connect.connectionID, msg.parameters.connect.error);
425                         break;
426                 case MSG_ACKDISCONNECT:
427                         mRoutingReceiveInterface->ackDisconnect(msg.parameters.connect.handle, msg.parameters.connect.connectionID, msg.parameters.connect.error);
428                         break;
429                 case MSG_ACKSETSINKVOLUMECHANGE:
430                         mRoutingReceiveInterface->ackSetSinkVolumeChange(msg.parameters.volume.handle, msg.parameters.volume.volume,msg.parameters.volume.error);
431                         break;
432                 case MSG_ACKSETSOURCEVOLUMECHANGE:
433                         mRoutingReceiveInterface->ackSetSourceVolumeChange(msg.parameters.volume.handle,msg.parameters.volume.volume,msg.parameters.volume.error);
434                         break;
435                 case MSG_ACKSETSOURCESTATE:
436                         mRoutingReceiveInterface->ackSetSourceState(msg.parameters.handle.handle,msg.parameters.handle.error);
437                         break;
438                 case MSG_ACKSETSINKSOUNDPROPERTY:
439                         mRoutingReceiveInterface->ackSetSinkSoundProperty(msg.parameters.handle.handle,msg.parameters.handle.error);
440                         break;
441                 case MSG_ACKSETSOURCESOUNDPROPERTY:
442                         mRoutingReceiveInterface->ackSetSourceSoundProperty(msg.parameters.handle.handle,msg.parameters.handle.error);
443                         break;
444                 case MSG_ACKCROSSFADING:
445                         mRoutingReceiveInterface->ackCrossFading(msg.parameters.crossfading.handle,msg.parameters.crossfading.hotSink,msg.parameters.crossfading.error);
446                         break;
447                 case MSG_ACKSOURCEVOLUMETICK:
448                         mRoutingReceiveInterface->ackSourceVolumeTick(msg.parameters.sourceVolumeTick.handle,msg.parameters.sourceVolumeTick.sourceID,msg.parameters.sourceVolumeTick.volume);
449                         break;
450                 case MSG_ACKSINKVOLUMETICK:
451                         mRoutingReceiveInterface->ackSinkVolumeTick(msg.parameters.sinkVolumeTick.handle,msg.parameters.sinkVolumeTick.sinkID,msg.parameters.sinkVolumeTick.volume);
452                         break;
453                 case MSG_HOOKINTERRUPTSTATUSCHANGE:
454                         mRoutingReceiveInterface->hookInterruptStatusChange(msg.parameters.interruptStatusChange.sourceID,msg.parameters.interruptStatusChange.interruptState);
455                         break;
456                 case MSG_HOOKSINKAVAILABLITYSTATUSCHANGE:
457                         mRoutingReceiveInterface->hookSinkAvailablityStatusChange(msg.parameters.sinkAvailability.sinkID,msg.parameters.sinkAvailability.availability);
458                         break;
459                 case MSG_HOOKSOURCEAVAILABLITYSTATUSCHANGE:
460                         mRoutingReceiveInterface->hookSourceAvailablityStatusChange(msg.parameters.sourceAvailability.sourceID,msg.parameters.sourceAvailability.availability);
461                         break;
462                 case MSG_HOOKDOMAINSTATECHANGE:
463                         mRoutingReceiveInterface->hookDomainStateChange(msg.parameters.domainStateChange.domainID,msg.parameters.domainStateChange.state);
464                         break;
465                 case MSG_HOOKTIMINGINFORMATIONCHANGED:
466                         mRoutingReceiveInterface->hookTimingInformationChanged(msg.parameters.timingInfoChange.connectionID,msg.parameters.timingInfoChange.delay);
467                         break;
468                 default:
469                         DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::asyncDispatcher unknown message was received:"),DLT_INT(msg.msgID));
470                         break;
471         }
472
473         bool retVal=false;
474         pthread_mutex_lock(&mMutex);
475         if(mQueue.size() > 0) retVal=true;
476         pthread_mutex_unlock(&mMutex);
477
478         return (retVal);
479 }
480
481 bool RoutingReceiverAsyncShadow::asyncChecker(const sh_pollHandle_t handle, void *userData)
482 {
483         (void)handle;
484         (void)userData;
485         bool returnVal=false;
486         pthread_mutex_lock(&mMutex);
487         if(mQueue.size() > 0) returnVal=true;
488         pthread_mutex_unlock(&mMutex);
489         return (returnVal);
490 }
491
492 am_Error_e RoutingReceiverAsyncShadow::setRoutingInterface(RoutingReceiveInterface *receiveInterface)
493 {
494         assert(receiveInterface!=0);
495         mRoutingReceiveInterface=receiveInterface;
496         mRoutingReceiveInterface->getSocketHandler(mSocketHandler);
497         if(pipe(mPipe)==-1)
498         {
499                 DLT_LOG(PluginRoutingAsync, DLT_LOG_ERROR, DLT_STRING("RoutingReceiverAsyncShadow::setRoutingInterface could not create pipe!:"));
500                 return (E_UNKNOWN);
501         }
502
503         short event = 0;
504         event |=POLLIN;
505         mSocketHandler->addFDPoll(mPipe[0],event,NULL,&asyncMsgReceive,&asyncCheck,&asyncDispatch,NULL,mHandle);
506         return (E_OK);
507 }