* Confirming routing ready state after a second domain has been registered.
[profile/ivi/genivi/genivi-audio-manager.git] / PluginRoutingInterfaceCAPI / src / CAmRoutingSenderCAPI.cpp
1 /**
2  *  Copyright (c) 2012 BMW
3  *
4  *  \author Aleksandar Donchev, aleksander.donchev@partner.bmw.de BMW 2013
5  *
6  *  \copyright
7  *  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction,
8  *  including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
9  *  subject to the following conditions:
10  *  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
12  *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
13  *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14  *
15  *  For further information see http://www.genivi.org/.
16  */
17
18 #include <cassert>
19 #include <map>
20 #include <algorithm>
21 #include <string>
22 #include <vector>
23 #include <set>
24 #include "shared/CAmDltWrapper.h"
25 #include "CAmRoutingSenderCAPI.h"
26 #include "CAmRoutingSenderCommon.h"
27
28
29
30
31 namespace am
32 {
33 DLT_DECLARE_CONTEXT(ctxCommandCAPI)
34
35
36 extern "C" IAmRoutingSend* PluginRoutingInterfaceCAPIFactory()
37 {
38     CAmDltWrapper::instance()->registerContext(ctxCommandCAPI, "DRS", "Common-API Plugin");
39     return (new CAmRoutingSenderCAPI(Am_CAPI));
40 }
41
42 extern "C" void destroyPluginRoutingInterfaceCAPI(IAmRoutingSend* routingSendInterface)
43 {
44     delete routingSendInterface;
45 }
46
47 const char * CAmRoutingSenderCAPI::ROUTING_INTERFACE_SERVICE = "local:org.genivi.audiomanager.routinginterface:org.genivi.audiomanager";
48
49 CAmRoutingSenderCAPI::CAmRoutingSenderCAPI() :
50                 mIsServiceStarted(false),
51                 mLookupData(),
52                                 mpCAmCAPIWrapper(NULL), //
53                                 mpIAmRoutingReceive(NULL),
54                                 mService()
55 {
56     log(&ctxCommandCAPI, DLT_LOG_INFO, "RoutingSender constructed");
57 }
58
59 CAmRoutingSenderCAPI::CAmRoutingSenderCAPI(CAmCommonAPIWrapper *aWrapper) :
60                 mIsServiceStarted(false),
61                 mLookupData(),
62                 mpCAmCAPIWrapper(aWrapper), //
63                 mpIAmRoutingReceive(NULL),
64                 mService()
65 {
66     log(&ctxCommandCAPI, DLT_LOG_INFO, "CommandSenderCAPI constructor called");
67     assert(mpCAmCAPIWrapper!=NULL);
68 }
69
70 CAmRoutingSenderCAPI::~CAmRoutingSenderCAPI()
71 {
72     log(&ctxCommandCAPI, DLT_LOG_INFO, "RoutingSender deallocate");
73     CAmDltWrapper::instance()->unregisterContext(ctxCommandCAPI);
74     tearDownInterface(mpIAmRoutingReceive);
75 }
76
77 am_Error_e CAmRoutingSenderCAPI::startService(IAmRoutingReceive* pIAmRoutingReceive)
78 {
79         log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__);
80         if(!mIsServiceStarted)
81         {
82                 assert(pIAmRoutingReceive);
83                 mService = std::make_shared<CAmRoutingService>(pIAmRoutingReceive, &mLookupData, mpCAmCAPIWrapper);
84             mService->setRoutingReadyAttribute(org::genivi::am::am_RoutingReady_e::RR_UNKNOWN);
85                 //Registers the service
86                 if( false == mpCAmCAPIWrapper->registerStub(mService, CAmRoutingSenderCAPI::ROUTING_INTERFACE_SERVICE) )
87                 {
88                         return (E_NOT_POSSIBLE);
89                 }
90                 mIsServiceStarted = true;
91         }
92     return (E_OK);
93 }
94
95 am_Error_e CAmRoutingSenderCAPI::startupInterface(IAmRoutingReceive* pIAmRoutingReceive)
96 {
97         log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__);
98     mpIAmRoutingReceive = pIAmRoutingReceive;
99     return startService(mpIAmRoutingReceive);
100 }
101
102 am_Error_e CAmRoutingSenderCAPI::tearDownInterface(IAmRoutingReceive*)
103 {
104         log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__);
105     if(mpCAmCAPIWrapper)
106     {
107         if(mIsServiceStarted)
108         {
109                 mIsServiceStarted = false;
110                         mpCAmCAPIWrapper->unregisterStub(CAmRoutingSenderCAPI::ROUTING_INTERFACE_SERVICE);
111                         mService.reset();
112         }
113                 return (E_OK);
114     }
115     return (E_NOT_POSSIBLE);
116 }
117
118 void CAmRoutingSenderCAPI::getInterfaceVersion(std::string & version) const
119 {
120     version = RoutingSendVersion;
121 }
122
123 void CAmRoutingSenderCAPI::setRoutingReady(const uint16_t handle)
124 {
125         assert(mpIAmRoutingReceive);
126         mService->setHandle(handle);
127
128     log(&ctxCommandCAPI, DLT_LOG_INFO, "sending routingReady signal");
129     mService->setRoutingReadyAttribute(org::genivi::am::am_RoutingReady_e::RR_READY);
130 }
131
132 void CAmRoutingSenderCAPI::setRoutingRundown(const uint16_t handle)
133 {
134         log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__);
135         assert(mpIAmRoutingReceive);
136         mService->setRoutingReadyAttribute(org::genivi::am::am_RoutingReady_e::RR_RUNDOWN);
137         mService->gotRundown(mLookupData.numberOfDomains(),handle);
138 }
139
140 am_Error_e CAmRoutingSenderCAPI::asyncAbort(const am_Handle_s handle)
141 {
142     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncAbort called");
143         return mLookupData.asyncAbort(handle,[](const CommonAPI::CallStatus& callStatus){
144                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
145         });
146 }
147
148 am_Error_e CAmRoutingSenderCAPI::asyncConnect(const am_Handle_s handle, const am_connectionID_t connectionID, const am_sourceID_t sourceID, const am_sinkID_t sinkID, const am_CustomConnectionFormat_t connectionFormat)
149 {
150     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncConnect called");
151         return mLookupData.asyncConnect(handle,connectionID, sourceID, sinkID, connectionFormat, [&,handle,connectionID](const CommonAPI::CallStatus& callStatus){
152                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
153                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
154                 {
155                         org::genivi::am::am_Handle_s dst;
156                         CAmConvertAM2CAPI(handle, dst);
157                         mService->ackConnect(dst, connectionID, org::genivi::am::am_Error_e::E_NON_EXISTENT);
158                 }
159         });
160 }
161
162 am_Error_e CAmRoutingSenderCAPI::asyncDisconnect(const am_Handle_s handle, const am_connectionID_t connectionID)
163 {
164         log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncDisconnect called");
165         return mLookupData.asyncDisconnect(handle,connectionID, [&, handle, connectionID](const CommonAPI::CallStatus& callStatus){
166                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
167                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
168                 {
169                         org::genivi::am::am_Handle_s dst;
170                         CAmConvertAM2CAPI(handle, dst);
171                         mService->ackDisconnect(dst, connectionID, org::genivi::am::am_Error_e::E_NON_EXISTENT);
172                 }
173         });
174 }
175
176 am_Error_e CAmRoutingSenderCAPI::asyncSetSinkVolume(const am_Handle_s handle, const am_sinkID_t sinkID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time)
177 {
178     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSinkVolume called");
179         return mLookupData.asyncSetSinkVolume(handle,sinkID, volume, ramp, time, [&, handle, volume](const CommonAPI::CallStatus& callStatus){
180                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
181                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
182                 {
183                         org::genivi::am::am_Handle_s dst;
184                         CAmConvertAM2CAPI(handle, dst);
185                         mService->ackSetSinkVolumeChange(dst, volume, org::genivi::am::am_Error_e::E_NON_EXISTENT);
186                 }
187         });
188 }
189
190 am_Error_e CAmRoutingSenderCAPI::asyncSetSourceVolume(const am_Handle_s handle, const am_sourceID_t sourceID, const am_volume_t volume, const am_CustomRampType_t ramp, const am_time_t time)
191 {
192     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSourceVolume called");
193         return mLookupData.asyncSetSourceVolume(handle,sourceID, volume, ramp, time, [&, handle, volume](const CommonAPI::CallStatus& callStatus){
194                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
195                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
196                 {
197                         org::genivi::am::am_Handle_s dst;
198                         CAmConvertAM2CAPI(handle, dst);
199                         mService->ackSetSourceVolumeChange(dst, volume, org::genivi::am::am_Error_e::E_NON_EXISTENT);
200                 }
201         });
202 }
203
204 am_Error_e CAmRoutingSenderCAPI::asyncSetSourceState(const am_Handle_s handle, const am_sourceID_t sourceID, const am_SourceState_e state)
205 {
206     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSourceState called");
207         return mLookupData.asyncSetSourceState(handle,sourceID, state,[&, handle](const CommonAPI::CallStatus& callStatus){
208                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
209                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
210                 {
211                         org::genivi::am::am_Handle_s dst;
212                         CAmConvertAM2CAPI(handle, dst);
213                         mService->ackSetSourceState(dst, org::genivi::am::am_Error_e::E_NON_EXISTENT);
214                 }
215         });
216 }
217
218 am_Error_e CAmRoutingSenderCAPI::asyncSetSinkSoundProperties(const am_Handle_s handle, const am_sinkID_t sinkID, const std::vector<am_SoundProperty_s>& listSoundProperties)
219 {
220     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSinkSoundProperties called");
221         return mLookupData.asyncSetSinkSoundProperties(handle,sinkID, listSoundProperties, [&, handle](const CommonAPI::CallStatus& callStatus){
222                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
223                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
224                 {
225                         org::genivi::am::am_Handle_s dst;
226                         CAmConvertAM2CAPI(handle, dst);
227                         mService->ackSetSinkSoundProperties(dst, org::genivi::am::am_Error_e::E_NON_EXISTENT);
228                 }
229         });
230 }
231
232 am_Error_e CAmRoutingSenderCAPI::asyncSetSinkSoundProperty(const am_Handle_s handle, const am_sinkID_t sinkID, const am_SoundProperty_s& soundProperty)
233 {
234     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSinkSoundProperty called");
235         return mLookupData.asyncSetSinkSoundProperty(handle, sinkID, soundProperty, [&, handle](const CommonAPI::CallStatus& callStatus){
236                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
237                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
238                 {
239                         org::genivi::am::am_Handle_s dst;
240                         CAmConvertAM2CAPI(handle, dst);
241                         mService->ackSetSinkSoundProperty(dst, org::genivi::am::am_Error_e::E_NON_EXISTENT);
242                 }
243         });
244 }
245
246 am_Error_e CAmRoutingSenderCAPI::asyncSetSourceSoundProperties(const am_Handle_s handle, const am_sourceID_t sourceID, const std::vector<am_SoundProperty_s>& listSoundProperties)
247 {
248     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSourceSoundProperties called");
249         return mLookupData.asyncSetSourceSoundProperties(handle, sourceID, listSoundProperties, [&, handle](const CommonAPI::CallStatus& callStatus){
250                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
251                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
252                 {
253                         org::genivi::am::am_Handle_s dst;
254                         CAmConvertAM2CAPI(handle, dst);
255                         mService->ackSetSourceSoundProperties(dst, org::genivi::am::am_Error_e::E_NON_EXISTENT);
256                 }
257         });
258 }
259
260 am_Error_e CAmRoutingSenderCAPI::asyncSetSourceSoundProperty(const am_Handle_s handle, const am_sourceID_t sourceID, const am_SoundProperty_s& soundProperty)
261 {
262     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSourceSoundProperty called");
263         return mLookupData.asyncSetSourceSoundProperty(handle, sourceID, soundProperty, [&, handle](const CommonAPI::CallStatus& callStatus){
264                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
265                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
266                 {
267                         org::genivi::am::am_Handle_s dst;
268                         CAmConvertAM2CAPI(handle, dst);
269                         mService->ackSetSourceSoundProperty(dst, org::genivi::am::am_Error_e::E_NON_EXISTENT);
270                 }
271         });
272 }
273
274 am_Error_e CAmRoutingSenderCAPI::asyncCrossFade(const am_Handle_s handle, const am_crossfaderID_t crossfaderID, const am_HotSink_e hotSink, const am_CustomRampType_t rampType, const am_time_t time)
275 {
276         return mLookupData.asyncCrossFade(handle, crossfaderID, hotSink, rampType, time, [&, handle, hotSink](const CommonAPI::CallStatus& callStatus){
277                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
278                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
279                 {
280                         org::genivi::am::am_Handle_s dst;
281                         CAmConvertAM2CAPI(handle, dst);
282                         mService->ackCrossFading(dst, (org::genivi::am::am_HotSink_e)hotSink, org::genivi::am::am_Error_e::E_NON_EXISTENT);
283                 }
284         });
285 }
286
287 am_Error_e CAmRoutingSenderCAPI::setDomainState(const am_domainID_t domainID, const am_DomainState_e domainState)
288 {
289     log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::setDomainState called");
290         return mLookupData.setDomainState(domainID, domainState, [](const CommonAPI::CallStatus& callStatus, org::genivi::am::am_Error_e error){
291                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus),"Error",static_cast<am_Error_e>(error));
292         });
293 }
294
295 am_Error_e CAmRoutingSenderCAPI::returnBusName(std::string& BusName) const
296 {
297     BusName = CAmLookupData::BUS_NAME;
298     return (E_OK);
299 }
300
301 am_Error_e CAmRoutingSenderCAPI::asyncSetVolumes(const am_Handle_s handle, const std::vector<am_Volumes_s>& volumes)
302 {
303         log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetVolumes called");
304         return mLookupData.asyncSetVolumes(handle, volumes, [&, handle, volumes](const CommonAPI::CallStatus& callStatus){
305                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
306                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
307                 {
308                         org::genivi::am::am_Handle_s dst;
309                         CAmConvertAM2CAPI(handle, dst);
310                         org::genivi::am::am_Volumes_L list;
311                         CAmConvertAMVector2CAPI(volumes, list);
312                         mService->ackSetVolumes(dst, list, org::genivi::am::am_Error_e::E_NON_EXISTENT);
313                 }
314         });
315 }
316
317 am_Error_e CAmRoutingSenderCAPI::asyncSetSinkNotificationConfiguration(const am_Handle_s handle, const am_sinkID_t sinkID, const am_NotificationConfiguration_s& nc)
318 {
319         log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSinkNotificationConfiguration called");
320         return mLookupData.asyncSetSinkNotificationConfiguration(handle, sinkID, nc, [&, handle](const CommonAPI::CallStatus& callStatus){
321                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
322                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
323                 {
324                         org::genivi::am::am_Handle_s dst;
325                         CAmConvertAM2CAPI(handle, dst);
326                         mService->ackSinkNotificationConfiguration(dst, org::genivi::am::am_Error_e::E_NON_EXISTENT);
327                 }
328         });
329 }
330
331 am_Error_e CAmRoutingSenderCAPI::asyncSetSourceNotificationConfiguration(const am_Handle_s handle, const am_sourceID_t sourceID, const am_NotificationConfiguration_s& nc)
332 {
333         log(&ctxCommandCAPI, DLT_LOG_INFO, "CAmRoutingSenderCAPI::asyncSetSourceNotificationConfiguration called");
334         return mLookupData.asyncSetSourceNotificationConfiguration(handle, sourceID, nc, [&, handle](const CommonAPI::CallStatus& callStatus){
335                 log(&ctxCommandCAPI, DLT_LOG_INFO, __PRETTY_FUNCTION__, "Response with call status:", static_cast<int16_t>(callStatus));
336                 if (callStatus != CommonAPI::CallStatus::SUCCESS)
337                 {
338                         org::genivi::am::am_Handle_s dst;
339                         CAmConvertAM2CAPI(handle, dst);
340                         mService->ackSourceNotificationConfiguration(dst, org::genivi::am::am_Error_e::E_NON_EXISTENT);
341                 }
342         });
343 }
344
345 }
346