31 #include <dbus/dbus.h> 45 : conn(c) , dispatcher(NULL), server(s)
50 Connection::Private::Private(DBusBusType
type)
51 : dispatcher(NULL), server(NULL)
55 conn = dbus_bus_get_private(type, e);
57 if (e)
throw Error(e);
62 Connection::Private::~Private()
64 debug_log(
"terminating connection 0x%08x", conn);
68 if (dbus_connection_get_is_connected(conn))
70 std::vector<std::string>::iterator i = names.begin();
72 while (i != names.end())
74 debug_log(
"%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str());
75 dbus_bus_release_name(conn, i->c_str(), NULL);
78 dbus_connection_close(conn);
80 dbus_connection_unref(conn);
83 void Connection::Private::init()
85 dbus_connection_ref(conn);
86 dbus_connection_ref(conn);
89 this, &Connection::Private::disconn_filter_function
92 dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL);
94 dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub,
this, 0);
95 dbus_connection_set_exit_on_disconnect(conn,
false);
96 dbus_connection_set_unix_user_function (conn, 0, 0, 0);
99 void Connection::Private::detach_server()
120 bool Connection::Private::do_dispatch()
124 if (!dbus_connection_get_is_connected(conn))
133 return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS;
136 void Connection::Private::dispatch_status_stub(DBusConnection *dc, DBusDispatchStatus status,
void *data)
138 Private *p =
static_cast<Private *
>(data);
142 case DBUS_DISPATCH_DATA_REMAINS:
143 debug_log(
"some dispatching to do on %p", dc);
144 p->dispatcher->queue_connection(p);
147 case DBUS_DISPATCH_COMPLETE:
148 debug_log(
"all dispatching done on %p", dc);
151 case DBUS_DISPATCH_NEED_MEMORY:
152 debug_log(
"connection %p needs memory", dc);
157 DBusHandlerResult Connection::Private::message_filter_stub(DBusConnection *conn, DBusMessage *dmsg,
void *data)
163 return slot && !slot->
empty() && slot->
call(msg)
164 ? DBUS_HANDLER_RESULT_HANDLED
165 : DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
168 bool Connection::Private::disconn_filter_function(
const Message &msg)
170 if (msg.
is_signal(DBUS_INTERFACE_LOCAL,
"Disconnected"))
172 debug_log(
"%p disconnected by local bus", conn);
173 dbus_connection_close(conn);
180 DBusDispatchStatus Connection::Private::dispatch_status()
182 return dbus_connection_get_dispatch_status(conn);
185 bool Connection::Private::has_something_to_dispatch()
187 return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
210 DBusConnection *conn = priv
211 ? dbus_connection_open_private(address, e)
212 : dbus_connection_open(address, e);
214 if (e)
throw Error(e);
232 dbus_connection_ref(
_pvt->conn);
237 dbus_connection_unref(
_pvt->conn);
242 debug_log(
"registering stubs for connection %p",
_pvt->conn);
246 if (!dispatcher)
throw ErrorFailed(
"no default dispatcher set for new connection");
254 dbus_connection_set_watch_functions(
256 Dispatcher::Private::on_add_watch,
257 Dispatcher::Private::on_rem_watch,
258 Dispatcher::Private::on_toggle_watch,
263 dbus_connection_set_timeout_functions(
265 Dispatcher::Private::on_add_timeout,
266 Dispatcher::Private::on_rem_timeout,
267 Dispatcher::Private::on_toggle_timeout,
284 bool r = dbus_bus_register(
_pvt->conn, e);
293 return dbus_connection_get_is_connected(
_pvt->conn);
299 dbus_connection_close(
_pvt->conn);
304 dbus_connection_set_exit_on_disconnect(
_pvt->conn, exit);
309 return dbus_bus_set_unique_name(
_pvt->conn, n);
314 return dbus_bus_get_unique_name(
_pvt->conn);
319 dbus_connection_flush(
_pvt->conn);
326 dbus_bus_add_match(
_pvt->conn, rule, e);
330 if (e)
throw Error(e);
338 dbus_bus_remove_match(
_pvt->conn, rule, e);
347 debug_log(
"DBus::Connection::remove_match: %s (%s).",
348 static_cast<DBusError *>(e)->message,
349 static_cast<DBusError *>(e)->name);
356 return dbus_connection_add_filter(
_pvt->conn, Private::message_filter_stub, &s, NULL);
362 dbus_connection_remove_filter(
_pvt->conn, Private::message_filter_stub, &s);
367 return dbus_connection_send(
_pvt->conn, msg.
_pvt->msg, serial);
377 reply = dbus_connection_send_with_reply_and_block(
_pvt->conn, msg.
_pvt->msg, this->_timeout, e);
381 reply = dbus_connection_send_with_reply_and_block(
_pvt->conn, msg.
_pvt->msg, timeout, e);
384 if (e)
throw Error(e);
391 DBusPendingCall *pending;
393 if (!dbus_connection_send_with_reply(
_pvt->conn, msg.
_pvt->msg, &pending, timeout))
411 int ret = dbus_bus_request_name(
_pvt->conn, name, flags, e);
415 if (e)
throw Error(e);
422 _pvt->names.push_back(name);
423 std::string match =
"destination='" +
_pvt->names.back() +
"'";
432 unsigned long ul = dbus_bus_get_unix_user(
_pvt->conn, sender, e);
434 if (e)
throw Error(e);
443 bool b = dbus_bus_name_has_owner(
_pvt->conn, name, e);
445 if (e)
throw Error(e);
459 bool b = dbus_bus_start_service_by_name(
_pvt->conn, name, flags, NULL, e);
461 if (e)
throw Error(e);
bool add_filter(MessageSlot &s)
Adds a message filter.
Message send_blocking(Message &msg, int timeout=-1)
Sends a message and blocks a certain time period while waiting for a reply.
DXXAPI Dispatcher * default_dispatcher
const char * unique_name() const
Gets the unique name of the connection as assigned by the message bus.
void add_match(const char *rule)
Adds a match rule to match messages going through the message bus.
bool operator==(const Connection &) const
bool has_name(const char *name)
Asks the bus whether a certain name has an owner.
DXXAPI LogFunction debug_log
void request_name(const char *name, int flags=0)
Dispatcher * setup(Dispatcher *)
static Connection SessionBus()
bool send(const Message &msg, unsigned int *serial=NULL)
Adds a message to the outgoing message queue.
bool is_signal(const char *interface, const char *member) const
bool register_bus()
Registers a connection with the bus.
void flush()
Blocks until the outgoing message queue is empty.
void queue_connection(Connection::Private *)
void remove_filter(MessageSlot &s)
Removes a previously-added message filter.
Private(DBusConnection *, Server::Private *=NULL)
PendingCall send_async(Message &msg, int timeout=-1)
Queues a message to send, as with send(), but also returns a DBusPendingCall used to receive a reply ...
unsigned long sender_unix_uid(const char *sender)
bool start_service(const char *name, unsigned long flags)
Starts a service that will request ownership of the given name.
void set_timeout(int timeout)
bool connected() const
Gets whether the connection is currently open.
void remove_match(const char *rule, bool throw_on_error)
Removes a previously-added match rule "by value" (the most recently-added identical rule gets removed...
static Connection ActivationBus()
const std::vector< std::string > & names()
void disconnect()
Closes a private connection, so no further data can be sent or received.
void exit_on_disconnect(bool exit)
Set whether _exit() should be called when the connection receives a disconnect signal.