summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeeshan Ali (Khattak) <zeeshanak@gnome.org>2014-06-21 17:17:24 +0100
committerZeeshan Ali (Khattak) <zeeshanak@gnome.org>2014-06-21 17:17:24 +0100
commitc84a0972058de25e2a4eb987458f31317bcf47a6 (patch)
tree4dd0ac4ce348a5b5df42eb59ac22d852e85b96c6
parentb3102efe8144f4608372dd9246f39b91c24bf3bd (diff)
Split-out ModemManager code
GClueModem is not an interface and the new GClueModemManager class now implements this interface using ModemManager. This is pretty useless on its own right now but its intended to make it easy to add alternative Modem source(s), e.g ofono-based.
-rw-r--r--src/Makefile.am5
-rw-r--r--src/gclue-3g.c4
-rw-r--r--src/gclue-modem-gps.c4
-rw-r--r--src/gclue-modem-manager.c725
-rw-r--r--src/gclue-modem-manager.h68
-rw-r--r--src/gclue-modem.c666
-rw-r--r--src/gclue-modem.h97
7 files changed, 930 insertions, 639 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index fd5016b..f542d8f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -95,7 +95,10 @@ libgeoclue_la_SOURCES = \
$(NULL)
if BUILD_MODEM_SOURCE
-libgeoclue_la_SOURCES += gclue-modem.c gclue-modem.h
+libgeoclue_la_SOURCES += gclue-modem.c \
+ gclue-modem.h \
+ gclue-modem-manager.c \
+ gclue-modem-manager.h
endif
if BUILD_3G_SOURCE
diff --git a/src/gclue-3g.c b/src/gclue-3g.c
index 3292fbe..7ab1a8d 100644
--- a/src/gclue-3g.c
+++ b/src/gclue-3g.c
@@ -24,7 +24,7 @@
#include <libsoup/soup.h>
#include <string.h>
#include "gclue-3g.h"
-#include "gclue-modem.h"
+#include "gclue-modem-manager.h"
#include "geocode-glib/geocode-location.h"
#include "gclue-mozilla.h"
@@ -157,7 +157,7 @@ gclue_3g_init (GClue3G *source)
priv->cancellable = g_cancellable_new ();
- priv->modem = gclue_modem_get_singleton ();
+ priv->modem = gclue_modem_manager_get_singleton ();
priv->threeg_notify_id =
g_signal_connect (priv->modem,
"notify::is-3g-available",
diff --git a/src/gclue-modem-gps.c b/src/gclue-modem-gps.c
index c788965..7f1338f 100644
--- a/src/gclue-modem-gps.c
+++ b/src/gclue-modem-gps.c
@@ -23,7 +23,7 @@
#include <glib.h>
#include <string.h>
#include "gclue-modem-gps.h"
-#include "gclue-modem.h"
+#include "gclue-modem-manager.h"
#include "geocode-glib/geocode-location.h"
/**
@@ -146,7 +146,7 @@ gclue_modem_gps_init (GClueModemGPS *source)
priv->cancellable = g_cancellable_new ();
- priv->modem = gclue_modem_get_singleton ();
+ priv->modem = gclue_modem_manager_get_singleton ();
priv->gps_notify_id =
g_signal_connect (priv->modem,
"notify::is-gps-available",
diff --git a/src/gclue-modem-manager.c b/src/gclue-modem-manager.c
new file mode 100644
index 0000000..57c461b
--- /dev/null
+++ b/src/gclue-modem-manager.c
@@ -0,0 +1,725 @@
+/* vim: set et ts=8 sw=8: */
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * Geoclue 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.
+ *
+ * Geoclue 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 Geoclue; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+ */
+
+#include <stdlib.h>
+#include <glib.h>
+#include <string.h>
+#include <libmm-glib.h>
+#include "gclue-modem-manager.h"
+#include "gclue-marshal.h"
+
+/**
+ * SECTION:gclue-modem-manager
+ * @short_description: Modem handler
+ *
+ * This class is used by GClue3G and GClueModemGPS to deal with modem through
+ * ModemManager.
+ **/
+
+static void
+gclue_modem_interface_init (GClueModemInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GClueModemManager, gclue_modem_manager, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GCLUE_TYPE_MODEM,
+ gclue_modem_interface_init))
+
+struct _GClueModemManagerPrivate {
+ MMManager *manager;
+ MMObject *mm_object;
+ MMModem *modem;
+ MMModemLocation *modem_location;
+ MMLocation3gpp *location_3gpp;
+
+ GCancellable *cancellable;
+
+ MMModemLocationSource caps; /* Caps we set or are going to set */
+};
+
+enum
+{
+ PROP_0,
+ PROP_IS_3G_AVAILABLE,
+ PROP_IS_GPS_AVAILABLE,
+ LAST_PROP
+};
+
+static GParamSpec *gParamSpecs[LAST_PROP];
+
+enum {
+ FIX_3G,
+ FIX_GPS,
+ SIGNAL_LAST
+};
+
+static guint signals[SIGNAL_LAST];
+
+static gboolean
+gclue_modem_manager_get_is_3g_available (GClueModem *modem);
+static gboolean
+gclue_modem_manager_get_is_gps_available (GClueModem *modem);
+static void
+gclue_modem_manager_enable_3g (GClueModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+static gboolean
+gclue_modem_manager_enable_3g_finish (GClueModem *modem,
+ GAsyncResult *result,
+ GError **error);
+static void
+gclue_modem_manager_enable_gps (GClueModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+static gboolean
+gclue_modem_manager_enable_gps_finish (GClueModem *modem,
+ GAsyncResult *result,
+ GError **error);
+static gboolean
+gclue_modem_manager_disable_3g (GClueModem *modem,
+ GCancellable *cancellable,
+ GError **error);
+static gboolean
+gclue_modem_manager_disable_gps (GClueModem *modem,
+ GCancellable *cancellable,
+ GError **error);
+
+static void
+gclue_modem_manager_finalize (GObject *gmodem)
+{
+ GClueModemManager *manager = GCLUE_MODEM_MANAGER (gmodem);
+ GClueModemManagerPrivate *priv = manager->priv;
+
+ G_OBJECT_CLASS (gclue_modem_manager_parent_class)->finalize (gmodem);
+
+ g_cancellable_cancel (priv->cancellable);
+ g_clear_object (&priv->cancellable);
+ g_clear_object (&priv->manager);
+ g_clear_object (&priv->mm_object);
+ g_clear_object (&priv->modem);
+ g_clear_object (&priv->modem_location);
+}
+
+static void
+gclue_modem_manager_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GClueModem *modem = GCLUE_MODEM (object);
+
+ switch (prop_id) {
+ case PROP_IS_3G_AVAILABLE:
+ g_value_set_boolean (value,
+ gclue_modem_get_is_3g_available (modem));
+ break;
+
+ case PROP_IS_GPS_AVAILABLE:
+ g_value_set_boolean (value,
+ gclue_modem_get_is_gps_available (modem));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+gclue_modem_manager_constructed (GObject *object);
+
+static void
+gclue_modem_manager_class_init (GClueModemManagerClass *klass)
+{
+ GObjectClass *gmodem_class = G_OBJECT_CLASS (klass);
+
+ gmodem_class->get_property = gclue_modem_manager_get_property;
+ gmodem_class->finalize = gclue_modem_manager_finalize;
+ gmodem_class->constructed = gclue_modem_manager_constructed;
+
+ g_type_class_add_private (klass, sizeof (GClueModemManagerPrivate));
+
+ g_object_class_override_property (gmodem_class,
+ PROP_IS_3G_AVAILABLE,
+ "is-3g-available");
+ gParamSpecs[PROP_IS_3G_AVAILABLE] =
+ g_object_class_find_property (gmodem_class,
+ "is-3g-available");
+ g_object_class_override_property (gmodem_class,
+ PROP_IS_GPS_AVAILABLE,
+ "is-gps-available");
+ gParamSpecs[PROP_IS_GPS_AVAILABLE] =
+ g_object_class_find_property (gmodem_class,
+ "is-gps-available");
+
+ signals[FIX_3G] = g_signal_lookup ("fix-3g", GCLUE_TYPE_MODEM);
+ signals[FIX_GPS] = g_signal_lookup ("fix-gps", GCLUE_TYPE_MODEM);
+}
+
+static void
+gclue_modem_interface_init (GClueModemInterface *iface)
+{
+ iface->get_is_3g_available = gclue_modem_manager_get_is_3g_available;
+ iface->get_is_gps_available = gclue_modem_manager_get_is_gps_available;
+ iface->enable_3g = gclue_modem_manager_enable_3g;
+ iface->enable_3g_finish = gclue_modem_manager_enable_3g_finish;
+ iface->enable_gps = gclue_modem_manager_enable_gps;
+ iface->enable_gps_finish = gclue_modem_manager_enable_gps_finish;
+ iface->disable_3g = gclue_modem_manager_disable_3g;
+ iface->disable_gps = gclue_modem_manager_disable_gps;
+}
+
+static gboolean
+is_location_3gpp_same (GClueModemManager *manager,
+ guint new_mcc,
+ guint new_mnc,
+ gulong new_lac,
+ gulong new_cell_id)
+{
+ GClueModemManagerPrivate *priv = manager->priv;
+ guint mcc, mnc;
+ gulong lac, cell_id;
+
+ if (priv->location_3gpp == NULL)
+ return FALSE;
+
+ mcc = mm_location_3gpp_get_mobile_country_code (priv->location_3gpp);
+ mnc = mm_location_3gpp_get_mobile_network_code (priv->location_3gpp);
+ lac = mm_location_3gpp_get_location_area_code (priv->location_3gpp);
+ cell_id = mm_location_3gpp_get_cell_id (priv->location_3gpp);
+
+ return (mcc == new_mcc &&
+ mnc == new_mnc &&
+ lac == new_lac &&
+ cell_id == new_cell_id);
+}
+
+static void
+on_get_3gpp_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
+ GClueModemManagerPrivate *priv = manager->priv;
+ MMModemLocation *modem_location = MM_MODEM_LOCATION (source_object);
+ MMLocation3gpp *location_3gpp;
+ GError *error = NULL;
+ guint mcc, mnc;
+ gulong lac, cell_id;
+
+ location_3gpp = mm_modem_location_get_3gpp_finish (modem_location,
+ res,
+ &error);
+ if (error != NULL) {
+ g_warning ("Failed to get location from 3GPP: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (location_3gpp == NULL) {
+ g_debug ("No 3GPP");
+ return;
+ }
+
+ mcc = mm_location_3gpp_get_mobile_country_code (location_3gpp);
+ mnc = mm_location_3gpp_get_mobile_network_code (location_3gpp);
+ lac = mm_location_3gpp_get_location_area_code (location_3gpp);
+ cell_id = mm_location_3gpp_get_cell_id (location_3gpp);
+
+ if (is_location_3gpp_same (manager, mcc, mnc, lac, cell_id)) {
+ g_debug ("New 3GPP location is same as last one");
+ return;
+ }
+ g_clear_object (&priv->location_3gpp);
+ priv->location_3gpp = location_3gpp;
+
+ g_signal_emit (manager, signals[FIX_3G], 0, mcc, mnc, lac, cell_id);
+}
+
+static void
+on_get_gps_nmea_ready (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ MMModemLocation *modem_location = MM_MODEM_LOCATION (source_object);
+ MMLocationGpsNmea *location_nmea;
+ const char *gga;
+ GError *error = NULL;
+
+ location_nmea = mm_modem_location_get_gps_nmea_finish (modem_location,
+ res,
+ &error);
+ if (error != NULL) {
+ g_warning ("Failed to get location from NMEA information: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (location_nmea == NULL) {
+ g_debug ("No NMEA");
+ return;
+ }
+
+ gga = mm_location_gps_nmea_get_trace (location_nmea, "$GPGGA");
+ if (gga == NULL) {
+ g_debug ("No GGA trace");
+ goto out;
+ }
+
+ g_debug ("New GPGGA trace: %s", gga);
+ g_signal_emit (GCLUE_MODEM_MANAGER (user_data), signals[FIX_GPS], 0, gga);
+out:
+ g_object_unref (location_nmea);
+}
+
+static void
+on_location_changed (GObject *modem_object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ MMModemLocation *modem_location = MM_MODEM_LOCATION (modem_object);
+ GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
+
+ mm_modem_location_get_3gpp (modem_location,
+ manager->priv->cancellable,
+ on_get_3gpp_ready,
+ manager);
+ if ((manager->priv->caps & MM_MODEM_LOCATION_SOURCE_GPS_NMEA) != 0)
+ mm_modem_location_get_gps_nmea (modem_location,
+ manager->priv->cancellable,
+ on_get_gps_nmea_ready,
+ manager);
+}
+
+static void
+on_modem_location_setup (GObject *modem_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GTask *task = G_TASK (user_data);
+ GClueModemManager *manager;
+ GClueModemManagerPrivate *priv;
+ GError *error = NULL;
+
+ if (!mm_modem_location_setup_finish (MM_MODEM_LOCATION (modem_object),
+ res,
+ &error)) {
+ g_task_return_error (task, error);
+
+ goto out;
+ }
+ manager = GCLUE_MODEM_MANAGER (g_task_get_source_object (task));
+ priv = manager->priv;
+ g_debug ("Modem '%s' setup.", mm_object_get_path (priv->mm_object));
+
+ on_location_changed (modem_object, NULL, manager);
+
+ g_task_return_boolean (task, TRUE);
+out:
+ g_object_unref (task);
+}
+
+static void
+on_modem_enabled (GObject *modem_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GTask *task = G_TASK (user_data);
+ GClueModemManagerPrivate *priv;
+ MMModemLocationSource caps;
+ GError *error = NULL;
+
+ if (!mm_modem_enable_finish (MM_MODEM (modem_object), res, &error)) {
+ if (error->code == MM_CORE_ERROR_IN_PROGRESS)
+ /* Seems a previous async call hasn't returned yet. */
+ g_task_return_boolean (task, TRUE);
+ else
+ g_task_return_error (task, error);
+ g_object_unref (task);
+
+ return;
+ }
+ priv = GCLUE_MODEM_MANAGER (g_task_get_source_object (task))->priv;
+ g_debug ("manager '%s' enabled.", mm_object_get_path (priv->mm_object));
+
+ caps = mm_modem_location_get_enabled (priv->modem_location) | priv->caps;
+ mm_modem_location_setup (priv->modem_location,
+ caps,
+ TRUE,
+ g_task_get_cancellable (task),
+ on_modem_location_setup,
+ task);
+}
+
+static void
+enable_caps (GClueModemManager *manager,
+ MMModemLocationSource caps,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GClueModemManagerPrivate *priv = manager->priv;
+ GTask *task;
+
+ priv->caps |= caps;
+ task = g_task_new (manager, cancellable, callback, user_data);
+
+ mm_modem_enable (priv->modem,
+ cancellable,
+ on_modem_enabled,
+ task);
+}
+
+static gboolean
+enable_caps_finish (GClueModemManager *manager,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (manager), FALSE);
+ g_return_val_if_fail (g_task_is_valid (result, manager), FALSE);
+
+ return g_task_propagate_boolean (G_TASK (result), error);
+}
+
+static gboolean
+clear_caps (GClueModemManager *manager,
+ MMModemLocationSource caps,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GClueModemManagerPrivate *priv;
+
+ priv = manager->priv;
+
+ if (priv->modem_location == NULL)
+ return TRUE;
+
+ priv->caps &= ~caps;
+
+ return mm_modem_location_setup_sync (priv->modem_location,
+ priv->caps,
+ FALSE,
+ cancellable,
+ error);
+}
+
+static gboolean
+modem_has_caps (GClueModemManager *manager,
+ MMModemLocationSource caps)
+{
+ MMModemLocation *modem_location = manager->priv->modem_location;
+ MMModemLocationSource avail_caps;
+
+ if (modem_location == NULL)
+ return FALSE;
+
+ avail_caps = mm_modem_location_get_capabilities (modem_location);
+
+ return ((caps & avail_caps) != 0);
+}
+
+static void
+on_mm_object_added (GDBusObjectManager *object_manager,
+ GDBusObject *object,
+ gpointer user_data)
+{
+ MMObject *mm_object = MM_OBJECT (object);
+ GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
+ MMModemLocation *modem_location;
+
+ if (manager->priv->mm_object != NULL)
+ return;
+
+ g_debug ("New modem '%s'", mm_object_get_path (mm_object));
+ modem_location = mm_object_peek_modem_location (mm_object);
+ if (modem_location == NULL)
+ return;
+
+ g_debug ("Modem '%s' has location capabilities",
+ mm_object_get_path (mm_object));
+
+ manager->priv->mm_object = g_object_ref (mm_object);
+ manager->priv->modem = mm_object_get_modem (mm_object);
+ manager->priv->modem_location = mm_object_get_modem_location (mm_object);
+
+ g_signal_connect (G_OBJECT (manager->priv->modem_location),
+ "notify::location",
+ G_CALLBACK (on_location_changed),
+ manager);
+
+ g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_3G_AVAILABLE]);
+ g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_GPS_AVAILABLE]);
+}
+
+static void
+on_mm_object_removed (GDBusObjectManager *object_manager,
+ GDBusObject *object,
+ gpointer user_data)
+{
+ MMObject *mm_object = MM_OBJECT (object);
+ GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
+ GClueModemManagerPrivate *priv = manager->priv;
+
+ if (priv->mm_object == NULL || priv->mm_object != mm_object)
+ return;
+ g_debug ("Modem '%s' removed.", mm_object_get_path (priv->mm_object));
+
+ g_signal_handlers_disconnect_by_func (G_OBJECT (priv->modem_location),
+ G_CALLBACK (on_location_changed),
+ user_data);
+ g_clear_object (&priv->mm_object);
+ g_clear_object (&priv->modem);
+ g_clear_object (&priv->modem_location);
+
+ g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_3G_AVAILABLE]);
+ g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_GPS_AVAILABLE]);
+}
+
+static void
+on_manager_new_ready (GObject *modem_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GClueModemManagerPrivate *priv = GCLUE_MODEM_MANAGER (user_data)->priv;
+ GList *objects, *node;
+ GError *error = NULL;
+
+ priv->manager = mm_manager_new_finish (res, &error);
+ if (priv->manager == NULL) {
+ g_warning ("Failed to connect to ModemManager: %s",
+ error->message);
+ g_error_free (error);
+
+ return;
+ }
+
+ objects = g_dbus_object_manager_get_objects
+ (G_DBUS_OBJECT_MANAGER (priv->manager));
+ for (node = objects; node != NULL; node = node->next) {
+ on_mm_object_added (G_DBUS_OBJECT_MANAGER (priv->manager),
+ G_DBUS_OBJECT (node->data),
+ user_data);
+
+ /* FIXME: Currently we only support 1 modem device */
+ if (priv->modem != NULL)
+ break;
+ }
+ g_list_free_full (objects, g_object_unref);
+
+ g_signal_connect (G_OBJECT (priv->manager),
+ "object-added",
+ G_CALLBACK (on_mm_object_added),
+ user_data);
+
+ g_signal_connect (G_OBJECT (priv->manager),
+ "object-removed",
+ G_CALLBACK (on_mm_object_removed),
+ user_data);
+}
+
+static void
+on_bus_get_ready (GObject *modem_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GClueModemManagerPrivate *priv = GCLUE_MODEM_MANAGER (user_data)->priv;
+ GDBusConnection *connection;
+ GError *error = NULL;
+
+ connection = g_bus_get_finish (res, &error);
+ if (connection == NULL) {
+ g_warning ("Failed to connect to system D-Bus: %s",
+ error->message);
+ g_error_free (error);
+
+ return;
+ }
+
+ mm_manager_new (connection,
+ 0,
+ priv->cancellable,
+ on_manager_new_ready,
+ user_data);
+}
+
+static void
+gclue_modem_manager_constructed (GObject *object)
+{
+ GClueModemManagerPrivate *priv = GCLUE_MODEM_MANAGER (object)->priv;
+
+ G_OBJECT_CLASS (gclue_modem_manager_parent_class)->constructed (object);
+
+ priv->cancellable = g_cancellable_new ();
+
+ g_bus_get (G_BUS_TYPE_SYSTEM,
+ priv->cancellable,
+ on_bus_get_ready,
+ object);
+}
+
+static void
+gclue_modem_manager_init (GClueModemManager *manager)
+{
+ manager->priv = G_TYPE_INSTANCE_GET_PRIVATE ((manager),
+ GCLUE_TYPE_MODEM_MANAGER,
+ GClueModemManagerPrivate);
+}
+
+static void
+on_modem_destroyed (gpointer data,
+ GObject *where_the_object_was)
+{
+ GClueModemManager **manager = (GClueModemManager **) data;
+
+ *manager = NULL;
+}
+
+/**
+ * gclue_modem_manager_get_singleton:
+ *
+ * Get the #GClueModemManager singleton.
+ *
+ * Returns: (transfer full): a #GClueModemManager as #GClueModem.
+ **/
+GClueModem *
+gclue_modem_manager_get_singleton (void)
+{
+ static GClueModemManager *manager = NULL;
+
+ if (manager == NULL) {
+ manager = g_object_new (GCLUE_TYPE_MODEM_MANAGER, NULL);
+ g_object_weak_ref (G_OBJECT (manager),
+ on_modem_destroyed,
+ &manager);
+ } else
+ g_object_ref (manager);
+
+ return GCLUE_MODEM (manager);
+}
+
+static gboolean
+gclue_modem_manager_get_is_3g_available (GClueModem *modem)
+{
+ g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
+
+ return modem_has_caps (GCLUE_MODEM_MANAGER (modem),
+ MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI);
+}
+
+static gboolean
+gclue_modem_manager_get_is_gps_available (GClueModem *modem)
+{
+ g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
+
+ return modem_has_caps (GCLUE_MODEM_MANAGER (modem),
+ MM_MODEM_LOCATION_SOURCE_GPS_NMEA);
+}
+
+static void
+gclue_modem_manager_enable_3g (GClueModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GCLUE_IS_MODEM_MANAGER (modem));
+ g_return_if_fail (gclue_modem_manager_get_is_3g_available (modem));
+
+ enable_caps (GCLUE_MODEM_MANAGER (modem),
+ MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
+ cancellable,
+ callback,
+ user_data);
+}
+
+static gboolean
+gclue_modem_manager_enable_3g_finish (GClueModem *modem,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
+
+ return enable_caps_finish (GCLUE_MODEM_MANAGER (modem),
+ result,
+ error);
+}
+
+static void
+gclue_modem_manager_enable_gps (GClueModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (GCLUE_IS_MODEM_MANAGER (modem));
+ g_return_if_fail (gclue_modem_manager_get_is_gps_available (modem));
+
+ enable_caps (GCLUE_MODEM_MANAGER (modem),
+ MM_MODEM_LOCATION_SOURCE_GPS_NMEA,
+ cancellable,
+ callback,
+ user_data);
+}
+
+static gboolean
+gclue_modem_manager_enable_gps_finish (GClueModem *modem,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
+
+ return enable_caps_finish (GCLUE_MODEM_MANAGER (modem),
+ result,
+ error);
+}
+
+static gboolean
+gclue_modem_manager_disable_3g (GClueModem *modem,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GClueModemManager *manager;
+
+ g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
+ g_return_val_if_fail (gclue_modem_manager_get_is_3g_available (modem), FALSE);
+ manager = GCLUE_MODEM_MANAGER (modem);
+
+ g_clear_object (&manager->priv->location_3gpp);
+ g_debug ("Clearing 3GPP location caps from modem");
+ return clear_caps (manager,
+ MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
+ cancellable,
+ error);
+}
+
+static gboolean
+gclue_modem_manager_disable_gps (GClueModem *modem,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
+ g_return_val_if_fail (gclue_modem_manager_get_is_gps_available (modem), FALSE);
+
+ g_debug ("Clearing GPS NMEA caps from modem");
+ return clear_caps (GCLUE_MODEM_MANAGER (modem),
+ MM_MODEM_LOCATION_SOURCE_GPS_NMEA,
+ cancellable,
+ error);
+}
diff --git a/src/gclue-modem-manager.h b/src/gclue-modem-manager.h
new file mode 100644
index 0000000..d67e36e
--- /dev/null
+++ b/src/gclue-modem-manager.h
@@ -0,0 +1,68 @@
+/* vim: set et ts=8 sw=8: */
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * Geoclue 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.
+ *
+ * Geoclue 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 Geoclue; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
+ */
+
+#ifndef GCLUE_MODEM_MANAGER_H
+#define GCLUE_MODEM_MANAGER_H
+
+#include <gio/gio.h>
+#include "gclue-modem.h"
+
+G_BEGIN_DECLS
+
+GType gclue_modem_manager_get_type (void) G_GNUC_CONST;
+
+#define GCLUE_TYPE_MODEM_MANAGER (gclue_modem_manager_get_type ())
+#define GCLUE_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCLUE_TYPE_MODEM_MANAGER, GClueModemManager))
+#define GCLUE_IS_MODEM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCLUE_TYPE_MODEM_MANAGER))
+#define GCLUE_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCLUE_TYPE_MODEM_MANAGER, GClueModemManagerClass))
+#define GCLUE_IS_MODEM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCLUE_TYPE_MODEM_MANAGER))
+#define GCLUE_MODEM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCLUE_TYPE_MODEM_MANAGER, GClueModemManagerClass))
+
+/**
+ * GClueModemManager:
+ *
+ * All the fields in the #GClueModemManager structure are private and should never be accessed directly.
+**/
+typedef struct _GClueModemManager GClueModemManager;
+typedef struct _GClueModemManagerClass GClueModemManagerClass;
+typedef struct _GClueModemManagerPrivate GClueModemManagerPrivate;
+
+struct _GClueModemManager {
+ /* <private> */
+ GObject parent_instance;
+ GClueModemManagerPrivate *priv;
+};
+
+/**
+ * GClueModemManagerClass:
+ *
+ * All the fields in the #GClueModemManagerClass structure are private and should never be accessed directly.
+**/
+struct _GClueModemManagerClass {
+ /* <private> */
+ GObjectClass parent_class;
+};
+
+GClueModem* gclue_modem_manager_get_singleton (void);
+
+G_END_DECLS
+
+#endif /* GCLUE_MODEM_MANAGER_H */
diff --git a/src/gclue-modem.c b/src/gclue-modem.c
index 85b2799..2dcee0a 100644
--- a/src/gclue-modem.c
+++ b/src/gclue-modem.c
@@ -22,7 +22,6 @@
#include <stdlib.h>
#include <glib.h>
#include <string.h>
-#include <libmm-glib.h>
#include "gclue-modem.h"
#include "gclue-marshal.h"
@@ -30,581 +29,73 @@
* SECTION:gclue-modem
* @short_description: Modem handler
*
- * This class is used by GClue3G and GClueModemGPS to deal with modem through
- * ModemManager.
+ * This interface is implemented by Modem handing modules. Currently there is
+ * only one class, ModemManager implementing this interface. Normally it
+ * wouldn't make sense to have it separate from the class but intention is to
+ * make it very easy to add alternative modem sources, e.g ofono-based.
**/
-G_DEFINE_TYPE (GClueModem, gclue_modem, G_TYPE_OBJECT)
-
-struct _GClueModemPrivate {
- MMManager *manager;
- MMObject *mm_object;
- MMModem *modem;
- MMModemLocation *modem_location;
- MMLocation3gpp *location_3gpp;
-
- GCancellable *cancellable;
-
- MMModemLocationSource caps; /* Caps we set or are going to set */
-};
-
-enum
-{
- PROP_0,
- PROP_IS_3G_AVAILABLE,
- PROP_IS_GPS_AVAILABLE,
- LAST_PROP
-};
-
-static GParamSpec *gParamSpecs[LAST_PROP];
-
-enum {
- FIX_3G,
- FIX_GPS,
- SIGNAL_LAST
-};
-
-static guint signals[SIGNAL_LAST];
-
-static void
-gclue_modem_finalize (GObject *gmodem)
-{
- GClueModem *modem = GCLUE_MODEM (gmodem);
- GClueModemPrivate *priv = modem->priv;
-
- G_OBJECT_CLASS (gclue_modem_parent_class)->finalize (gmodem);
-
- g_cancellable_cancel (priv->cancellable);
- g_clear_object (&priv->cancellable);
- g_clear_object (&priv->manager);
- g_clear_object (&priv->mm_object);
- g_clear_object (&priv->modem);
- g_clear_object (&priv->modem_location);
-}
-
-static void
-gclue_modem_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GClueModem *modem = GCLUE_MODEM (object);
-
- switch (prop_id) {
- case PROP_IS_3G_AVAILABLE:
- g_value_set_boolean (value,
- gclue_modem_get_is_3g_available (modem));
- break;
-
- case PROP_IS_GPS_AVAILABLE:
- g_value_set_boolean (value,
- gclue_modem_get_is_gps_available (modem));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
-
-static void
-gclue_modem_constructed (GObject *object);
-
-static void
-gclue_modem_class_init (GClueModemClass *klass)
-{
- GObjectClass *gmodem_class = G_OBJECT_CLASS (klass);
-
- gmodem_class->get_property = gclue_modem_get_property;
- gmodem_class->finalize = gclue_modem_finalize;
- gmodem_class->constructed = gclue_modem_constructed;
-
- g_type_class_add_private (klass, sizeof (GClueModemPrivate));
-
- gParamSpecs[PROP_IS_3G_AVAILABLE] =
- g_param_spec_boolean ("is-3g-available",
- "Is3GAvailable",
- "Is 3G Available?",
- FALSE,
- G_PARAM_READABLE);
- g_object_class_install_property (gmodem_class,
- PROP_IS_3G_AVAILABLE,
- gParamSpecs[PROP_IS_3G_AVAILABLE]);
- gParamSpecs[PROP_IS_GPS_AVAILABLE] =
- g_param_spec_boolean ("is-gps-available",
- "IsGPSAvailable",
- "Is GPS Available?",
- FALSE,
- G_PARAM_READABLE);
- g_object_class_install_property (gmodem_class,
- PROP_IS_GPS_AVAILABLE,
- gParamSpecs[PROP_IS_GPS_AVAILABLE]);
-
- signals[FIX_3G] =
- g_signal_new ("fix-3g",
- GCLUE_TYPE_MODEM,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- gclue_marshal_VOID__UINT_UINT_ULONG_ULONG,
- G_TYPE_NONE,
- 4,
- G_TYPE_UINT,
- G_TYPE_UINT,
- G_TYPE_ULONG,
- G_TYPE_ULONG);
-
- signals[FIX_GPS] =
- g_signal_new ("fix-gps",
- GCLUE_TYPE_MODEM,
- G_SIGNAL_RUN_LAST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE,
- 1,
- G_TYPE_STRING);
-}
-
-static gboolean
-is_location_3gpp_same (GClueModem *modem,
- guint new_mcc,
- guint new_mnc,
- gulong new_lac,
- gulong new_cell_id)
-{
- GClueModemPrivate *priv = modem->priv;
- guint mcc, mnc;
- gulong lac, cell_id;
-
- if (priv->location_3gpp == NULL)
- return FALSE;
-
- mcc = mm_location_3gpp_get_mobile_country_code (priv->location_3gpp);
- mnc = mm_location_3gpp_get_mobile_network_code (priv->location_3gpp);
- lac = mm_location_3gpp_get_location_area_code (priv->location_3gpp);
- cell_id = mm_location_3gpp_get_cell_id (priv->location_3gpp);
-
- return (mcc == new_mcc &&
- mnc == new_mnc &&
- lac == new_lac &&
- cell_id == new_cell_id);
-}
-
-static void
-on_get_3gpp_ready (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GClueModem *modem = GCLUE_MODEM (user_data);
- GClueModemPrivate *priv = modem->priv;
- MMModemLocation *modem_location = MM_MODEM_LOCATION (source_object);
- MMLocation3gpp *location_3gpp;
- GError *error = NULL;
- guint mcc, mnc;
- gulong lac, cell_id;
-
- location_3gpp = mm_modem_location_get_3gpp_finish (modem_location,
- res,
- &error);
- if (error != NULL) {
- g_warning ("Failed to get location from 3GPP: %s",
- error->message);
- g_error_free (error);
- return;
- }
-
- if (location_3gpp == NULL) {
- g_debug ("No 3GPP");
- return;
- }
-
- mcc = mm_location_3gpp_get_mobile_country_code (location_3gpp);
- mnc = mm_location_3gpp_get_mobile_network_code (location_3gpp);
- lac = mm_location_3gpp_get_location_area_code (location_3gpp);
- cell_id = mm_location_3gpp_get_cell_id (location_3gpp);
-
- if (is_location_3gpp_same (modem, mcc, mnc, lac, cell_id)) {
- g_debug ("New 3GPP location is same as last one");
- return;
- }
- g_clear_object (&priv->location_3gpp);
- priv->location_3gpp = location_3gpp;
-
- g_signal_emit (modem, signals[FIX_3G], 0, mcc, mnc, lac, cell_id);
-}
-
-static void
-on_get_gps_nmea_ready (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- MMModemLocation *modem_location = MM_MODEM_LOCATION (source_object);
- MMLocationGpsNmea *location_nmea;
- const char *gga;
- GError *error = NULL;
-
- location_nmea = mm_modem_location_get_gps_nmea_finish (modem_location,
- res,
- &error);
- if (error != NULL) {
- g_warning ("Failed to get location from NMEA information: %s",
- error->message);
- g_error_free (error);
- return;
- }
-
- if (location_nmea == NULL) {
- g_debug ("No NMEA");
- return;
- }
-
- gga = mm_location_gps_nmea_get_trace (location_nmea, "$GPGGA");
- if (gga == NULL) {
- g_debug ("No GGA trace");
- goto out;
- }
-
- g_debug ("New GPGGA trace: %s", gga);
- g_signal_emit (GCLUE_MODEM (user_data), signals[FIX_GPS], 0, gga);
-out:
- g_object_unref (location_nmea);
-}
-
-static void
-on_location_changed (GObject *modem_object,
- GParamSpec *pspec,
- gpointer user_data)
-{
- MMModemLocation *modem_location = MM_MODEM_LOCATION (modem_object);
- GClueModem *modem = GCLUE_MODEM (user_data);
-
- mm_modem_location_get_3gpp (modem_location,
- modem->priv->cancellable,
- on_get_3gpp_ready,
- modem);
- if ((modem->priv->caps & MM_MODEM_LOCATION_SOURCE_GPS_NMEA) != 0)
- mm_modem_location_get_gps_nmea (modem_location,
- modem->priv->cancellable,
- on_get_gps_nmea_ready,
- modem);
-}
-
-static void
-on_modem_location_setup (GObject *modem_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GTask *task = G_TASK (user_data);
- GClueModem *modem;
- GClueModemPrivate *priv;
- GError *error = NULL;
-
- if (!mm_modem_location_setup_finish (MM_MODEM_LOCATION (modem_object),
- res,
- &error)) {
- g_task_return_error (task, error);
-
- goto out;
- }
- modem = GCLUE_MODEM (g_task_get_source_object (task));
- priv = modem->priv;
- g_debug ("Modem '%s' setup.", mm_object_get_path (priv->mm_object));
-
- on_location_changed (modem_object, NULL, modem);
-
- g_task_return_boolean (task, TRUE);
-out:
- g_object_unref (task);
-}
-
-static void
-on_modem_enabled (GObject *modem_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GTask *task = G_TASK (user_data);
- GClueModemPrivate *priv;
- MMModemLocationSource caps;
- GError *error = NULL;
-
- if (!mm_modem_enable_finish (MM_MODEM (modem_object), res, &error)) {
- if (error->code == MM_CORE_ERROR_IN_PROGRESS)
- /* Seems a previous async call hasn't returned yet. */
- g_task_return_boolean (task, TRUE);
- else
- g_task_return_error (task, error);
- g_object_unref (task);
-
- return;
- }
- priv = GCLUE_MODEM (g_task_get_source_object (task))->priv;
- g_debug ("modem '%s' enabled.", mm_object_get_path (priv->mm_object));
-
- caps = mm_modem_location_get_enabled (priv->modem_location) | priv->caps;
- mm_modem_location_setup (priv->modem_location,
- caps,
- TRUE,
- g_task_get_cancellable (task),
- on_modem_location_setup,
- task);
-}
-
-static void
-enable_caps (GClueModem *modem,
- MMModemLocationSource caps,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GClueModemPrivate *priv = modem->priv;
- GTask *task;
-
- priv->caps |= caps;
- task = g_task_new (modem, cancellable, callback, user_data);
-
- mm_modem_enable (priv->modem,
- cancellable,
- on_modem_enabled,
- task);
-}
-
-static gboolean
-enable_caps_finish (GClueModem *modem,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (GCLUE_IS_MODEM (modem), FALSE);
- g_return_val_if_fail (g_task_is_valid (result, modem), FALSE);
-
- return g_task_propagate_boolean (G_TASK (result), error);
-}
-
-static gboolean
-clear_caps (GClueModem *modem,
- MMModemLocationSource caps,
- GCancellable *cancellable,
- GError **error)
-{
- GClueModemPrivate *priv;
-
- priv = modem->priv;
-
- if (priv->modem_location == NULL)
- return TRUE;
-
- priv->caps &= ~caps;
-
- return mm_modem_location_setup_sync (priv->modem_location,
- priv->caps,
- FALSE,
- cancellable,
- error);
-}
-
-static gboolean
-modem_has_caps (GClueModem *modem,
- MMModemLocationSource caps)
-{
- MMModemLocation *modem_location = modem->priv->modem_location;
- MMModemLocationSource avail_caps;
-
- if (modem_location == NULL)
- return FALSE;
-
- avail_caps = mm_modem_location_get_capabilities (modem_location);
-
- return ((caps & avail_caps) != 0);
-}
-
-static void
-on_mm_object_added (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data)
-{
- MMObject *mm_object = MM_OBJECT (object);
- GClueModem *modem = GCLUE_MODEM (user_data);
- MMModemLocation *modem_location;
-
- if (modem->priv->mm_object != NULL)
- return;
-
- g_debug ("New modem '%s'", mm_object_get_path (mm_object));
- modem_location = mm_object_peek_modem_location (mm_object);
- if (modem_location == NULL)
- return;
-
- g_debug ("Modem '%s' has location capabilities",
- mm_object_get_path (mm_object));
-
- modem->priv->mm_object = g_object_ref (mm_object);
- modem->priv->modem = mm_object_get_modem (mm_object);
- modem->priv->modem_location = mm_object_get_modem_location (mm_object);
-
- g_signal_connect (G_OBJECT (modem->priv->modem_location),
- "notify::location",
- G_CALLBACK (on_location_changed),
- modem);
-
- g_object_notify_by_pspec (G_OBJECT (modem), gParamSpecs[PROP_IS_3G_AVAILABLE]);
- g_object_notify_by_pspec (G_OBJECT (modem), gParamSpecs[PROP_IS_GPS_AVAILABLE]);
-}
-
-static void
-on_mm_object_removed (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data)
-{
- MMObject *mm_object = MM_OBJECT (object);
- GClueModem *modem = GCLUE_MODEM (user_data);
- GClueModemPrivate *priv = modem->priv;
-
- if (priv->mm_object == NULL || priv->mm_object != mm_object)
- return;
- g_debug ("Modem '%s' removed.", mm_object_get_path (priv->mm_object));
-
- g_signal_handlers_disconnect_by_func (G_OBJECT (priv->modem_location),
- G_CALLBACK (on_location_changed),
- user_data);
- g_clear_object (&priv->mm_object);
- g_clear_object (&priv->modem);
- g_clear_object (&priv->modem_location);
-
- g_object_notify_by_pspec (G_OBJECT (modem), gParamSpecs[PROP_IS_3G_AVAILABLE]);
- g_object_notify_by_pspec (G_OBJECT (modem), gParamSpecs[PROP_IS_GPS_AVAILABLE]);
-}
-
-static void
-on_manager_new_ready (GObject *modem_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GClueModemPrivate *priv = GCLUE_MODEM (user_data)->priv;
- GList *objects, *node;
- GError *error = NULL;
-
- priv->manager = mm_manager_new_finish (res, &error);
- if (priv->manager == NULL) {
- g_warning ("Failed to connect to ModemManager: %s",
- error->message);
- g_error_free (error);
-
- return;
- }
-
- objects = g_dbus_object_manager_get_objects
- (G_DBUS_OBJECT_MANAGER (priv->manager));
- for (node = objects; node != NULL; node = node->next) {
- on_mm_object_added (G_DBUS_OBJECT_MANAGER (priv->manager),
- G_DBUS_OBJECT (node->data),
- user_data);
-
- /* FIXME: Currently we only support 1 modem device */
- if (priv->modem != NULL)
- break;
- }
- g_list_free_full (objects, g_object_unref);
-
- g_signal_connect (G_OBJECT (priv->manager),
- "object-added",
- G_CALLBACK (on_mm_object_added),
- user_data);
-
- g_signal_connect (G_OBJECT (priv->manager),
- "object-removed",
- G_CALLBACK (on_mm_object_removed),
- user_data);
-}
-
-static void
-on_bus_get_ready (GObject *modem_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- GClueModemPrivate *priv = GCLUE_MODEM (user_data)->priv;
- GDBusConnection *connection;
- GError *error = NULL;
-
- connection = g_bus_get_finish (res, &error);
- if (connection == NULL) {
- g_warning ("Failed to connect to system D-Bus: %s",
- error->message);
- g_error_free (error);
-
- return;
- }
-
- mm_manager_new (connection,
- 0,
- priv->cancellable,
- on_manager_new_ready,
- user_data);
-}
-
-static void
-gclue_modem_constructed (GObject *object)
-{
- GClueModemPrivate *priv = GCLUE_MODEM (object)->priv;
-
- G_OBJECT_CLASS (gclue_modem_parent_class)->constructed (object);
-
- priv->cancellable = g_cancellable_new ();
-
- g_bus_get (G_BUS_TYPE_SYSTEM,
- priv->cancellable,
- on_bus_get_ready,
- object);
-}
-
-static void
-gclue_modem_init (GClueModem *modem)
-{
- modem->priv = G_TYPE_INSTANCE_GET_PRIVATE ((modem), GCLUE_TYPE_MODEM, GClueModemPrivate);
-}
-
-static void
-on_modem_destroyed (gpointer data,
- GObject *where_the_object_was)
-{
- GClueModem **modem = (GClueModem **) data;
-
- *modem = NULL;
-}
-
-/**
- * gclue_modem_get_singleton:
- *
- * Get the #GClueModem singleton.
- *
- * Returns: (transfer full): a #GClueModem.
- **/
-GClueModem *
-gclue_modem_get_singleton (void)
-{
- static GClueModem *modem = NULL;
-
- if (modem == NULL) {
- modem = g_object_new (GCLUE_TYPE_MODEM, NULL);
- g_object_weak_ref (G_OBJECT (modem),
- on_modem_destroyed,
- &modem);
- } else
- g_object_ref (modem);
-
- return modem;
+G_DEFINE_INTERFACE (GClueModem, gclue_modem, 0);
+
+static void
+gclue_modem_default_init (GClueModemInterface *iface)
+{
+ GParamSpec *spec;
+
+ spec = g_param_spec_boolean ("is-3g-available",
+ "Is3GAvailable",
+ "Is 3G Available?",
+ FALSE,
+ G_PARAM_READABLE);
+ g_object_interface_install_property (iface, spec);
+
+ spec = g_param_spec_boolean ("is-gps-available",
+ "IsGPSAvailable",
+ "Is GPS Available?",
+ FALSE,
+ G_PARAM_READABLE);
+ g_object_interface_install_property (iface, spec);
+
+ g_signal_new ("fix-3g",
+ GCLUE_TYPE_MODEM,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ gclue_marshal_VOID__UINT_UINT_ULONG_ULONG,
+ G_TYPE_NONE,
+ 4,
+ G_TYPE_UINT,
+ G_TYPE_UINT,
+ G_TYPE_ULONG,
+ G_TYPE_ULONG);
+
+ g_signal_new ("fix-gps",
+ GCLUE_TYPE_MODEM,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
}
gboolean
gclue_modem_get_is_3g_available (GClueModem *modem)
{
- return modem_has_caps (modem, MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI);
+ g_return_val_if_fail (GCLUE_IS_MODEM (modem), FALSE);
+
+ return GCLUE_MODEM_GET_INTERFACE (modem)->get_is_3g_available (modem);
}
gboolean
gclue_modem_get_is_gps_available (GClueModem *modem)
{
- return modem_has_caps (modem, MM_MODEM_LOCATION_SOURCE_GPS_NMEA);
+ g_return_val_if_fail (GCLUE_IS_MODEM (modem), FALSE);
+
+ return GCLUE_MODEM_GET_INTERFACE (modem)->get_is_gps_available (modem);
}
void
@@ -616,11 +107,10 @@ gclue_modem_enable_3g (GClueModem *modem,
g_return_if_fail (GCLUE_IS_MODEM (modem));
g_return_if_fail (gclue_modem_get_is_3g_available (modem));
- enable_caps (modem,
- MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
- cancellable,
- callback,
- user_data);
+ GCLUE_MODEM_GET_INTERFACE (modem)->enable_3g (modem,
+ cancellable,
+ callback,
+ user_data);
}
gboolean
@@ -628,7 +118,11 @@ gclue_modem_enable_3g_finish (GClueModem *modem,
GAsyncResult *result,
GError **error)
{
- return enable_caps_finish (modem, result, error);
+ g_return_val_if_fail (GCLUE_IS_MODEM (modem), FALSE);
+
+ return GCLUE_MODEM_GET_INTERFACE (modem)->enable_3g_finish (modem,
+ result,
+ error);
}
void
@@ -640,11 +134,10 @@ gclue_modem_enable_gps (GClueModem *modem,
g_return_if_fail (GCLUE_IS_MODEM (modem));
g_return_if_fail (gclue_modem_get_is_gps_available (modem));
- enable_caps (modem,
- MM_MODEM_LOCATION_SOURCE_GPS_NMEA,
- cancellable,
- callback,
- user_data);
+ GCLUE_MODEM_GET_INTERFACE (modem)->enable_gps (modem,
+ cancellable,
+ callback,
+ user_data);
}
gboolean
@@ -652,7 +145,11 @@ gclue_modem_enable_gps_finish (GClueModem *modem,
GAsyncResult *result,
GError **error)
{
- return enable_caps_finish (modem, result, error);
+ g_return_val_if_fail (GCLUE_IS_MODEM (modem), FALSE);
+
+ return GCLUE_MODEM_GET_INTERFACE (modem)->enable_gps_finish (modem,
+ result,
+ error);
}
gboolean
@@ -663,12 +160,9 @@ gclue_modem_disable_3g (GClueModem *modem,
g_return_val_if_fail (GCLUE_IS_MODEM (modem), FALSE);
g_return_val_if_fail (gclue_modem_get_is_3g_available (modem), FALSE);
- g_clear_object (&modem->priv->location_3gpp);
- g_debug ("Clearing 3GPP location caps from modem");
- return clear_caps (modem,
- MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
- cancellable,
- error);
+ return GCLUE_MODEM_GET_INTERFACE (modem)->disable_3g (modem,
+ cancellable,
+ error);
}
gboolean
@@ -679,9 +173,7 @@ gclue_modem_disable_gps (GClueModem *modem,
g_return_val_if_fail (GCLUE_IS_MODEM (modem), FALSE);
g_return_val_if_fail (gclue_modem_get_is_gps_available (modem), FALSE);
- g_debug ("Clearing GPS NMEA caps from modem");
- return clear_caps (modem,
- MM_MODEM_LOCATION_SOURCE_GPS_NMEA,
- cancellable,
- error);
+ return GCLUE_MODEM_GET_INTERFACE (modem)->disable_gps (modem,
+ cancellable,
+ error);
}
diff --git a/src/gclue-modem.h b/src/gclue-modem.h
index 26530e0..4a03c30 100644
--- a/src/gclue-modem.h
+++ b/src/gclue-modem.h
@@ -28,61 +28,64 @@ G_BEGIN_DECLS
GType gclue_modem_get_type (void) G_GNUC_CONST;
-#define GCLUE_TYPE_MODEM (gclue_modem_get_type ())
-#define GCLUE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCLUE_TYPE_MODEM, GClueModem))
-#define GCLUE_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCLUE_TYPE_MODEM))
-#define GCLUE_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCLUE_TYPE_MODEM, GClueModemClass))
-#define GCLUE_IS_MODEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCLUE_TYPE_MODEM))
-#define GCLUE_MODEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCLUE_TYPE_MODEM, GClueModemClass))
+#define GCLUE_TYPE_MODEM (gclue_modem_get_type ())
+#define GCLUE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCLUE_TYPE_MODEM, GClueModem))
+#define GCLUE_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCLUE_TYPE_MODEM))
+#define GCLUE_MODEM_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GCLUE_TYPE_MODEM, GClueModemInterface))
-/**
- * GClueModem:
- *
- * All the fields in the #GClueModem structure are private and should never be accessed directly.
-**/
-typedef struct _GClueModem GClueModem;
-typedef struct _GClueModemClass GClueModemClass;
-typedef struct _GClueModemPrivate GClueModemPrivate;
+typedef struct _GClueModem GClueModem;
+typedef struct _GClueModemInterface GClueModemInterface;
-struct _GClueModem {
+struct _GClueModemInterface {
/* <private> */
- GObject parent_instance;
- GClueModemPrivate *priv;
-};
+ GTypeInterface parent_iface;
-/**
- * GClueModemClass:
- *
- * All the fields in the #GClueModemClass structure are private and should never be accessed directly.
-**/
-struct _GClueModemClass {
- /* <private> */
- GObjectClass parent_class;
+ gboolean (*get_is_3g_available) (GClueModem *modem);
+ gboolean (*get_is_gps_available) (GClueModem *modem);
+ void (*enable_3g) (GClueModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*enable_3g_finish) (GClueModem *modem,
+ GAsyncResult *result,
+ GError **error);
+ void (*enable_gps) (GClueModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+ gboolean (*enable_gps_finish) (GClueModem *modem,
+ GAsyncResult *result,
+ GError **error);
+ gboolean (*disable_3g) (GClueModem *modem,
+ GCancellable *cancellable,
+ GError **error);
+ gboolean (*disable_gps) (GClueModem *modem,
+ GCancellable *cancellable,
+ GError **error);
};
-GClueModem * gclue_modem_get_singleton (void);
gboolean gclue_modem_get_is_3g_available (GClueModem *modem);
gboolean gclue_modem_get_is_gps_available (GClueModem *modem);
-void gclue_modem_enable_3g (GClueModem *modem,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean gclue_modem_enable_3g_finish (GClueModem *modem,
- GAsyncResult *result,
- GError **error);
-void gclue_modem_enable_gps (GClueModem *modem,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-gboolean gclue_modem_enable_gps_finish (GClueModem *modem,
- GAsyncResult *result,
- GError **error);
-gboolean gclue_modem_disable_3g (GClueModem *modem,
- GCancellable *cancellable,
- GError **error);
-gboolean gclue_modem_disable_gps (GClueModem *modem,
- GCancellable *cancellable,
- GError **error);
+void gclue_modem_enable_3g (GClueModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean gclue_modem_enable_3g_finish (GClueModem *modem,
+ GAsyncResult *result,
+ GError **error);
+void gclue_modem_enable_gps (GClueModem *modem,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean gclue_modem_enable_gps_finish (GClueModem *modem,
+ GAsyncResult *result,
+ GError **error);
+gboolean gclue_modem_disable_3g (GClueModem *modem,
+ GCancellable *cancellable,
+ GError **error);
+gboolean gclue_modem_disable_gps (GClueModem *modem,
+ GCancellable *cancellable,
+ GError **error);
G_END_DECLS