From bd8ebf3d0f7ac7bb8a3b441de24fd5eff3404acc Mon Sep 17 00:00:00 2001 From: Daniel Wagner Date: Wed, 4 Jan 2012 18:10:52 +0100 Subject: [PATCH] dundee: Add skeleton implementation --- Makefile.am | 12 +++ bootstrap-configure | 1 + configure.ac | 4 + dundee/dundee.h | 46 ++++++++ dundee/main.c | 255 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 318 insertions(+) create mode 100644 dundee/dundee.h create mode 100644 dundee/main.c diff --git a/Makefile.am b/Makefile.am index 869bd2b8..99254358 100644 --- a/Makefile.am +++ b/Makefile.am @@ -683,6 +683,18 @@ tools_lookup_provider_name_SOURCES = plugins/mbpi.c plugins/mbpi.h \ tools_lookup_provider_name_LDADD = @GLIB_LIBS@ endif +if DUNDEE + +sbin_PROGRAMS += dundee/dundee + +dundee_dundee_SOURCES = $(gdbus_sources) \ + src/log.c src/dbus.c \ + dundee/dundee.h dundee/main.c + +dundee_dundee_LDADD = $(builtin_libadd) @GLIB_LIBS@ @DBUS_LIBS@ @CAPNG_LIBS@ -ldl + +endif + noinst_PROGRAMS += gatchat/gsmdial gatchat/test-server gatchat/test-qcdm gatchat_gsmdial_SOURCES = gatchat/gsmdial.c $(gatchat_sources) diff --git a/bootstrap-configure b/bootstrap-configure index db70c665..1fae158b 100755 --- a/bootstrap-configure +++ b/bootstrap-configure @@ -14,4 +14,5 @@ fi --localstatedir=/var \ --enable-capng \ --enable-tools \ + --enable-dundee \ --disable-datafiles $* diff --git a/configure.ac b/configure.ac index 9f77a3ca..0377298d 100644 --- a/configure.ac +++ b/configure.ac @@ -152,6 +152,10 @@ if (test "${enable_tools}" = "yes"); then fi AM_CONDITIONAL(TOOLS, test "${enable_tools}" = "yes") +AC_ARG_ENABLE(dundee, AC_HELP_STRING([--enable-dundee], + [enable DUN deamon support]), [enable_dundee=${enableval}]) +AM_CONDITIONAL(DUNDEE, test "${enable_dundee}" = "yes") + AC_ARG_ENABLE(atmodem, AC_HELP_STRING([--disable-atmodem], [disable ETSI AT modem support]), [enable_atmodem=${enableval}]) diff --git a/dundee/dundee.h b/dundee/dundee.h new file mode 100644 index 00000000..c4c98002 --- /dev/null +++ b/dundee/dundee.h @@ -0,0 +1,46 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2012 Intel Corporation. All rights reserved. + * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 + * + */ + +#include + +#define OFONO_API_SUBJECT_TO_CHANGE + +#include + +void __dundee_exit(void); + +#include + +int __ofono_log_init(const char *program, const char *debug, + ofono_bool_t detach); +void __ofono_log_cleanup(void); +void __ofono_log_enable(struct ofono_debug_desc *start, + struct ofono_debug_desc *stop); + +#include + +#define DUNDEE_SERVICE "org.ofono.dundee" + +int __ofono_dbus_init(DBusConnection *conn); +void __ofono_dbus_cleanup(void); + +void __ofono_dbus_pending_reply(DBusMessage **msg, DBusMessage *reply); diff --git a/dundee/main.c b/dundee/main.c new file mode 100644 index 00000000..95ee7957 --- /dev/null +++ b/dundee/main.c @@ -0,0 +1,255 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2012 Intel Corporation. All rights reserved. + * Copyright (C) 2012 BMW Car IT GmbH. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_CAPNG +#include +#endif + +#include "dundee.h" + +#define SHUTDOWN_GRACE_SECONDS 10 + +static GMainLoop *event_loop; + +void __dundee_exit(void) +{ + g_main_loop_quit(event_loop); +} + +static gboolean quit_eventloop(gpointer user_data) +{ + __dundee_exit(); + return FALSE; +} + +static unsigned int __terminated = 0; + +static gboolean signal_handler(GIOChannel *channel, GIOCondition cond, + gpointer user_data) +{ + struct signalfd_siginfo si; + ssize_t result; + int fd; + + if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) + return FALSE; + + fd = g_io_channel_unix_get_fd(channel); + + result = read(fd, &si, sizeof(si)); + if (result != sizeof(si)) + return FALSE; + + switch (si.ssi_signo) { + case SIGINT: + case SIGTERM: + if (__terminated == 0) { + ofono_info("Terminating"); + g_timeout_add_seconds(SHUTDOWN_GRACE_SECONDS, + quit_eventloop, NULL); + + quit_eventloop(NULL); + } + + __terminated = 1; + break; + } + + return TRUE; +} + +static guint setup_signalfd(void) +{ + GIOChannel *channel; + guint source; + sigset_t mask; + int fd; + + sigemptyset(&mask); + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + + if (sigprocmask(SIG_BLOCK, &mask, NULL) < 0) { + perror("Failed to set signal mask"); + return 0; + } + + fd = signalfd(-1, &mask, 0); + if (fd < 0) { + perror("Failed to create signal descriptor"); + return 0; + } + + channel = g_io_channel_unix_new(fd); + + g_io_channel_set_close_on_unref(channel, TRUE); + g_io_channel_set_encoding(channel, NULL, NULL); + g_io_channel_set_buffered(channel, FALSE); + + source = g_io_add_watch(channel, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + signal_handler, NULL); + + g_io_channel_unref(channel); + + return source; +} + +static void system_bus_disconnected(DBusConnection *conn, void *user_data) +{ + ofono_error("System bus has disconnected!"); + + g_main_loop_quit(event_loop); +} + +static gchar *option_debug = NULL; +static gboolean option_detach = TRUE; +static gboolean option_version = FALSE; + +static gboolean parse_debug(const char *key, const char *value, + gpointer user_data, GError **error) +{ + if (value) + option_debug = g_strdup(value); + else + option_debug = g_strdup("*"); + + return TRUE; +} + +static GOptionEntry options[] = { + { "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG, + G_OPTION_ARG_CALLBACK, parse_debug, + "Specify debug options to enable", "DEBUG" }, + { "nodetach", 'n', G_OPTION_FLAG_REVERSE, + G_OPTION_ARG_NONE, &option_detach, + "Don't run as daemon in background" }, + { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version, + "Show version information and exit" }, + { NULL }, +}; + +int main(int argc, char **argv) +{ + GOptionContext *context; + GError *err = NULL; + DBusConnection *conn; + DBusError error; + guint signal; + +#ifdef HAVE_CAPNG + /* Drop capabilities */ + capng_clear(CAPNG_SELECT_BOTH); + capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, + CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, + CAP_NET_RAW, CAP_SYS_ADMIN, -1); + capng_apply(CAPNG_SELECT_BOTH); +#endif + + context = g_option_context_new(NULL); + g_option_context_add_main_entries(context, options, NULL); + + if (g_option_context_parse(context, &argc, &argv, &err) == FALSE) { + if (err != NULL) { + g_printerr("%s\n", err->message); + g_error_free(err); + return 1; + } + + g_printerr("An unknown error occurred\n"); + return 1; + } + + g_option_context_free(context); + + if (option_version == TRUE) { + printf("%s\n", VERSION); + exit(0); + } + + if (option_detach == TRUE) { + if (daemon(0, 0)) { + perror("Can't start daemon"); + return 1; + } + } + + event_loop = g_main_loop_new(NULL, FALSE); + + signal = setup_signalfd(); + + __ofono_log_init(argv[0], option_debug, option_detach); + + dbus_error_init(&error); + + conn = g_dbus_setup_bus(DBUS_BUS_SYSTEM, DUNDEE_SERVICE, &error); + if (conn == NULL) { + if (dbus_error_is_set(&error) == TRUE) { + ofono_error("Unable to hop onto D-Bus: %s", + error.message); + dbus_error_free(&error); + } else { + ofono_error("Unable to hop onto D-Bus"); + } + + goto cleanup; + } + + g_dbus_set_disconnect_function(conn, system_bus_disconnected, + NULL, NULL); + + __ofono_dbus_init(conn); + + /* + * The reason why this DBG is here is that we have the __stop__debug, + * __start__debug linking symbols in the object. As soon we + * have real DBG we can remove this one again. + */ + DBG(""); + + g_main_loop_run(event_loop); + + __ofono_dbus_cleanup(); + dbus_connection_unref(conn); + +cleanup: + g_source_remove(signal); + + g_main_loop_unref(event_loop); + + __ofono_log_cleanup(); + + return 0; +}