diff options
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | modules/Makefile.am | 5 | ||||
-rw-r--r-- | modules/connman/Makefile.am | 22 | ||||
-rw-r--r-- | modules/connman/evolution-connman.c | 204 |
4 files changed, 244 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 7e88758f1e..3b427e0805 100644 --- a/configure.ac +++ b/configure.ac @@ -1139,10 +1139,21 @@ if test "$enable_nm" = yes; then AC_SUBST(HAVE_NM) AC_SUBST(NM_CFLAGS) fi - AM_CONDITIONAL([ENABLE_NETWORK_MANAGER], [test "$enable_nm" = yes]) dnl ****************************** +dnl Enable ConnMan support ? +dnl ****************************** +AC_ARG_ENABLE([connman], + [AS_HELP_STRING([--enable-connman], + [enable ConnMan support (default=no)])], + [enable_connman=$enableval],[enable_connman=no]) +if test "x$enable_nm$enable_connman" = "xyesyes"; then + AC_MSG_ERROR([It is not possible to enable both ConnMan and NetworkManager]) +fi +AM_CONDITIONAL([ENABLE_CONNMAN], [test "$enable_connman" = yes]) + +dnl ****************************** dnl Camel Flags dnl ****************************** EVO_SET_COMPILE_FLAGS(CAMEL, camel-provider-1.2, $MANUAL_NSS_CFLAGS, $MOXILLA_NSS_CFLAGS) @@ -1690,6 +1701,7 @@ modules/addressbook/Makefile modules/calendar/Makefile modules/mail/Makefile modules/network-manager/Makefile +modules/connman/Makefile modules/plugin-lib/Makefile modules/plugin-mono/Makefile modules/plugin-python/Makefile diff --git a/modules/Makefile.am b/modules/Makefile.am index 0b6ccf22ec..c38f26b24a 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -10,6 +10,10 @@ if ENABLE_NETWORK_MANAGER NETWORK_MANAGER_DIR = network-manager endif +if ENABLE_CONNMAN +CONNMAN_DIR = connman +endif + SUBDIRS = \ addressbook \ calendar \ @@ -18,5 +22,6 @@ SUBDIRS = \ $(MONO_DIR) \ $(PYTHON_DIR) \ $(NETWORK_MANAGER_DIR) + $(CONNMAN_DIR) -include $(top_srcdir)/git.mk diff --git a/modules/connman/Makefile.am b/modules/connman/Makefile.am new file mode 100644 index 0000000000..63822262c4 --- /dev/null +++ b/modules/connman/Makefile.am @@ -0,0 +1,22 @@ +module_LTLIBRARIES = libevolution-module-connman.la + +libevolution_module_connman_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -DG_LOG_DOMAIN=\"evolution-connman\" \ + $(GNOME_PLATFORM_CFLAGS) \ + $(DBUS_GLIB_CFLAGS) + +libevolution_module_connman_la_SOURCES = \ + evolution-connman.c + +libevolution_module_connman_la_LIBADD = \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/shell/libeshell.la \ + $(GNOME_PLATFORM_LIBS) \ + $(DBUS_GLIB_LIBS) + +libevolution_module_connman_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) + +-include $(top_srcdir)/git.mk diff --git a/modules/connman/evolution-connman.c b/modules/connman/evolution-connman.c new file mode 100644 index 0000000000..c55d09c54a --- /dev/null +++ b/modules/connman/evolution-connman.c @@ -0,0 +1,204 @@ +/* + * evolution-connman.c + * + * This program 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 of the License, or (at your option) version 3. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + */ + +#include <dbus/dbus.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include <shell/e-shell.h> +#include <e-util/e-extension.h> + +#define CM_DBUS_SERVICE "org.moblin.connman" +#define CM_DBUS_INTERFACE "org.moblin.connman.Manager" +#define CM_DBUS_PATH "/" + +/* Standard GObject macros */ +#define E_TYPE_CONNMAN \ + (e_connman_get_type ()) +#define E_CONNMAN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CONNMAN, EConnMan)) + +typedef struct { + EExtension parent; + DBusConnection *connection; +} EConnMan; +typedef EExtensionClass EConnManClass; + +/* Module Entry Points */ +void e_module_load (GTypeModule *type_module); +void e_module_unload (GTypeModule *type_module); + +/* Forward Declarations */ +GType e_connman_get_type (void); +static gboolean network_manager_connect (EConnMan *extension); + +G_DEFINE_DYNAMIC_TYPE (EConnMan, e_connman, E_TYPE_EXTENSION) + +static void +extension_set_state (EConnMan *extension, const char *state) +{ + EExtensible *extensible; + + extensible = e_extension_get_extensible (E_EXTENSION (extension)); + g_return_if_fail (E_IS_SHELL (extensible)); + + e_shell_set_network_available (E_SHELL (extensible), !g_strcmp0 (state, "online")); +} + +static DBusHandlerResult +connman_monitor (DBusConnection *connection G_GNUC_UNUSED, + DBusMessage *message, + gpointer user_data) +{ + char *value; + EConnMan *extension = user_data; + DBusError error = DBUS_ERROR_INIT; + DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (!dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &value, + DBUS_TYPE_INVALID)) + goto err_exit; + + extension_set_state (extension, value); + ret = DBUS_HANDLER_RESULT_HANDLED; + + err_exit: + return ret; +} + +static void +connman_check_initial_state (EConnMan *extension) +{ + DBusMessage *message = NULL; + DBusMessage *response = NULL; + DBusError error = DBUS_ERROR_INIT; + + message = dbus_message_new_method_call ( + CM_DBUS_SERVICE, CM_DBUS_PATH, CM_DBUS_INTERFACE, "GetState"); + + /* XXX Assuming this should be safe to call synchronously. */ + response = dbus_connection_send_with_reply_and_block ( + extension->connection, message, 100, &error); + + if (response != NULL) { + const char *value; + if (dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &value, + DBUS_TYPE_INVALID)) + extension_set_state (extension, value); + } else { + g_warning ("%s", error.message); + dbus_error_free (&error); + return; + } + + dbus_message_unref (message); + dbus_message_unref (response); +} + +static gboolean +network_manager_connect (EConnMan *extension) +{ + DBusError error = DBUS_ERROR_INIT; + + /* This is a timeout callback, so the return value denotes + * whether to reschedule, not whether we're successful. */ + + if (extension->connection != NULL) + return FALSE; + + extension->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (extension->connection == NULL) { + g_warning ("%s", error.message); + dbus_error_free (&error); + return TRUE; + } + + dbus_connection_setup_with_g_main (extension->connection, NULL); + dbus_connection_set_exit_on_disconnect (extension->connection, FALSE); + + if (!dbus_connection_add_filter ( + extension->connection, connman_monitor, extension, NULL)) + goto fail; + + dbus_bus_add_match ( + extension->connection, + "type='signal'," + "interface='" CM_DBUS_INTERFACE "'," + "sender='" CM_DBUS_SERVICE "'," + "member='StateChanged'," + "path='" CM_DBUS_PATH "'", + &error); + if (dbus_error_is_set (&error)) { + g_warning ("%s", error.message); + dbus_error_free (&error); + goto fail; + } + + connman_check_initial_state (extension); + + return FALSE; + +fail: + dbus_connection_unref (extension->connection); + extension->connection = NULL; + + return TRUE; +} + +static void +network_manager_constructed (GObject *object) +{ + network_manager_connect (E_CONNMAN (object)); +} + +static void +e_connman_class_init (EConnManClass *class) +{ + GObjectClass *object_class; + EExtensionClass *extension_class; + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = network_manager_constructed; + + extension_class = E_EXTENSION_CLASS (class); + extension_class->extensible_type = E_TYPE_SHELL; +} + +static void +e_connman_class_finalize (EConnManClass *class) +{ +} + +static void +e_connman_init (EConnMan *extension) +{ +} + +G_MODULE_EXPORT void +e_module_load (GTypeModule *type_module) +{ + e_connman_register_type (type_module); +} + +G_MODULE_EXPORT void +e_module_unload (GTypeModule *type_module) +{ +} |