Blame src/gclue-modem-manager.c

Packit ce9521
/* vim: set et ts=8 sw=8: */
Packit ce9521
/*
Packit ce9521
 * Copyright 2014 Red Hat, Inc.
Packit ce9521
 *
Packit ce9521
 * Geoclue is free software; you can redistribute it and/or modify it under
Packit ce9521
 * the terms of the GNU General Public License as published by the Free
Packit ce9521
 * Software Foundation; either version 2 of the License, or (at your option)
Packit ce9521
 * any later version.
Packit ce9521
 *
Packit ce9521
 * Geoclue is distributed in the hope that it will be useful, but WITHOUT ANY
Packit ce9521
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
Packit ce9521
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
Packit ce9521
 * details.
Packit ce9521
 *
Packit ce9521
 * You should have received a copy of the GNU General Public License along
Packit ce9521
 * with Geoclue; if not, write to the Free Software Foundation, Inc.,
Packit ce9521
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit ce9521
 *
Packit ce9521
 * Authors: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
Packit ce9521
 */
Packit ce9521
Packit ce9521
#include <stdlib.h>
Packit ce9521
#include <glib.h>
Packit ce9521
#include <string.h>
Packit ce9521
#include <libmm-glib.h>
Packit ce9521
#include "gclue-modem-manager.h"
Packit ce9521
#include "gclue-marshal.h"
Packit ce9521
Packit ce9521
/**
Packit ce9521
 * SECTION:gclue-modem-manager
Packit ce9521
 * @short_description: Modem handler
Packit ce9521
 *
Packit ce9521
 * This class is used by GClue3G and GClueModemGPS to deal with modem through
Packit ce9521
 * ModemManager.
Packit ce9521
 **/
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_interface_init (GClueModemInterface *iface);
Packit ce9521
Packit ce9521
struct _GClueModemManagerPrivate {
Packit ce9521
        MMManager *manager;
Packit ce9521
        MMObject *mm_object;
Packit ce9521
        MMModem *modem;
Packit ce9521
        MMModemLocation *modem_location;
Packit ce9521
        MMLocation3gpp *location_3gpp;
Packit ce9521
        MMLocationGpsNmea *location_nmea;
Packit ce9521
Packit ce9521
        GCancellable *cancellable;
Packit ce9521
Packit ce9521
        MMModemLocationSource caps; /* Caps we set or are going to set */
Packit ce9521
Packit ce9521
        guint time_threshold;
Packit ce9521
};
Packit ce9521
Packit ce9521
G_DEFINE_TYPE_WITH_CODE (GClueModemManager, gclue_modem_manager, G_TYPE_OBJECT,
Packit ce9521
                         G_IMPLEMENT_INTERFACE (GCLUE_TYPE_MODEM,
Packit ce9521
                                                gclue_modem_interface_init)
Packit ce9521
                         G_ADD_PRIVATE (GClueModemManager))
