diff options
-rw-r--r-- | input/Makefile.am | 2 | ||||
-rw-r--r-- | input/input-service.c | 172 | ||||
-rw-r--r-- | input/input-service.h | 29 | ||||
-rw-r--r-- | input/main.c | 69 |
4 files changed, 271 insertions, 1 deletions
diff --git a/input/Makefile.am b/input/Makefile.am index c684432d..c23df9ba 100644 --- a/input/Makefile.am +++ b/input/Makefile.am @@ -1,7 +1,7 @@ noinst_PROGRAMS = bt.inputd -bt_inputd_SOURCES = main.c +bt_inputd_SOURCES = main.c input-service.h input-service.c bt_inputd_LDADD = @DBUS_LIBS@ @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a diff --git a/input/input-service.c b/input/input-service.c new file mode 100644 index 00000000..b036bf70 --- /dev/null +++ b/input/input-service.c @@ -0,0 +1,172 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2006 Marcel Holtmann <marcel@holtmann.org> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <signal.h> + +#include "dbus.h" +#include "logging.h" + +#include <dbus/dbus.h> + +#define INPUT_PATH "/org/bluez/input" + +static DBusConnection *connection = NULL; + +static DBusHandlerResult start_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + + info("Starting example service"); + + reply = dbus_message_new_method_return(msg); + if (!reply) { + error("Can't create reply message"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult stop_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + + info("Stopping example service"); + + reply = dbus_message_new_method_return(msg); + if (!reply) { + error("Can't create reply message"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult release_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + + reply = dbus_message_new_method_return(msg); + if (!reply) { + error("Can't create reply message"); + return DBUS_HANDLER_RESULT_NEED_MEMORY; + } + + dbus_connection_send(conn, reply, NULL); + + dbus_message_unref(reply); + + info("Got Release method. Exiting."); + + raise(SIGTERM); + + return DBUS_HANDLER_RESULT_HANDLED; +} + + +static DBusHandlerResult input_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + if (dbus_message_is_method_call(msg, "org.bluez.ServiceAgent", "Start")) + return start_message(conn, msg, data); + + if (dbus_message_is_method_call(msg, "org.bluez.ServiceAgent", "Stop")) + return stop_message(conn, msg, data); + + if (dbus_message_is_method_call(msg, "org.bluez.ServiceAgent", "Release")) + return release_message(conn, msg, data); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + + +static const DBusObjectPathVTable input_table = { + .message_function = input_message, +}; + +int input_dbus_init(void) +{ + DBusError err; + DBusMessage *msg, *reply; + const char *name = "Input service"; + const char *description = "A service for input devices"; + const char *input_path = INPUT_PATH; + + connection = init_dbus(NULL, NULL); + if (!connection) + return -1; + + dbus_error_init(&err); + + if (!dbus_connection_register_object_path(connection, input_path, + &input_table, NULL)) { + error("D-Bus failed to register %s path", INPUT_PATH); + return -1; + } + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Manager", "RegisterService"); + if (!msg) { + error("Can't allocate new method call"); + return -1; + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &input_path, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &description, + DBUS_TYPE_INVALID); + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, + &err); + + dbus_message_unref(msg); + + if (!reply) { + error("Can't register service agent"); + if (dbus_error_is_set(&err)) { + error("%s", err.message); + dbus_error_free(&err); + } + return -1; + } + + return 0; +} + diff --git a/input/input-service.h b/input/input-service.h new file mode 100644 index 00000000..6cc0b413 --- /dev/null +++ b/input/input-service.h @@ -0,0 +1,29 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2006 Marcel Holtmann <marcel@holtmann.org> + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef __INPUT_SERVICE_H +#define __INPUT_SERVICE_H + +int input_dbus_init(void); + +#endif /* __INPUT_SERVICE_H */ diff --git a/input/main.c b/input/main.c index c04bb251..df3b5160 100644 --- a/input/main.c +++ b/input/main.c @@ -26,9 +26,78 @@ #endif #include <stdio.h> +#include <unistd.h> +#include <string.h> #include <errno.h> +#include <signal.h> +#include <getopt.h> +#include <dbus/dbus.h> + +#include "dbus.h" +#include "logging.h" +#include "glib-ectomy.h" + +#include "input-service.h" + +static GMainLoop *main_loop; + +static void usage(void) +{ + printf("bt.inputd - Bluetooth Input daemon ver %s\n", VERSION); + printf("Usage: \n"); + printf("\tbt.inputd [-n not_daemon]\n"); +} + +static void sig_term(int sig) +{ + g_main_quit(main_loop); +} int main(int argc, char *argv[]) { + struct sigaction sa; + int opt, daemonize = 1; + + while ((opt = getopt(argc, argv, "n")) != EOF) { + switch (opt) { + case 'n': + daemonize = 0; + break; + + default: + usage(); + exit(1); + } + } + + if (daemonize && daemon(0, 0)) { + error("Can't daemonize: %s (%d)", strerror(errno), errno); + exit(1); + } + + start_logging("bt.inputd", "Bluetooth Input daemon"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + enable_debug(); + + /* Create event loop */ + main_loop = g_main_new(FALSE); + + if (input_dbus_init() < 0) { + error("Unable to get on D-Bus"); + exit(1); + } + + g_main_run(main_loop); + return 0; } |