25 #include <audiomanagerconfig.h> 41 #define ROOT_INTROSPECT_XML \ 42 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \ 44 "<interface name='org.AudioManager.freedesktop.DBus.Introspectable'>" \ 45 "<method name='Introspect'>" \ 46 " <arg name='xml_data' type='s' direction='out'/>" \ 50 CAmDbusWrapper* CAmDbusWrapper::mpReference = NULL;
54 pDbusDispatchCallback(this, &
CAmDbusWrapper::dbusDispatchCallback),
62 mpSocketHandler(socketHandler),
65 assert(mpSocketHandler!=0);
67 dbus_error_init(&mDBusError);
69 if (!dbus_threads_init_default())
70 logError(
"CAmDbusWrapper::CAmDbusWrapper threads init call failed");
72 logInfo(
"DBusWrapper::DBusWrapper Opening DBus connection of:", prefix, objectPath);
73 mpDbusConnection = dbus_bus_get(mDbusType, &mDBusError);
74 if (dbus_error_is_set(&mDBusError))
76 logError(
"DBusWrapper::DBusWrapper Error while getting the DBus");
77 dbus_error_free(&mDBusError);
79 if (NULL == mpDbusConnection)
81 logError(
"DBusWrapper::DBusWrapper DBus Connection is null");
85 logInfo(
"DBusWrapper::DBusWrapper DBus Connection is", mpDbusConnection);
90 dbus_connection_set_exit_on_disconnect(mpDbusConnection, FALSE);
99 logError(
"DBusWrapper::DBusWrapper Registering of watch functions failed");
106 logError(
"DBusWrapper::DBusWrapper Registering of timer functions failed");
109 if (prefix.empty() && objectPath.empty())
111 logInfo(
"DBusWrapper::DBusWrapper We don't register a connection object!");
116 mObjectPathVTable.message_function = CAmDbusWrapper::cbRootIntrospection;
117 dbus_connection_register_object_path(mpDbusConnection, objectPath.c_str(), &mObjectPathVTable,
this);
118 int ret = dbus_bus_request_name(mpDbusConnection, prefix.c_str(), DBUS_NAME_FLAG_DO_NOT_QUEUE, &mDBusError);
119 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER == ret)
121 logInfo(
"DBusWrapper::DBusWrapper We own", prefix);
125 std::ostringstream sserror(
"DBusWrapper::DBusWrapper ");
129 sserror <<
"Couldn't acquire name " << prefix <<
". DBus message: " << mDBusError.message;
130 dbus_error_free(&mDBusError);
132 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
133 sserror <<
"We are queued for " << prefix;
135 case DBUS_REQUEST_NAME_REPLY_EXISTS:
136 sserror <<
":-( " << prefix <<
" already exists!";
138 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
139 sserror <<
"Eh? We already own " << prefix;
142 sserror <<
"Unknown result = " << ret;
147 throw std::runtime_error(sserror.str().c_str());
154 logInfo(
"DBusWrapper::~DBusWrapper Closing DBus connection");
155 dbus_connection_unref(mpDbusConnection);
158 std::vector<sh_timerHandle_t*>::iterator it = mpListTimerhandles.begin();
159 for (; it != mpListTimerhandles.end(); ++it)
175 logInfo(
"DBusWrapper::registerCallback register callback:", path);
177 std::string completePath = prefix +
"/" + path;
178 dbus_error_init(&mDBusError);
179 dbus_connection_register_object_path(mpDbusConnection, completePath.c_str(), vtable, userdata);
180 if (dbus_error_is_set(&mDBusError))
182 logError(
"DBusWrapper::registerCallack error: ", mDBusError.message);
183 dbus_error_free(&mDBusError);
185 mListNodes.push_back(path);
196 logInfo(
"DBusWrapper::registerSignalWatch register callback:", rule);
197 dbus_error_init(&mDBusError);
198 dbus_bus_add_match(mpDbusConnection, rule.c_str(), &mDBusError);
199 dbus_connection_flush(mpDbusConnection);
200 dbus_connection_add_filter(mpDbusConnection, handler, userdata, 0);
202 if (dbus_error_is_set(&mDBusError))
204 logError(
"DBusWrapper::registerCallack error: ", mDBusError.message);
205 dbus_error_free(&mDBusError);
215 DBusHandlerResult CAmDbusWrapper::cbRootIntrospection(DBusConnection *conn, DBusMessage *msg,
void *reference)
220 std::vector<std::string> nodesList = mpReference->mListNodes;
222 DBusMessageIter args;
223 dbus_uint32_t serial = 0;
224 if (dbus_message_is_method_call(msg, DBUS_INTERFACE_INTROSPECTABLE,
"Introspect"))
226 std::vector<std::string>::iterator nodeIter = nodesList.begin();
228 std::stringstream introspect;
229 introspect << std::string(xml);
230 for (; nodeIter != nodesList.end(); ++nodeIter)
232 introspect <<
"<node name='" << nodeIter->c_str() <<
"'/>";
234 introspect <<
"</node>";
236 reply = dbus_message_new_method_return(msg);
237 std::string s = introspect.str();
238 const char*
string = s.c_str();
241 dbus_message_iter_init_append(reply, &args);
242 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &
string))
244 logError(
"DBusWrapper::~cbRootIntrospection DBUS Out Of Memory!");
248 if (!dbus_connection_send(conn, reply, &serial))
250 logError(
"DBusWrapper::~cbRootIntrospection DBUS Out Of Memory!");
252 dbus_connection_flush(conn);
254 dbus_message_unref(reply);
256 return (DBUS_HANDLER_RESULT_HANDLED);
260 return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
270 connection = mpDbusConnection;
276 assert(mpReference!=0);
277 return (mpReference->addWatchDelegate(watch, userData));
280 dbus_bool_t CAmDbusWrapper::addWatchDelegate(DBusWatch * watch,
void* userData)
285 uint flags = dbus_watch_get_flags(watch);
288 if (dbus_watch_get_enabled(watch))
290 if (flags & DBUS_WATCH_READABLE)
292 if (flags & DBUS_WATCH_WRITABLE)
295 logInfo(
"DBusWrapper::addWatchDelegate entered new watch, fd=", dbus_watch_get_unix_fd(watch),
"event flag=", event);
299 if (error ==
E_OK && handle != 0)
301 mMapHandleWatch.insert(std::make_pair(watch, handle));
304 logError(
"DBusWrapper::addWatchDelegate entering watch failed");
312 assert(mpReference!=0);
313 mpReference->removeWatchDelegate(watch, userData);
316 void CAmDbusWrapper::removeWatchDelegate(DBusWatch *watch,
void *userData)
319 std::map<DBusWatch*, sh_pollHandle_t>::iterator iterator = mMapHandleWatch.begin();
320 iterator = mMapHandleWatch.find(watch);
321 if (iterator != mMapHandleWatch.end())
324 logInfo(
"DBusWrapper::removeWatch removed watch with handle", iterator->second);
325 mMapHandleWatch.erase(iterator);
329 logError(
"DBusWrapper::removeWatch could not find handle !");
336 assert(mpReference!=0);
337 mpReference->toogleWatchDelegate(watch, userData);
340 void CAmDbusWrapper::toogleWatchDelegate(DBusWatch *watch,
void *userData)
344 dbus_watch_get_unix_fd(watch);
345 uint flags = dbus_watch_get_flags(watch);
347 if (dbus_watch_get_enabled(watch))
349 if (flags & DBUS_WATCH_READABLE)
351 if (flags & DBUS_WATCH_WRITABLE)
354 std::map<DBusWatch*, sh_pollHandle_t>::iterator iterator = mMapHandleWatch.begin();
355 iterator = mMapHandleWatch.find(watch);
356 if (iterator != mMapHandleWatch.end())
363 assert(mpReference!=0);
364 return (mpReference->addTimeoutDelegate(timeout, userData));
367 dbus_bool_t CAmDbusWrapper::addTimeoutDelegate(DBusTimeout *timeout,
void* userData)
371 if (!dbus_timeout_get_enabled(timeout))
375 timespec pollTimeout;
376 int localTimeout = dbus_timeout_get_interval(timeout);
377 pollTimeout.tv_sec = localTimeout / 1000;
378 pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000;
382 mpListTimerhandles.push_back(handle);
388 dbus_timeout_set_data(timeout, handle, NULL);
396 assert(mpReference!=0);
397 mpReference->removeTimeoutDelegate(timeout, userData);
400 void CAmDbusWrapper::removeTimeoutDelegate(DBusTimeout *timeout,
void* userData)
408 std::vector<sh_timerHandle_t*>::iterator it = mpListTimerhandles.begin();
409 for (; it != mpListTimerhandles.end(); ++it)
413 mpListTimerhandles.erase(it);
423 assert(mpReference!=0);
424 mpReference->toggleTimeoutDelegate(timeout, userData);
431 bool returnVal =
true;
432 dbus_connection_ref(mpDbusConnection);
433 if (dbus_connection_dispatch(mpDbusConnection) == DBUS_DISPATCH_COMPLETE)
435 dbus_connection_unref(mpDbusConnection);
444 bool returnVal =
false;
445 dbus_connection_ref(mpDbusConnection);
446 if (dbus_connection_get_dispatch_status(mpDbusConnection) == DBUS_DISPATCH_DATA_REMAINS)
448 dbus_connection_unref(mpDbusConnection);
457 assert(userData!=NULL);
460 if (pollfd.revents & POLLIN)
461 flags |= DBUS_WATCH_READABLE;
462 if (pollfd.revents & POLLOUT)
463 flags |= DBUS_WATCH_WRITABLE;
464 if (pollfd.revents & POLLHUP)
465 flags |= DBUS_WATCH_HANGUP;
466 if (pollfd.revents & POLLERR)
467 flags |= DBUS_WATCH_ERROR;
469 DBusWatch *watch = (DBusWatch*) userData;
471 dbus_connection_ref(mpDbusConnection);
472 dbus_watch_handle(watch, flags);
473 dbus_connection_unref(mpDbusConnection);
481 dbus_connection_ref(mpDbusConnection);
482 while (dbus_connection_get_dispatch_status(mpDbusConnection) == DBUS_DISPATCH_DATA_REMAINS)
484 dbus_connection_dispatch(mpDbusConnection);
487 dbus_connection_unref(mpDbusConnection);
490 void CAmDbusWrapper::toggleTimeoutDelegate(DBusTimeout *timeout,
void* userData)
497 if (dbus_timeout_get_enabled(timeout))
500 timespec pollTimeout;
501 int localTimeout = dbus_timeout_get_interval(timeout);
502 pollTimeout.tv_sec = localTimeout / 1000;
503 pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000;
504 mpSocketHandler->
updateTimer(*handle, pollTimeout);
514 assert(userData!=NULL);
515 for (
auto && timerHandle : mpListTimerhandles)
517 if (*timerHandle == handle)
519 if (dbus_timeout_get_enabled((DBusTimeout*) userData))
523 dbus_timeout_handle((DBusTimeout*) userData);
527 logWarning(
"CAmDbusWrapper::dbusTimerCallback Unknown timer handle");
void logWarning(T value, TArgs...args)
logs given values with warninglevel with the default context
void registerCallback(const DBusObjectPathVTable *vtable, const std::string &path, void *userdata, const std::string &prefix=DBUS_SERVICE_OBJECT_PATH)
registers a callback that is entered as path below the main path.
A Common-API wrapper class, which loads the common-api runtime and instantiates all necessary objects...
TAmShTimerCallBack< CAmDbusWrapper > pDbusTimerCallback
am_Error_e
the errors of the audiomanager.
void logInfo(T value, TArgs...args)
logs given values with infolevel with the default context
bool dbusDispatchCallback(const sh_pollHandle_t handle, void *userData)
am_Error_e restartTimer(const sh_timerHandle_t handle)
restarts a timer with the original value
void dbusTimerCallback(sh_timerHandle_t handle, void *userData)
TAmShPollFired< CAmDbusWrapper > pDbusFireCallback
The am::CAmSocketHandler implements a mainloop for the AudioManager.
static void toggleTimeout(DBusTimeout *timeout, void *userData)
TAmShPollPrepare< CAmDbusWrapper > pDbusPrepareCallback
uint16_t sh_pollHandle_t
this is a handle for a filedescriptor to be used with the SocketHandler
SPDX license identifier: MPL-2.0.
am_Error_e removeFDPoll(const sh_pollHandle_t handle)
removes a filedescriptor from the poll loop
am_Error_e removeTimer(const sh_timerHandle_t handle)
removes a timer from the list of timers
am_Error_e stopTimer(const sh_timerHandle_t handle)
stops a timer
static void toogleWatch(DBusWatch *watch, void *userData)
am_Error_e updateTimer(const sh_timerHandle_t handle, const timespec &timeouts)
restarts a timer and updates with a new interva
CAmDbusWrapper(CAmSocketHandler *socketHandler, DBusBusType type=DBUS_BUS_SESSION, const std::string &prefix=DBUS_SERVICE_PREFIX, const std::string &objectPath=DBUS_SERVICE_OBJECT_PATH)
am_Error_e updateEventFlags(const sh_pollHandle_t handle, const short events)
updates the eventFlags of a poll
void registerSignalWatch(DBusHandleMessageFunction handler, const std::string &rule, void *userdata)
register signal watch callback to matching rule
TAmShPollDispatch< CAmDbusWrapper > pDbusDispatchCallback
am_Error_e addFDPoll(const int fd, const short event, std::function< void(const sh_pollHandle_t handle, void *userData)> prepare, std::function< void(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)> fired, std::function< bool(const sh_pollHandle_t handle, void *userData)> check, std::function< bool(const sh_pollHandle_t handle, void *userData)> dispatch, void *userData, sh_pollHandle_t &handle)
Adds a filedescriptor to the polling loop.
SPDX license identifier: MPL-2.0.
#define ROOT_INTROSPECT_XML
introspectio header
bool dbusCheckCallback(const sh_pollHandle_t handle, void *userData)
void logError(T value, TArgs...args)
logs given values with errorlevel with the default context
virtual ~CAmDbusWrapper()
static void removeWatch(DBusWatch *watch, void *userData)
This wraps dbus and provides everything needed to anyone who wants to use dbus (including plugins)...
no error - positive reply
static dbus_bool_t addTimeout(DBusTimeout *timeout, void *userData)
static dbus_bool_t addWatch(DBusWatch *watch, void *userData)
void dbusFireCallback(const pollfd pollfd, const sh_pollHandle_t handle, void *userData)
static void removeTimeout(DBusTimeout *timeout, void *userData)
void getDBusConnection(DBusConnection *&connection) const
returns the dbus connection
SPDX license identifier: MPL-2.0.
TAmShPollCheck< CAmDbusWrapper > pDbusCheckCallback
void dbusPrepareCallback(const sh_pollHandle_t handle, void *userData)
sh_pollHandle_t sh_timerHandle_t
this is a handle for a timer to be used with the SocketHandler
am_Error_e addTimer(const timespec &timeouts, IAmShTimerCallBack *callback, sh_timerHandle_t &handle, void *userData, const bool __attribute__((__unused__)) repeats=false)