#include #include #include /* A convenience macro */ #define panic(fmt, args...) fprintf (stderr, fmt "\n", ## args) DBusConnection * register_service (const char *service_name, const char *service_path); int service_listen (DBusConnection *conn); DBusHandlerResult message_handler (DBusConnection *conn, DBusMessage *msg, void *user_data); void message_handler_unregister (DBusConnection *conn, void *user_data); int main (int argc, char **argv) { DBusConnection *conn; conn = register_service ("fi.imaami.service", // Service name "/fi/imaami/foobar"); // Object path name if (!conn) { return EXIT_FAILURE; } return service_listen (conn); } /** * Register a D-Bus service. */ DBusConnection * register_service (const char *service_name, const char *service_path) { DBusConnection *conn; DBusError error; DBusObjectPathVTable vtable; /* Initialize the error struct. */ dbus_error_init (&error); /* Register a client with the session bus. */ conn = dbus_bus_get (DBUS_BUS_SESSION, &error); if (dbus_error_is_set (&error)) { panic ("Couldn't register bus client: %s", error.message); dbus_error_free (&error); goto fail; } /* Register the given name for the client. */ if (dbus_bus_request_name (conn, service_name, DBUS_NAME_FLAG_DO_NOT_QUEUE, &error) != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { if (dbus_error_is_set (&error)) { panic ("Couldn't register service name \"%s\": %s", service_name, error.message); dbus_error_free (&error); } else { panic ("Couldn't register service name \"%s\"", service_name); } goto fail_unref; } /* Register the service's object path. */ vtable.unregister_function = message_handler_unregister; vtable.message_function = message_handler; if (!dbus_connection_register_object_path (conn, service_path, &vtable, NULL)) { panic ("Not enough memory to register object path \"%s\" for service \"%s\"", service_path, service_name); goto fail_unref; } return conn; fail_unref: dbus_connection_unref (conn); fail: return NULL; } /** * The D-Bus connection main loop. */ int service_listen (DBusConnection *conn) { /* The loop. */ while (dbus_connection_read_write_dispatch (conn, -1)); dbus_connection_unref (conn); return EXIT_SUCCESS; } /** * The object path's message handler callback function. */ DBusHandlerResult message_handler (DBusConnection *conn, DBusMessage *msg, void *user_data) { /* Get message properties. */ int type = dbus_message_get_type (msg); const char *path = dbus_message_get_path (msg); const char *interface = dbus_message_get_interface (msg); const char *member = dbus_message_get_member (msg); /* Check for NULL strings. */ if (!path) path = ""; if (!member) interface = ""; if (!member) member = ""; printf ("Got message:\n" "\t type == \"%s\"\n" "\t path == \"%s\"\n" "\tinterface == \"%s\"\n" "\t member == \"%s\"\n", dbus_message_type_to_string (type), path, interface, member); /* If the message is a method call and requires a reply * respond with a void method return. */ if (type == DBUS_MESSAGE_TYPE_METHOD_CALL && !dbus_message_get_no_reply (msg)) { DBusMessage *return_msg; return_msg = dbus_message_new_method_return (msg); if (!return_msg) { panic ("Ran out of memory constructing method return"); goto end; } else if (!dbus_connection_send (conn, return_msg, NULL)) { panic ("Ran out of memory sending method return"); } else { dbus_connection_flush (conn); } dbus_message_unref (return_msg); } end: return DBUS_HANDLER_RESULT_HANDLED; } /** * The object path unregister callback function. */ void message_handler_unregister (DBusConnection *conn, void *user_data) { printf ("Message handler unregistered\n"); }