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");
110 mObjectPathVTable.message_function = CAmDbusWrapper::cbRootIntrospection;
111 dbus_connection_register_object_path(mpDbusConnection, objectPath.c_str(), &mObjectPathVTable,
this);
112 int ret = dbus_bus_request_name(mpDbusConnection, prefix.c_str(), DBUS_NAME_FLAG_DO_NOT_QUEUE, &mDBusError);
113 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER == ret)
115 logInfo(
"DBusWrapper::DBusWrapper We own", prefix);
119 std::ostringstream sserror(
"DBusWrapper::DBusWrapper ");
123 sserror <<
"Couldn't acquire name " << prefix <<
". DBus message: " << mDBusError.message;
124 dbus_error_free(&mDBusError);
126 case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
127 sserror <<
"We are queued for " << prefix;
129 case DBUS_REQUEST_NAME_REPLY_EXISTS:
130 sserror <<
":-( " << prefix <<
" already exists!";
132 case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
133 sserror <<
"Eh? We already own " << prefix;
136 sserror <<
"Unknown result = " << ret;
141 throw std::runtime_error(sserror.str().c_str());
148 logInfo(
"DBusWrapper::~DBusWrapper Closing DBus connection");
149 dbus_connection_unref(mpDbusConnection);
152 std::vector<sh_timerHandle_t*>::iterator it = mpListTimerhandles.begin();
153 for (; it != mpListTimerhandles.end(); ++it)
169 logInfo(
"DBusWrapper::registerCallback register callback:", path);
171 std::string completePath = prefix +
"/" + path;
172 dbus_error_init(&mDBusError);
173 mpDbusConnection = dbus_bus_get(mDbusType, &mDBusError);
174 dbus_connection_register_object_path(mpDbusConnection, completePath.c_str(), vtable, userdata);
175 if (dbus_error_is_set(&mDBusError))
177 logError(
"DBusWrapper::registerCallack error: ", mDBusError.message);
178 dbus_error_free(&mDBusError);
180 mListNodes.push_back(path);
191 logInfo(
"DBusWrapper::registerSignalWatch register callback:", rule);
192 dbus_error_init(&mDBusError);
193 mpDbusConnection = dbus_bus_get(mDbusType, &mDBusError);
194 dbus_bus_add_match(mpDbusConnection, rule.c_str(), &mDBusError);
195 dbus_connection_flush(mpDbusConnection);
196 dbus_connection_add_filter(mpDbusConnection, handler, userdata, 0);
198 if (dbus_error_is_set(&mDBusError))
200 logError(
"DBusWrapper::registerCallack error: ", mDBusError.message);
201 dbus_error_free(&mDBusError);
211 DBusHandlerResult CAmDbusWrapper::cbRootIntrospection(DBusConnection *conn, DBusMessage *msg,
void *reference)
216 std::vector<std::string> nodesList = mpReference->mListNodes;
218 DBusMessageIter args;
219 dbus_uint32_t serial = 0;
220 if (dbus_message_is_method_call(msg, DBUS_INTERFACE_INTROSPECTABLE,
"Introspect"))
222 std::vector<std::string>::iterator nodeIter = nodesList.begin();
224 std::stringstream introspect;
225 introspect << std::string(xml);
226 for (; nodeIter != nodesList.end(); ++nodeIter)
228 introspect <<
"<node name='" << nodeIter->c_str() <<
"'/>";
230 introspect <<
"</node>";
232 reply = dbus_message_new_method_return(msg);
233 std::string s = introspect.str();
234 const char*
string = s.c_str();
237 dbus_message_iter_init_append(reply, &args);
238 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &
string))
240 logError(
"DBusWrapper::~cbRootIntrospection DBUS Out Of Memory!");
244 if (!dbus_connection_send(conn, reply, &serial))
246 logError(
"DBusWrapper::~cbRootIntrospection DBUS Out Of Memory!");
248 dbus_connection_flush(conn);
250 dbus_message_unref(reply);
252 return (DBUS_HANDLER_RESULT_HANDLED);
256 return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
266 connection = mpDbusConnection;
272 assert(mpReference!=0);
273 return (mpReference->addWatchDelegate(watch, userData));
276 dbus_bool_t CAmDbusWrapper::addWatchDelegate(DBusWatch * watch,
void* userData)
281 uint flags = dbus_watch_get_flags(watch);
284 if (dbus_watch_get_enabled(watch))
286 if (flags & DBUS_WATCH_READABLE)
288 if (flags & DBUS_WATCH_WRITABLE)
292 logInfo(
"DBusWrapper::addWatchDelegate entered new watch, fd=", dbus_watch_get_unix_fd(watch),
"event flag=", event);
296 if (error ==
E_OK && handle != 0)
298 mMapHandleWatch.insert(std::make_pair(watch, handle));
301 logError(
"DBusWrapper::addWatchDelegate entering watch failed");
308 assert(mpReference!=0);
309 mpReference->removeWatchDelegate(watch, userData);
312 void CAmDbusWrapper::removeWatchDelegate(DBusWatch *watch,
void *userData)
315 std::map<DBusWatch*, sh_pollHandle_t>::iterator iterator = mMapHandleWatch.begin();
316 iterator = mMapHandleWatch.find(watch);
317 if (iterator != mMapHandleWatch.end())
320 logInfo(
"DBusWrapper::removeWatch removed watch with handle", iterator->second);
321 mMapHandleWatch.erase(iterator);
325 logError(
"DBusWrapper::removeWatch could not find handle !");
332 assert(mpReference!=0);
333 mpReference->toogleWatchDelegate(watch, userData);
336 void CAmDbusWrapper::toogleWatchDelegate(DBusWatch *watch,
void *userData)
340 dbus_watch_get_unix_fd(watch);
341 uint flags = dbus_watch_get_flags(watch);
343 if (dbus_watch_get_enabled(watch))
345 if (flags & DBUS_WATCH_READABLE)
347 if (flags & DBUS_WATCH_WRITABLE)
350 std::map<DBusWatch*, sh_pollHandle_t>::iterator iterator = mMapHandleWatch.begin();
351 iterator = mMapHandleWatch.find(watch);
352 if (iterator != mMapHandleWatch.end())
359 assert(mpReference!=0);
360 return (mpReference->addTimeoutDelegate(timeout, userData));
363 dbus_bool_t CAmDbusWrapper::addTimeoutDelegate(DBusTimeout *timeout,
void* userData)
367 if (!dbus_timeout_get_enabled(timeout))
371 timespec pollTimeout;
372 int localTimeout = dbus_timeout_get_interval(timeout);
373 pollTimeout.tv_sec = localTimeout / 1000;
374 pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000;
378 mpListTimerhandles.push_back(handle);
384 dbus_timeout_set_data(timeout, handle, NULL);
394 assert(mpReference!=0);
395 mpReference->removeTimeoutDelegate(timeout, userData);
398 void CAmDbusWrapper::removeTimeoutDelegate(DBusTimeout *timeout,
void* userData)
406 std::vector<sh_timerHandle_t*>::iterator it = mpListTimerhandles.begin();
407 for (; it != mpListTimerhandles.end(); ++it)
411 mpListTimerhandles.erase(it);
421 assert(mpReference!=0);
422 mpReference->toggleTimeoutDelegate(timeout, userData);
429 bool returnVal =
true;
430 dbus_connection_ref(mpDbusConnection);
431 if (dbus_connection_dispatch(mpDbusConnection) == DBUS_DISPATCH_COMPLETE)
433 dbus_connection_unref(mpDbusConnection);
442 bool returnVal =
false;
443 dbus_connection_ref(mpDbusConnection);
444 if (dbus_connection_get_dispatch_status(mpDbusConnection) == DBUS_DISPATCH_DATA_REMAINS)
446 dbus_connection_unref(mpDbusConnection);
455 assert(userData!=NULL);
458 if (pollfd.revents & POLLIN)
459 flags |= DBUS_WATCH_READABLE;
460 if (pollfd.revents & POLLOUT)
461 flags |= DBUS_WATCH_WRITABLE;
462 if (pollfd.revents & POLLHUP)
463 flags |= DBUS_WATCH_HANGUP;
464 if (pollfd.revents & POLLERR)
465 flags |= DBUS_WATCH_ERROR;
467 DBusWatch *watch = (DBusWatch*) userData;
469 dbus_connection_ref(mpDbusConnection);
470 dbus_watch_handle(watch, flags);
471 dbus_connection_unref(mpDbusConnection);
479 dbus_connection_ref(mpDbusConnection);
480 while (dbus_connection_get_dispatch_status(mpDbusConnection) == DBUS_DISPATCH_DATA_REMAINS)
482 dbus_connection_dispatch(mpDbusConnection);
485 dbus_connection_unref(mpDbusConnection);
488 void CAmDbusWrapper::toggleTimeoutDelegate(DBusTimeout *timeout,
void* userData)
495 if (dbus_timeout_get_enabled(timeout))
498 timespec pollTimeout;
499 int localTimeout = dbus_timeout_get_interval(timeout);
500 pollTimeout.tv_sec = localTimeout / 1000;
501 pollTimeout.tv_nsec = (localTimeout % 1000) * 1000000;
502 mpSocketHandler->
updateTimer(*handle, pollTimeout);
512 assert(userData!=NULL);
513 if (dbus_timeout_get_enabled((DBusTimeout*) userData))
517 dbus_timeout_handle((DBusTimeout*) userData);
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.
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
am_Error_e addTimer(const timespec timeouts, IAmShTimerCallBack *callback, sh_timerHandle_t &handle, void *userData)
adds a timer to the list of timers.
SPDX license identifier: MPL-2.0.
am_Error_e removeFDPoll(const sh_pollHandle_t handle)
removes a filedescriptor from the poll loop
uint16_t sh_timerHandle_t
this is a handle for a timer to be used with the SocketHandler
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
am_Error_e addFDPoll(const int fd, const short event, IAmShPollPrepare *prepare, IAmShPollFired *fired, IAmShPollCheck *check, IAmShPollDispatch *dispatch, void *userData, sh_pollHandle_t &handle)
Adds a filedescriptor to the polling loop.
static void toogleWatch(DBusWatch *watch, void *userData)
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 updateTimer(const sh_timerHandle_t handle, const timespec timeouts)
restarts a timer and updates with a new interva
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)