AudioManager  7.5.11
Native Application Runtime Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
CAmCommandSender.cpp
Go to the documentation of this file.
1 
24 #include "CAmCommandSender.h"
25 #include <dirent.h>
26 #include <errno.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <sstream>
30 #include <string>
31 #include <cstring>
32 #include <stdexcept>
33 #include "CAmCommandReceiver.h"
34 #include "TAmPluginTemplate.h"
35 #include "CAmDltWrapper.h"
36 #include "audiomanagerconfig.h"
37 
38 namespace am
39 {
40 
44 #define CALL_ALL_INTERFACES(...) \
45  std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin(); \
46  std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end(); \
47  for (; iter<iterEnd;++iter) \
48  { \
49  (*iter)->__VA_ARGS__; \
50  }
51 
52 CAmCommandSender::CAmCommandSender(const std::vector<std::string>& listOfPluginDirectories) :
53  mListInterfaces(), //
54  mListLibraryHandles(), //
55  mListLibraryNames(), //
56  mCommandReceiver()
57 {
58  if (listOfPluginDirectories.empty())
59  {
60  logError("CAmCommandSender::CAmCommandSender: List of commandplugins is empty");
61  }
62 
63  std::vector<std::string> sharedLibraryNameList;
64  std::vector<std::string>::const_iterator dirIter = listOfPluginDirectories.begin();
65  std::vector<std::string>::const_iterator dirIterEnd = listOfPluginDirectories.end();
66 
67  // search communicator plugins in configured directories
68  for (; dirIter < dirIterEnd; ++dirIter)
69  {
70  const char* directoryName = dirIter->c_str();
71  logInfo("Searching for CommandPlugins in", *dirIter);
72  DIR *directory = opendir(directoryName);
73 
74  if (!directory)
75  {
76  logError("Error opening directory ", *dirIter);
77  continue;
78  }
79 
80  // iterate content of directory
81  struct dirent *itemInDirectory = 0;
82  while ((itemInDirectory = readdir(directory)))
83  {
84  unsigned char entryType = itemInDirectory->d_type;
85  std::string entryName = itemInDirectory->d_name;
86  std::string fullName = *dirIter + "/" + entryName;
87 
88  bool regularFile = (entryType == DT_REG || entryType == DT_LNK);
89  bool sharedLibExtension = ("so" == entryName.substr(entryName.find_last_of(".") + 1));
90 
91  // Handle cases where readdir() could not determine the file type
92  if (entryType == DT_UNKNOWN) {
93  struct stat buf;
94 
95  if (stat(fullName.c_str(), &buf)) {
96  logInfo(__PRETTY_FUNCTION__,"Failed to stat file: ", entryName, errno);
97  continue;
98  }
99 
100  regularFile = S_ISREG(buf.st_mode);
101  }
102 
103  if (regularFile && sharedLibExtension)
104  {
105  std::string name(directoryName);
106  sharedLibraryNameList.push_back(name + "/" + entryName);
107  }
108  }
109  closedir(directory);
110  }
111 
112  // iterate all communicator plugins and start them
113  std::vector<std::string>::iterator iter = sharedLibraryNameList.begin();
114  std::vector<std::string>::iterator iterEnd = sharedLibraryNameList.end();
115 
116  for (; iter < iterEnd; ++iter)
117  {
118  logInfo("Loading CommandSender plugin", *iter);
119  IAmCommandSend* (*createFunc)();
120  void* tempLibHandle = NULL;
121  createFunc = getCreateFunction<IAmCommandSend*()>(*iter, tempLibHandle);
122 
123  if (!createFunc)
124  {
125  logInfo("Entry point of CommandPlugin not found", *iter);
126  continue;
127  }
128 
129  IAmCommandSend* commander = createFunc();
130 
131  if (!commander)
132  {
133  logInfo("CommandPlugin initialization failed. Entry Function not callable");
134  dlclose(tempLibHandle);
135  continue;
136  }
137 
138  //check libversion
139  std::string version, cVersion(CommandVersion);
140  commander->getInterfaceVersion(version);
141  uint16_t minorVersion, majorVersion, cMinorVersion, cMajorVersion;
142  std::istringstream(version.substr(0, 1)) >> majorVersion;
143  std::istringstream(version.substr(2, 1)) >> minorVersion;
144  std::istringstream(cVersion.substr(0, 1)) >> cMajorVersion;
145  std::istringstream(cVersion.substr(2, 1)) >> cMinorVersion;
146 
147 
148 
149  if (majorVersion < cMajorVersion || ((majorVersion == cMajorVersion) && (minorVersion > cMinorVersion)))
150  {
151  logError("CommandInterface initialization failed. Version of Interface to old");
152  dlclose(tempLibHandle);
153  continue;
154  }
155 
156  mListInterfaces.push_back(commander);
157  mListLibraryHandles.push_back(tempLibHandle);
158  mListLibraryNames.push_back(iter->c_str());
159  }
160 }
161 
163 {
164  //unloadLibraries();
165 }
166 
168 {
169  mCommandReceiver = iCommandReceiver;
170  am_Error_e returnError = E_OK;
171 
172  std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
173  std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
174  for (; iter < iterEnd; ++iter)
175  {
176  am_Error_e error = (*iter)->startupInterface(iCommandReceiver);
177  if (error != E_OK)
178  {
179  returnError = error;
180  }
181  }
182  return (returnError);
183 }
184 
186 {
188 }
189 
191 {
193 }
194 
196 {
197  CALL_ALL_INTERFACES(cbMainConnectionStateChanged(connectionID,connectionState))
198 }
199 
201 {
203 }
204 
206 {
208 }
209 
211 {
212  CALL_ALL_INTERFACES(cbSinkAvailabilityChanged(sinkID,availability))
213 }
214 
216 {
217  CALL_ALL_INTERFACES(cbSourceAvailabilityChanged(sourceID,availability))
218 }
219 
221 {
222  CALL_ALL_INTERFACES(cbVolumeChanged(sinkID,volume))
223 }
224 
226 {
228 }
229 
231 {
233 }
234 
236 {
237  CALL_ALL_INTERFACES(cbTimingInformationChanged(mainConnection,time))
238 }
239 
241 {
243 }
244 
246 {
248 }
249 
251 {
253 }
254 
256 {
258 }
259 
261 {
263 }
264 
266 {
268 }
269 
271 {
272  mCommandReceiver->waitOnStartup(false);
273 
274  //create a list of handles
275  std::vector<uint16_t> listStartupHandles;
276  for (size_t i = 0; i < mListInterfaces.size(); i++)
277  {
278  listStartupHandles.push_back(mCommandReceiver->getStartupHandle());
279  }
280 
281  //set the receiver ready to wait for replies
282  mCommandReceiver->waitOnStartup(true);
283 
284  //now do the calls
285  std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
286  std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
287  std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
288  for (; iter < iterEnd; ++iter)
289  {
290  (*iter)->setCommandReady(*(handleIter++));
291  }
292 }
293 
295 {
296  mCommandReceiver->waitOnRundown(false);
297  //create a list of handles
298  std::vector<uint16_t> listStartupHandles;
299  for (size_t i = 0; i < mListInterfaces.size(); i++)
300  {
301  listStartupHandles.push_back(mCommandReceiver->getRundownHandle());
302  }
303 
304  //set the receiver ready to wait for replies
305  mCommandReceiver->waitOnRundown(true);
306 
307  //now do the calls
308  std::vector<IAmCommandSend*>::iterator iter = mListInterfaces.begin();
309  std::vector<IAmCommandSend*>::iterator iterEnd = mListInterfaces.end();
310  std::vector<uint16_t>::const_iterator handleIter(listStartupHandles.begin());
311  for (; iter < iterEnd; ++iter)
312  {
313  (*iter)->setCommandRundown(*(handleIter++));
314  }
315 }
316 
317 void CAmCommandSender::getInterfaceVersion(std::string & version) const
318 {
319  version = CommandVersion;
320 }
321 
322 am_Error_e am::CAmCommandSender::getListPlugins(std::vector<std::string> & interfaces) const
323 {
324  interfaces = mListLibraryNames;
325  return (E_OK);
326 }
327 
328 void CAmCommandSender::cbSinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
329 {
330  CALL_ALL_INTERFACES(cbSinkUpdated(sinkID,sinkClassID,listMainSoundProperties));
331 }
332 
333 void CAmCommandSender::cbSourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector<am_MainSoundProperty_s>& listMainSoundProperties)
334 {
335  CALL_ALL_INTERFACES(cbSourceUpdated(sourceID,sourceClassID,listMainSoundProperties));
336 }
337 
339 {
340  CALL_ALL_INTERFACES(cbSinkNotification(sinkID,notification));
341 }
342 
344 {
345  CALL_ALL_INTERFACES(cbSourceNotification(sourceID,notification));
346 }
347 
349 {
350  CALL_ALL_INTERFACES(cbMainSinkNotificationConfigurationChanged(sinkID,mainNotificationConfiguration));
351 }
352 
354 {
355  CALL_ALL_INTERFACES(cbMainSourceNotificationConfigurationChanged(sourceID,mainNotificationConfiguration));
356 }
357 
358 void CAmCommandSender::unloadLibraries(void)
359 {
360  std::vector<void*>::iterator iterator = mListLibraryHandles.begin();
361  for (; iterator < mListLibraryHandles.end(); ++iterator)
362  {
363  dlclose(*iterator);
364  }
365  mListLibraryHandles.clear();
366 }
367 }
am_Error_e getListPlugins(std::vector< std::string > &interfaces) const
void cbNewSink(am_SinkType_s sink)
This class realizes the command Interface.
uint16_t getRundownHandle()
returns a rundown handle
#define CommandVersion
Definition: IAmCommand.h:37
am_Error_e startupInterfaces(CAmCommandReceiver *iCommandReceiver)
uint16_t am_sinkClass_t
am_Error_e
the errors of the audiomanager.
This struct holds information about the configuration for notifications.
void logInfo(T value, TArgs...args)
logs given values with infolevel with the default context
void cbSystemPropertyChanged(const am_SystemProperty_s &systemProperty)
void cbSinkUpdated(const am_sinkID_t sinkID, const am_sinkClass_t sinkClassID, const std::vector< am_MainSoundProperty_s > &listMainSoundProperties)
void cbNewMainConnection(const am_MainConnectionType_s mainConnection)
This struct holds the payload of a notification.
virtual void getInterfaceVersion(std::string &version) const =0
returns the interface version as string.
#define CALL_ALL_INTERFACES(...)
macro to call all interfaces
void cbSourceNotification(const am_sourceID_t sourceID, const am_NotificationPayload_s &notification)
this type holds all information of sinks relevant to the HMI
int16_t am_timeSync_t
offset time that is introduced in milli seconds.
void cbMainSinkSoundPropertyChanged(const am_sinkID_t sinkID, const am_MainSoundProperty_s &soundProperty)
SPDX license identifier: MPL-2.0.
void cbMainSourceSoundPropertyChanged(const am_sourceID_t sourceID, const am_MainSoundProperty_s &soundProperty)
void cbRemovedSource(const am_sourceID_t source)
void cbTimingInformationChanged(const am_mainConnectionID_t mainConnectionID, const am_timeSync_t time)
void cbNewSource(const am_SourceType_s source)
struct describing system properties
void waitOnRundown(bool rundown)
tells the ComandReceiver to start waiting for all handles to be confirmed
SPDX license identifier: MPL-2.0.
CAmCommandSender(const std::vector< std::string > &listOfPluginDirectories)
struct describung mainsound property
void getInterfaceVersion(std::string &version) const
uint16_t am_sourceID_t
a source ID
void cbSinkNotification(const am_sinkID_t sinkID, const am_NotificationPayload_s &notification)
am_ConnectionState_e
represents the connection state
void cbSourceMainNotificationConfigurationChanged(const am_sourceID_t sourceID, const am_NotificationConfiguration_s &mainNotificationConfiguration)
this type holds all information of connections relevant to the HMI
void cbSourceUpdated(const am_sourceID_t sourceID, const am_sourceClass_t sourceClassID, const std::vector< am_MainSoundProperty_s > &listMainSoundProperties)
void cbSinkMuteStateChanged(const am_sinkID_t sinkID, const am_MuteState_e muteState)
uint16_t am_sourceClass_t
void cbRemovedMainConnection(const am_mainConnectionID_t mainConnection)
this describes the availability of a sink or a source together with the latest change ...
void logError(T value, TArgs...args)
logs given values with errorlevel with the default context
void cbSinkAvailabilityChanged(const am_sinkID_t sinkID, const am_Availability_s &availability)
void waitOnStartup(bool startup)
tells the ComandReceiver to start waiting for all handles to be confirmed
void cbVolumeChanged(const am_sinkID_t sinkID, const am_mainVolume_t volume)
void cbSinkMainNotificationConfigurationChanged(const am_sinkID_t sinkID, const am_NotificationConfiguration_s &mainNotificationConfiguration)
void cbMainConnectionStateChanged(const am_mainConnectionID_t connectionID, const am_ConnectionState_e connectionState)
SPDX license identifier: MPL-2.0.
int16_t am_mainVolume_t
This is the volume presented on the command interface.
no error - positive reply
void cbSourceAvailabilityChanged(const am_sourceID_t sourceID, const am_Availability_s &availability)
uint16_t getStartupHandle()
returns a startup handle
this type holds all information of sources relevant to the HMI
uint16_t am_sinkID_t
a sink ID
uint16_t am_mainConnectionID_t
a mainConnection ID
This interface handles all communication from the AudioManagerDaemon towards the system.
Definition: IAmCommand.h:243
void cbRemovedSink(const am_sinkID_t sink)