* add setSinkVolume to telnetserver
[profile/ivi/audiomanager.git] / AudioManagerDaemon / src / CAmCommandSender.cpp
1 /**
2  * Copyright (C) 2012, BMW AG
3  *
4  * This file is part of GENIVI Project AudioManager.
5  *
6  * Contributions are licensed to the GENIVI Alliance under one or more
7  * Contribution License Agreements.
8  *
9  * \copyright
10  * This Source Code Form is subject to the terms of the
11  * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed with
12  * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
13  *
14  *
15  * \author Christian Mueller, christian.ei.mueller@bmw.de BMW 2011,2012
16  *
17  * \file CAmCommandSender.cpp
18  * For further information see http://www.genivi.org/.
19  *
20  */
21
22 #include "CAmCommandSender.h"
23 #include <dirent.h>
24 #include <sstream>
25 #include <string>
26 #include "CAmCommandReceiver.h"
27 #include "TAmPluginTemplate.h"
28 #include "shared/CAmDltWrapper.h"
29
30 namespace am
31 {
32
33 #define REQUIRED_INTERFACE_VERSION_MAJOR 1  //!< major interface version. All versions smaller than this will be rejected
34 #define REQUIRED_INTERFACE_VERSION_MINOR 0 //!< minor interface version. All versions smaller than this will be rejected
35
36 /**
37  *  macro to call all interfaces
38  */
39 #define CALL_ALL_INTERFACES(...)                                                                                                                 \
40                 std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();           \
41                 std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();          \
42                 for (; iter<iterEnd;++iter)                                                                                                              \
43                 {                                                                                                                                                                \
44                         (*iter)->__VA_ARGS__;                                                                                                            \
45                 }
46
47 CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginDirectories) :
48         mListInterfaces(), //
49         mListLibraryHandles(), //
50         mListLibraryNames(), //
51         mCommandReceiver()
52 {
53     std::vector<std::string> sharedLibraryNameList;
54     std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin();
55     std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end();
56
57     // search communicator plugins in configured directories
58     for (; dirIter < dirIterEnd; ++dirIter)
59     {
60         const char* directoryName = dirIter->c_str();
61         logInfo("Searching for CommandPlugins in", *dirIter);
62         DIR *directory = opendir(directoryName);
63
64         if (!directory)
65         {
66             logError("Error opening directory ", *dirIter);
67             continue;
68         }
69
70         // iterate content of directory
71         struct dirent *itemInDirectory = 0;
72         while ((itemInDirectory = readdir(directory)))
73         {
74             unsigned char entryType = itemInDirectory->d_type;
75             std::string entryName = itemInDirectory->d_name;
76
77             bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
78             bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
79
80             if (regularFile && sharedLibExtension)
81             {
82                 std::string name(directoryName);
83                 sharedLibraryNameList.push_back(name + "/" + entryName);
84             }
85         }
86         closedir(directory);
87     }
88
89     // iterate all communicator plugins and start them
90     std::vector<std::string>::iterator iter = sharedLibraryNameList.begin();
91     std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end();
92
93     for (; iter < iterEnd; ++iter)
94     {
95         logInfo("Loading CommandSender plugin", *iter);
96         IAmCommandSend* (*createFunc)();
97         void* tempLibHandle = NULL;
98         createFunc = getCreateFunction<IAmCommandSend*()>(*iter, tempLibHandle);
99
100         if (!createFunc)
101         {
102             logInfo("Entry point of CommandPlugin not found", *iter);
103             continue;
104         }
105
106         IAmCommandSend* commander = createFunc();
107
108         if (!commander)
109         {
110             logInfo("CommandPlugin initialization failed. Entry Function not callable");
111             continue;
112         }
113
114         //check libversion
115         std::string version;
116         commander->getInterfaceVersion(version);
117         uint16_t minorVersion, majorVersion;
118         std::istringstream(version.substr(0, 1)) >> majorVersion;
119         std::istringstream(version.substr(2, 1)) >> minorVersion;
120
121         if (majorVersion < REQUIRED_INTERFACE_VERSION_MAJOR || ((majorVersion == REQUIRED_INTERFACE_VERSION_MAJOR) && (minorVersion > REQUIRED_INTERFACE_VERSION_MINOR)))
122         {
123             logInfo("CommandInterface initialization failed. Version of Interface to old");
124             continue;
125         }
126
127         mListInterfaces.push_back(commander);
128         mListLibraryHandles.push_back(tempLibHandle);
129         mListLibraryNames.push_back(iter->c_str());
130     }
131 }
132
133 CAmCommandSender::~CAmCommandSender()
134 {
135     unloadLibraries();
136 }
137
138 am_Error_e CAmCommandSender::startupInterfaces(CAmCommandReceiver *iCommandReceiver)
139 {
140     mCommandReceiver = iCommandReceiver;
141     am_Error_e returnError = E_OK;
142
143     std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
144     std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
145     for (; iter < iterEnd; ++iter)
146     {
147         am_Error_e error = (*iter)->startupInterface(iCommandReceiver);
148         if (error != E_OK)
149         {
150             returnError = error;
151         }
152     }
153     return (returnError);
154 }
155
156 void CAmCommandSender::cbNumberOfSinkClassesChanged()
157 {
158     CALL_ALL_INTERFACES(cbNumberOfSinkClassesChanged())
159 }
160
161 void CAmCommandSender::cbNumberOfSourceClassesChanged()
162 {
163     CALL_ALL_INTERFACES(cbNumberOfSourceClassesChanged())
164 }
165
166 void CAmCommandSender::cbMainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState)
167 {
168     CALL_ALL_INTERFACES(cbMainConnectionStateChanged(connectionID,connectionState))
169 }
170
171 void CAmCommandSender::cbMainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s& SoundProperty)
172 {
173     CALL_ALL_INTERFACES(cbMainSinkSoundPropertyChanged(sinkID,SoundProperty))
174 }
175
176 void CAmCommandSender::cbMainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s& SoundProperty)
177 {
178     CALL_ALL_INTERFACES(cbMainSourceSoundPropertyChanged(sourceID,SoundProperty))
179 }
180
181 void CAmCommandSender::cbSinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s & availability)
182 {
183     CALL_ALL_INTERFACES(cbSinkAvailabilityChanged(sinkID,availability))
184 }
185
186 void CAmCommandSender::cbSourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s & availability)
187 {
188     CALL_ALL_INTERFACES(cbSourceAvailabilityChanged(sourceID,availability))
189 }
190
191 void CAmCommandSender::cbVolumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume)
192 {
193     CALL_ALL_INTERFACES(cbVolumeChanged(sinkID,volume))
194 }
195
196 void CAmCommandSender::cbSinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState)
197 {
198     CALL_ALL_INTERFACES(cbSinkMuteStateChanged(sinkID,muteState))
199 }
200
201 void CAmCommandSender::cbSystemPropertyChanged(const am_SystemProperty_s & SystemProperty)
202 {
203     CALL_ALL_INTERFACES(cbSystemPropertyChanged(SystemProperty))
204 }
205
206 void CAmCommandSender::cbTimingInformationChanged(const am_mainConnectionID_t mainConnection, const am_timeSync_t time)
207 {
208     CALL_ALL_INTERFACES(cbTimingInformationChanged(mainConnection,time))
209 }
210
211 void CAmCommandSender::cbNewMainConnection(const am_MainConnectionType_s mainConnection)
212 {
213     CALL_ALL_INTERFACES(cbNewMainConnection(mainConnection))
214 }
215
216 void CAmCommandSender::cbRemovedMainConnection(const am_mainConnectionID_t mainConnection)
217 {
218     CALL_ALL_INTERFACES(cbRemovedMainConnection(mainConnection))
219 }
220
221 void CAmCommandSender::cbNewSink(const am_SinkType_s sink)
222 {
223     CALL_ALL_INTERFACES(cbNewSink(sink))
224 }
225
226 void CAmCommandSender::cbRemovedSink(const am_sinkID_t sink)
227 {
228     CALL_ALL_INTERFACES(cbRemovedSink(sink))
229 }
230
231 void CAmCommandSender::cbNewSource(const am_SourceType_s source)
232 {
233     CALL_ALL_INTERFACES(cbNewSource(source))
234 }
235
236 void CAmCommandSender::cbRemovedSource(const am_sourceID_t source)
237 {
238     CALL_ALL_INTERFACES(cbRemovedSource(source))
239 }
240
241 void CAmCommandSender::setCommandReady()
242 {
243     mCommandReceiver->waitOnStartup(false);
244     std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
245     std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
246     for (; iter < iterEnd; ++iter)
247     {
248         (*iter)->setCommandReady(mCommandReceiver->getStartupHandle());
249     }
250     mCommandReceiver->waitOnStartup(true);
251 }
252
253 void CAmCommandSender::setCommandRundown()
254 {
255     mCommandReceiver->waitOnRundown(false);
256     std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
257     std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
258     for (; iter < iterEnd; ++iter)
259     {
260         (*iter)->setCommandRundown(mCommandReceiver->getRundownHandle());
261     }
262     mCommandReceiver->waitOnRundown(true);
263 }
264
265 void CAmCommandSender::getInterfaceVersion(std::string & version) const
266 {
267     version = CommandSendVersion;
268 }
269
270 am_Error_e am::CAmCommandSender::getListPlugins(std::vector<std::string> & interfaces) const
271 {
272     interfaces = mListLibraryNames;
273     return (E_OK);
274 }
275
276 void CAmCommandSender::unloadLibraries(void)
277 {
278     std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
279     for (; iterator < mListLibraryHandles.end(); ++iterator)
280     {
281         dlclose(*iterator);
282     }
283     mListLibraryHandles.clear();
284 }
285 }