/* * Copyright (C) 2011 Intel Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #include "gdbus-cxx-bridge.h" #include #include void intrusive_ptr_add_ref(DBusConnection *con) { dbus_connection_ref(con); } void intrusive_ptr_release(DBusConnection *con) { dbus_connection_unref(con); } void intrusive_ptr_add_ref(DBusMessage *msg) { dbus_message_ref(msg); } void intrusive_ptr_release(DBusMessage *msg) { dbus_message_unref(msg); } void intrusive_ptr_add_ref(DBusPendingCall *call) { dbus_pending_call_ref (call); } void intrusive_ptr_release(DBusPendingCall *call) { dbus_pending_call_unref (call); } namespace GDBusCXX { DBusConnectionPtr dbus_get_bus_connection(const char *busType, const char *name, bool unshared, DBusErrorCXX *err) { return DBusConnectionPtr(b_dbus_setup_bus(boost::iequals(busType, "SYSTEM") ? DBUS_BUS_SYSTEM : DBUS_BUS_SESSION, name, unshared, err), false); } static void ConnectionLost(DBusConnection *connection, void *user_data) { DBusConnectionPtr::Disconnect_t *cb = static_cast(user_data); (*cb)(); } static void DestroyDisconnect(void *user_data) { DBusConnectionPtr::Disconnect_t *cb = static_cast(user_data); delete cb; } void DBusConnectionPtr::setDisconnect(const Disconnect_t &func) { b_dbus_set_disconnect_function(get(), ConnectionLost, new Disconnect_t(func), DestroyDisconnect); } DBusConnectionPtr dbus_get_bus_connection(const std::string &address, DBusErrorCXX *err) { DBusConnectionPtr conn(dbus_connection_open_private(address.c_str(), err), false); if (conn) { b_dbus_setup_connection(conn.get(), TRUE, NULL); dbus_connection_set_exit_on_disconnect(conn.get(), FALSE); } return conn; } void dbus_bus_connection_undelay(const DBusConnectionPtr &/*ptr*/) { // no op } boost::shared_ptr DBusServerCXX::listen(const NewConnection_t &newConnection, DBusErrorCXX *err) { DBusServer *server = NULL; char address[80]; address[0] = 0; for (int counter = 1; counter < 100 && !server; counter++) { if (*err) { g_debug("dbus_server_listen(%s) failed, trying next candidate: %s", address, err->message); dbus_error_init(err); } sprintf(address, "unix:abstract=gdbuscxx-%d", counter); server = dbus_server_listen(address, err); } if (!server) { return boost::shared_ptr(); } b_dbus_setup_server(server); boost::shared_ptr res(new DBusServerCXX(server, address)); res->m_newConnection = newConnection; dbus_server_set_new_connection_function(server, DBusServerCXX::newConnection, res.get(), NULL); return res; } void DBusServerCXX::newConnection(DBusServer *server, DBusConnection *newConn, void *data) throw() { DBusServerCXX *me = static_cast(data); if (me->m_newConnection) { try { b_dbus_setup_connection(newConn, FALSE, NULL); dbus_connection_set_exit_on_disconnect(newConn, FALSE); DBusConnectionPtr conn(newConn); me->m_newConnection(*me, conn); } catch (...) { g_error("handling new D-Bus connection failed with C++ exception"); } } } DBusServerCXX::DBusServerCXX(DBusServer *server, const std::string &address) : m_server(server), m_address(address) { } DBusServerCXX::~DBusServerCXX() { if (m_server) { dbus_server_disconnect(m_server.get()); } } bool CheckError(const DBusMessagePtr &reply, std::string &buffer) { const char* errname = dbus_message_get_error_name (reply.get()); if (errname) { buffer = errname; DBusMessageIter iter; if (dbus_message_iter_init(reply.get(), &iter)) { if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) { buffer += ": "; const char *str; dbus_message_iter_get_basic(&iter, &str); buffer += str; } } return true; } else { return false; } } }