Packit ce9521
Packit ce9521
enum
Packit ce9521
{
Packit ce9521
        PROP_0,
Packit ce9521
        PROP_IS_3G_AVAILABLE,
Packit ce9521
        PROP_IS_CDMA_AVAILABLE,
Packit ce9521
        PROP_IS_GPS_AVAILABLE,
Packit ce9521
        PROP_TIME_THRESHOLD,
Packit ce9521
        LAST_PROP
Packit ce9521
};
Packit ce9521
Packit ce9521
static GParamSpec *gParamSpecs[LAST_PROP];
Packit ce9521
Packit ce9521
enum {
Packit ce9521
        FIX_3G,
Packit ce9521
        FIX_CDMA,
Packit ce9521
        FIX_GPS,
Packit ce9521
        SIGNAL_LAST
Packit ce9521
};
Packit ce9521
Packit ce9521
static guint signals[SIGNAL_LAST];
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_get_is_3g_available (GClueModem *modem);
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_get_is_cdma_available (GClueModem *modem);
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_get_is_gps_available (GClueModem *modem);
Packit ce9521
static guint
Packit ce9521
gclue_modem_manager_get_time_threshold (GClueModem *modem);
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_set_time_threshold (GClueModem *modem,
Packit ce9521
                                        guint       time_threshold);
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_enable_3g (GClueModem         *modem,
Packit ce9521
                               GCancellable       *cancellable,
Packit ce9521
                               GAsyncReadyCallback callback,
Packit ce9521
                               gpointer            user_data);
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_enable_3g_finish (GClueModem   *modem,
Packit ce9521
                                      GAsyncResult *result,
Packit ce9521
                                      GError      **error);
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_enable_cdma (GClueModem         *modem,
Packit ce9521
                                 GCancellable       *cancellable,
Packit ce9521
                                 GAsyncReadyCallback callback,
Packit ce9521
                                 gpointer            user_data);
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_enable_cdma_finish (GClueModem   *modem,
Packit ce9521
                                        GAsyncResult *result,
Packit ce9521
                                        GError      **error);
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_enable_gps (GClueModem         *modem,
Packit ce9521
                                GCancellable       *cancellable,
Packit ce9521
                                GAsyncReadyCallback callback,
Packit ce9521
                                gpointer            user_data);
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_enable_gps_finish (GClueModem   *modem,
Packit ce9521
                                       GAsyncResult *result,
Packit ce9521
                                       GError      **error);
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_disable_3g (GClueModem   *modem,
Packit ce9521
                                GCancellable *cancellable,
Packit ce9521
                                GError      **error);
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_disable_cdma (GClueModem   *modem,
Packit ce9521
                                  GCancellable *cancellable,
Packit ce9521
                                  GError      **error);
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_disable_gps (GClueModem   *modem,
Packit ce9521
                                 GCancellable *cancellable,
Packit ce9521
                                 GError      **error);
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_finalize (GObject *gmodem)
Packit ce9521
{
Packit ce9521
        GClueModemManager *manager = GCLUE_MODEM_MANAGER (gmodem);
Packit ce9521
        GClueModemManagerPrivate *priv = manager->priv;
Packit ce9521
Packit ce9521
        G_OBJECT_CLASS (gclue_modem_manager_parent_class)->finalize (gmodem);
Packit ce9521
Packit ce9521
        g_cancellable_cancel (priv->cancellable);
Packit ce9521
        g_clear_object (&priv->cancellable);
Packit ce9521
        g_clear_object (&priv->manager);
Packit ce9521
        g_clear_object (&priv->mm_object);
Packit ce9521
        g_clear_object (&priv->modem);
Packit ce9521
        g_clear_object (&priv->modem_location);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_get_property (GObject    *object,
Packit ce9521
                                  guint       prop_id,
Packit ce9521
                                  GValue     *value,
Packit ce9521
                                  GParamSpec *pspec)
Packit ce9521
{
Packit ce9521
        GClueModem *modem = GCLUE_MODEM (object);
Packit ce9521
Packit ce9521
        switch (prop_id) {
Packit ce9521
        case PROP_IS_3G_AVAILABLE:
Packit ce9521
                g_value_set_boolean (value,
Packit ce9521
                                     gclue_modem_get_is_3g_available (modem));
Packit ce9521
                break;
Packit ce9521
Packit ce9521
        case PROP_IS_CDMA_AVAILABLE:
Packit ce9521
                g_value_set_boolean (value,
Packit ce9521
                                     gclue_modem_get_is_cdma_available (modem));
Packit ce9521
                break;
Packit ce9521
Packit ce9521
        case PROP_IS_GPS_AVAILABLE:
Packit ce9521
                g_value_set_boolean (value,
Packit ce9521
                                     gclue_modem_get_is_gps_available (modem));
Packit ce9521
                break;
Packit ce9521
Packit ce9521
        case PROP_TIME_THRESHOLD:
Packit ce9521
                g_value_set_uint (value,
Packit ce9521
                                  gclue_modem_get_time_threshold (modem));
Packit ce9521
                break;
Packit ce9521
Packit ce9521
        default:
Packit ce9521
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit ce9521
        }
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_set_property (GObject      *object,
Packit ce9521
                                  guint         prop_id,
Packit ce9521
                                  const GValue *value,
Packit ce9521
                                  GParamSpec   *pspec)
Packit ce9521
{
Packit ce9521
        GClueModem *modem = GCLUE_MODEM (object);
Packit ce9521
Packit ce9521
        switch (prop_id) {
Packit ce9521
        case PROP_TIME_THRESHOLD:
Packit ce9521
                gclue_modem_set_time_threshold (modem,
Packit ce9521
                                                g_value_get_uint (value));
Packit ce9521
                break;
Packit ce9521
Packit ce9521
        default:
Packit ce9521
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit ce9521
        }
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_constructed (GObject *object);
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_class_init (GClueModemManagerClass *klass)
Packit ce9521
{
Packit ce9521
        GObjectClass *gmodem_class = G_OBJECT_CLASS (klass);
Packit ce9521
Packit ce9521
        gmodem_class->get_property = gclue_modem_manager_get_property;
Packit ce9521
        gmodem_class->set_property = gclue_modem_manager_set_property;
Packit ce9521
        gmodem_class->finalize = gclue_modem_manager_finalize;
Packit ce9521
        gmodem_class->constructed = gclue_modem_manager_constructed;
Packit ce9521
Packit ce9521
        g_object_class_override_property (gmodem_class,
Packit ce9521
                                          PROP_IS_3G_AVAILABLE,
Packit ce9521
                                          "is-3g-available");
Packit ce9521
        gParamSpecs[PROP_IS_3G_AVAILABLE] =
Packit ce9521
                        g_object_class_find_property (gmodem_class,
Packit ce9521
                                                      "is-3g-available");
Packit ce9521
        g_object_class_override_property (gmodem_class,
Packit ce9521
                                          PROP_IS_CDMA_AVAILABLE,
Packit ce9521
                                          "is-cdma-available");
Packit ce9521
        gParamSpecs[PROP_IS_CDMA_AVAILABLE] =
Packit ce9521
                        g_object_class_find_property (gmodem_class,
Packit ce9521
                                                      "is-cdma-available");
Packit ce9521
        g_object_class_override_property (gmodem_class,
Packit ce9521
                                          PROP_IS_GPS_AVAILABLE,
Packit ce9521
                                          "is-gps-available");
Packit ce9521
        gParamSpecs[PROP_IS_GPS_AVAILABLE] =
Packit ce9521
                        g_object_class_find_property (gmodem_class,
Packit ce9521
                                                      "is-gps-available");
Packit ce9521
        g_object_class_override_property (gmodem_class,
Packit ce9521
                                          PROP_TIME_THRESHOLD,
Packit ce9521
                                          "time-threshold");
Packit ce9521
        gParamSpecs[PROP_TIME_THRESHOLD] =
Packit ce9521
                        g_object_class_find_property (gmodem_class,
Packit ce9521
                                                      "time-threshold");
Packit ce9521
Packit ce9521
        signals[FIX_3G] = g_signal_lookup ("fix-3g", GCLUE_TYPE_MODEM);
Packit ce9521
        signals[FIX_CDMA] = g_signal_lookup ("fix-cdma", GCLUE_TYPE_MODEM);
Packit ce9521
        signals[FIX_GPS] = g_signal_lookup ("fix-gps", GCLUE_TYPE_MODEM);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_interface_init (GClueModemInterface *iface)
Packit ce9521
{
Packit ce9521
        iface->get_is_3g_available = gclue_modem_manager_get_is_3g_available;
Packit ce9521
        iface->get_is_cdma_available = gclue_modem_manager_get_is_cdma_available;
Packit ce9521
        iface->get_is_gps_available = gclue_modem_manager_get_is_gps_available;
Packit ce9521
        iface->get_time_threshold = gclue_modem_manager_get_time_threshold;
Packit ce9521
        iface->set_time_threshold = gclue_modem_manager_set_time_threshold;
Packit ce9521
        iface->enable_3g = gclue_modem_manager_enable_3g;
Packit ce9521
        iface->enable_3g_finish = gclue_modem_manager_enable_3g_finish;
Packit ce9521
        iface->enable_cdma = gclue_modem_manager_enable_cdma;
Packit ce9521
        iface->enable_cdma_finish = gclue_modem_manager_enable_cdma_finish;
Packit ce9521
        iface->enable_gps = gclue_modem_manager_enable_gps;
Packit ce9521
        iface->enable_gps_finish = gclue_modem_manager_enable_gps_finish;
Packit ce9521
        iface->disable_3g = gclue_modem_manager_disable_3g;
Packit ce9521
        iface->disable_cdma = gclue_modem_manager_disable_cdma;
Packit ce9521
        iface->disable_gps = gclue_modem_manager_disable_gps;
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
is_location_3gpp_same (GClueModemManager *manager,
Packit ce9521
                       guint       new_mcc,
Packit ce9521
                       guint       new_mnc,
Packit ce9521
                       gulong      new_lac,
Packit ce9521
                       gulong      new_cell_id)
Packit ce9521
{
Packit ce9521
        GClueModemManagerPrivate *priv = manager->priv;
Packit ce9521
        guint mcc, mnc;
Packit ce9521
        gulong lac, cell_id;
Packit ce9521
Packit ce9521
        if (priv->location_3gpp == NULL)
Packit ce9521
                return FALSE;
Packit ce9521
Packit ce9521
        mcc = mm_location_3gpp_get_mobile_country_code (priv->location_3gpp);
Packit ce9521
        mnc = mm_location_3gpp_get_mobile_network_code (priv->location_3gpp);
Packit ce9521
        lac = mm_location_3gpp_get_location_area_code (priv->location_3gpp);
Packit ce9521
        cell_id = mm_location_3gpp_get_cell_id (priv->location_3gpp);
Packit ce9521
Packit ce9521
        return (mcc == new_mcc &&
Packit ce9521
                mnc == new_mnc &&
Packit ce9521
                lac == new_lac &&
Packit ce9521
                cell_id == new_cell_id);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_get_3gpp_ready (GObject      *source_object,
Packit ce9521
                   GAsyncResult *res,
Packit ce9521
                   gpointer      user_data)
Packit ce9521
{
Packit ce9521
        GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
Packit ce9521
        GClueModemManagerPrivate *priv = manager->priv;
Packit ce9521
        MMModemLocation *modem_location = MM_MODEM_LOCATION (source_object);
Packit ce9521
        MMLocation3gpp *location_3gpp;
Packit ce9521
        GError *error = NULL;
Packit ce9521
        guint mcc, mnc;
Packit ce9521
        gulong lac, cell_id;
Packit ce9521
Packit ce9521
        location_3gpp = mm_modem_location_get_3gpp_finish (modem_location,
Packit ce9521
                                                           res,
Packit ce9521
                                                           &error);
Packit ce9521
        if (error != NULL) {
Packit ce9521
                g_warning ("Failed to get location from 3GPP: %s",
Packit ce9521
                           error->message);
Packit ce9521
                g_error_free (error);
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        if (location_3gpp == NULL) {
Packit ce9521
                g_debug ("No 3GPP");
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        mcc = mm_location_3gpp_get_mobile_country_code (location_3gpp);
Packit ce9521
        mnc = mm_location_3gpp_get_mobile_network_code (location_3gpp);
Packit ce9521
        lac = mm_location_3gpp_get_location_area_code (location_3gpp);
Packit ce9521
        cell_id = mm_location_3gpp_get_cell_id (location_3gpp);
Packit ce9521
Packit ce9521
        if (is_location_3gpp_same (manager, mcc, mnc, lac, cell_id)) {
Packit ce9521
                g_debug ("New 3GPP location is same as last one");
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
        g_clear_object (&priv->location_3gpp);
Packit ce9521
        priv->location_3gpp = location_3gpp;
Packit ce9521
Packit ce9521
        g_signal_emit (manager, signals[FIX_3G], 0, mcc, mnc, lac, cell_id);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_get_cdma_ready (GObject      *source_object,
Packit ce9521
                   GAsyncResult *res,
Packit ce9521
                   gpointer      user_data)
Packit ce9521
{
Packit ce9521
        GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
Packit ce9521
        MMModemLocation *modem_location = MM_MODEM_LOCATION (source_object);
Packit ce9521
        MMLocationCdmaBs *location_cdma;
Packit ce9521
        GError *error = NULL;
Packit ce9521
Packit ce9521
        location_cdma = mm_modem_location_get_cdma_bs_finish (modem_location,
Packit ce9521
                                                              res,
Packit ce9521
                                                              &error);
Packit ce9521
        if (error != NULL) {
Packit ce9521
                g_warning ("Failed to get location from 3GPP: %s",
Packit ce9521
                           error->message);
Packit ce9521
                g_error_free (error);
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        if (location_cdma == NULL) {
Packit ce9521
                g_debug ("No CDMA");
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        g_signal_emit (manager,
Packit ce9521
                       signals[FIX_CDMA],
Packit ce9521
                       0,
Packit ce9521
                       mm_location_cdma_bs_get_latitude (location_cdma),
Packit ce9521
                       mm_location_cdma_bs_get_longitude (location_cdma));
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
is_location_gga_same (GClueModemManager *manager,
Packit ce9521
                       const char       *new_gga)
Packit ce9521
{
Packit ce9521
        GClueModemManagerPrivate *priv = manager->priv;
Packit ce9521
        const char *gga;
Packit ce9521
Packit ce9521
        if (priv->location_nmea == NULL)
Packit ce9521
                return FALSE;
Packit ce9521
Packit ce9521
        gga = mm_location_gps_nmea_get_trace (priv->location_nmea, "$GPGGA");
Packit ce9521
        return (g_strcmp0 (gga, new_gga) == 0);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_get_gps_nmea_ready (GObject      *source_object,
Packit ce9521
                       GAsyncResult *res,
Packit ce9521
                       gpointer      user_data)
Packit ce9521
{
Packit ce9521
        GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
Packit ce9521
        GClueModemManagerPrivate *priv = manager->priv;
Packit ce9521
        MMModemLocation *modem_location = MM_MODEM_LOCATION (source_object);
Packit ce9521
        MMLocationGpsNmea *location_nmea;
Packit ce9521
        const char *gga;
Packit ce9521
        GError *error = NULL;
Packit ce9521
Packit ce9521
        location_nmea = mm_modem_location_get_gps_nmea_finish (modem_location,
Packit ce9521
                                                               res,
Packit ce9521
                                                               &error);
Packit ce9521
        if (error != NULL) {
Packit ce9521
                g_warning ("Failed to get location from NMEA information: %s",
Packit ce9521
                           error->message);
Packit ce9521
                g_error_free (error);
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        if (location_nmea == NULL) {
Packit ce9521
                g_debug ("No NMEA");
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        gga = mm_location_gps_nmea_get_trace (location_nmea, "$GPGGA");
Packit ce9521
        if (gga == NULL) {
Packit ce9521
                g_debug ("No GGA trace");
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        if (is_location_gga_same (manager, gga)) {
Packit ce9521
                g_debug ("New GGA trace is same as last one: %s", gga);
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
        g_clear_object (&priv->location_nmea);
Packit ce9521
        priv->location_nmea = location_nmea;
Packit ce9521
Packit ce9521
        g_debug ("New GPGGA trace: %s", gga);
Packit ce9521
        g_signal_emit (manager, signals[FIX_GPS], 0, gga);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_location_changed (GObject    *modem_object,
Packit ce9521
                     GParamSpec *pspec,
Packit ce9521
                     gpointer    user_data)
Packit ce9521
{
Packit ce9521
        MMModemLocation *modem_location = MM_MODEM_LOCATION (modem_object);
Packit ce9521
        GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
Packit ce9521
Packit ce9521
        if ((manager->priv->caps & MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI) != 0)
Packit ce9521
                mm_modem_location_get_3gpp (modem_location,
Packit ce9521
                                            manager->priv->cancellable,
Packit ce9521
                                            on_get_3gpp_ready,
Packit ce9521
                                            manager);
Packit ce9521
        if ((manager->priv->caps & MM_MODEM_LOCATION_SOURCE_CDMA_BS) != 0)
Packit ce9521
                mm_modem_location_get_cdma_bs (modem_location,
Packit ce9521
                                               manager->priv->cancellable,
Packit ce9521
                                               on_get_cdma_ready,
Packit ce9521
                                               manager);
Packit ce9521
        if ((manager->priv->caps & MM_MODEM_LOCATION_SOURCE_GPS_NMEA) != 0)
Packit ce9521
                mm_modem_location_get_gps_nmea (modem_location,
Packit ce9521
                                                manager->priv->cancellable,
Packit ce9521
                                                on_get_gps_nmea_ready,
Packit ce9521
                                                manager);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_modem_location_setup (GObject      *modem_object,
Packit ce9521
                         GAsyncResult *res,
Packit ce9521
                         gpointer      user_data)
Packit ce9521
{
Packit ce9521
        GTask *task = G_TASK (user_data);
Packit ce9521
        GClueModemManager *manager;
Packit ce9521
        GClueModemManagerPrivate *priv;
Packit ce9521
        GError *error = NULL;
Packit ce9521
Packit ce9521
        if (!mm_modem_location_setup_finish (MM_MODEM_LOCATION (modem_object),
Packit ce9521
                                             res,
Packit ce9521
                                             &error)) {
Packit ce9521
                g_task_return_error (task, error);
Packit ce9521
Packit ce9521
                goto out;
Packit ce9521
        }
Packit ce9521
        manager = GCLUE_MODEM_MANAGER (g_task_get_source_object (task));
Packit ce9521
        priv = manager->priv;
Packit ce9521
        g_debug ("Modem '%s' setup.", mm_object_get_path (priv->mm_object));
Packit ce9521
Packit ce9521
        on_location_changed (modem_object, NULL, manager);
Packit ce9521
Packit ce9521
        g_task_return_boolean (task, TRUE);
Packit ce9521
out:
Packit ce9521
        g_object_unref (task);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
enable_caps (GClueModemManager    *manager,
Packit ce9521
             MMModemLocationSource caps,
Packit ce9521
             GCancellable         *cancellable,
Packit ce9521
             GAsyncReadyCallback   callback,
Packit ce9521
             gpointer              user_data)
Packit ce9521
{
Packit ce9521
        GClueModemManagerPrivate *priv = manager->priv;
Packit ce9521
        GTask *task;
Packit ce9521
Packit ce9521
        priv->caps |= caps;
Packit ce9521
        task = g_task_new (manager, cancellable, callback, user_data);
Packit ce9521
Packit ce9521
        priv = GCLUE_MODEM_MANAGER (g_task_get_source_object (task))->priv;
Packit ce9521
Packit ce9521
        caps = mm_modem_location_get_enabled (priv->modem_location) | priv->caps;
Packit ce9521
        mm_modem_location_setup (priv->modem_location,
Packit ce9521
                                 caps,
Packit ce9521
                                 TRUE,
Packit ce9521
                                 g_task_get_cancellable (task),
Packit ce9521
                                 on_modem_location_setup,
Packit ce9521
                                 task);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
enable_caps_finish (GClueModemManager   *manager,
Packit ce9521
                    GAsyncResult *result,
Packit ce9521
                    GError      **error)
Packit ce9521
{
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (manager), FALSE);
Packit ce9521
        g_return_val_if_fail (g_task_is_valid (result, manager), FALSE);
Packit ce9521
Packit ce9521
        return g_task_propagate_boolean (G_TASK (result), error);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
clear_caps (GClueModemManager    *manager,
Packit ce9521
            MMModemLocationSource caps,
Packit ce9521
            GCancellable         *cancellable,
Packit ce9521
            GError              **error)
Packit ce9521
{
Packit ce9521
        GClueModemManagerPrivate *priv;
Packit ce9521
Packit ce9521
        priv = manager->priv;
Packit ce9521
Packit ce9521
        if (priv->modem_location == NULL)
Packit ce9521
                return TRUE;
Packit ce9521
Packit ce9521
        priv->caps &= ~caps;
Packit ce9521
Packit ce9521
        return mm_modem_location_setup_sync (priv->modem_location,
Packit ce9521
                                             priv->caps,
Packit ce9521
                                             FALSE,
Packit ce9521
                                             cancellable,
Packit ce9521
                                             error);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
modem_has_caps (GClueModemManager    *manager,
Packit ce9521
                MMModemLocationSource caps)
Packit ce9521
{
Packit ce9521
        MMModemLocation *modem_location = manager->priv->modem_location;
Packit ce9521
        MMModemLocationSource avail_caps;
Packit ce9521
Packit ce9521
        if (modem_location == NULL)
Packit ce9521
                return FALSE;
Packit ce9521
Packit ce9521
        avail_caps = mm_modem_location_get_capabilities (modem_location);
Packit ce9521
Packit ce9521
        return ((caps & avail_caps) != 0);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_mm_object_added (GDBusObjectManager *object_manager,
Packit ce9521
                    GDBusObject        *object,
Packit ce9521
                    gpointer            user_data);
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_mm_modem_state_notify (GObject    *gobject,
Packit ce9521
                          GParamSpec *pspec,
Packit ce9521
                          gpointer    user_data)
Packit ce9521
{
Packit ce9521
        MMModem *mm_modem = MM_MODEM (gobject);
Packit ce9521
        GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
Packit ce9521
        GClueModemManagerPrivate *priv = manager->priv;
Packit ce9521
        GDBusObjectManager *obj_manager = G_DBUS_OBJECT_MANAGER (priv->manager);
Packit ce9521
        const char *path = mm_modem_get_path (mm_modem);
Packit ce9521
        GDBusObject *object;
Packit ce9521
Packit ce9521
        if (priv->mm_object != NULL) {
Packit ce9521
                // In the meantime another modem with location caps was found.
Packit ce9521
                g_signal_handlers_disconnect_by_func (mm_modem,
Packit ce9521
                                                      on_mm_modem_state_notify,
Packit ce9521
                                                      user_data);
Packit ce9521
                g_object_unref (gobject);
Packit ce9521
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        if (mm_modem_get_state (mm_modem) < MM_MODEM_STATE_ENABLED)
Packit ce9521
                return;
Packit ce9521
Packit ce9521
        g_debug ("Modem '%s' now enabled", path);
Packit ce9521
Packit ce9521
        g_signal_handlers_disconnect_by_func (mm_modem,
Packit ce9521
                                              on_mm_modem_state_notify,
Packit ce9521
                                              user_data);
Packit ce9521
Packit ce9521
        object = g_dbus_object_manager_get_object (obj_manager, path);
Packit ce9521
        on_mm_object_added (obj_manager, object, user_data);
Packit ce9521
        g_object_unref (mm_modem);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_gps_refresh_rate_set (GObject      *source_object,
Packit ce9521
                         GAsyncResult *res,
Packit ce9521
                         gpointer      user_data)
Packit ce9521
{
Packit ce9521
        gboolean ret;
Packit ce9521
        GError *error = NULL;
Packit ce9521
Packit ce9521
        ret = mm_modem_location_set_gps_refresh_rate_finish
Packit ce9521
                (MM_MODEM_LOCATION (source_object), res, &error);
Packit ce9521
        if (!ret) {
Packit ce9521
                g_warning ("Failed to set GPS refresh rate: %s",
Packit ce9521
                           error->message);
Packit ce9521
                g_error_free (error);
Packit ce9521
        }
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_mm_object_added (GDBusObjectManager *object_manager,
Packit ce9521
                    GDBusObject        *object,
Packit ce9521
                    gpointer            user_data)
Packit ce9521
{
Packit ce9521
        MMObject *mm_object = MM_OBJECT (object);
Packit ce9521
        GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
Packit ce9521
        MMModem *mm_modem;
Packit ce9521
        MMModemLocation *modem_location;
Packit ce9521
Packit ce9521
        if (manager->priv->mm_object != NULL)
Packit ce9521
                return;
Packit ce9521
Packit ce9521
        g_debug ("New modem '%s'", mm_object_get_path (mm_object));
Packit ce9521
        mm_modem = mm_object_get_modem (mm_object);
Packit ce9521
        if (mm_modem_get_state (mm_modem) < MM_MODEM_STATE_ENABLED) {
Packit ce9521
                g_debug ("Modem '%s' not enabled",
Packit ce9521
                         mm_object_get_path (mm_object));
Packit ce9521
Packit ce9521
                g_signal_connect_object (mm_modem,
Packit ce9521
                                         "notify::state",
Packit ce9521
                                         G_CALLBACK (on_mm_modem_state_notify),
Packit ce9521
                                         manager,
Packit ce9521
                                         0);
Packit ce9521
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        modem_location = mm_object_peek_modem_location (mm_object);
Packit ce9521
        if (modem_location == NULL)
Packit ce9521
                return;
Packit ce9521
Packit ce9521
        g_debug ("Modem '%s' has location capabilities",
Packit ce9521
                 mm_object_get_path (mm_object));
Packit ce9521
Packit ce9521
        manager->priv->mm_object = g_object_ref (mm_object);
Packit ce9521
        manager->priv->modem = mm_modem;
Packit ce9521
        manager->priv->modem_location = mm_object_get_modem_location (mm_object);
Packit ce9521
Packit ce9521
        mm_modem_location_set_gps_refresh_rate (manager->priv->modem_location,
Packit ce9521
                                                manager->priv->time_threshold,
Packit ce9521
                                                manager->priv->cancellable,
Packit ce9521
                                                on_gps_refresh_rate_set,
Packit ce9521
                                                NULL);
Packit ce9521
Packit ce9521
        g_signal_connect (G_OBJECT (manager->priv->modem_location),
Packit ce9521
                          "notify::location",
Packit ce9521
                          G_CALLBACK (on_location_changed),
Packit ce9521
                          manager);
Packit ce9521
Packit ce9521
        g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_3G_AVAILABLE]);
Packit ce9521
        g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_CDMA_AVAILABLE]);
Packit ce9521
        g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_GPS_AVAILABLE]);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_mm_object_removed (GDBusObjectManager *object_manager,
Packit ce9521
                      GDBusObject        *object,
Packit ce9521
                      gpointer            user_data)
Packit ce9521
{
Packit ce9521
        MMObject *mm_object = MM_OBJECT (object);
Packit ce9521
        GClueModemManager *manager = GCLUE_MODEM_MANAGER (user_data);
Packit ce9521
        GClueModemManagerPrivate *priv = manager->priv;
Packit ce9521
Packit ce9521
        if (priv->mm_object == NULL || priv->mm_object != mm_object)
Packit ce9521
                return;
Packit ce9521
        g_debug ("Modem '%s' removed.", mm_object_get_path (priv->mm_object));
Packit ce9521
Packit ce9521
        g_signal_handlers_disconnect_by_func (G_OBJECT (priv->modem_location),
Packit ce9521
                                              G_CALLBACK (on_location_changed),
Packit ce9521
                                              user_data);
Packit ce9521
        g_clear_object (&priv->mm_object);
Packit ce9521
        g_clear_object (&priv->modem);
Packit ce9521
        g_clear_object (&priv->modem_location);
Packit ce9521
Packit ce9521
        g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_3G_AVAILABLE]);
Packit ce9521
        g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_CDMA_AVAILABLE]);
Packit ce9521
        g_object_notify_by_pspec (G_OBJECT (manager), gParamSpecs[PROP_IS_GPS_AVAILABLE]);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_manager_new_ready (GObject      *modem_object,
Packit ce9521
                      GAsyncResult *res,
Packit ce9521
                      gpointer      user_data)
Packit ce9521
{
Packit ce9521
        GClueModemManagerPrivate *priv = GCLUE_MODEM_MANAGER (user_data)->priv;
Packit ce9521
        GList *objects, *node;
Packit ce9521
        GError *error = NULL;
Packit ce9521
Packit ce9521
        priv->manager = mm_manager_new_finish (res, &error);
Packit ce9521
        if (priv->manager == NULL) {
Packit ce9521
                g_warning ("Failed to connect to ModemManager: %s",
Packit ce9521
                           error->message);
Packit ce9521
                g_error_free (error);
Packit ce9521
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        objects = g_dbus_object_manager_get_objects
Packit ce9521
                        (G_DBUS_OBJECT_MANAGER (priv->manager));
Packit ce9521
        for (node = objects; node != NULL; node = node->next) {
Packit ce9521
                on_mm_object_added (G_DBUS_OBJECT_MANAGER (priv->manager),
Packit ce9521
                                    G_DBUS_OBJECT (node->data),
Packit ce9521
                                    user_data);
Packit ce9521
Packit ce9521
                /* FIXME: Currently we only support 1 modem device */
Packit ce9521
                if (priv->modem != NULL)
Packit ce9521
                        break;
Packit ce9521
        }
Packit ce9521
        g_list_free_full (objects, g_object_unref);
Packit ce9521
Packit ce9521
        g_signal_connect (G_OBJECT (priv->manager),
Packit ce9521
                          "object-added",
Packit ce9521
                          G_CALLBACK (on_mm_object_added),
Packit ce9521
                          user_data);
Packit ce9521
Packit ce9521
        g_signal_connect (G_OBJECT (priv->manager),
Packit ce9521
                          "object-removed",
Packit ce9521
                          G_CALLBACK (on_mm_object_removed),
Packit ce9521
                          user_data);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_bus_get_ready (GObject      *modem_object,
Packit ce9521
                  GAsyncResult *res,
Packit ce9521
                  gpointer      user_data)
Packit ce9521
{
Packit ce9521
        GClueModemManagerPrivate *priv = GCLUE_MODEM_MANAGER (user_data)->priv;
Packit ce9521
        GDBusConnection *connection;
Packit ce9521
        GError *error = NULL;
Packit ce9521
Packit ce9521
        connection = g_bus_get_finish (res, &error);
Packit ce9521
        if (connection == NULL) {
Packit ce9521
                g_warning ("Failed to connect to system D-Bus: %s",
Packit ce9521
                           error->message);
Packit ce9521
                g_error_free (error);
Packit ce9521
Packit ce9521
                return;
Packit ce9521
        }
Packit ce9521
Packit ce9521
        mm_manager_new (connection,
Packit ce9521
                        0,
Packit ce9521
                        priv->cancellable,
Packit ce9521
                        on_manager_new_ready,
Packit ce9521
                        user_data);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_constructed (GObject *object)
Packit ce9521
{
Packit ce9521
        GClueModemManagerPrivate *priv = GCLUE_MODEM_MANAGER (object)->priv;
Packit ce9521
Packit ce9521
        G_OBJECT_CLASS (gclue_modem_manager_parent_class)->constructed (object);
Packit ce9521
Packit ce9521
        priv->cancellable = g_cancellable_new ();
Packit ce9521
Packit ce9521
        g_bus_get (G_BUS_TYPE_SYSTEM,
Packit ce9521
                   priv->cancellable,
Packit ce9521
                   on_bus_get_ready,
Packit ce9521
                   object);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_init (GClueModemManager *manager)
Packit ce9521
{
Packit ce9521
        manager->priv = G_TYPE_INSTANCE_GET_PRIVATE ((manager),
Packit ce9521
                                                     GCLUE_TYPE_MODEM_MANAGER,
Packit ce9521
                                                     GClueModemManagerPrivate);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
on_modem_destroyed (gpointer data,
Packit ce9521
                    GObject *where_the_object_was)
Packit ce9521
{
Packit ce9521
        GClueModemManager **manager = (GClueModemManager **) data;
Packit ce9521
Packit ce9521
        *manager = NULL;
Packit ce9521
}
Packit ce9521
Packit ce9521
/**
Packit ce9521
 * gclue_modem_manager_get_singleton:
Packit ce9521
 *
Packit ce9521
 * Get the #GClueModemManager singleton.
Packit ce9521
 *
Packit ce9521
 * Returns: (transfer full): a #GClueModemManager as #GClueModem.
Packit ce9521
 **/
Packit ce9521
GClueModem *
Packit ce9521
gclue_modem_manager_get_singleton (void)
Packit ce9521
{
Packit ce9521
        static GClueModemManager *manager = NULL;
Packit ce9521
Packit ce9521
        if (manager == NULL) {
Packit ce9521
                manager = g_object_new (GCLUE_TYPE_MODEM_MANAGER, NULL);
Packit ce9521
                g_object_weak_ref (G_OBJECT (manager),
Packit ce9521
                                   on_modem_destroyed,
Packit ce9521
                                   &manager);
Packit ce9521
        } else
Packit ce9521
                g_object_ref (manager);
Packit ce9521
Packit ce9521
        return GCLUE_MODEM (manager);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_get_is_3g_available (GClueModem *modem)
Packit ce9521
{
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
Packit ce9521
        return modem_has_caps (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                                MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_get_is_cdma_available (GClueModem *modem)
Packit ce9521
{
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
Packit ce9521
        return modem_has_caps (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                               MM_MODEM_LOCATION_SOURCE_CDMA_BS);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_get_is_gps_available (GClueModem *modem)
Packit ce9521
{
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
Packit ce9521
        return modem_has_caps (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                               MM_MODEM_LOCATION_SOURCE_GPS_NMEA);
Packit ce9521
}
Packit ce9521
Packit ce9521
static guint
Packit ce9521
gclue_modem_manager_get_time_threshold (GClueModem *modem)
Packit ce9521
{
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), 0);
Packit ce9521
Packit ce9521
        return GCLUE_MODEM_MANAGER (modem)->priv->time_threshold;
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_set_time_threshold (GClueModem *modem,
Packit ce9521
                                        guint       time_threshold)
Packit ce9521
{
Packit ce9521
        GClueModemManager *manager;
Packit ce9521
Packit ce9521
        g_return_if_fail (GCLUE_IS_MODEM_MANAGER (modem));
Packit ce9521
Packit ce9521
        manager = GCLUE_MODEM_MANAGER (modem);
Packit ce9521
        manager->priv->time_threshold = time_threshold;
Packit ce9521
Packit ce9521
        if (manager->priv->modem_location != NULL) {
Packit ce9521
                mm_modem_location_set_gps_refresh_rate
Packit ce9521
                        (manager->priv->modem_location,
Packit ce9521
                         time_threshold,
Packit ce9521
                         manager->priv->cancellable,
Packit ce9521
                         on_gps_refresh_rate_set,
Packit ce9521
                         NULL);
Packit ce9521
        }
Packit ce9521
Packit ce9521
        g_object_notify_by_pspec (G_OBJECT (manager),
Packit ce9521
                                  gParamSpecs[PROP_TIME_THRESHOLD]);
Packit ce9521
        g_debug ("%s: New time-threshold:  %u",
Packit ce9521
                 G_OBJECT_TYPE_NAME (manager),
Packit ce9521
                 time_threshold);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_enable_3g (GClueModem         *modem,
Packit ce9521
                               GCancellable       *cancellable,
Packit ce9521
                               GAsyncReadyCallback callback,
Packit ce9521
                               gpointer            user_data)
Packit ce9521
{
Packit ce9521
        g_return_if_fail (GCLUE_IS_MODEM_MANAGER (modem));
Packit ce9521
        g_return_if_fail (gclue_modem_manager_get_is_3g_available (modem));
Packit ce9521
Packit ce9521
        enable_caps (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                     MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
Packit ce9521
                     cancellable,
Packit ce9521
                     callback,
Packit ce9521
                     user_data);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_enable_3g_finish (GClueModem   *modem,
Packit ce9521
                                      GAsyncResult *result,
Packit ce9521
                                      GError      **error)
Packit ce9521
{
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
Packit ce9521
        return enable_caps_finish (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                                   result,
Packit ce9521
                                   error);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_enable_cdma (GClueModem         *modem,
Packit ce9521
                                 GCancellable       *cancellable,
Packit ce9521
                                 GAsyncReadyCallback callback,
Packit ce9521
                                 gpointer            user_data)
Packit ce9521
{
Packit ce9521
        g_return_if_fail (GCLUE_IS_MODEM_MANAGER (modem));
Packit ce9521
        g_return_if_fail (gclue_modem_manager_get_is_cdma_available (modem));
Packit ce9521
Packit ce9521
        enable_caps (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                     MM_MODEM_LOCATION_SOURCE_CDMA_BS,
Packit ce9521
                     cancellable,
Packit ce9521
                     callback,
Packit ce9521
                     user_data);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_enable_cdma_finish (GClueModem   *modem,
Packit ce9521
                                        GAsyncResult *result,
Packit ce9521
                                        GError      **error)
Packit ce9521
{
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
Packit ce9521
        return enable_caps_finish (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                                   result,
Packit ce9521
                                   error);
Packit ce9521
}
Packit ce9521
Packit ce9521
static void
Packit ce9521
gclue_modem_manager_enable_gps (GClueModem         *modem,
Packit ce9521
                                GCancellable       *cancellable,
Packit ce9521
                                GAsyncReadyCallback callback,
Packit ce9521
                                gpointer            user_data)
Packit ce9521
{
Packit ce9521
        g_return_if_fail (GCLUE_IS_MODEM_MANAGER (modem));
Packit ce9521
        g_return_if_fail (gclue_modem_manager_get_is_gps_available (modem));
Packit ce9521
Packit ce9521
        enable_caps (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                     MM_MODEM_LOCATION_SOURCE_GPS_NMEA,
Packit ce9521
                     cancellable,
Packit ce9521
                     callback,
Packit ce9521
                     user_data);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_enable_gps_finish (GClueModem   *modem,
Packit ce9521
                                       GAsyncResult *result,
Packit ce9521
                                       GError      **error)
Packit ce9521
{
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
Packit ce9521
        return enable_caps_finish (GCLUE_MODEM_MANAGER (modem),
Packit ce9521
                                   result,
Packit ce9521
                                   error);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_disable_3g (GClueModem   *modem,
Packit ce9521
                                GCancellable *cancellable,
Packit ce9521
                                GError      **error)
Packit ce9521
{
Packit ce9521
        GClueModemManager *manager;
Packit ce9521
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
        g_return_val_if_fail (gclue_modem_manager_get_is_3g_available (modem), FALSE);
Packit ce9521
        manager = GCLUE_MODEM_MANAGER (modem);
Packit ce9521
Packit ce9521
        g_clear_object (&manager->priv->location_3gpp);
Packit ce9521
        g_debug ("Clearing 3GPP location caps from modem");
Packit ce9521
        return clear_caps (manager,
Packit ce9521
                           MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI,
Packit ce9521
                           cancellable,
Packit ce9521
                           error);
Packit ce9521
}
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_disable_cdma (GClueModem   *modem,
Packit ce9521
                                  GCancellable *cancellable,
Packit ce9521
                                  GError      **error)
Packit ce9521
{
Packit ce9521
        GClueModemManager *manager;
Packit ce9521
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
        g_return_val_if_fail (gclue_modem_manager_get_is_cdma_available (modem), FALSE);
Packit ce9521
        manager = GCLUE_MODEM_MANAGER (modem);
Packit ce9521
Packit ce9521
        g_clear_object (&manager->priv->location_3gpp);
Packit ce9521
        g_debug ("Clearing CDMA location caps from modem");
Packit ce9521
        return clear_caps (manager,
Packit ce9521
                           MM_MODEM_LOCATION_SOURCE_CDMA_BS,
Packit ce9521
                           cancellable,
Packit ce9521
                           error);
Packit ce9521
}
Packit ce9521
Packit ce9521
Packit ce9521
static gboolean
Packit ce9521
gclue_modem_manager_disable_gps (GClueModem   *modem,
Packit ce9521
                                 GCancellable *cancellable,
Packit ce9521
                                 GError      **error)
Packit ce9521
{
Packit ce9521
        GClueModemManager *manager;
Packit ce9521
Packit ce9521
        g_return_val_if_fail (GCLUE_IS_MODEM_MANAGER (modem), FALSE);
Packit ce9521
        g_return_val_if_fail (gclue_modem_manager_get_is_gps_available (modem), FALSE);
Packit ce9521
        manager = GCLUE_MODEM_MANAGER (modem);
Packit ce9521
Packit ce9521
        g_clear_object (&manager->priv->location_nmea);
Packit ce9521
        g_debug ("Clearing GPS NMEA caps from modem");
Packit ce9521
        return clear_caps (manager,
Packit ce9521
                           MM_MODEM_LOCATION_SOURCE_GPS_NMEA,
Packit ce9521
                           cancellable,
Packit ce9521
                           error);
Packit ce9521
}