aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-callback-info.c276
-rw-r--r--src/mm-callback-info.h87
-rw-r--r--src/mm-generic-cdma.c2626
-rw-r--r--src/mm-generic-cdma.h155
-rw-r--r--src/mm-generic-gsm.c7020
-rw-r--r--src/mm-generic-gsm.h265
-rw-r--r--src/mm-modem-base.c1323
-rw-r--r--src/mm-modem-base.h121
-rw-r--r--src/mm-modem-cdma.c433
-rw-r--r--src/mm-modem-cdma.h126
-rw-r--r--src/mm-modem-firmware.c316
-rw-r--r--src/mm-modem-firmware.h72
-rw-r--r--src/mm-modem-gsm-card.c702
-rw-r--r--src/mm-modem-gsm-card.h134
-rw-r--r--src/mm-modem-gsm-network.c647
-rw-r--r--src/mm-modem-gsm-network.h158
-rw-r--r--src/mm-modem-gsm-sms.c836
-rw-r--r--src/mm-modem-gsm-sms.h114
-rw-r--r--src/mm-modem-gsm-ussd.c404
-rw-r--r--src/mm-modem-gsm-ussd.h95
-rw-r--r--src/mm-modem-location.c331
-rw-r--r--src/mm-modem-location.h69
-rw-r--r--src/mm-modem-simple.c156
-rw-r--r--src/mm-modem-simple.h59
-rw-r--r--src/mm-modem.c1008
-rw-r--r--src/mm-modem.h300
-rw-r--r--src/mm-properties-changed-signal.c352
-rw-r--r--src/mm-properties-changed-signal.h40
-rw-r--r--src/mm-sms-utils.c795
-rw-r--r--src/mm-sms-utils.h49
30 files changed, 0 insertions, 19069 deletions
diff --git a/src/mm-callback-info.c b/src/mm-callback-info.c
deleted file mode 100644
index bbe6cb88..00000000
--- a/src/mm-callback-info.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#include "mm-callback-info.h"
-
-#include <ModemManager.h>
-#include <mm-errors-types.h>
-
-#define CALLBACK_INFO_RESULT "callback-info-result"
-
-static void
-invoke_mm_modem_fn (MMCallbackInfo *info)
-{
- MMModemFn callback = (MMModemFn) info->callback;
-
- callback (info->modem, info->error, info->user_data);
-}
-
-static void
-invoke_mm_modem_uint_fn (MMCallbackInfo *info)
-{
- MMModemUIntFn callback = (MMModemUIntFn) info->callback;
-
- callback (info->modem,
- GPOINTER_TO_UINT (mm_callback_info_get_data (info, CALLBACK_INFO_RESULT)),
- info->error, info->user_data);
-}
-
-static void
-invoke_mm_modem_string_fn (MMCallbackInfo *info)
-{
- MMModemStringFn callback = (MMModemStringFn) info->callback;
-
- callback (info->modem,
- (const char *) mm_callback_info_get_data (info, CALLBACK_INFO_RESULT),
- info->error, info->user_data);
-}
-
-static void
-invoke_mm_modem_array_fn (MMCallbackInfo *info)
-{
- MMModemArrayFn callback = (MMModemArrayFn) info->callback;
-
- callback (info->modem,
- (GArray *) mm_callback_info_get_data (info, CALLBACK_INFO_RESULT),
- info->error, info->user_data);
-}
-
-static void
-modem_destroyed_cb (gpointer data, GObject *destroyed)
-{
- MMCallbackInfo *info = data;
-
- /* Reset modem pointer, so that callback know that they shouldn't do
- * anything else */
- info->modem = NULL;
-
- /* Overwrite any possible previous error set */
- g_clear_error (&(info->error));
- info->error = g_error_new_literal (MM_CORE_ERROR,
- MM_CORE_ERROR_ABORTED,
- "The modem was removed.");
-
- /* Only schedule the info if not already done before */
- if (!info->pending_id)
- mm_callback_info_schedule (info);
-}
-
-static void
-callback_info_done (gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- info->pending_id = 0;
- info->called = TRUE;
-
- if (info->invoke_fn && info->callback)
- info->invoke_fn (info);
-
- mm_callback_info_unref (info);
-}
-
-static gboolean
-callback_info_do (gpointer user_data)
-{
- /* Nothing here, everything is done in callback_info_done to make sure the info->callback
- always gets called, even if the pending call gets cancelled. */
- return FALSE;
-}
-
-void
-mm_callback_info_schedule (MMCallbackInfo *info)
-{
- g_return_if_fail (info != NULL);
- g_return_if_fail (info->pending_id == 0);
- g_return_if_fail (info->called == FALSE);
-
- g_warn_if_fail (info->chain_left == 0);
-
- info->pending_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, callback_info_do, info, callback_info_done);
-}
-
-MMCallbackInfo *
-mm_callback_info_new_full (MMModem *modem,
- MMCallbackInfoInvokeFn invoke_fn,
- GCallback callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- g_return_val_if_fail (modem != NULL, NULL);
-
- info = g_slice_new0 (MMCallbackInfo);
- g_datalist_init (&info->qdata);
- info->modem = modem;
- g_object_weak_ref (G_OBJECT (modem), modem_destroyed_cb, info);
- info->invoke_fn = invoke_fn;
- info->callback = callback;
- info->user_data = user_data;
- info->refcount = 1;
-
- return info;
-}
-
-MMCallbackInfo *
-mm_callback_info_new (MMModem *modem, MMModemFn callback, gpointer user_data)
-{
- g_return_val_if_fail (modem != NULL, NULL);
-
- return mm_callback_info_new_full (modem, invoke_mm_modem_fn, (GCallback) callback, user_data);
-}
-
-MMCallbackInfo *
-mm_callback_info_uint_new (MMModem *modem,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- g_return_val_if_fail (modem != NULL, NULL);
-
- return mm_callback_info_new_full (modem, invoke_mm_modem_uint_fn, (GCallback) callback, user_data);
-}
-
-MMCallbackInfo *
-mm_callback_info_string_new (MMModem *modem,
- MMModemStringFn callback,
- gpointer user_data)
-{
- g_return_val_if_fail (modem != NULL, NULL);
-
- return mm_callback_info_new_full (modem, invoke_mm_modem_string_fn, (GCallback) callback, user_data);
-}
-
-MMCallbackInfo *
-mm_callback_info_array_new (MMModem *modem,
- MMModemArrayFn callback,
- gpointer user_data)
-{
- g_return_val_if_fail (modem != NULL, NULL);
-
- return mm_callback_info_new_full (modem, invoke_mm_modem_array_fn, (GCallback) callback, user_data);
-}
-
-gpointer
-mm_callback_info_get_result (MMCallbackInfo *info)
-{
- g_return_val_if_fail (info != NULL, NULL);
-
- return mm_callback_info_get_data (info, CALLBACK_INFO_RESULT);
-}
-
-void
-mm_callback_info_set_result (MMCallbackInfo *info,
- gpointer data,
- GDestroyNotify destroy)
-{
- g_return_if_fail (info != NULL);
-
- mm_callback_info_set_data (info, CALLBACK_INFO_RESULT, data, destroy);
-}
-
-void
-mm_callback_info_set_data (MMCallbackInfo *info,
- const char *key,
- gpointer data,
- GDestroyNotify destroy)
-{
- g_return_if_fail (info != NULL);
- g_return_if_fail (key != NULL);
-
- g_datalist_id_set_data_full (&info->qdata, g_quark_from_string (key), data,
- data ? destroy : (GDestroyNotify) NULL);
-}
-
-gpointer
-mm_callback_info_get_data (MMCallbackInfo *info, const char *key)
-{
- GQuark quark;
-
- g_return_val_if_fail (info != NULL, NULL);
- g_return_val_if_fail (key != NULL, NULL);
-
- quark = g_quark_try_string (key);
-
- return quark ? g_datalist_id_get_data (&info->qdata, quark) : NULL;
-}
-
-gboolean
-mm_callback_info_check_modem_removed (MMCallbackInfo *info)
-{
- g_return_val_if_fail (info != NULL, TRUE);
-
- return (info->modem ? FALSE : TRUE);
-}
-
-MMCallbackInfo *
-mm_callback_info_ref (MMCallbackInfo *info)
-{
- g_return_val_if_fail (info != NULL, NULL);
- g_return_val_if_fail (info->refcount > 0, NULL);
-
- info->refcount++;
- return info;
-}
-
-void
-mm_callback_info_unref (MMCallbackInfo *info)
-{
- g_return_if_fail (info != NULL);
-
- info->refcount--;
- if (info->refcount == 0) {
- if (info->error)
- g_error_free (info->error);
-
- if (info->modem)
- g_object_weak_unref (G_OBJECT (info->modem), modem_destroyed_cb, info);
-
- g_datalist_clear (&info->qdata);
- g_slice_free (MMCallbackInfo, info);
- }
-}
-
-void
-mm_callback_info_chain_start (MMCallbackInfo *info, guint num)
-{
- g_return_if_fail (info != NULL);
- g_return_if_fail (num > 0);
- g_return_if_fail (info->chain_left == 0);
-
- info->chain_left = num;
-}
-
-void
-mm_callback_info_chain_complete_one (MMCallbackInfo *info)
-{
- g_return_if_fail (info != NULL);
- g_return_if_fail (info->chain_left > 0);
-
- info->chain_left--;
- if (info->chain_left == 0)
- mm_callback_info_schedule (info);
-}
-
diff --git a/src/mm-callback-info.h b/src/mm-callback-info.h
deleted file mode 100644
index 67fea8d5..00000000
--- a/src/mm-callback-info.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- */
-
-#ifndef MM_CALLBACK_INFO_H
-#define MM_CALLBACK_INFO_H
-
-#include "mm-modem.h"
-
-typedef struct _MMCallbackInfo MMCallbackInfo;
-
-typedef void (*MMCallbackInfoInvokeFn) (MMCallbackInfo *info);
-
-struct _MMCallbackInfo {
- guint32 refcount;
-
- /* # of ops left in this callback chain */
- guint32 chain_left;
-
- GData *qdata;
- MMModem *modem;
-
- MMCallbackInfoInvokeFn invoke_fn;
- GCallback callback;
- gboolean called;
-
- gpointer user_data;
- GError *error;
- guint pending_id;
-};
-
-MMCallbackInfo *mm_callback_info_new_full (MMModem *modem,
- MMCallbackInfoInvokeFn invoke_fn,
- GCallback callback,
- gpointer user_data);
-
-MMCallbackInfo *mm_callback_info_new (MMModem *modem,
- MMModemFn callback,
- gpointer user_data);
-
-MMCallbackInfo *mm_callback_info_uint_new (MMModem *modem,
- MMModemUIntFn callback,
- gpointer user_data);
-
-MMCallbackInfo *mm_callback_info_string_new (MMModem *modem,
- MMModemStringFn callback,
- gpointer user_data);
-
-MMCallbackInfo *mm_callback_info_array_new (MMModem *modem,
- MMModemArrayFn callback,
- gpointer user_data);
-
-void mm_callback_info_schedule (MMCallbackInfo *info);
-gpointer mm_callback_info_get_result (MMCallbackInfo *info);
-void mm_callback_info_set_result (MMCallbackInfo *info,
- gpointer data,
- GDestroyNotify destroy);
-
-void mm_callback_info_set_data (MMCallbackInfo *info,
- const char *key,
- gpointer data,
- GDestroyNotify destroy);
-
-gpointer mm_callback_info_get_data (MMCallbackInfo *info,
- const char *key);
-
-gboolean mm_callback_info_check_modem_removed (MMCallbackInfo *info);
-
-MMCallbackInfo *mm_callback_info_ref (MMCallbackInfo *info);
-void mm_callback_info_unref (MMCallbackInfo *info);
-
-void mm_callback_info_chain_start (MMCallbackInfo *info, guint num);
-void mm_callback_info_chain_complete_one (MMCallbackInfo *info);
-
-#endif /* MM_CALLBACK_INFO_H */
-
diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c
deleted file mode 100644
index 5397ce95..00000000
--- a/src/mm-generic-cdma.c
+++ /dev/null
@@ -1,2626 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-
-#include "mm-generic-cdma.h"
-#include "mm-modem-cdma.h"
-#include "mm-modem-simple.h"
-#include "mm-at-serial-port.h"
-#include "mm-qcdm-serial-port.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-serial-parsers.h"
-#include "mm-modem-helpers.h"
-#include "libqcdm/src/commands.h"
-#include "libqcdm/src/errors.h"
-#include "mm-log.h"
-
-#define MM_GENERIC_CDMA_PREV_STATE_TAG "prev-state"
-
-typedef enum {
- RM_PROTO_ASYNC = 0,
- RM_PROTO_RELAY = 1,
- RM_PROTO_NETWORK_PPP = 2,
- RM_PROTO_NETWORK_SLIP = 3,
- RM_PROTO_STU_III = 4
-} RmProtocol;
-
-
-static void simple_reg_callback (MMModemCdma *modem,
- MMModemCdmaRegistrationState cdma_1x_reg_state,
- MMModemCdmaRegistrationState evdo_reg_state,
- GError *error,
- gpointer user_data);
-
-static void simple_state_machine (MMModem *modem, GError *error, gpointer user_data);
-
-static void update_enabled_state (MMGenericCdma *self,
- gboolean stay_connected,
- MMModemStateReason reason);
-
-static void modem_init (MMModem *modem_class);
-static void modem_cdma_init (MMModemCdma *cdma_class);
-static void modem_simple_init (MMModemSimple *class);
-
-G_DEFINE_TYPE_EXTENDED (MMGenericCdma, mm_generic_cdma, MM_TYPE_MODEM_BASE, 0,
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_CDMA, modem_cdma_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init))
-
-#define MM_GENERIC_CDMA_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_GENERIC_CDMA, MMGenericCdmaPrivate))
-
-typedef struct {
- guint32 cdma1x_quality;
- guint32 evdo_quality;
- gboolean valid;
- gboolean evdo_rev0;
- gboolean evdo_revA;
- gboolean reg_try_css;
- gboolean has_spservice;
- gboolean has_speri;
-
- /* Original and current Rm interface protocol */
- RmProtocol orig_crm;
- RmProtocol cur_crm;
-
- guint poll_id;
-
- char *meid;
-
- MMModemCdmaRegistrationState cdma_1x_reg_state;
- MMModemCdmaRegistrationState evdo_reg_state;
-
- guint reg_tries;
- guint reg_retry_id;
- guint reg_state_changed_id;
- MMCallbackInfo *simple_connect_info;
-
- MMAtSerialPort *primary;
- MMAtSerialPort *secondary;
- MMQcdmSerialPort *qcdm;
- MMPort *data;
- gboolean data_opened_at_connect;
-} MMGenericCdmaPrivate;
-
-enum {
- PROP_0,
- PROP_EVDO_REV0,
- PROP_EVDO_REVA,
- PROP_REG_TRY_CSS,
- LAST_PROP
-};
-
-MMModem *
-mm_generic_cdma_new (const char *device,
- const char *driver,
- const char *plugin,
- gboolean evdo_rev0,
- gboolean evdo_revA,
- guint vendor,
- guint product)
-{
- g_return_val_if_fail (device != NULL, NULL);
- g_return_val_if_fail (driver != NULL, NULL);
- g_return_val_if_fail (plugin != NULL, NULL);
-
- return MM_MODEM (g_object_new (MM_TYPE_GENERIC_CDMA,
- MM_MODEM_MASTER_DEVICE, device,
- MM_MODEM_DRIVER, driver,
- MM_MODEM_PLUGIN, plugin,
- MM_GENERIC_CDMA_EVDO_REV0, evdo_rev0,
- MM_GENERIC_CDMA_EVDO_REVA, evdo_revA,
- MM_MODEM_HW_VID, vendor,
- MM_MODEM_HW_PID, product,
- NULL));
-}
-
-/*****************************************************************************/
-
-static void
-check_valid (MMGenericCdma *self)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- gboolean new_valid = FALSE;
-
- if (priv->primary && priv->data)
- new_valid = TRUE;
-
- mm_modem_base_set_valid (MM_MODEM_BASE (self), new_valid);
-}
-
-static void
-get_esn_cb (MMModem *modem,
- const char *result,
- GError *error,
- gpointer user_data)
-{
- if (modem) {
- mm_modem_base_set_equipment_identifier (MM_MODEM_BASE (modem), error ? "" : result);
- mm_serial_port_close (MM_SERIAL_PORT (MM_GENERIC_CDMA_GET_PRIVATE (modem)->primary));
- check_valid (MM_GENERIC_CDMA (modem));
- }
-}
-
-static void
-initial_esn_check (MMGenericCdma *self)
-{
- GError *error = NULL;
- MMGenericCdmaPrivate *priv;
-
- g_return_if_fail (MM_IS_GENERIC_CDMA (self));
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- g_return_if_fail (priv->primary != NULL);
-
- if (mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error)) {
- /* Make sure echoing is off */
- mm_at_serial_port_queue_command (priv->primary, "E0", 3, NULL, NULL);
- mm_modem_cdma_get_esn (MM_MODEM_CDMA (self), get_esn_cb, NULL);
- } else {
- g_warning ("%s: failed to open serial port: (%d) %s",
- __func__,
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- check_valid (self);
- }
-}
-
-static void
-get_info_cb (MMModem *modem,
- const char *manufacturer,
- const char *model,
- const char *version,
- GError *error,
- gpointer user_data)
-{
- /* Base class handles saving the info for us */
- if (modem)
- mm_serial_port_close (MM_SERIAL_PORT (MM_GENERIC_CDMA_GET_PRIVATE (modem)->primary));
-}
-
-static void
-initial_info_check (MMGenericCdma *self)
-{
- GError *error = NULL;
- MMGenericCdmaPrivate *priv;
-
- g_return_if_fail (MM_IS_GENERIC_CDMA (self));
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- g_return_if_fail (priv->primary != NULL);
-
- if (mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error)) {
- /* Make sure echoing is off */
- mm_at_serial_port_queue_command (priv->primary, "E0", 3, NULL, NULL);
- mm_modem_base_get_card_info (MM_MODEM_BASE (self),
- priv->primary,
- NULL,
- get_info_cb,
- NULL);
- } else {
- g_warning ("%s: failed to open serial port: (%d) %s",
- __func__,
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
-}
-
-static gboolean
-owns_port (MMModem *modem, const char *subsys, const char *name)
-{
- return !!mm_modem_base_get_port (MM_MODEM_BASE (modem), subsys, name);
-}
-
-static void
-port_grabbed (MMModemBase *base,
- MMPort *port,
- MMAtPortFlags at_pflags,
- gpointer user_data)
-{
- MMGenericCdma *self = MM_GENERIC_CDMA (base);
-
- if (MM_IS_AT_SERIAL_PORT (port)) {
- g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL);
- mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (port), at_pflags);
-
- mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port),
- mm_serial_parser_v1_e1_parse,
- mm_serial_parser_v1_e1_new (),
- mm_serial_parser_v1_e1_destroy);
- }
-
- if (MM_GENERIC_CDMA_GET_CLASS (self)->port_grabbed)
- MM_GENERIC_CDMA_GET_CLASS (self)->port_grabbed (self, port, at_pflags, user_data);
-}
-
-static gboolean
-organize_ports (MMModem *modem, GError **error)
-{
- MMGenericCdma *self = MM_GENERIC_CDMA (modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- if (!mm_modem_base_organize_ports (MM_MODEM_BASE (modem),
- &priv->primary,
- &priv->secondary,
- &priv->data,
- &priv->qcdm,
- error))
- return FALSE;
-
- /* Let subclasses twiddle ports if they want */
- if (MM_GENERIC_CDMA_GET_CLASS (self)->ports_organized)
- MM_GENERIC_CDMA_GET_CLASS (self)->ports_organized (self, priv->primary);
-
- g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE);
-
- /* Get the modem's general info */
- initial_info_check (self);
-
- /* Get modem's ESN number */
- initial_esn_check (self);
-
- check_valid (self);
- return TRUE;
-}
-
-static void
-release_port (MMModem *modem, const char *subsys, const char *name)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
- MMPort *port;
-
- port = mm_modem_base_get_port (MM_MODEM_BASE (modem), subsys, name);
- if (!port)
- return;
-
- if (port == (MMPort *) priv->primary) {
- mm_modem_base_remove_port (MM_MODEM_BASE (modem), port);
- priv->primary = NULL;
- }
-
- if (port == priv->data) {
- priv->data = NULL;
- g_object_notify (G_OBJECT (modem), MM_MODEM_DATA_DEVICE);
- }
-
- if (port == (MMPort *) priv->secondary) {
- mm_modem_base_remove_port (MM_MODEM_BASE (modem), port);
- priv->secondary = NULL;
- }
-
- if (port == (MMPort *) priv->qcdm) {
- mm_modem_base_remove_port (MM_MODEM_BASE (modem), port);
- priv->qcdm = NULL;
- }
-
- check_valid (MM_GENERIC_CDMA (modem));
-}
-
-MMAtSerialPort *
-mm_generic_cdma_get_at_port (MMGenericCdma *modem,
- MMAtPortFlags flag)
-{
- MMGenericCdmaPrivate *priv;
-
- g_return_val_if_fail (MM_IS_GENERIC_CDMA (modem), NULL);
-
- /* We only search for a single value even though it's a bitfield */
- g_return_val_if_fail ( flag == MM_AT_PORT_FLAG_NONE
- || flag == MM_AT_PORT_FLAG_PRIMARY
- || flag == MM_AT_PORT_FLAG_SECONDARY
- || flag == MM_AT_PORT_FLAG_PPP, NULL);
-
- priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
-
- if (flag == MM_AT_PORT_FLAG_SECONDARY)
- return priv->secondary;
- else if (flag == MM_AT_PORT_FLAG_PRIMARY)
- return priv->primary;
- else if ((flag == MM_AT_PORT_FLAG_PPP) && MM_IS_AT_SERIAL_PORT (priv->data))
- return MM_AT_SERIAL_PORT (priv->data);
-
- return NULL;
-}
-
-MMAtSerialPort *
-mm_generic_cdma_get_best_at_port (MMGenericCdma *self, GError **error)
-{
- MMGenericCdmaPrivate *priv;
-
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_GENERIC_CDMA (self), NULL);
-
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- if (!mm_port_get_connected (MM_PORT (priv->primary)))
- return priv->primary;
-
- if (!priv->secondary) {
- g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
- "Cannot perform this operation while connected");
- }
-
- return priv->secondary;
-}
-
-MMQcdmSerialPort *
-mm_generic_cdma_get_best_qcdm_port (MMGenericCdma *self, GError **error)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_GENERIC_CDMA (self), NULL);
-
- return MM_GENERIC_CDMA_GET_PRIVATE (self)->qcdm;
-}
-
-/*****************************************************************************/
-
-void
-mm_generic_cdma_set_1x_registration_state (MMGenericCdma *self,
- MMModemCdmaRegistrationState new_state)
-{
- MMGenericCdmaPrivate *priv;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_GENERIC_CDMA (self));
-
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- if (priv->cdma_1x_reg_state != new_state) {
- priv->cdma_1x_reg_state = new_state;
-
- update_enabled_state (self, TRUE, MM_MODEM_STATE_REASON_NONE);
- mm_modem_cdma_emit_registration_state_changed (MM_MODEM_CDMA (self),
- priv->cdma_1x_reg_state,
- priv->evdo_reg_state);
- }
-}
-
-void
-mm_generic_cdma_set_evdo_registration_state (MMGenericCdma *self,
- MMModemCdmaRegistrationState new_state)
-{
- MMGenericCdmaPrivate *priv;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_GENERIC_CDMA (self));
-
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- if (priv->evdo_reg_state == new_state)
- return;
-
- /* Don't update EVDO state if the card doesn't support it */
- if ( priv->evdo_rev0
- || priv->evdo_revA
- || (new_state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)) {
- priv->evdo_reg_state = new_state;
-
- update_enabled_state (self, TRUE, MM_MODEM_STATE_REASON_NONE);
- mm_modem_cdma_emit_registration_state_changed (MM_MODEM_CDMA (self),
- priv->cdma_1x_reg_state,
- priv->evdo_reg_state);
- }
-}
-
-MMModemCdmaRegistrationState
-mm_generic_cdma_1x_get_registration_state_sync (MMGenericCdma *self)
-{
- g_return_val_if_fail (self != NULL, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- g_return_val_if_fail (MM_IS_GENERIC_CDMA (self), MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
-
- return MM_GENERIC_CDMA_GET_PRIVATE (self)->cdma_1x_reg_state;
-}
-
-MMModemCdmaRegistrationState
-mm_generic_cdma_evdo_get_registration_state_sync (MMGenericCdma *self)
-{
- g_return_val_if_fail (self != NULL, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- g_return_val_if_fail (MM_IS_GENERIC_CDMA (self), MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
-
- return MM_GENERIC_CDMA_GET_PRIVATE (self)->evdo_reg_state;
-}
-
-/*****************************************************************************/
-
-static void
-periodic_poll_reg_cb (MMModemCdma *modem,
- MMModemCdmaRegistrationState cdma_1x_reg_state,
- MMModemCdmaRegistrationState evdo_reg_state,
- GError *error,
- gpointer user_data)
-{
- /* cached reg state already updated */
-}
-
-static void
-periodic_poll_signal_quality_cb (MMModem *modem,
- guint32 result,
- GError *error,
- gpointer user_data)
-{
- /* cached signal quality already updated */
-}
-
-static gboolean
-periodic_poll_cb (gpointer user_data)
-{
- MMGenericCdma *self = MM_GENERIC_CDMA (user_data);
-
- mm_modem_cdma_get_registration_state (MM_MODEM_CDMA (self), periodic_poll_reg_cb, NULL);
- mm_modem_cdma_get_signal_quality (MM_MODEM_CDMA (self), periodic_poll_signal_quality_cb, NULL);
-
- return TRUE;
-}
-
-/*****************************************************************************/
-
-static void
-update_enabled_state (MMGenericCdma *self,
- gboolean stay_connected,
- MMModemStateReason reason)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- /* While connected we don't want registration status changes to change
- * the modem's state away from CONNECTED.
- */
- if (stay_connected && (mm_modem_get_state (MM_MODEM (self)) >= MM_MODEM_STATE_DISCONNECTING))
- return;
-
- if ( priv->cdma_1x_reg_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN
- || priv->evdo_reg_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
- mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_REGISTERED, reason);
- else
- mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_ENABLED, reason);
-}
-
-static void
-registration_cleanup (MMGenericCdma *self, GQuark error_class, guint32 error_num)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- GError *error = NULL;
-
- priv->reg_tries = 0;
-
- if (priv->reg_state_changed_id) {
- g_signal_handler_disconnect (self, priv->reg_state_changed_id);
- priv->reg_state_changed_id = 0;
- }
-
- if (priv->reg_retry_id) {
- g_source_remove (priv->reg_retry_id);
- priv->reg_retry_id = 0;
- }
-
- /* Return an error to any explicit callers of simple_connect */
- if (priv->simple_connect_info && error_class) {
- error = g_error_new_literal (error_class, error_num,
- "Connection attempt terminated");
- simple_state_machine (MM_MODEM (self), error, priv->simple_connect_info);
- g_error_free (error);
- }
- priv->simple_connect_info = NULL;
-}
-
-static void
-get_enable_info_done (MMModem *modem,
- const char *manufacturer,
- const char *model,
- const char *version,
- GError *error,
- gpointer user_data)
-{
- /* Modem base class handles the response for us */
-}
-
-static void
-spservice_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- if (!error) {
- MM_GENERIC_CDMA_GET_PRIVATE (user_data)->has_spservice = TRUE;
-
- /* +SPSERVICE provides a better indicator of registration status than
- * +CSS, which some devices implement inconsistently.
- */
- MM_GENERIC_CDMA_GET_PRIVATE (user_data)->reg_try_css = FALSE;
- }
-}
-
-static void
-speri_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- if (!error)
- MM_GENERIC_CDMA_GET_PRIVATE (user_data)->has_speri = TRUE;
-}
-
-static void
-crm_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- const char *p;
- unsigned long num;
-
- if (error)
- return;
-
- p = mm_strip_tag (response->str, "+CRM:");
- if (p) {
- errno = 0;
- num = strtoul (p, NULL, 10);
- if (num <= 4 && (errno == 0)) {
- MM_GENERIC_CDMA_GET_PRIVATE (user_data)->orig_crm = (guint32) num;
- MM_GENERIC_CDMA_GET_PRIVATE (user_data)->cur_crm = (guint32) num;
- }
- }
-}
-
-static void
-enable_all_done (MMModem *modem, GError *error, gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- if (error)
- info->error = g_error_copy (error);
- else {
- /* Try to enable XON/XOFF flow control */
- mm_at_serial_port_queue_command (priv->primary, "+IFC=1,1", 3, NULL, NULL);
-
- /* Open up the second port, if one exists */
- if (priv->secondary) {
- if (!mm_serial_port_open (MM_SERIAL_PORT (priv->secondary), &info->error)) {
- g_assert (info->error);
- goto out;
- }
- }
-
- /* Open up the second port, if one exists */
- if (priv->qcdm) {
- if (!mm_serial_port_open (MM_SERIAL_PORT (priv->qcdm), &info->error)) {
- g_assert (info->error);
- goto out;
- }
- }
-
- update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE);
-
- /* Grab device info right away */
- mm_modem_get_info (modem, get_enable_info_done, NULL);
-
- /* Check for support of Sprint-specific phone commands */
- mm_at_serial_port_queue_command (priv->primary, "+SPSERVICE?", 3, spservice_done, self);
- mm_at_serial_port_queue_command (priv->primary, "$SPERI?", 3, speri_done, self);
-
- /* Grab default CRM */
- mm_at_serial_port_queue_command (priv->primary, "+CRM?", 3, crm_done, self);
- }
-
-out:
- if (info->error) {
- mm_modem_set_state (MM_MODEM (info->modem),
- MM_MODEM_STATE_DISABLED,
- MM_MODEM_STATE_REASON_NONE);
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-init_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- mm_modem_set_state (MM_MODEM (info->modem),
- MM_MODEM_STATE_DISABLED,
- MM_MODEM_STATE_REASON_NONE);
-
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- } else {
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
-
- /* Try enabling better error reporting on CDMA devices, but few
- * actually support +CMEE as it's more of a GSM command.
- */
- mm_at_serial_port_queue_command (port, "+CMEE=1", 3, NULL, NULL);
-
- if (MM_GENERIC_CDMA_GET_CLASS (self)->post_enable)
- MM_GENERIC_CDMA_GET_CLASS (self)->post_enable (self, enable_all_done, info);
- else
- enable_all_done (MM_MODEM (self), NULL, info);
- }
-}
-
-static void
-flash_done (MMSerialPort *port, GError *error, gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- if (error) {
- mm_modem_set_state (MM_MODEM (info->modem),
- MM_MODEM_STATE_DISABLED,
- MM_MODEM_STATE_REASON_NONE);
-
- /* Flash failed for some reason */
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "Z E0 V1 X4 &C1", 3, init_done, user_data);
-}
-
-static void
-enable (MMModem *modem,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericCdma *self = MM_GENERIC_CDMA (modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- if (!mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &info->error)) {
- g_assert (info->error);
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_modem_set_state (MM_MODEM (info->modem),
- MM_MODEM_STATE_ENABLING,
- MM_MODEM_STATE_REASON_NONE);
-
- mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 100, FALSE, flash_done, info);
-}
-
-static void
-disable_set_previous_state (MMModem *modem, MMCallbackInfo *info)
-{
- MMModemState prev_state;
-
- /* Reset old state since the operation failed */
- prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_CDMA_PREV_STATE_TAG));
- mm_modem_set_state (modem, prev_state, MM_MODEM_STATE_REASON_NONE);
-}
-
-static void
-disable_all_done (MMModem *modem, GError *error, gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (!modem || mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- disable_set_previous_state (modem, info);
- } else {
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- mm_serial_port_close_force (MM_SERIAL_PORT (priv->primary));
- mm_modem_set_state (modem, MM_MODEM_STATE_DISABLED, MM_MODEM_STATE_REASON_NONE);
-
- priv->cdma_1x_reg_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
- priv->evdo_reg_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-disable_flash_done (MMSerialPort *port,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMGenericCdma *self;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
-
- disable_set_previous_state (info->modem, info);
- mm_callback_info_schedule (info);
- return;
- }
-
- self = MM_GENERIC_CDMA (info->modem);
-
- if (MM_GENERIC_CDMA_GET_CLASS (self)->post_disable)
- MM_GENERIC_CDMA_GET_CLASS (self)->post_disable (self, disable_all_done, info);
- else
- disable_all_done (MM_MODEM (self), NULL, info);
-}
-
-static void
-disable (MMModem *modem,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericCdma *self = MM_GENERIC_CDMA (modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- MMCallbackInfo *info;
- MMModemState state;
-
- /* Tear down any ongoing registration */
- registration_cleanup (self, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL);
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- /* Cache the previous state so we can reset it if the operation fails */
- state = mm_modem_get_state (modem);
- mm_callback_info_set_data (info,
- MM_GENERIC_CDMA_PREV_STATE_TAG,
- GUINT_TO_POINTER (state),
- NULL);
-
- /* Close auxiliary serial ports */
- if (priv->secondary)
- mm_serial_port_close_force (MM_SERIAL_PORT (priv->secondary));
- if (priv->qcdm)
- mm_serial_port_close_force (MM_SERIAL_PORT (priv->qcdm));
-
- mm_modem_set_state (MM_MODEM (info->modem),
- MM_MODEM_STATE_DISABLING,
- MM_MODEM_STATE_REASON_NONE);
-
- if (mm_port_get_connected (MM_PORT (priv->primary)))
- mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, TRUE, disable_flash_done, info);
- else
- disable_flash_done (MM_SERIAL_PORT (priv->primary), NULL, info);
-}
-
-static void
-dial_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- update_enabled_state (MM_GENERIC_CDMA (info->modem), FALSE, MM_MODEM_STATE_REASON_NONE);
- } else {
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- /* Clear reg tries; we're obviously registered by this point */
- registration_cleanup (self, 0, 0);
-
- mm_port_set_connected (priv->data, TRUE);
- mm_modem_set_state (info->modem, MM_MODEM_STATE_CONNECTED, MM_MODEM_STATE_REASON_NONE);
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-connect (MMModem *modem,
- const char *number,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- char *command;
- MMAtSerialPort *dial_port;
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- /* Dial port might not be the primary port*/
- priv->data_opened_at_connect = FALSE;
- dial_port = priv->primary;
- if (MM_IS_AT_SERIAL_PORT (priv->data)) {
- dial_port = MM_AT_SERIAL_PORT (priv->data);
-
- if (!mm_serial_port_open (MM_SERIAL_PORT (dial_port), &info->error)) {
- g_warning ("%s: failed to open dial port: (%d) %s",
- __func__,
- info->error ? info->error->code : -1,
- info->error && info->error->message ? info->error->message : "(unknown)");
- mm_callback_info_schedule (info);
- return;
- }
- priv->data_opened_at_connect = TRUE;
- }
-
- mm_modem_set_state (modem, MM_MODEM_STATE_CONNECTING, MM_MODEM_STATE_REASON_NONE);
-
- command = g_strconcat ("DT", number, NULL);
- mm_at_serial_port_queue_command (dial_port, command, 90, dial_done, info);
- g_free (command);
-}
-
-static void
-disconnect_flash_done (MMSerialPort *port,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericCdma *self;
- MMGenericCdmaPrivate *priv;
- MMModemState prev_state;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- self = MM_GENERIC_CDMA (info->modem);
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- if (error) {
- info->error = g_error_copy (error);
-
- /* Reset old state since the operation failed */
- prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_CDMA_PREV_STATE_TAG));
- mm_modem_set_state (MM_MODEM (info->modem),
- prev_state,
- MM_MODEM_STATE_REASON_NONE);
- } else {
- mm_port_set_connected (priv->data, FALSE);
- update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE);
- }
-
- /* Balance any open from connect(); subclasses may not use the generic
- * class' connect function and so the dial port may not have been
- * opened at all.
- */
- if (priv->data_opened_at_connect) {
- if (MM_IS_AT_SERIAL_PORT (port))
- mm_serial_port_close (port);
- priv->data_opened_at_connect = FALSE;
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-disconnect (MMModem *modem,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- MMModemState state;
- MMAtSerialPort *dial_port;
-
- g_return_if_fail (priv->primary != NULL);
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- /* Cache the previous state so we can reset it if the operation fails */
- state = mm_modem_get_state (modem);
- mm_callback_info_set_data (info,
- MM_GENERIC_CDMA_PREV_STATE_TAG,
- GUINT_TO_POINTER (state),
- NULL);
-
- mm_modem_set_state (modem, MM_MODEM_STATE_DISCONNECTING, MM_MODEM_STATE_REASON_NONE);
-
- dial_port = priv->primary;
- if (MM_IS_AT_SERIAL_PORT (priv->data))
- dial_port = MM_AT_SERIAL_PORT (priv->data);
-
- mm_serial_port_flash (MM_SERIAL_PORT (dial_port), 1000, TRUE, disconnect_flash_done, info);
-}
-
-static void
-get_card_info (MMModem *modem,
- MMModemInfoFn callback,
- gpointer user_data)
-{
- MMAtSerialPort *port;
- GError *error = NULL;
-
- port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (modem), &error);
- mm_modem_base_get_card_info (MM_MODEM_BASE (modem), port, error, callback, user_data);
- g_clear_error (&error);
-}
-
-/*****************************************************************************/
-
-void
-mm_generic_cdma_update_cdma1x_quality (MMGenericCdma *self, guint32 quality)
-{
- MMGenericCdmaPrivate *priv;
-
- g_return_if_fail (MM_IS_GENERIC_CDMA (self));
- g_return_if_fail (quality >= 0 && quality <= 100);
-
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- if (priv->cdma1x_quality != quality) {
- priv->cdma1x_quality = quality;
- mm_modem_cdma_emit_signal_quality_changed (MM_MODEM_CDMA (self), quality);
- }
-}
-
-void
-mm_generic_cdma_update_evdo_quality (MMGenericCdma *self, guint32 quality)
-{
- MMGenericCdmaPrivate *priv;
-
- g_return_if_fail (MM_IS_GENERIC_CDMA (self));
- g_return_if_fail (quality >= 0 && quality <= 100);
-
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- if (priv->evdo_quality != quality) {
- priv->evdo_quality = quality;
- // FIXME: emit a signal
- }
-}
-
-#define CSQ2_TRIED "csq?-tried"
-
-static void
-get_signal_quality_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMGenericCdmaPrivate *priv;
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- if (mm_callback_info_get_data (info, CSQ2_TRIED))
- info->error = g_error_copy (error);
- else {
- /* Some modems want +CSQ, others want +CSQ?, and some of both types
- * will return ERROR if they don't get the command they want. So
- * try the other command if the first one fails.
- */
- mm_callback_info_set_data (info, CSQ2_TRIED, GUINT_TO_POINTER (1), NULL);
- mm_at_serial_port_queue_command (port, "+CSQ?", 3, get_signal_quality_done, info);
- return;
- }
- } else {
- const char *reply = response->str;
- int quality, ber;
-
- /* Got valid reply */
- if (!strncmp (reply, "+CSQ: ", 6))
- reply += 6;
-
- if (sscanf (reply, "%d, %d", &quality, &ber)) {
- /* 99 means unknown/no service */
- if (quality == 99) {
- info->error = g_error_new_literal (MM_MOBILE_ERROR,
- MM_MOBILE_ERROR_NO_NETWORK,
- "No service");
- } else {
- /* Normalize the quality */
- quality = CLAMP (quality, 0, 31) * 100 / 31;
-
- priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
- mm_callback_info_set_result (info, GUINT_TO_POINTER (quality), NULL);
- if (priv->cdma1x_quality != quality) {
- priv->cdma1x_quality = quality;
- mm_modem_cdma_emit_signal_quality_changed (MM_MODEM_CDMA (info->modem), quality);
- }
- }
- } else
- info->error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "%s", "Could not parse signal quality results");
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-qcdm_pilot_sets_cb (MMQcdmSerialPort *port,
- GByteArray *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMGenericCdmaPrivate *priv;
- QcdmResult *result;
- guint32 num = 0, quality = 0, i;
- float best_db = -28;
- int err = QCDM_SUCCESS;
-
- if (error) {
- info->error = g_error_copy (error);
- goto done;
- }
-
- priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
-
- /* Parse the response */
- result = qcdm_cmd_pilot_sets_result ((const char *) response->data, response->len, &err);
- if (!result) {
- g_set_error (&info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Failed to parse pilot sets command result: %d", err);
- goto done;
- }
-
- qcdm_cmd_pilot_sets_result_get_num (result, QCDM_CMD_PILOT_SETS_TYPE_ACTIVE, &num);
- for (i = 0; i < num; i++) {
- guint32 pn_offset = 0, ecio = 0;
- float db = 0;
-
- qcdm_cmd_pilot_sets_result_get_pilot (result,
- QCDM_CMD_PILOT_SETS_TYPE_ACTIVE,
- i,
- &pn_offset,
- &ecio,
- &db);
- best_db = MAX (db, best_db);
- }
- qcdm_result_unref (result);
-
- if (num > 0) {
- #define BEST_ECIO 3
- #define WORST_ECIO 25
-
- /* EC/IO dB ranges from roughly 0 to -31 dB. Lower == worse. We
- * really only care about -3 to -25 dB though, since that's about what
- * you'll see in real-world usage.
- */
- best_db = CLAMP (ABS (best_db), BEST_ECIO, WORST_ECIO) - BEST_ECIO;
- quality = (guint32) (100 - (best_db * 100 / (WORST_ECIO - BEST_ECIO)));
- }
-
- mm_callback_info_set_result (info, GUINT_TO_POINTER (quality), NULL);
-
- if (priv->cdma1x_quality != quality) {
- priv->cdma1x_quality = quality;
- mm_modem_cdma_emit_signal_quality_changed (MM_MODEM_CDMA (info->modem), quality);
- }
-
-done:
- mm_callback_info_schedule (info);
-}
-
-static void
-get_signal_quality (MMModemCdma *modem,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- MMAtSerialPort *at_port;
-
- info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
-
- at_port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (modem), &info->error);
- if (!at_port && !priv->qcdm) {
- mm_dbg ("Returning saved signal quality %d", priv->cdma1x_quality);
- mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->cdma1x_quality), NULL);
- mm_callback_info_schedule (info);
- return;
- }
- g_clear_error (&info->error);
-
- if (at_port)
- mm_at_serial_port_queue_command (at_port, "+CSQ", 3, get_signal_quality_done, info);
- else if (priv->qcdm) {
- GByteArray *pilot_sets;
-
- /* Use CDMA1x pilot EC/IO if we can */
- pilot_sets = g_byte_array_sized_new (25);
- pilot_sets->len = qcdm_cmd_pilot_sets_new ((char *) pilot_sets->data, 25);
- g_assert (pilot_sets->len);
- mm_qcdm_serial_port_queue_command (priv->qcdm, pilot_sets, 3, qcdm_pilot_sets_cb, info);
- }
-}
-
-static void
-get_string_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- const char *p;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- p = mm_strip_tag (response->str, "+GSN:");
- mm_callback_info_set_result (info, g_strdup (p), g_free);
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-get_esn (MMModemCdma *modem,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
-
- port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_at_serial_port_queue_command_cached (port, "+GSN", 3, get_string_done, info);
-}
-
-static void
-serving_system_invoke (MMCallbackInfo *info)
-{
- MMModemCdmaServingSystemFn callback = (MMModemCdmaServingSystemFn) info->callback;
-
- callback (MM_MODEM_CDMA (info->modem),
- GPOINTER_TO_UINT (mm_callback_info_get_data (info, "class")),
- (unsigned char) GPOINTER_TO_UINT (mm_callback_info_get_data (info, "band")),
- GPOINTER_TO_UINT (mm_callback_info_get_data (info, "sid")),
- info->error,
- info->user_data);
-}
-
-static int
-normalize_class (const char *orig_class)
-{
- char class;
-
- g_return_val_if_fail (orig_class != NULL, '0');
-
- class = toupper (orig_class[0]);
-
- /* Cellular (850MHz) */
- if (class == '1' || class == 'C')
- return 1;
- /* PCS (1900MHz) */
- if (class == '2' || class == 'P')
- return 2;
-
- /* Unknown/not registered */
- return 0;
-}
-
-static char
-normalize_band (const char *long_band, int *out_class)
-{
- char band;
-
- g_return_val_if_fail (long_band != NULL, 'Z');
-
- /* There are two response formats for the band; one includes the band
- * class and the other doesn't. For modems that include the band class
- * (ex Novatel S720) you'll see "Px" or "Cx" depending on whether the modem
- * is registered on a PCS/1900 (P) or Cellular/850 (C) system.
- */
- band = toupper (long_band[0]);
-
- /* Possible band class in first position; return it */
- if (band == 'C' || band == 'P') {
- char tmp[2] = { band, '\0' };
-
- *out_class = normalize_class (tmp);
- band = toupper (long_band[1]);
- }
-
- /* normalize to A - F, and Z */
- if (band >= 'A' && band <= 'F')
- return band;
-
- /* Unknown/not registered */
- return 'Z';
-}
-
-static int
-convert_sid (const char *sid)
-{
- long int tmp_sid;
-
- g_return_val_if_fail (sid != NULL, 99999);
-
- errno = 0;
- tmp_sid = strtol (sid, NULL, 10);
- if ((errno == EINVAL) || (errno == ERANGE))
- return 99999;
- else if (tmp_sid < G_MININT || tmp_sid > G_MAXINT)
- return 99999;
-
- return (int) tmp_sid;
-}
-
-static GError *
-new_css_no_service_error (void)
-{
- /* NOTE: update reg_state_css_response() if this error changes */
- return g_error_new_literal (MM_MOBILE_ERROR,
- MM_MOBILE_ERROR_NO_NETWORK,
- "No service");
-}
-
-static void
-serving_system_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- char *reply;
- int class = 0, sid = 99999, num;
- unsigned char band = 'Z';
- gboolean success = FALSE;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- goto out;
- }
-
- reply = response->str;
- if (strstr (reply, "+CSS: "))
- reply += 6;
-
- num = sscanf (reply, "? , %d", &sid);
- if (num == 1) {
- /* UTStarcom and Huawei modems that use IS-707-A format; note that
- * this format obviously doesn't have other indicators like band and
- * class and thus SID 0 will be reported as "no service" (see below).
- */
- class = 0;
- band = 'Z';
- success = TRUE;
- } else {
- GRegex *r;
- GMatchInfo *match_info;
- int override_class = 0;
-
- /* Format is "<band_class>,<band>,<sid>" */
- r = g_regex_new ("\\s*([^,]*?)\\s*,\\s*([^,]*?)\\s*,\\s*(\\d+)", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- if (!r) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse Serving System results (regex creation failed).");
- goto out;
- }
-
- g_regex_match (r, reply, 0, &match_info);
- if (g_match_info_get_match_count (match_info) >= 3) {
- char *str;
-
- /* band class */
- str = g_match_info_fetch (match_info, 1);
- class = normalize_class (str);
- g_free (str);
-
- /* band */
- str = g_match_info_fetch (match_info, 2);
- band = normalize_band (str, &override_class);
- if (override_class)
- class = override_class;
- g_free (str);
-
- /* sid */
- str = g_match_info_fetch (match_info, 3);
- sid = convert_sid (str);
- g_free (str);
-
- success = TRUE;
- }
-
- g_match_info_free (match_info);
- g_regex_unref (r);
- }
-
- if (success) {
- gboolean class_ok = FALSE, band_ok = FALSE;
-
- /* Normalize the SID */
- if (sid < 0 || sid > 32767)
- sid = 99999;
-
- if (class == 1 || class == 2)
- class_ok = TRUE;
- if (band != 'Z')
- band_ok = TRUE;
-
- /* Return 'no service' if none of the elements of the +CSS response
- * indicate that the modem has service. Note that this allows SID 0
- * when at least one of the other elements indicates service.
- * Normally we'd treat SID 0 as 'no service' but some modems
- * (Sierra 5725) sometimes return SID 0 even when registered.
- */
- if (sid == 0 && !class_ok && !band_ok)
- sid = 99999;
-
- /* 99999 means unknown/no service */
- if (sid == 99999)
- info->error = new_css_no_service_error ();
- else {
- mm_callback_info_set_data (info, "class", GUINT_TO_POINTER (class), NULL);
- mm_callback_info_set_data (info, "band", GUINT_TO_POINTER ((guint32) band), NULL);
- mm_callback_info_set_data (info, "sid", GUINT_TO_POINTER (sid), NULL);
- }
- } else {
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Could not parse Serving System results.");
- }
-
- out:
- mm_callback_info_schedule (info);
-}
-
-static void
-legacy_get_serving_system (MMGenericCdma *self, MMCallbackInfo *info)
-{
- MMAtSerialPort *port;
-
- port = mm_generic_cdma_get_best_at_port (self, &info->error);
- if (port)
- mm_at_serial_port_queue_command (port, "+CSS?", 3, serving_system_done, info);
- else
- mm_callback_info_schedule (info);
-}
-
-static void
-cdma_status_cb (MMQcdmSerialPort *port,
- GByteArray *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- QcdmResult *result;
- guint32 sid, rxstate;
- int err = QCDM_SUCCESS;
-
- if (error)
- goto error;
-
- /* Parse the response */
- result = qcdm_cmd_cdma_status_result ((const char *) response->data, response->len, &err);
- if (!result) {
- g_set_error (&info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Failed to parse cdma status command result: %d", err);
- goto error;
- }
-
- qcdm_result_get_u32 (result, QCDM_CMD_CDMA_STATUS_ITEM_RX_STATE, &rxstate);
- qcdm_result_get_u32 (result, QCDM_CMD_CDMA_STATUS_ITEM_SID, &sid);
- qcdm_result_unref (result);
-
- if (rxstate == QCDM_CMD_CDMA_STATUS_RX_STATE_ENTERING_CDMA)
- info->error = new_css_no_service_error ();
- else {
- mm_callback_info_set_data (info, "class", GUINT_TO_POINTER (0), NULL);
- mm_callback_info_set_data (info, "band", GUINT_TO_POINTER ((guint32) 'Z'), NULL);
- mm_callback_info_set_data (info, "sid", GUINT_TO_POINTER (sid), NULL);
- }
-
- mm_callback_info_schedule (info);
- return;
-
-error:
- /* If there was some error, fall back to use +CSS like we did before QCDM */
- legacy_get_serving_system (MM_GENERIC_CDMA (info->modem), info);
-}
-
-static void
-get_serving_system (MMModemCdma *modem,
- MMModemCdmaServingSystemFn callback,
- gpointer user_data)
-{
- MMGenericCdma *self = MM_GENERIC_CDMA (modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (modem),
- serving_system_invoke,
- G_CALLBACK (callback),
- user_data);
-
- if (priv->qcdm) {
- GByteArray *cdma_status;
-
- cdma_status = g_byte_array_sized_new (25);
- cdma_status->len = qcdm_cmd_cdma_status_new ((char *) cdma_status->data, 25);
- g_assert (cdma_status->len);
- mm_qcdm_serial_port_queue_command (priv->qcdm, cdma_status, 3, cdma_status_cb, info);
- } else
- legacy_get_serving_system (self, info);
-}
-
-/*****************************************************************************/
-
-/* Registration state stuff */
-
-#define CDMA_1X_STATE_TAG "cdma-1x-reg-state"
-#define EVDO_STATE_TAG "evdo-reg-state"
-
-MMModemCdmaRegistrationState
-mm_generic_cdma_query_reg_state_get_callback_1x_state (MMCallbackInfo *info)
-{
- g_return_val_if_fail (info != NULL, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- g_return_val_if_fail (info->modem != NULL, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- g_return_val_if_fail (MM_IS_GENERIC_CDMA (info->modem), MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
-
- return GPOINTER_TO_UINT (mm_callback_info_get_data (info, CDMA_1X_STATE_TAG));
-}
-
-void
-mm_generic_cdma_query_reg_state_set_callback_1x_state (MMCallbackInfo *info,
- MMModemCdmaRegistrationState new_state)
-{
- g_return_if_fail (info != NULL);
- g_return_if_fail (info->modem != NULL);
- g_return_if_fail (MM_IS_GENERIC_CDMA (info->modem));
-
- mm_callback_info_set_data (info, CDMA_1X_STATE_TAG, GUINT_TO_POINTER (new_state), NULL);
-}
-
-MMModemCdmaRegistrationState
-mm_generic_cdma_query_reg_state_get_callback_evdo_state (MMCallbackInfo *info)
-{
- g_return_val_if_fail (info != NULL, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- g_return_val_if_fail (info->modem != NULL, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- g_return_val_if_fail (MM_IS_GENERIC_CDMA (info->modem), MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
-
- return GPOINTER_TO_UINT (mm_callback_info_get_data (info, EVDO_STATE_TAG));
-}
-
-void
-mm_generic_cdma_query_reg_state_set_callback_evdo_state (MMCallbackInfo *info,
- MMModemCdmaRegistrationState new_state)
-{
- g_return_if_fail (info != NULL);
- g_return_if_fail (info->modem != NULL);
- g_return_if_fail (MM_IS_GENERIC_CDMA (info->modem));
-
- mm_callback_info_set_data (info, EVDO_STATE_TAG, GUINT_TO_POINTER (new_state), NULL);
-}
-
-static void
-registration_state_invoke (MMCallbackInfo *info)
-{
- MMModemCdmaRegistrationStateFn callback = (MMModemCdmaRegistrationStateFn) info->callback;
-
- /* note: This is the MMModemCdma interface callback */
- callback (MM_MODEM_CDMA (info->modem),
- mm_generic_cdma_query_reg_state_get_callback_1x_state (info),
- mm_generic_cdma_query_reg_state_get_callback_evdo_state (info),
- info->error,
- info->user_data);
-}
-
-MMCallbackInfo *
-mm_generic_cdma_query_reg_state_callback_info_new (MMGenericCdma *self,
- MMModemCdmaRegistrationState cur_cdma_state,
- MMModemCdmaRegistrationState cur_evdo_state,
- MMModemCdmaRegistrationStateFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_GENERIC_CDMA (self), NULL);
- g_return_val_if_fail (callback != NULL, NULL);
-
- info = mm_callback_info_new_full (MM_MODEM (self),
- registration_state_invoke,
- G_CALLBACK (callback),
- user_data);
-
- /* Fill with current state */
- mm_generic_cdma_query_reg_state_set_callback_1x_state (info, cur_cdma_state);
- mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, cur_evdo_state);
- return info;
-}
-
-static void
-set_callback_1x_state_helper (MMCallbackInfo *info,
- MMModemCdmaRegistrationState new_state)
-{
- if (info->modem) {
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
-
- mm_generic_cdma_set_1x_registration_state (self, new_state);
- mm_generic_cdma_query_reg_state_set_callback_1x_state (info, priv->cdma_1x_reg_state);
- }
-}
-
-static void
-set_callback_evdo_state_helper (MMCallbackInfo *info,
- MMModemCdmaRegistrationState new_state)
-{
- if (info->modem) {
- MMGenericCdma *self = MM_GENERIC_CDMA (info->modem);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
-
- mm_generic_cdma_set_evdo_registration_state (self, new_state);
- mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, priv->evdo_reg_state);
- }
-}
-
-static void
-subclass_reg_query_done (MMModemCdma *cdma,
- MMModemCdmaRegistrationState cdma_reg_state,
- MMModemCdmaRegistrationState evdo_reg_state,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- /* Set final registration state */
- set_callback_1x_state_helper (info, cdma_reg_state);
- set_callback_evdo_state_helper (info, evdo_reg_state);
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-reg_query_speri_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- gboolean roam = FALSE;
- const char *p;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- goto done;
-
- p = mm_strip_tag (response->str, "$SPERI:");
- if (!p || !mm_cdma_parse_eri (p, &roam, NULL, NULL))
- goto done;
-
- if (roam) {
- /* Change the 1x and EVDO registration states to roaming if they were
- * anything other than UNKNOWN.
- */
- if (mm_generic_cdma_query_reg_state_get_callback_1x_state (info))
- mm_generic_cdma_query_reg_state_set_callback_1x_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING);
-
- if (mm_generic_cdma_query_reg_state_get_callback_evdo_state (info))
- mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING);
- } else {
- /* Change 1x and/or EVDO registration state to home if home/roaming wasn't previously known */
- if (mm_generic_cdma_query_reg_state_get_callback_1x_state (info) == MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED)
- mm_generic_cdma_query_reg_state_set_callback_1x_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_HOME);
-
- if (mm_generic_cdma_query_reg_state_get_callback_evdo_state (info) == MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED)
- mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_HOME);
- }
-
-done:
- mm_callback_info_schedule (info);
-}
-
-static void
-reg_query_spservice_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMModemCdmaRegistrationState cdma_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
- MMModemCdmaRegistrationState evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else if (mm_cdma_parse_spservice_response (response->str, &cdma_state, &evdo_state)) {
- mm_generic_cdma_query_reg_state_set_callback_1x_state (info, cdma_state);
- mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, evdo_state);
-
- if (MM_GENERIC_CDMA_GET_PRIVATE (info->modem)->has_speri) {
- /* Get roaming status to override generic registration state */
- mm_at_serial_port_queue_command (port, "$SPERI?", 3, reg_query_speri_done, info);
- return;
- }
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-real_query_registration_state (MMGenericCdma *self,
- MMModemCdmaRegistrationState cur_cdma_state,
- MMModemCdmaRegistrationState cur_evdo_state,
- MMModemCdmaRegistrationStateFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- /* Seed this CallbackInfo with any previously determined registration state */
- info = mm_generic_cdma_query_reg_state_callback_info_new (self,
- cur_cdma_state,
- cur_evdo_state,
- callback,
- user_data);
-
- port = mm_generic_cdma_get_best_at_port (self, &info->error);
- if (!port) {
- /* If we can't get an AT port, but less specific registration checks
- * were successful, just use that and don't return an error.
- */
- if ( cur_cdma_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN
- || cur_evdo_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
- g_clear_error (&info->error);
- mm_callback_info_schedule (info);
- return;
- }
-
- if (MM_GENERIC_CDMA_GET_PRIVATE (self)->has_spservice) {
- /* Try Sprint-specific commands */
- mm_at_serial_port_queue_command (port, "+SPSERVICE?", 3, reg_query_spservice_done, info);
- } else {
- /* Assume we're at least registered on the 1x network if we passed
- * +CAD, +CSS, and QCDM Call Manager checking. But don't override a
- * more specific registration state passed from a caller.
- */
- if (cur_cdma_state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
- mm_generic_cdma_query_reg_state_set_callback_1x_state (info, MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED);
-
- /* Don't touch EVDO state; it's already either UNKNOWN, or been set
- * by generic checking earlier.
- */
-
- mm_callback_info_schedule (info);
- }
-}
-
-static void
-reg_state_css_response (MMModemCdma *cdma,
- guint32 class,
- unsigned char band,
- guint32 sid,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* We'll get an error if the SID isn't valid, so detect that and
- * report unknown registration state.
- */
- if (error) {
- if (g_error_matches (error, MM_MOBILE_ERROR, MM_MOBILE_ERROR_NO_NETWORK)) {
- set_callback_1x_state_helper (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- set_callback_evdo_state_helper (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- } else {
- /* Some other error parsing CSS results */
- info->error = g_error_copy (error);
- }
- mm_callback_info_schedule (info);
- } else {
- /* We're registered on the CDMA 1x network at least, but let subclasses
- * do more specific registration checking.
- */
- MM_GENERIC_CDMA_GET_CLASS (cdma)->query_registration_state (MM_GENERIC_CDMA (info->modem),
- MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED,
- MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
- subclass_reg_query_done,
- info);
- }
-}
-
-static void
-get_analog_digital_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- const char *reply;
- long int int_cad;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- goto error;
- }
-
- /* Strip any leading command tag and spaces */
- reply = mm_strip_tag (response->str, "+CAD:");
-
- errno = 0;
- int_cad = strtol (reply, NULL, 10);
- if ((errno == EINVAL) || (errno == ERANGE)) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Failed to parse +CAD response");
- goto error;
- }
-
- if (int_cad == 1) { /* 1 == CDMA service */
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (info->modem);
-
- /* Now that we have some sort of service, check if the the device is
- * registered on the network.
- */
-
- /* Some devices key the AT+CSS? response off the 1X state, but if the
- * device has EVDO service but no 1X service, then reading AT+CSS? will
- * error out too early. Let subclasses that know that their AT+CSS?
- * response is wrong in this case handle more specific registration
- * themselves; if they do, they'll set priv->reg_try_css to FALSE.
- */
- if (priv->reg_try_css) {
- get_serving_system (MM_MODEM_CDMA (info->modem),
- reg_state_css_response,
- info);
- } else {
- /* Subclass knows that AT+CSS? will respond incorrectly to EVDO
- * state, so skip AT+CSS? query.
- */
- MM_GENERIC_CDMA_GET_CLASS (info->modem)->query_registration_state (MM_GENERIC_CDMA (info->modem),
- MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
- MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
- subclass_reg_query_done,
- info);
- }
- return;
- } else {
- /* No service */
- set_callback_1x_state_helper (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- set_callback_evdo_state_helper (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- }
-
-error:
- mm_callback_info_schedule (info);
-}
-
-static void
-reg_hdrstate_cb (MMQcdmSerialPort *port,
- GByteArray *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- QcdmResult *result = NULL;
- guint32 sysmode;
- MMModemCdmaRegistrationState cdma_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
- MMModemCdmaRegistrationState evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
- MMAtSerialPort *at_port;
- gboolean evdo_registered = FALSE;
-
- if (error)
- goto error;
-
- sysmode = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "sysmode"));
-
- /* Get HDR subsystem state to determine EVDO registration when in 1X mode */
- result = qcdm_cmd_hdr_subsys_state_info_result ((const char *) response->data,
- response->len,
- NULL);
- if (result) {
- guint8 session_state = QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_CLOSED;
- guint8 almp_state = QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_INACTIVE;
- guint8 hybrid_mode = 0;
-
- if ( qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_SESSION_STATE, &session_state)
- && qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ALMP_STATE, &almp_state)
- && qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_HDR_HYBRID_MODE, &hybrid_mode)) {
-
- /* EVDO state is registered if the HDR subsystem is registered, and
- * we're in hybrid mode, and the Call Manager system mode is
- * CDMA.
- */
- if ( hybrid_mode
- && session_state == QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_OPEN
- && ( almp_state == QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_IDLE
- || almp_state == QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_CONNECTED))
- evdo_registered = TRUE;
- }
-
- qcdm_result_unref (result);
- }
-
- switch (sysmode) {
- case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_CDMA:
- cdma_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
- if (evdo_registered)
- evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
- break;
- case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_HDR:
- evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED;
- break;
- case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_AMPS:
- case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_NO_SERVICE:
- case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_WCDMA:
- default:
- break;
- }
-
- if (cdma_state || evdo_state) {
- /* Device is registered to something; see if the subclass has a
- * better idea of whether we're roaming or not and what the
- * access technology is.
- */
- if (MM_GENERIC_CDMA_GET_CLASS (info->modem)->query_registration_state) {
- MM_GENERIC_CDMA_GET_CLASS (info->modem)->query_registration_state (MM_GENERIC_CDMA (info->modem),
- cdma_state,
- evdo_state,
- subclass_reg_query_done,
- info);
- return;
- }
- }
-
- set_callback_1x_state_helper (info, cdma_state);
- set_callback_evdo_state_helper (info, evdo_state);
- mm_callback_info_schedule (info);
- return;
-
-error:
- /* If there was some error, fall back to use +CAD like we did before QCDM */
- at_port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (info->modem), &info->error);
- if (at_port)
- mm_at_serial_port_queue_command (at_port, "+CAD?", 3, get_analog_digital_done, info);
- else
- mm_callback_info_schedule (info);
-}
-
-static void
-reg_cmstate_cb (MMQcdmSerialPort *port,
- GByteArray *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMAtSerialPort *at_port = NULL;
- QcdmResult *result = NULL;
- guint32 opmode = 0, sysmode = 0;
- int err = QCDM_SUCCESS;
-
- /* Parse the response */
- if (!error)
- result = qcdm_cmd_cm_subsys_state_info_result ((const char *) response->data, response->len, &err);
-
- if (!result) {
- /* If there was some error, fall back to use +CAD like we did before QCDM */
- if (info->modem)
- at_port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (info->modem), &info->error);
- else {
- g_set_error (&info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Failed to parse CM subsys state info command result: %d", err);
- }
-
- if (at_port)
- mm_at_serial_port_queue_command (at_port, "+CAD?", 3, get_analog_digital_done, info);
- else
- mm_callback_info_schedule (info);
- return;
- }
-
- qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE, &opmode);
- qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE, &sysmode);
- qcdm_result_unref (result);
-
- if (opmode == QCDM_CMD_CM_SUBSYS_STATE_INFO_OPERATING_MODE_ONLINE) {
- GByteArray *hdrstate;
-
- mm_callback_info_set_data (info, "sysmode", GUINT_TO_POINTER (sysmode), NULL);
-
- /* Get HDR subsystem state */
- hdrstate = g_byte_array_sized_new (25);
- hdrstate->len = qcdm_cmd_hdr_subsys_state_info_new ((char *) hdrstate->data, 25);
- g_assert (hdrstate->len);
- mm_qcdm_serial_port_queue_command (port, hdrstate, 3, reg_hdrstate_cb, info);
- } else {
- /* No service */
- set_callback_1x_state_helper (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- set_callback_evdo_state_helper (info, MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
- mm_callback_info_schedule (info);
- }
-}
-
-static void
-get_registration_state (MMModemCdma *modem,
- MMModemCdmaRegistrationStateFn callback,
- gpointer user_data)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- info = mm_generic_cdma_query_reg_state_callback_info_new (MM_GENERIC_CDMA (modem),
- MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
- MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
- callback,
- user_data);
-
- port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (modem), &info->error);
- if (!port && !priv->qcdm) {
- mm_dbg ("Returning saved registration states: 1x: %d EVDO: %d",
- priv->cdma_1x_reg_state, priv->evdo_reg_state);
- mm_generic_cdma_query_reg_state_set_callback_1x_state (info, priv->cdma_1x_reg_state);
- mm_generic_cdma_query_reg_state_set_callback_evdo_state (info, priv->evdo_reg_state);
- mm_callback_info_schedule (info);
- return;
- }
- g_clear_error (&info->error);
-
- /* Use QCDM for Call Manager state or HDR state before trying CAD, since
- * CAD doesn't always reflect the state of the HDR radio's registration
- * status.
- */
- if (priv->qcdm) {
- GByteArray *cmstate;
-
- cmstate = g_byte_array_sized_new (25);
- cmstate->len = qcdm_cmd_cm_subsys_state_info_new ((char *) cmstate->data, 25);
- g_assert (cmstate->len);
- mm_qcdm_serial_port_queue_command (priv->qcdm, cmstate, 3, reg_cmstate_cb, info);
- } else
- mm_at_serial_port_queue_command (port, "+CAD?", 3, get_analog_digital_done, info);
-}
-
-/*****************************************************************************/
-
-static void
-set_rm_proto_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- if (mm_callback_info_check_modem_removed (info) == FALSE) {
- if (error)
- info->error = g_error_copy (error);
-
- mm_callback_info_schedule (info);
- }
-}
-
-static void
-mm_generic_cdma_set_rm_protocol (MMGenericCdma *self,
- RmProtocol proto,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMAtSerialPort *port;
- char *cmd;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
-
- port = mm_generic_cdma_get_best_at_port (self, &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
- g_clear_error (&info->error);
-
- if (proto < RM_PROTO_ASYNC || proto > RM_PROTO_STU_III) {
- g_set_error (&info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Invalid Rm interface protocol %d",
- proto);
- mm_callback_info_schedule (info);
- return;
- }
-
- cmd = g_strdup_printf ("+CRM=%d", proto);
- mm_at_serial_port_queue_command (port, cmd, 3, set_rm_proto_done, info);
- g_free (cmd);
-}
-
-/*****************************************************************************/
-/* MMModemSimple interface */
-
-typedef enum {
- SIMPLE_STATE_BEGIN = 0,
- SIMPLE_STATE_ENABLE,
- SIMPLE_STATE_REGISTER,
- SIMPLE_STATE_PRE_CONNECT,
- SIMPLE_STATE_CONNECT,
- SIMPLE_STATE_DONE
-} SimpleState;
-
-static const char *
-simple_get_string_property (MMCallbackInfo *info, const char *name, GError **error)
-{
- GHashTable *properties = (GHashTable *) mm_callback_info_get_data (info, "simple-connect-properties");
- GValue *value;
-
- value = (GValue *) g_hash_table_lookup (properties, name);
- if (!value)
- return NULL;
-
- if (G_VALUE_HOLDS_STRING (value))
- return g_value_get_string (value);
-
- g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Invalid property type for '%s': %s (string expected)",
- name, G_VALUE_TYPE_NAME (value));
-
- return NULL;
-}
-
-static gboolean
-simple_get_uint_property (MMCallbackInfo *info,
- const char *name,
- guint32 *out_val,
- GError **error)
-{
- GHashTable *properties = (GHashTable *) mm_callback_info_get_data (info, "simple-connect-properties");
- GValue *value;
-
- g_return_val_if_fail (out_val != NULL, FALSE);
-
- value = (GValue *) g_hash_table_lookup (properties, name);
- if (value) {
- if (G_VALUE_HOLDS_UINT (value)) {
- *out_val = g_value_get_uint (value);
- return TRUE;
- }
-
- g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Invalid property type for '%s': %s (uint expected)",
- name, G_VALUE_TYPE_NAME (value));
- }
-
- return FALSE;
-}
-
-static gboolean
-simple_reg_retry (gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- mm_modem_cdma_get_registration_state (MM_MODEM_CDMA (info->modem),
- simple_reg_callback,
- info);
- return TRUE;
-}
-
-static void
-simple_reg_callback (MMModemCdma *modem,
- MMModemCdmaRegistrationState cdma_1x_reg_state,
- MMModemCdmaRegistrationState evdo_reg_state,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem);
- gboolean no_service_error = FALSE;
-
- if ( error
- && (error->domain == MM_MOBILE_ERROR)
- && (error->code == MM_MOBILE_ERROR_NO_NETWORK))
- no_service_error = TRUE;
-
- /* Fail immediately on anything but "no service" */
- if (error && !no_service_error) {
- simple_state_machine (MM_MODEM (modem), error, info);
- g_error_free (error);
- return;
- }
-
- if ( no_service_error
- || ( (cdma_1x_reg_state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
- && (evdo_reg_state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN))) {
- /* Not registered yet, queue up a retry */
- priv->reg_tries++;
- if (priv->reg_tries > 15) {
- error = g_error_new_literal (MM_MOBILE_ERROR,
- MM_MOBILE_ERROR_NO_NETWORK,
- "No service");
- simple_state_machine (MM_MODEM (modem), error, info);
- g_error_free (error);
- return;
- }
-
- /* otherwise, just try again in a bit */
- if (!priv->reg_retry_id)
- priv->reg_retry_id = g_timeout_add_seconds (4, simple_reg_retry, info);
- } else {
- /* Yay, at least one of 1x or EVDO is registered, we can proceed to dial */
- simple_state_machine (MM_MODEM (modem), NULL, info);
- }
-}
-
-static void
-reg_state_changed (MMModemCdma *self,
- MMModemCdmaRegistrationState cdma_1x_new_state,
- MMModemCdmaRegistrationState evdo_new_state,
- gpointer user_data)
-{
-/* Disabled for now... changing the registration state from the
- * subclass' query_registration_state handler also emits the registration
- * state changed signal, which will call this function, and execute
- * simple_state_machine() to advance to the next state. Then however
- * query_registration_state will call its callback, which ends up in
- * simple_reg_callback(), which calls simple_state_machine() too in
- * the same mainloop iteration. Not good. So until that's sorted out
- * we'll just have to poll registration state (every 4 seconds so its
- * not that bad.
- */
-#if 0
- MMCallbackInfo *info = user_data;
-
- /* If we're registered, we can proceed */
- if ( (cdma_1x_reg_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
- || (evdo_reg_state != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN))
- simple_state_machine (MM_MODEM (modem), NULL, info);
-#endif
-}
-
-static SimpleState
-set_simple_state (MMCallbackInfo *info, SimpleState state)
-{
- mm_callback_info_set_data (info, "simple-connect-state", GUINT_TO_POINTER (state), NULL);
- return state;
-}
-
-static void
-simple_state_machine (MMModem *modem, GError *error, gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericCdma *self;
- MMGenericCdmaPrivate *priv;
- SimpleState state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "simple-connect-state"));
- const char *str;
- guint id, rm_protocol = 0;
-
- /* Do nothing if modem removed */
- if (!modem || mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- goto out;
- }
-
- self = MM_GENERIC_CDMA (info->modem);
- priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- switch (state) {
- case SIMPLE_STATE_BEGIN:
- /* Enable state */
- state = set_simple_state (info, SIMPLE_STATE_ENABLE);
- mm_modem_enable (modem, simple_state_machine, info);
- break;
- case SIMPLE_STATE_ENABLE:
- /* Register state */
- state = set_simple_state (info, SIMPLE_STATE_REGISTER);
- mm_modem_cdma_get_registration_state (MM_MODEM_CDMA (modem),
- simple_reg_callback,
- info);
- id = g_signal_connect (modem,
- MM_MODEM_CDMA_REGISTRATION_STATE_CHANGED,
- G_CALLBACK (reg_state_changed),
- info);
- priv->reg_state_changed_id = id;
- break;
- case SIMPLE_STATE_REGISTER:
- /* Pre Connect state */
- registration_cleanup (MM_GENERIC_CDMA (modem), 0, 0);
- state = set_simple_state (info, SIMPLE_STATE_PRE_CONNECT);
- mm_modem_set_state (modem, MM_MODEM_STATE_REGISTERED, MM_MODEM_STATE_REASON_NONE);
-
- /* Change the Rm interface protocol due to manager request if needed */
- if (simple_get_uint_property (info, "rm-protocol", &rm_protocol, &info->error)) {
- mm_generic_cdma_set_rm_protocol (self, rm_protocol, simple_state_machine, info);
- break;
- }
-
- /* Or if the Rm protocol isn't the default, and there was no request
- * to change it, do that now.
- */
- if (priv->cur_crm != priv->orig_crm) {
- mm_generic_cdma_set_rm_protocol (self, priv->orig_crm, simple_state_machine, info);
- break;
- }
-
- /* Fall through */
- case SIMPLE_STATE_PRE_CONNECT:
- /* Connect state */
- state = set_simple_state (info, SIMPLE_STATE_CONNECT);
- str = simple_get_string_property (info, "number", &info->error);
- mm_modem_connect (modem, str, simple_state_machine, info);
- break;
- case SIMPLE_STATE_CONNECT:
- /* All done! */
- state = set_simple_state (info, SIMPLE_STATE_DONE);
- break;
- case SIMPLE_STATE_DONE:
- break;
- }
-
- out:
- if (info->error || state == SIMPLE_STATE_DONE) {
- if (modem)
- registration_cleanup (MM_GENERIC_CDMA (modem), 0, 0);
- mm_callback_info_schedule (info);
- }
-}
-
-static void
-simple_connect (MMModemSimple *simple,
- GHashTable *properties,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericCdma *self = MM_GENERIC_CDMA (simple);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- MMCallbackInfo *info;
- GError *error = NULL;
-
- if (priv->simple_connect_info) {
- error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
- "Connection is already in progress");
- callback (MM_MODEM (simple), error, user_data);
- g_clear_error (&error);
- return;
- }
-
- info = mm_callback_info_new (MM_MODEM (simple), callback, user_data);
- priv->simple_connect_info = info;
- mm_callback_info_set_data (info, "simple-connect-properties",
- g_hash_table_ref (properties),
- (GDestroyNotify) g_hash_table_unref);
-
- /* At least number must be present */
- if (!simple_get_string_property (info, "number", &error)) {
- if (!error)
- error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Missing number property");
- }
-
- simple_state_machine (MM_MODEM (simple), error, info);
- g_clear_error (&error);
-}
-
-static void
-simple_free_gvalue (gpointer data)
-{
- g_value_unset ((GValue *) data);
- g_slice_free (GValue, data);
-}
-
-static GValue *
-simple_uint_value (guint32 i)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_UINT);
- g_value_set_uint (val, i);
-
- return val;
-}
-
-#define SS_HASH_TAG "simple-get-status"
-
-static void
-simple_status_got_signal_quality (MMModem *modem,
- guint32 result,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- GHashTable *properties;
-
- if (error) {
- info->error = g_error_copy (error);
- g_warning ("Error getting signal quality: %s", error->message);
- } else {
- properties = (GHashTable *) mm_callback_info_get_data (info, SS_HASH_TAG);
- g_hash_table_insert (properties, "signal_quality", simple_uint_value (result));
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-simple_get_status_invoke (MMCallbackInfo *info)
-{
- MMModemSimpleGetStatusFn callback = (MMModemSimpleGetStatusFn) info->callback;
-
- callback (MM_MODEM_SIMPLE (info->modem),
- (GHashTable *) mm_callback_info_get_data (info, SS_HASH_TAG),
- info->error, info->user_data);
-}
-
-static void
-simple_get_status (MMModemSimple *simple,
- MMModemSimpleGetStatusFn callback,
- gpointer user_data)
-{
- GHashTable *properties;
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (simple),
- simple_get_status_invoke,
- G_CALLBACK (callback),
- user_data);
-
- properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, simple_free_gvalue);
- mm_callback_info_set_data (info, SS_HASH_TAG, properties, (GDestroyNotify) g_hash_table_unref);
- mm_modem_cdma_get_signal_quality (MM_MODEM_CDMA (simple), simple_status_got_signal_quality, info);
-}
-
-/*****************************************************************************/
-
-static void
-modem_valid_changed (MMGenericCdma *self, GParamSpec *pspec, gpointer user_data)
-{
- /* Be paranoid about tearing down any pending registration */
- if (!mm_modem_get_valid (MM_MODEM (self)))
- registration_cleanup (self, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL);
-}
-
-static void
-modem_state_changed (MMGenericCdma *self, GParamSpec *pspec, gpointer user_data)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
- MMModemState state;
-
- /* Start polling registration status and signal quality when enabled */
-
- state = mm_modem_get_state (MM_MODEM (self));
- if (state >= MM_MODEM_STATE_ENABLED) {
- if (!priv->poll_id) {
- priv->poll_id = g_timeout_add_seconds (30, periodic_poll_cb, self);
- /* Kick one off immediately */
- periodic_poll_cb (self);
- }
- } else {
- if (priv->poll_id)
- g_source_remove (priv->poll_id);
- priv->poll_id = 0;
- }
-}
-
-/*****************************************************************************/
-
-static void
-modem_init (MMModem *modem_class)
-{
- modem_class->owns_port = owns_port;
- modem_class->organize_ports = organize_ports;
- modem_class->release_port = release_port;
- modem_class->enable = enable;
- modem_class->disable = disable;
- modem_class->connect = connect;
- modem_class->disconnect = disconnect;
- modem_class->get_info = get_card_info;
-}
-
-static void
-modem_cdma_init (MMModemCdma *cdma_class)
-{
- cdma_class->get_signal_quality = get_signal_quality;
- cdma_class->get_esn = get_esn;
- cdma_class->get_serving_system = get_serving_system;
- cdma_class->get_registration_state = get_registration_state;
-}
-
-static void
-modem_simple_init (MMModemSimple *class)
-{
- class->connect = simple_connect;
- class->get_status = simple_get_status;
-}
-
-static void
-mm_generic_cdma_init (MMGenericCdma *self)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- g_signal_connect (self, "notify::" MM_MODEM_VALID,
- G_CALLBACK (modem_valid_changed), NULL);
- g_signal_connect (self, "notify::" MM_MODEM_STATE,
- G_CALLBACK (modem_state_changed), NULL);
-
- /* Default to Network Layer Rm interface/PPP */
- priv->orig_crm = priv->cur_crm = RM_PROTO_NETWORK_PPP;
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (object);
-
- switch (prop_id) {
- case MM_MODEM_PROP_TYPE:
- break;
- case PROP_EVDO_REV0:
- priv->evdo_rev0 = g_value_get_boolean (value);
- break;
- case PROP_EVDO_REVA:
- priv->evdo_revA = g_value_get_boolean (value);
- break;
- case PROP_REG_TRY_CSS:
- priv->reg_try_css = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (object);
-
- switch (prop_id) {
- case MM_MODEM_PROP_DATA_DEVICE:
- if (priv->data)
- g_value_set_string (value, mm_port_get_device (priv->data));
- else
- g_value_set_string (value, NULL);
- break;
- case MM_MODEM_PROP_TYPE:
- g_value_set_uint (value, MM_MODEM_TYPE_CDMA);
- break;
- case MM_MODEM_CDMA_PROP_MEID:
- g_value_set_string (value, priv->meid);
- break;
- case PROP_EVDO_REV0:
- g_value_set_boolean (value, priv->evdo_rev0);
- break;
- case PROP_EVDO_REVA:
- g_value_set_boolean (value, priv->evdo_revA);
- break;
- case PROP_REG_TRY_CSS:
- g_value_set_boolean (value, priv->reg_try_css);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-dispose (GObject *object)
-{
- MMGenericCdma *self = MM_GENERIC_CDMA (object);
- MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self);
-
- registration_cleanup (self, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL);
-
- if (priv->poll_id)
- g_source_remove (priv->poll_id);
-
- G_OBJECT_CLASS (mm_generic_cdma_parent_class)->dispose (object);
-}
-
-static void
-mm_generic_cdma_class_init (MMGenericCdmaClass *generic_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (generic_class);
- MMModemBaseClass *base_class = MM_MODEM_BASE_CLASS (generic_class);
-
- mm_generic_cdma_parent_class = g_type_class_peek_parent (generic_class);
- g_type_class_add_private (object_class, sizeof (MMGenericCdmaPrivate));
-
- /* Virtual methods */
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->dispose = dispose;
- base_class->port_grabbed = port_grabbed;
- generic_class->query_registration_state = real_query_registration_state;
-
- /* Properties */
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_DATA_DEVICE,
- MM_MODEM_DATA_DEVICE);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_TYPE,
- MM_MODEM_TYPE);
-
- g_object_class_override_property (object_class,
- MM_MODEM_CDMA_PROP_MEID,
- MM_MODEM_CDMA_MEID);
-
- g_object_class_install_property (object_class, PROP_EVDO_REV0,
- g_param_spec_boolean (MM_GENERIC_CDMA_EVDO_REV0,
- "EVDO rev0",
- "Supports EVDO rev0",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class, PROP_EVDO_REVA,
- g_param_spec_boolean (MM_GENERIC_CDMA_EVDO_REVA,
- "EVDO revA",
- "Supports EVDO revA",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (object_class, PROP_REG_TRY_CSS,
- g_param_spec_boolean (MM_GENERIC_CDMA_REGISTRATION_TRY_CSS,
- "RegistrationTryCss",
- "Use Serving System response when checking modem"
- " registration state.",
- TRUE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
diff --git a/src/mm-generic-cdma.h b/src/mm-generic-cdma.h
deleted file mode 100644
index ba7b76f8..00000000
--- a/src/mm-generic-cdma.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#ifndef MM_GENERIC_CDMA_H
-#define MM_GENERIC_CDMA_H
-
-#include "mm-modem.h"
-#include "mm-modem-base.h"
-#include "mm-modem-cdma.h"
-#include "mm-at-serial-port.h"
-#include "mm-qcdm-serial-port.h"
-#include "mm-callback-info.h"
-
-#define MM_TYPE_GENERIC_CDMA (mm_generic_cdma_get_type ())
-#define MM_GENERIC_CDMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_GENERIC_CDMA, MMGenericCdma))
-#define MM_GENERIC_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_GENERIC_CDMA, MMGenericCdmaClass))
-#define MM_IS_GENERIC_CDMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_GENERIC_CDMA))
-#define MM_IS_GENERIC_CDMA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_GENERIC_CDMA))
-#define MM_GENERIC_CDMA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_GENERIC_CDMA, MMGenericCdmaClass))
-
-#define MM_GENERIC_CDMA_EVDO_REV0 "evdo-rev0"
-#define MM_GENERIC_CDMA_EVDO_REVA "evdo-revA"
-
-#define MM_GENERIC_CDMA_REGISTRATION_TRY_CSS "registration-try-css"
-
-typedef struct {
- MMModemBase parent;
-} MMGenericCdma;
-
-typedef struct {
- MMModemBaseClass parent;
-
- /* Called to allow subclasses to update port flags, attach unsolicited
- * result code handlers, change port attributes, etc. This is called
- * after the generic class has installed it's own handlers; if the
- * generic class' behavior is not desired, subclasses can override the
- * port_grabbed() method of MMModemBase.
- */
- void (*port_grabbed) (MMGenericCdma *self,
- MMPort *port,
- MMAtPortFlags at_pflags,
- gpointer user_data);
-
- /* Called after all ports have been organized to allow subclasses to
- * make changes to ports after we've assigned primary, secondary, and data
- * designations.
- */
- void (*ports_organized) (MMGenericCdma *self, MMAtSerialPort *primary);
-
- /* Subclasses should implement this function if they can more accurately
- * determine the registration state and/or roaming status than the base
- * class can (by using manufacturer custom AT commands or whatever).
- * The base class passes its detected registration state in the
- * cur_cdma_state and cur_evdo_state arguments, which the subclass should
- * override if necessary before passing to the callback.
- *
- * Subclasses can use the helper functions
- * mm_generic_cdma_query_reg_state_callback_info_new(),
- * mm_generic_cdma_query_reg_state_set_callback_1x_state(), and
- * mm_generic_cdma_query_reg_state_set_callback_evdo_state() to create the
- * MMCallbackInfo object and to set the registration state which is passed
- * to the callback when the subclass' registration query completes.
- *
- * Subclasses should generally not return parsing or other non-critical
- * errors to the callback since that fails the entire registration check,
- * rendering the superclass' checks useless.
- */
- void (*query_registration_state) (MMGenericCdma *self,
- MMModemCdmaRegistrationState cur_cdma_state,
- MMModemCdmaRegistrationState cur_evdo_state,
- MMModemCdmaRegistrationStateFn callback,
- gpointer user_data);
-
- /* Called after generic enable operations, but before the modem has entered
- * the ENABLED state.
- */
- void (*post_enable) (MMGenericCdma *self,
- MMModemFn callback,
- gpointer user_data);
-
- /* Called after generic disable operations, but before the modem has entered
- * the DISABLED state.
- */
- void (*post_disable) (MMGenericCdma *self,
- MMModemFn callback,
- gpointer user_data);
-} MMGenericCdmaClass;
-
-GType mm_generic_cdma_get_type (void);
-
-MMModem *mm_generic_cdma_new (const char *device,
- const char *driver,
- const char *plugin,
- gboolean evdo_rev0,
- gboolean evdo_revA,
- guint vendor,
- guint product);
-
-/* Private, for subclasses */
-
-/* Returns the first port (if any) which has the given flag */
-MMAtSerialPort *mm_generic_cdma_get_at_port (MMGenericCdma *modem, MMAtPortFlags flag);
-
-MMAtSerialPort *mm_generic_cdma_get_best_at_port (MMGenericCdma *modem,
- GError **error);
-
-MMQcdmSerialPort *mm_generic_cdma_get_best_qcdm_port (MMGenericCdma *modem,
- GError **error);
-
-void mm_generic_cdma_update_cdma1x_quality (MMGenericCdma *self, guint32 quality);
-void mm_generic_cdma_update_evdo_quality (MMGenericCdma *self, guint32 quality);
-
-/* For unsolicited 1x registration state changes */
-void mm_generic_cdma_set_1x_registration_state (MMGenericCdma *self,
- MMModemCdmaRegistrationState new_state);
-
-/* For unsolicited EVDO registration state changes */
-void mm_generic_cdma_set_evdo_registration_state (MMGenericCdma *self,
- MMModemCdmaRegistrationState new_state);
-
-MMModemCdmaRegistrationState mm_generic_cdma_1x_get_registration_state_sync (MMGenericCdma *self);
-
-MMModemCdmaRegistrationState mm_generic_cdma_evdo_get_registration_state_sync (MMGenericCdma *self);
-
-/* query_registration_state class function helpers */
-MMCallbackInfo *mm_generic_cdma_query_reg_state_callback_info_new (MMGenericCdma *self,
- MMModemCdmaRegistrationState cur_cdma_state,
- MMModemCdmaRegistrationState cur_evdo_state,
- MMModemCdmaRegistrationStateFn callback,
- gpointer user_data);
-
-MMModemCdmaRegistrationState mm_generic_cdma_query_reg_state_get_callback_1x_state (MMCallbackInfo *info);
-
-void mm_generic_cdma_query_reg_state_set_callback_1x_state (MMCallbackInfo *info,
- MMModemCdmaRegistrationState new_state);
-
-MMModemCdmaRegistrationState mm_generic_cdma_query_reg_state_get_callback_evdo_state (MMCallbackInfo *info);
-
-void mm_generic_cdma_query_reg_state_set_callback_evdo_state (MMCallbackInfo *info,
- MMModemCdmaRegistrationState new_state);
-
-#endif /* MM_GENERIC_CDMA_H */
diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c
deleted file mode 100644
index 426d3db4..00000000
--- a/src/mm-generic-gsm.c
+++ /dev/null
@@ -1,7020 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 - 2012 Red Hat, Inc.
- * Copyright (C) 2009 - 2010 Ericsson
- */
-
-#include <config.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include "mm-generic-gsm.h"
-#include "mm-modem-gsm-card.h"
-#include "mm-modem-gsm-network.h"
-#include "mm-modem-gsm-sms.h"
-#include "mm-modem-gsm-ussd.h"
-#include "mm-modem-simple.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-at-serial-port.h"
-#include "mm-qcdm-serial-port.h"
-#include "mm-serial-parsers.h"
-#include "mm-modem-helpers.h"
-#include "mm-log.h"
-#include "mm-properties-changed-signal.h"
-#include "mm-utils.h"
-#include "mm-modem-location.h"
-#include "mm-sms-utils.h"
-
-static void modem_init (MMModem *modem_class);
-static void modem_gsm_card_init (MMModemGsmCard *gsm_card_class);
-static void modem_gsm_network_init (MMModemGsmNetwork *gsm_network_class);
-static void modem_gsm_sms_init (MMModemGsmSms *gsm_sms_class);
-static void modem_gsm_ussd_init (MMModemGsmUssd *gsm_ussd_class);
-static void modem_simple_init (MMModemSimple *class);
-static void modem_location_init (MMModemLocation *class);
-
-G_DEFINE_TYPE_EXTENDED (MMGenericGsm, mm_generic_gsm, MM_TYPE_MODEM_BASE, 0,
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_CARD, modem_gsm_card_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_NETWORK, modem_gsm_network_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_SMS, modem_gsm_sms_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_LOCATION, modem_location_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_GSM_USSD, modem_gsm_ussd_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_SIMPLE, modem_simple_init))
-
-#define MM_GENERIC_GSM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_GENERIC_GSM, MMGenericGsmPrivate))
-
-typedef struct {
- char *driver;
- char *plugin;
- char *device;
-
- gboolean valid;
- gboolean pin_checked;
- guint32 pin_check_tries;
- guint pin_check_timeout;
- char *simid;
- gboolean simid_checked;
- guint32 simid_tries;
-
- MMModemGsmAllowedMode allowed_mode;
-
- gboolean roam_allowed;
-
- char *oper_code;
- char *oper_name;
- guint32 ip_method;
-
- GPtrArray *reg_regex;
-
- guint poll_id;
-
- /* CREG and CGREG info */
- gboolean creg_poll;
- gboolean cgreg_poll;
- /* Index 0 for CREG, index 1 for CGREG */
- gulong lac[2];
- gulong cell_id[2];
- MMModemGsmAccessTech act;
-
- /* Index 0 for CREG, index 1 for CGREG */
- MMModemGsmNetworkRegStatus reg_status[2];
- guint pending_reg_id;
- MMCallbackInfo *pending_reg_info;
- gboolean manual_reg;
-
- gboolean cmer_enabled;
- guint roam_ind;
- guint signal_ind;
- guint service_ind;
-
- guint signal_quality_id;
- time_t signal_emit_timestamp;
- time_t signal_update_timestamp;
- guint32 signal_quality;
- gint cid;
-
- guint32 charsets;
- guint32 cur_charset;
-
- MMAtSerialPort *primary;
- MMAtSerialPort *secondary;
- MMQcdmSerialPort *qcdm;
- MMPort *data;
- gboolean data_opened_at_connect;
-
- /* Location API */
- guint32 loc_caps;
- gboolean loc_enabled;
- gboolean loc_signal;
-
- gboolean ussd_enabled;
- MMCallbackInfo *pending_ussd_info;
- MMModemGsmUssdState ussd_state;
- char *ussd_network_request;
- char *ussd_network_notification;
-
- /* SMS */
- GHashTable *sms_present;
- /* Map from SMS index numbers to parsed PDUs (themselves as hash tables) */
- GHashTable *sms_contents;
- /*
- * Map from multipart SMS reference numbers to SMSMultiPartMessage
- * structures.
- */
- GHashTable *sms_parts;
- gboolean sms_pdu_mode;
- gboolean sms_pdu_supported;
-
- guint sms_fetch_pending;
-
- /* Facility locks */
- MMModemGsmFacility enabled_facilities;
-} MMGenericGsmPrivate;
-
-static void get_registration_status (MMAtSerialPort *port, MMCallbackInfo *info);
-
-static void reg_state_changed (MMAtSerialPort *port,
- GMatchInfo *match_info,
- gpointer user_data);
-
-static gboolean handle_reg_status_response (MMGenericGsm *self,
- GString *response,
- GError **error);
-
-static MMModemGsmAccessTech etsi_act_to_mm_act (gint act);
-
-static void _internal_update_access_technology (MMGenericGsm *modem,
- MMModemGsmAccessTech act);
-
-static void reg_info_updated (MMGenericGsm *self,
- gboolean update_rs,
- MMGenericGsmRegType rs_type,
- MMModemGsmNetworkRegStatus status,
- gboolean update_code,
- const char *oper_code,
- gboolean update_name,
- const char *oper_name);
-
-static void update_lac_ci (MMGenericGsm *self, gulong lac, gulong ci, guint idx);
-
-static void ciev_received (MMAtSerialPort *port,
- GMatchInfo *info,
- gpointer user_data);
-
-static void cmti_received (MMAtSerialPort *port,
- GMatchInfo *info,
- gpointer user_data);
-
-static void cusd_received (MMAtSerialPort *port,
- GMatchInfo *info,
- gpointer user_data);
-
-static void clck_cb (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data);
-
-#define GS_HASH_TAG "get-sms"
-static GValue *simple_string_value (const char *str);
-static GValue *simple_uint_value (guint32 i);
-static void simple_free_gvalue (gpointer data);
-
-MMModem *
-mm_generic_gsm_new (const char *device,
- const char *driver,
- const char *plugin,
- guint vendor,
- guint product)
-{
- g_return_val_if_fail (device != NULL, NULL);
- g_return_val_if_fail (driver != NULL, NULL);
- g_return_val_if_fail (plugin != NULL, NULL);
-
- return MM_MODEM (g_object_new (MM_TYPE_GENERIC_GSM,
- MM_MODEM_MASTER_DEVICE, device,
- MM_MODEM_DRIVER, driver,
- MM_MODEM_PLUGIN, plugin,
- MM_MODEM_HW_VID, vendor,
- MM_MODEM_HW_PID, product,
- NULL));
-}
-
-gint
-mm_generic_gsm_get_cid (MMGenericGsm *modem)
-{
- g_return_val_if_fail (MM_IS_GENERIC_GSM (modem), 0);
-
- return MM_GENERIC_GSM_GET_PRIVATE (modem)->cid;
-}
-
-typedef struct {
- const char *result;
- const char *normalized;
- guint code;
-} CPinResult;
-
-static CPinResult unlock_results[] = {
- /* Longer entries first so we catch the correct one with strcmp() */
- { "PH-NETSUB PIN", "ph-netsub-pin", MM_MOBILE_ERROR_NETWORK_SUBSET_PIN },
- { "PH-NETSUB PUK", "ph-netsub-puk", MM_MOBILE_ERROR_NETWORK_SUBSET_PUK },
- { "PH-FSIM PIN", "ph-fsim-pin", MM_MOBILE_ERROR_PH_FSIM_PIN },
- { "PH-FSIM PUK", "ph-fsim-puk", MM_MOBILE_ERROR_PH_FSIM_PUK },
- { "PH-CORP PIN", "ph-corp-pin", MM_MOBILE_ERROR_CORP_PIN },
- { "PH-CORP PUK", "ph-corp-puk", MM_MOBILE_ERROR_CORP_PUK },
- { "PH-SIM PIN", "ph-sim-pin", MM_MOBILE_ERROR_PH_SIM_PIN },
- { "PH-NET PIN", "ph-net-pin", MM_MOBILE_ERROR_NETWORK_PIN },
- { "PH-NET PUK", "ph-net-puk", MM_MOBILE_ERROR_NETWORK_PUK },
- { "PH-SP PIN", "ph-sp-pin", MM_MOBILE_ERROR_SERVICE_PIN },
- { "PH-SP PUK", "ph-sp-puk", MM_MOBILE_ERROR_SERVICE_PUK },
- { "SIM PIN2", "sim-pin2", MM_MOBILE_ERROR_SIM_PIN2 },
- { "SIM PUK2", "sim-puk2", MM_MOBILE_ERROR_SIM_PUK2 },
- { "SIM PIN", "sim-pin", MM_MOBILE_ERROR_SIM_PIN },
- { "SIM PUK", "sim-puk", MM_MOBILE_ERROR_SIM_PUK },
- { NULL, NULL, MM_MOBILE_ERROR_PHONE_FAILURE },
-};
-
-static GError *
-error_for_unlock_required (const char *unlock)
-{
- CPinResult *iter = &unlock_results[0];
-
- if (!unlock || !strlen (unlock))
- return NULL;
-
- /* Translate the error */
- while (iter->result) {
- if (!strcmp (iter->normalized, unlock))
- return mm_mobile_error_for_code (iter->code);
- iter++;
- }
-
- return g_error_new (MM_MOBILE_ERROR,
- MM_MOBILE_ERROR_UNKNOWN,
- "Unknown unlock request '%s'", unlock);
-}
-
-static void
-get_unlock_retries_cb (MMModem *modem,
- GArray *result,
- GError *error,
- gpointer user_data)
-{
- if (!error)
- mm_modem_base_set_pin_retry_counts (MM_MODEM_BASE (modem), result);
- else {
- if (result)
- g_array_unref (result);
- mm_modem_base_set_pin_retry_counts (MM_MODEM_BASE (modem), NULL);
- }
-}
-
-static void
-pin_check_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- gboolean parsed = FALSE;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else if (response && strstr (response->str, "+CPIN:")) {
- const char *str = strstr (response->str, "+CPIN:") + 6;
-
- /* Skip possible whitespaces after '+CPIN:' and before the response */
- while (*str == ' ')
- str++;
-
- /* Some phones (Motorola EZX models) seem to quote the response */
- if (str[0] == '"')
- str++;
-
- if (g_str_has_prefix (str, "READY")) {
- mm_modem_base_set_unlock_required (MM_MODEM_BASE (info->modem), NULL);
- mm_modem_gsm_card_get_unlock_retries (MM_MODEM_GSM_CARD (info->modem),
- get_unlock_retries_cb,
- NULL);
- parsed = TRUE;
- } else {
- CPinResult *iter = &unlock_results[0];
-
- /* Translate the error */
- while (iter->result) {
- if (g_str_has_prefix (str, iter->result)) {
- info->error = mm_mobile_error_for_code (iter->code);
- mm_modem_base_set_unlock_required (MM_MODEM_BASE (info->modem), iter->normalized);
- mm_modem_gsm_card_get_unlock_retries (MM_MODEM_GSM_CARD (info->modem),
- get_unlock_retries_cb,
- NULL);
- parsed = TRUE;
- break;
- }
- iter++;
- }
- }
- }
-
- if (!parsed) {
- /* Assume unlocked if we don't recognize the pin request result */
- mm_modem_base_set_unlock_required (MM_MODEM_BASE (info->modem), NULL);
- mm_modem_gsm_card_get_unlock_retries (MM_MODEM_GSM_CARD (info->modem),
- get_unlock_retries_cb, NULL);
- if (!info->error) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse PIN request response '%s'",
- response ? response->str : "(unknown)");
- }
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-check_pin (MMGenericGsm *modem,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv;
- MMCallbackInfo *info;
-
- g_return_if_fail (MM_IS_GENERIC_GSM (modem));
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
- mm_at_serial_port_queue_command (priv->primary, "+CPIN?", 3, pin_check_done, info);
-}
-
-static void
-get_imei_cb (MMModem *modem,
- const char *result,
- GError *error,
- gpointer user_data)
-{
- if (modem) {
- mm_modem_base_set_equipment_identifier (MM_MODEM_BASE (modem), error ? "" : result);
- mm_serial_port_close (MM_SERIAL_PORT (MM_GENERIC_GSM_GET_PRIVATE (modem)->primary));
- }
-}
-
-static void
-get_info_cb (MMModem *modem,
- const char *manufacturer,
- const char *model,
- const char *version,
- GError *error,
- gpointer user_data)
-{
- /* Base class handles saving the info for us */
- if (modem)
- mm_serial_port_close (MM_SERIAL_PORT (MM_GENERIC_GSM_GET_PRIVATE (modem)->primary));
-}
-
-/*****************************************************************************/
-
-static MMModemGsmNetworkRegStatus
-gsm_reg_status (MMGenericGsm *self, guint32 *out_idx)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- guint32 idx = 1;
-
- /* Some devices (Blackberries for example) will respond to +CGREG, but
- * return ERROR for +CREG, probably because their firmware is just stupid.
- * So here we prefer the +CREG response, but if we never got a successful
- * +CREG response, we'll take +CGREG instead.
- */
-
- if ( priv->reg_status[0] == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME
- || priv->reg_status[0] == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING) {
- idx = 0;
- goto out;
- }
-
- if ( priv->reg_status[1] == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME
- || priv->reg_status[1] == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING) {
- idx = 1;
- goto out;
- }
-
- if (priv->reg_status[0] == MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING) {
- idx = 0;
- goto out;
- }
-
- if (priv->reg_status[1] == MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING) {
- idx = 1;
- goto out;
- }
-
- if (priv->reg_status[0] != MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN) {
- idx = 0;
- goto out;
- }
-
-out:
- if (out_idx)
- *out_idx = idx;
- return priv->reg_status[idx];
-}
-
-void
-mm_generic_gsm_update_enabled_state (MMGenericGsm *self,
- gboolean stay_connected,
- MMModemStateReason reason)
-{
- /* While connected we don't want registration status changes to change
- * the modem's state away from CONNECTED.
- */
- if (stay_connected && (mm_modem_get_state (MM_MODEM (self)) >= MM_MODEM_STATE_DISCONNECTING))
- return;
-
- switch (gsm_reg_status (self, NULL)) {
- case MM_MODEM_GSM_NETWORK_REG_STATUS_HOME:
- case MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING:
- mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_REGISTERED, reason);
- break;
- case MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING:
- mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_SEARCHING, reason);
- break;
- case MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE:
- case MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED:
- case MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN:
- default:
- mm_modem_set_state (MM_MODEM (self), MM_MODEM_STATE_ENABLED, reason);
- break;
- }
-}
-
-static void
-check_valid (MMGenericGsm *self)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- gboolean new_valid = FALSE;
-
- if (priv->primary && priv->data && priv->pin_checked && priv->simid_checked)
- new_valid = TRUE;
-
- mm_modem_base_set_valid (MM_MODEM_BASE (self), new_valid);
-}
-
-
-static void
-get_iccid_done (MMModem *modem,
- const char *response,
- GError *error,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv;
- const char *p = response;
- GChecksum *sum = NULL;
-
- if (error || !response || !strlen (response))
- goto done;
-
- sum = g_checksum_new (G_CHECKSUM_SHA1);
-
- /* Make sure it looks like an ICCID */
- while (*p) {
- if (!isdigit (*p)) {
- g_warning ("%s: invalid ICCID format (not a digit)", __func__);
- goto done;
- }
- g_checksum_update (sum, (const guchar *) p++, 1);
- }
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- g_free (priv->simid);
- priv->simid = g_strdup (g_checksum_get_string (sum));
-
- mm_dbg ("SIM ID source '%s'", response);
- mm_dbg ("SIM ID '%s'", priv->simid);
-
- g_object_notify (G_OBJECT (modem), MM_MODEM_GSM_CARD_SIM_IDENTIFIER);
-
-done:
- if (sum)
- g_checksum_free (sum);
-
- if (modem) {
- MM_GENERIC_GSM_GET_PRIVATE (modem)->simid_checked = TRUE;
- check_valid (MM_GENERIC_GSM (modem));
- }
-}
-
-#define ICCID_CMD "+CRSM=176,12258,0,0,10"
-
-static void
-real_get_iccid_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- const char *str;
- int sw1, sw2;
- gboolean success = FALSE;
- char buf[21], swapped[21];
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- goto done;
- }
-
- memset (buf, 0, sizeof (buf));
- str = mm_strip_tag (response->str, "+CRSM:");
- if (sscanf (str, "%d,%d,\"%20c\"", &sw1, &sw2, (char *) &buf) == 3)
- success = TRUE;
- else {
- /* May not include quotes... */
- if (sscanf (str, "%d,%d,%20c", &sw1, &sw2, (char *) &buf) == 3)
- success = TRUE;
- }
-
- if (!success) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse the CRSM response");
- goto done;
- }
-
- if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x91) || (sw1 == 0x92) || (sw1 == 0x9f)) {
- gsize len = 0;
- int f_pos = -1, i;
-
- /* Make sure the buffer is only digits or 'F' */
- for (len = 0; len < sizeof (buf) && buf[len]; len++) {
- if (isdigit (buf[len]))
- continue;
- if (buf[len] == 'F' || buf[len] == 'f') {
- buf[len] = 'F'; /* canonicalize the F */
- f_pos = len;
- continue;
- }
- if (buf[len] == '\"') {
- buf[len] = 0;
- break;
- }
-
- /* Invalid character */
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "CRSM ICCID response contained invalid character '%c'",
- buf[len]);
- goto done;
- }
-
- /* BCD encoded ICCIDs are 20 digits long */
- if (len != 20) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Invalid +CRSM ICCID response size (was %zd, expected 20)",
- len);
- goto done;
- }
-
- /* Ensure if there's an 'F' that it's second-to-last */
- if ((f_pos >= 0) && (f_pos != len - 2)) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Invalid +CRSM ICCID length (unexpected F)");
- goto done;
- }
-
- /* Swap digits in the EFiccid response to get the actual ICCID, each
- * group of 2 digits is reversed in the +CRSM response. i.e.:
- *
- * 21436587 -> 12345678
- */
- memset (swapped, 0, sizeof (swapped));
- for (i = 0; i < 10; i++) {
- swapped[i * 2] = buf[(i * 2) + 1];
- swapped[(i * 2) + 1] = buf[i * 2];
- }
-
- /* Zero out the F for 19 digit ICCIDs */
- if (swapped[len - 1] == 'F')
- swapped[len - 1] = 0;
-
- mm_callback_info_set_result (info, g_strdup (swapped), g_free);
- } else {
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- if (priv->simid_tries++ < 2) {
- /* Try one more time... Gobi 1K cards may reply to the first
- * request with '+CRSM: 106,134,""' which is bogus because
- * subsequent requests work fine.
- */
- mm_at_serial_port_queue_command (port, ICCID_CMD, 20, real_get_iccid_done, info);
- return;
- } else {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
- sw1, sw2);
- }
- }
-
-done:
- /* Balance open from real_get_sim_iccid() */
- mm_serial_port_close (MM_SERIAL_PORT (port));
-
- mm_callback_info_schedule (info);
-}
-
-static void
-real_get_sim_iccid (MMGenericGsm *self,
- MMModemStringFn callback,
- gpointer callback_data)
-{
- MMCallbackInfo *info;
- MMAtSerialPort *port;
- GError *error = NULL;
-
- port = mm_generic_gsm_get_best_at_port (self, &error);
- if (!port) {
- callback (MM_MODEM (self), NULL, error, callback_data);
- g_clear_error (&error);
- return;
- }
-
- if (!mm_serial_port_open (MM_SERIAL_PORT (port), &error)) {
- callback (MM_MODEM (self), NULL, error, callback_data);
- g_clear_error (&error);
- return;
- }
-
- info = mm_callback_info_string_new (MM_MODEM (self), callback, callback_data);
-
- /* READ BINARY of EFiccid (ICC Identification) ETSI TS 102.221 section 13.2 */
- mm_at_serial_port_queue_command (port, ICCID_CMD, 20, real_get_iccid_done, info);
-}
-
-static void
-initial_iccid_check (MMGenericGsm *self)
-{
- g_assert (MM_GENERIC_GSM_GET_CLASS (self)->get_sim_iccid);
- MM_GENERIC_GSM_GET_CLASS (self)->get_sim_iccid (self, get_iccid_done, NULL);
-}
-
-static void initial_pin_check_done (MMModem *modem, GError *error, gpointer user_data);
-
-static gboolean
-pin_check_again (gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- priv->pin_check_timeout = 0;
- check_pin (self, initial_pin_check_done, NULL);
- return FALSE;
-}
-
-static void
-initial_pin_check_done (MMModem *modem, GError *error, gpointer user_data)
-{
- MMGenericGsmPrivate *priv;
-
- /* modem could have been removed before we get here, in which case
- * 'modem' will be NULL.
- */
- if (!modem)
- return;
-
- g_return_if_fail (MM_IS_GENERIC_GSM (modem));
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- if ( error
- && priv->pin_check_tries++ < 3
- && !mm_modem_base_get_unlock_required (MM_MODEM_BASE (modem))) {
- /* Try it again a few times */
- if (priv->pin_check_timeout)
- g_source_remove (priv->pin_check_timeout);
- priv->pin_check_timeout = g_timeout_add_seconds (2, pin_check_again, modem);
- } else {
- /* Set pin checked flag before launching ICCID check. Some plugins may
- * use their own ICCID check, which is completed right away without
- * scheduling it in a callback info, so modem enable request may be done
- * just here. */
- priv->pin_checked = TRUE;
-
- /* Try to get the SIM ICCID after we've checked PIN status and the SIM
- * is ready.
- */
- initial_iccid_check (MM_GENERIC_GSM (modem));
-
- mm_serial_port_close (MM_SERIAL_PORT (priv->primary));
- }
-}
-
-static void
-initial_pin_check (MMGenericGsm *self)
-{
- GError *error = NULL;
- MMGenericGsmPrivate *priv;
-
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- g_return_if_fail (priv->primary != NULL);
-
- if (mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error)) {
- mm_at_serial_port_queue_command (priv->primary, "+CMEE=1", 2, NULL, NULL);
- check_pin (self, initial_pin_check_done, NULL);
- } else {
- g_warning ("%s: failed to open serial port: (%d) %s",
- __func__,
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
-
- /* Ensure the modem is still somewhat usable if opening the serial
- * port fails for some reason.
- */
- initial_pin_check_done (MM_MODEM (self), NULL, NULL);
- }
-}
-
-static void
-initial_imei_check (MMGenericGsm *self)
-{
- GError *error = NULL;
- MMGenericGsmPrivate *priv;
-
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- g_return_if_fail (priv->primary != NULL);
-
- if (mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error)) {
- /* Make sure echoing is off */
- mm_at_serial_port_queue_command (priv->primary, "E0", 3, NULL, NULL);
-
- /* Get modem's imei number */
- mm_modem_gsm_card_get_imei (MM_MODEM_GSM_CARD (self),
- get_imei_cb,
- NULL);
- } else {
- g_warning ("%s: failed to open serial port: (%d) %s",
- __func__,
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
-}
-
-static void
-initial_info_check (MMGenericGsm *self)
-{
- GError *error = NULL;
- MMGenericGsmPrivate *priv;
-
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- g_return_if_fail (priv->primary != NULL);
-
- if (mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error)) {
- /* Make sure echoing is off */
- mm_at_serial_port_queue_command (priv->primary, "E0", 3, NULL, NULL);
- mm_modem_base_get_card_info (MM_MODEM_BASE (self),
- priv->primary,
- NULL,
- get_info_cb,
- NULL);
- } else {
- g_warning ("%s: failed to open serial port: (%d) %s",
- __func__,
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
-}
-
-static void
-initial_facility_lock_check (MMGenericGsm *self)
-{
- GError *error = NULL;
- MMGenericGsmPrivate *priv;
-
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- g_return_if_fail (priv->primary != NULL);
-
- if (mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error)) {
- mm_at_serial_port_queue_command (priv->primary, "+CLCK=?", 3, clck_cb, self);
- } else {
- g_warning ("%s: failed to open serial port: (%d) %s",
- __func__,
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_clear_error (&error);
- }
-}
-
-static gboolean
-owns_port (MMModem *modem, const char *subsys, const char *name)
-{
- return !!mm_modem_base_get_port (MM_MODEM_BASE (modem), subsys, name);
-}
-
-static void
-port_grabbed (MMModemBase *base,
- MMPort *port,
- MMAtPortFlags at_pflags,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (base);
- GPtrArray *array;
- GRegex *regex;
- int i;
-
- if (MM_IS_AT_SERIAL_PORT (port)) {
- mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port),
- mm_serial_parser_v1_parse,
- mm_serial_parser_v1_new (),
- mm_serial_parser_v1_destroy);
- mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (port), at_pflags);
-
- /* Set up CREG unsolicited message handlers */
- array = mm_gsm_creg_regex_get (FALSE);
- for (i = 0; i < array->len; i++) {
- regex = g_ptr_array_index (array, i);
- mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, reg_state_changed, self, NULL);
- }
- mm_gsm_creg_regex_destroy (array);
-
- regex = g_regex_new ("\\r\\n\\+CIEV: (\\d+),(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, ciev_received, self, NULL);
- g_regex_unref (regex);
-
- regex = g_regex_new ("\\r\\n\\+CMTI: \"(\\S+)\",(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, cmti_received, self, NULL);
- g_regex_unref (regex);
-
- regex = g_regex_new ("\\r\\n\\+CUSD:\\s*(.*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
- mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, cusd_received, self, NULL);
- g_regex_unref (regex);
- }
-
- if (MM_GENERIC_GSM_GET_CLASS (self)->port_grabbed)
- MM_GENERIC_GSM_GET_CLASS (self)->port_grabbed (self, port, at_pflags, user_data);
-}
-
-static gboolean
-organize_ports (MMModem *modem, GError **error)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (!mm_modem_base_organize_ports (MM_MODEM_BASE (modem),
- &priv->primary,
- &priv->secondary,
- &priv->data,
- &priv->qcdm,
- error))
- return FALSE;
-
- /* Let subclasses twiddle ports if they want */
- if (MM_GENERIC_GSM_GET_CLASS (self)->ports_organized)
- MM_GENERIC_GSM_GET_CLASS (self)->ports_organized (self, priv->primary);
-
- g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE);
-
- /* Get the modem's general info */
- initial_info_check (self);
-
- /* Get modem's IMEI */
- initial_imei_check (self);
-
- /* Get modem's initial lock/unlock state; this also ensures the
- * SIM is ready by waiting if necessary for the SIM to initalize.
- */
- initial_pin_check (self);
-
- /* Determine what facility locks are supported */
- initial_facility_lock_check (self);
-
- check_valid (self);
- return TRUE;
-}
-
-static void
-release_port (MMModem *modem, const char *subsys, const char *name)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMPort *port;
-
- if (strcmp (subsys, "tty") && strcmp (subsys, "net"))
- return;
-
- port = mm_modem_base_get_port (MM_MODEM_BASE (modem), subsys, name);
- if (!port)
- return;
-
- if (port == (MMPort *) priv->primary) {
- mm_modem_base_remove_port (MM_MODEM_BASE (modem), port);
- priv->primary = NULL;
- }
-
- if (port == priv->data) {
- priv->data = NULL;
- g_object_notify (G_OBJECT (modem), MM_MODEM_DATA_DEVICE);
- }
-
- if (port == (MMPort *) priv->secondary) {
- mm_modem_base_remove_port (MM_MODEM_BASE (modem), port);
- priv->secondary = NULL;
- }
-
- if (port == (MMPort *) priv->qcdm) {
- mm_modem_base_remove_port (MM_MODEM_BASE (modem), port);
- priv->qcdm = NULL;
- }
-
- check_valid (MM_GENERIC_GSM (modem));
-}
-
-static void
-add_loc_capability (MMGenericGsm *self, guint32 cap)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- guint32 old_caps = priv->loc_caps;
-
- priv->loc_caps |= cap;
- if (priv->loc_caps != old_caps) {
- g_object_notify (G_OBJECT (self), MM_MODEM_LOCATION_CAPABILITIES);
- }
-}
-
-static void
-reg_poll_response (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
-
- if (!error)
- handle_reg_status_response (self, response, NULL);
-}
-
-static void
-periodic_signal_quality_cb (MMModem *modem,
- guint32 result,
- GError *error,
- gpointer user_data)
-{
- /* Cached signal quality already updated */
-}
-
-static void
-periodic_access_tech_cb (MMModem *modem,
- guint32 act,
- GError *error,
- gpointer user_data)
-{
- if (modem && !error && act)
- mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (modem), act);
-}
-
-static gboolean
-ps_network_supported (MMGenericGsm *gsm)
-{
- gboolean supported;
-
- g_object_get (G_OBJECT (gsm),
- MM_GENERIC_GSM_PS_NETWORK_SUPPORTED,
- &supported, NULL);
- return supported;
-}
-
-static gboolean
-periodic_poll_cb (gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMAtSerialPort *port;
-
- port = mm_generic_gsm_get_best_at_port (self, NULL);
- if (!port)
- return TRUE; /* oh well, try later */
-
- if (priv->creg_poll)
- mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, self);
- if (priv->cgreg_poll)
- mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, self);
-
- /* Don't poll signal quality if we got a notification in the past 10 seconds */
- if (time (NULL) - priv->signal_update_timestamp > 10) {
- mm_modem_gsm_network_get_signal_quality (MM_MODEM_GSM_NETWORK (self),
- periodic_signal_quality_cb,
- NULL);
- }
-
- if (MM_GENERIC_GSM_GET_CLASS (self)->get_access_technology)
- MM_GENERIC_GSM_GET_CLASS (self)->get_access_technology (self, periodic_access_tech_cb, NULL);
-
- return TRUE; /* continue running */
-}
-
-#define CREG_NUM_TAG "creg-num"
-#define CGREG_NUM_TAG "cgreg-num"
-
-static void
-initial_unsolicited_reg_check_done (MMCallbackInfo *info)
-{
- MMGenericGsmPrivate *priv;
- guint creg_num, cgreg_num;
-
- if (!info->modem || info->error)
- goto done;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- if (!priv->secondary)
- goto done;
-
- /* Enable unsolicited registration responses on secondary ports too,
- * to ensure that we get the response even if the modem is connected
- * on the primary port. We enable responses on both ports because we
- * cannot trust modems to reliably send the responses on the port we
- * enable them on.
- */
-
- creg_num = GPOINTER_TO_UINT (mm_callback_info_get_data (info, CREG_NUM_TAG));
- switch (creg_num) {
- case 1:
- mm_at_serial_port_queue_command (priv->secondary, "+CREG=1", 3, NULL, NULL);
- break;
- case 2:
- mm_at_serial_port_queue_command (priv->secondary, "+CREG=2", 3, NULL, NULL);
- break;
- default:
- break;
- }
-
- cgreg_num = GPOINTER_TO_UINT (mm_callback_info_get_data (info, CGREG_NUM_TAG));
- switch (cgreg_num) {
- case 1:
- mm_at_serial_port_queue_command (priv->secondary, "+CGREG=1", 3, NULL, NULL);
- break;
- case 2:
- mm_at_serial_port_queue_command (priv->secondary, "+CGREG=2", 3, NULL, NULL);
- break;
- default:
- break;
- }
-
-done:
- mm_callback_info_schedule (info);
-}
-
-static void
-cgreg1_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- /* The modem doesn't like unsolicited CGREG, so we'll need to poll */
- priv->cgreg_poll = TRUE;
- } else
- mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (1), NULL);
-
- /* Success; get initial state */
- mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
-
- initial_unsolicited_reg_check_done (info);
-}
-
-static void
-cgreg2_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- /* Ignore errors */
- if (error) {
- /* Try CGREG=1 instead */
- mm_at_serial_port_queue_command (port, "+CGREG=1", 3, cgreg1_done, info);
- } else {
- add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI);
-
- mm_callback_info_set_data (info, CGREG_NUM_TAG, GUINT_TO_POINTER (2), NULL);
-
- /* Success; get initial state */
- mm_at_serial_port_queue_command (port, "+CGREG?", 10, reg_poll_response, info->modem);
-
- /* All done */
- initial_unsolicited_reg_check_done (info);
- }
-}
-
-static void
-creg1_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMGenericGsmPrivate *priv;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- if (error) {
- /* The modem doesn't like unsolicited CREG, so we'll need to poll */
- priv->creg_poll = TRUE;
- } else
- mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (1), NULL);
-
- /* Success; get initial state */
- mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
-
- /* Now try to set up CGREG messages */
- if (ps_network_supported (MM_GENERIC_GSM (info->modem)))
- mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
- else {
- /* All done */
- initial_unsolicited_reg_check_done (info);
- }
-}
-
-static void
-creg2_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- /* Ignore errors */
- if (error)
- mm_at_serial_port_queue_command (port, "+CREG=1", 3, creg1_done, info);
- else {
- add_loc_capability (MM_GENERIC_GSM (info->modem), MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI);
-
- mm_callback_info_set_data (info, CREG_NUM_TAG, GUINT_TO_POINTER (2), NULL);
-
- /* Success; get initial state */
- mm_at_serial_port_queue_command (port, "+CREG?", 10, reg_poll_response, info->modem);
-
- /* Now try to set up CGREG messages */
- if (ps_network_supported (MM_GENERIC_GSM (info->modem)))
- mm_at_serial_port_queue_command (port, "+CGREG=2", 3, cgreg2_done, info);
- else {
- /* All done */
- initial_unsolicited_reg_check_done (info);
- }
- }
-}
-
-static void
-enable_failed (MMModem *modem, GError *error, MMCallbackInfo *info)
-{
- MMGenericGsmPrivate *priv;
-
- /* If modem already removed, do nothing */
- if (!modem || mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
-
- mm_modem_set_state (modem,
- MM_MODEM_STATE_DISABLED,
- MM_MODEM_STATE_REASON_NONE);
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- if (priv->primary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->primary)))
- mm_serial_port_close_force (MM_SERIAL_PORT (priv->primary));
- if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary)))
- mm_serial_port_close_force (MM_SERIAL_PORT (priv->secondary));
-
- mm_callback_info_schedule (info);
-}
-
-static guint32 best_charsets[] = {
- MM_MODEM_CHARSET_UTF8,
- MM_MODEM_CHARSET_UCS2,
- MM_MODEM_CHARSET_8859_1,
- MM_MODEM_CHARSET_IRA,
- MM_MODEM_CHARSET_GSM,
- MM_MODEM_CHARSET_UNKNOWN
-};
-
-static void
-enabled_set_charset_done (MMModem *modem,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- guint idx;
-
- /* only modem removals are really a hard error */
- if (error) {
- if (!modem) {
- enable_failed (modem, error, info);
- return;
- }
-
- /* Try the next best charset */
- idx = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "best-charset")) + 1;
- if (best_charsets[idx] == MM_MODEM_CHARSET_UNKNOWN) {
- GError *tmp_error;
-
- /* No more character sets we can use */
- tmp_error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_UNSUPPORTED_CHARSET,
- "Failed to find a usable modem character set");
- enable_failed (modem, tmp_error, info);
- g_error_free (tmp_error);
- } else {
- /* Send the new charset */
- mm_callback_info_set_data (info, "best-charset", GUINT_TO_POINTER (idx), NULL);
- mm_modem_set_charset (modem, best_charsets[idx], enabled_set_charset_done, info);
- }
- } else {
- /* Modem is now enabled; update the state */
- mm_generic_gsm_update_enabled_state (MM_GENERIC_GSM (modem), FALSE, MM_MODEM_STATE_REASON_NONE);
-
- /* Set up unsolicited registration notifications */
- mm_at_serial_port_queue_command (MM_GENERIC_GSM_GET_PRIVATE (modem)->primary,
- "+CREG=2", 3, creg2_done, info);
- }
-}
-
-static void
-supported_charsets_done (MMModem *modem,
- guint32 charsets,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- if (!modem) {
- enable_failed (modem, error, info);
- return;
- }
-
- /* Switch the device's charset; we prefer UTF-8, but UCS2 will do too */
- mm_modem_set_charset (modem, best_charsets[0], enabled_set_charset_done, info);
-}
-
-static void
-get_allowed_mode_done (MMModem *modem,
- MMModemGsmAllowedMode mode,
- GError *error,
- gpointer user_data)
-{
- if (modem) {
- mm_generic_gsm_update_allowed_mode (MM_GENERIC_GSM (modem),
- error ? MM_MODEM_GSM_ALLOWED_MODE_ANY : mode);
- }
-}
-
-static void
-ciev_received (MMAtSerialPort *port,
- GMatchInfo *info,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- int quality = 0, ind = 0;
- char *str;
-
- if (!priv->cmer_enabled)
- return;
-
- str = g_match_info_fetch (info, 1);
- if (str)
- ind = atoi (str);
- g_free (str);
-
- if (ind == priv->signal_ind) {
- str = g_match_info_fetch (info, 2);
- if (str) {
- quality = atoi (str);
- mm_generic_gsm_update_signal_quality (self, quality * 20);
- }
- g_free (str);
- }
-
- /* FIXME: handle roaming and service indicators */
-}
-
-typedef struct {
- /*
- * The key index number that refers to this multipart message -
- * usually the index number of the first part received.
- */
- guint index;
-
- /* Number of parts in the complete message */
- guint numparts;
-
- /* Number of parts missing from the message */
- guint missing;
-
- /* Array of (index numbers of) message parts, in order */
- guint *parts;
-} SMSMultiPartMessage;
-
-static void
-sms_cache_insert (MMModem *modem, GHashTable *properties, guint idx)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- GHashTable *old_properties;
- GValue *ref;
-
- ref = g_hash_table_lookup (properties, "concat-reference");
- if (ref != NULL) {
- GValue *max, *seq;
- guint refnum, maxnum, seqnum;
- SMSMultiPartMessage *mpm;
-
- max = g_hash_table_lookup (properties, "concat-max");
- seq = g_hash_table_lookup (properties, "concat-sequence");
- if (max == NULL || seq == NULL) {
- /* Internal error - not all required data present */
- return;
- }
-
- refnum = g_value_get_uint (ref);
- maxnum = g_value_get_uint (max);
- seqnum = g_value_get_uint (seq);
-
- if (seqnum > maxnum) {
- /* Error - SMS says "part N of M", but N > M */
- return;
- }
-
- mpm = g_hash_table_lookup (priv->sms_parts, GUINT_TO_POINTER (refnum));
- if (mpm == NULL) {
- /* Create a new one */
- if (maxnum > 255)
- maxnum = 255;
- mpm = g_malloc0 (sizeof (*mpm));
- mpm->index = idx;
- mpm->numparts = maxnum;
- mpm->missing = maxnum;
- mpm->parts = g_malloc0 (maxnum * sizeof(*mpm->parts));
- g_hash_table_insert (priv->sms_parts, GUINT_TO_POINTER (refnum),
- mpm);
- }
-
- if (maxnum != mpm->numparts) {
- /* Error - other messages with this refnum claim a different number of parts */
- return;
- }
-
- if (mpm->parts[seqnum - 1] != 0) {
- /* Error - two SMS segments have claimed to be the same part of the same message. */
- return;
- }
-
- mpm->parts[seqnum - 1] = idx;
- mpm->missing--;
- }
-
- old_properties = g_hash_table_lookup (priv->sms_contents, GUINT_TO_POINTER (idx));
- if (old_properties != NULL)
- g_hash_table_unref (old_properties);
-
- g_hash_table_insert (priv->sms_contents, GUINT_TO_POINTER (idx),
- g_hash_table_ref (properties));
-}
-
-/*
- * Takes a hash table representing a (possibly partial) SMS and
- * determines if it is the key part of a complete SMS. The complete
- * SMS, if any, is returned. If there is no such SMS (for example, not
- * all parts are present yet), NULL is returned. The passed-in hash
- * table is dereferenced, and the returned hash table is referenced.
- */
-static GHashTable *
-sms_cache_lookup_full (MMModem *modem,
- GHashTable *properties,
- GError **error)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- int i, refnum, indexnum;
- SMSMultiPartMessage *mpm;
- GHashTable *full, *part, *first;
- GHashTableIter iter;
- gpointer key, value;
- char *fulltext;
- char **textparts;
- GValue *ref, *idx, *text;
-
- ref = g_hash_table_lookup (properties, "concat-reference");
- if (ref == NULL)
- return properties;
- refnum = g_value_get_uint (ref);
-
- idx = g_hash_table_lookup (properties, "index");
- if (idx == NULL) {
- g_hash_table_unref (properties);
- return NULL;
- }
-
- indexnum = g_value_get_uint (idx);
- g_hash_table_unref (properties);
-
- mpm = g_hash_table_lookup (priv->sms_parts,
- GUINT_TO_POINTER (refnum));
- if (mpm == NULL) {
- g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Internal error - no multipart structure for multipart SMS");
- return NULL;
- }
-
- /* Check that this is the key */
- if (indexnum != mpm->index)
- return NULL;
-
- if (mpm->missing != 0)
- return NULL;
-
- /* Complete multipart message is present. Assemble it */
- textparts = g_malloc0((1 + mpm->numparts) * sizeof (*textparts));
- for (i = 0 ; i < mpm->numparts ; i++) {
- part = g_hash_table_lookup (priv->sms_contents,
- GUINT_TO_POINTER (mpm->parts[i]));
- if (part == NULL) {
- g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Internal error - part %d (index %d) is missing",
- i, mpm->parts[i]);
- g_free (textparts);
- return NULL;
- }
- text = g_hash_table_lookup (part, "text");
- if (text == NULL) {
- g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Internal error - part %d (index %d) has no text element",
- i, mpm->parts[i]);
- g_free (textparts);
- return NULL;
- }
- textparts[i] = g_value_dup_string (text);
- }
- textparts[i] = NULL;
- fulltext = g_strjoinv (NULL, textparts);
- g_strfreev (textparts);
-
- first = g_hash_table_lookup (priv->sms_contents,
- GUINT_TO_POINTER (mpm->parts[0]));
- full = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
- simple_free_gvalue);
- g_hash_table_iter_init (&iter, first);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- const char *keystr = key;
- if (strncmp (keystr, "concat-", 7) == 0)
- continue;
- if (strcmp (keystr, "text") == 0 ||
- strcmp (keystr, "index") == 0)
- continue;
- if (strcmp (keystr, "class") == 0) {
- GValue *val;
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_UINT);
- g_value_copy (value, val);
- g_hash_table_insert (full, key, val);
- } else {
- GValue *val;
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_STRING);
- g_value_copy (value, val);
- g_hash_table_insert (full, key, val);
- }
- }
-
- g_hash_table_insert (full, "index", simple_uint_value (mpm->index));
- g_hash_table_insert (full, "text", simple_string_value (fulltext));
- g_free (fulltext);
-
- return full;
-}
-
-static void
-cmti_received_has_sms (MMModemGsmSms *modem,
- GHashTable *properties,
- GError *error,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- guint idx;
- gboolean complete;
- GValue *ref;
-
- if (properties == NULL)
- return;
-
- ref = g_hash_table_lookup (properties, "concat-reference");
- if (ref == NULL) {
- /* single-part message */
- GValue *idxval = g_hash_table_lookup (properties, "index");
- if (idxval == NULL)
- return;
- idx = g_value_get_uint (idxval);
- complete = TRUE;
- } else {
- SMSMultiPartMessage *mpm;
- mpm = g_hash_table_lookup (priv->sms_parts,
- GUINT_TO_POINTER (g_value_get_uint (ref)));
- if (mpm == NULL)
- return;
- idx = mpm->index;
- complete = (mpm->missing == 0);
- }
-
- if (complete)
- mm_modem_gsm_sms_completed (MM_MODEM_GSM_SMS (self), idx, TRUE);
-
- mm_modem_gsm_sms_received (MM_MODEM_GSM_SMS (self), idx, complete);
-}
-
-static void sms_get_invoke (MMCallbackInfo *info);
-static void sms_get_done (MMAtSerialPort *port, GString *response,
- GError *error, gpointer user_data);
-
-static void
-cmti_received (MMAtSerialPort *port,
- GMatchInfo *info,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMCallbackInfo *cbinfo;
- guint idx = 0;
- char *str, *command;
-
- str = g_match_info_fetch (info, 2);
- if (str)
- idx = atoi (str);
- g_free (str);
-
- /* Don't signal multiple times if there are multiple CMTI notifications for a message */
- if (g_hash_table_lookup_extended (priv->sms_present, GINT_TO_POINTER (idx), NULL, NULL))
- return;
-
- /* Nothing is currently stored in the hash table - presence is all that matters. */
- g_hash_table_insert (priv->sms_present, GINT_TO_POINTER (idx), NULL);
-
- /* Retrieve the message */
- cbinfo = mm_callback_info_new_full (MM_MODEM (user_data),
- sms_get_invoke,
- G_CALLBACK (cmti_received_has_sms),
- user_data);
- mm_callback_info_set_data (cbinfo,
- "complete-sms-only",
- GUINT_TO_POINTER (FALSE),
- NULL);
-
- if (priv->sms_fetch_pending != 0) {
- mm_err("sms_fetch_pending is %d, not 0", priv->sms_fetch_pending);
- }
- priv->sms_fetch_pending = idx;
-
- command = g_strdup_printf ("+CMGR=%d", idx);
- mm_at_serial_port_queue_command (port, command, 10, sms_get_done, cbinfo);
- /* Don't want to signal received here before we have the contents */
-}
-
-static void
-cmer_cb (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- if (!error) {
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (user_data);
-
- priv->cmer_enabled = TRUE;
-
- /* Enable CMER on the secondary port if we can too */
- if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) {
- gchar *cmd = NULL;
-
- g_object_get (G_OBJECT (user_data), MM_GENERIC_GSM_CMER_ENABLE_CMD, &cmd, NULL);
- if (cmd && strlen (cmd))
- mm_at_serial_port_queue_command (priv->secondary, cmd, 3, NULL, NULL);
- g_free (cmd);
- }
- }
-}
-
-static void
-cind_cb (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMGenericGsm *self;
- MMGenericGsmPrivate *priv;
- GHashTable *indicators;
-
- if (error)
- return;
-
- self = MM_GENERIC_GSM (user_data);
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- indicators = mm_parse_cind_test_response (response->str, NULL);
- if (indicators) {
- CindResponse *r;
- gchar *cmd = NULL;
-
- r = g_hash_table_lookup (indicators, "signal");
- if (r)
- priv->signal_ind = cind_response_get_index (r);
-
- r = g_hash_table_lookup (indicators, "roam");
- if (r)
- priv->roam_ind = cind_response_get_index (r);
-
- r = g_hash_table_lookup (indicators, "service");
- if (r)
- priv->service_ind = cind_response_get_index (r);
-
- /* Enable CMER in the primary port */
- g_object_get (G_OBJECT (user_data), MM_GENERIC_GSM_CMER_ENABLE_CMD, &cmd, NULL);
- if (cmd && strlen (cmd))
- mm_at_serial_port_queue_command (port, cmd, 3, cmer_cb, self);
- g_free (cmd);
- g_hash_table_destroy (indicators);
- }
-}
-
-static void
-cusd_enable_cb (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- if (error) {
- mm_warn ("(%s): failed to enable USSD notifications.",
- mm_port_get_device (MM_PORT (port)));
- return;
- }
-
- MM_GENERIC_GSM_GET_PRIVATE (user_data)->ussd_enabled = TRUE;
-}
-
-typedef struct {
- MMGenericGsmPrivate *priv;
- MMModemGsmFacility facility;
-} FacilityLockInfo;
-
-static void
-get_facility_lock_state_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- gboolean enabled = FALSE;
- FacilityLockInfo *finfo = (FacilityLockInfo *)user_data;
-
- if (!error && mm_gsm_parse_clck_response (response->str, &enabled)) {
- if (enabled)
- finfo->priv->enabled_facilities |= finfo->facility;
- else
- finfo->priv->enabled_facilities &= ~finfo->facility;
- }
- mm_serial_port_close (MM_SERIAL_PORT (port));
- g_free (finfo);
-}
-
-static void
-get_facility_lock_states (MMGenericGsm *self,
- MMModemGsmFacility facilities,
- MMAtSerialPort *port,
- GError *error)
-{
- gchar *cmd;
- MMGenericGsmPrivate *priv;
- gchar *facility_name;
- FacilityLockInfo *finfo;
- int i;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- for (i = 0; i < sizeof (MMModemGsmFacility) * 8; i++) {
- guint32 facility = 1 << i;
- if (facilities & facility) {
- facility_name = mm_gsm_get_facility_name (facility);
- if (facility_name != NULL && mm_serial_port_open (MM_SERIAL_PORT (port), &error)) {
- cmd = g_strdup_printf ("+CLCK=\"%s\",2", facility_name);
- finfo = g_malloc0 (sizeof (FacilityLockInfo));
- finfo->facility = facility;
- finfo->priv = priv;
- mm_at_serial_port_queue_command (port, cmd, 3, get_facility_lock_state_done, finfo);
- g_free (cmd);
- }
- }
- }
-}
-
-static void
-clck_cb (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMModemGsmFacility facilities;
-
- if (!error && mm_gsm_parse_clck_test_response (response->str, &facilities))
- get_facility_lock_states (MM_GENERIC_GSM (user_data), facilities, port, error);
- mm_serial_port_close (MM_SERIAL_PORT (port));
-}
-
-static void
-sms_set_format_cb (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (error) {
- mm_warn ("(%s): failed to set SMS mode, assuming text mode",
- mm_port_get_device (MM_PORT (port)));
- priv->sms_pdu_mode = FALSE;
- priv->sms_pdu_supported = FALSE;
- } else {
- mm_info ("(%s): using %s mode for SMS",
- mm_port_get_device (MM_PORT (port)),
- priv->sms_pdu_mode ? "PDU" : "text");
- }
-}
-
-
-#define CMGF_TAG "+CMGF:"
-
-static void
-sms_get_format_cb (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMGenericGsm *self;
- MMGenericGsmPrivate *priv;
- const char *reply;
- GRegex *r;
- GMatchInfo *match_info;
- char *s;
- int min = -1, max = -1;
-
- if (error) {
- mm_warn ("(%s): failed to query SMS mode, assuming text mode",
- mm_port_get_device (MM_PORT (port)));
- return;
- }
-
- /* Strip whitespace and response tag */
- reply = response->str;
- if (g_str_has_prefix (reply, CMGF_TAG))
- reply += strlen (CMGF_TAG);
- while (isspace (*reply))
- reply++;
-
- r = g_regex_new ("\\(?\\s*(\\d+)\\s*[-,]?\\s*(\\d+)?\\s*\\)?", 0, 0, NULL);
- if (!r) {
- mm_warn ("(%s): failed to parse CMGF query result", mm_port_get_device (MM_PORT (port)));
- return;
- }
-
- self = MM_GENERIC_GSM (user_data);
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- if (g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, NULL)) {
- s = g_match_info_fetch (match_info, 1);
- if (s)
- min = atoi (s);
- g_free (s);
-
- s = g_match_info_fetch (match_info, 2);
- if (s)
- max = atoi (s);
- g_free (s);
-
- /* If the modem only supports PDU mode, use PDUs.
- * FIXME: when the PDU code is more robust, default to PDU if the
- * modem supports it.
- */
- if (min == 0 && max < 1) {
- /* Will get reset to FALSE on receipt of error */
- priv->sms_pdu_mode = TRUE;
- mm_at_serial_port_queue_command (priv->primary, "AT+CMGF=0", 3, sms_set_format_cb, self);
- } else
- mm_at_serial_port_queue_command (priv->primary, "AT+CMGF=1", 3, sms_set_format_cb, self);
-
- /* Save whether PDU mode is supported so we can fall back to it if text fails */
- if (min == 0)
- priv->sms_pdu_supported = TRUE;
- }
- g_match_info_free (match_info);
-
- g_regex_unref (r);
-}
-
-void
-mm_generic_gsm_enable_complete (MMGenericGsm *self,
- GError *error,
- MMCallbackInfo *info)
-{
- MMGenericGsmPrivate *priv;
- gchar *cmd = NULL;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
- g_return_if_fail (info != NULL);
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (error) {
- enable_failed ((MMModem *) self, error, info);
- return;
- }
-
- /* Open the second port here if the modem has one. We'll use it for
- * signal strength and registration updates when the device is connected,
- * but also many devices will send unsolicited registration or other
- * messages to the secondary port but not the primary.
- */
- if (priv->secondary) {
- if (!mm_serial_port_open (MM_SERIAL_PORT (priv->secondary), &error)) {
- mm_dbg ("error opening secondary port: (%d) %s",
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- }
- }
-
- /* Try to enable flow control */
- g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_FLOW_CONTROL_CMD, &cmd, NULL);
- if (cmd && strlen (cmd))
- mm_at_serial_port_queue_command (priv->primary, cmd, 3, NULL, NULL);
- g_free (cmd);
-
- /* Set SMS storage locations */
- g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_SMS_STORAGE_LOCATION_CMD, &cmd, NULL);
- if (cmd && strlen (cmd))
- mm_at_serial_port_queue_command (priv->primary, cmd, 3, NULL, NULL);
- g_free (cmd);
-
- /* Enable SMS notifications */
- g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_SMS_INDICATION_ENABLE_CMD, &cmd, NULL);
- if (cmd && strlen (cmd))
- mm_at_serial_port_queue_command (priv->primary, cmd, 3, NULL, NULL);
- g_free (cmd);
-
- /* Check and enable the right SMS mode */
- mm_at_serial_port_queue_command (priv->primary, "AT+CMGF=?", 3, sms_get_format_cb, self);
-
- /* Enable USSD notifications */
- mm_at_serial_port_queue_command (priv->primary, "+CUSD=1", 3, cusd_enable_cb, self);
-
- mm_at_serial_port_queue_command (priv->primary, "+CIND=?", 3, cind_cb, self);
-
- /* Try one more time to get the SIM ID */
- if (!priv->simid)
- MM_GENERIC_GSM_GET_CLASS (self)->get_sim_iccid (self, get_iccid_done, NULL);
-
- /* Get allowed mode */
- if (MM_GENERIC_GSM_GET_CLASS (self)->get_allowed_mode)
- MM_GENERIC_GSM_GET_CLASS (self)->get_allowed_mode (self, get_allowed_mode_done, NULL);
-
- /* Try again to get facility locks */
- if (priv->enabled_facilities == 0)
- initial_facility_lock_check (self);
-
- /* And supported character sets */
- mm_modem_get_supported_charsets (MM_MODEM (self), supported_charsets_done, info);
-}
-
-static void
-real_do_enable_power_up_done (MMGenericGsm *self,
- GString *response,
- GError *error,
- MMCallbackInfo *info)
-{
- /* Ignore power-up errors as not all devices actually support CFUN=1 */
- mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), NULL, info);
-}
-
-static void
-enable_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- /* Let subclasses handle the power up command response/error; many devices
- * don't support +CFUN, but for those that do let them handle the error
- * correctly.
- */
- g_assert (MM_GENERIC_GSM_GET_CLASS (info->modem)->do_enable_power_up_done);
- MM_GENERIC_GSM_GET_CLASS (info->modem)->do_enable_power_up_done (MM_GENERIC_GSM (info->modem),
- response,
- error,
- info);
-}
-
-static void
-enable_power_up_check_needed_done (MMModem *self,
- guint32 needed,
- GError *error,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- char *cmd = NULL;
-
- if (needed)
- g_object_get (G_OBJECT (self), MM_GENERIC_GSM_POWER_UP_CMD, &cmd, NULL);
- else
- mm_dbg ("Power-up not needed, skipping...");
-
- if (cmd && strlen (cmd))
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (priv->primary), cmd, 5, enable_done, user_data);
- else
- enable_done (MM_AT_SERIAL_PORT (priv->primary), NULL, NULL, user_data);
- g_free (cmd);
-}
-
-static void
-init_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- char *cmd = NULL;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info);
- return;
- }
-
- /* Ensure echo is off after the init command; some modems ignore the
- * E0 when it's in the same line as ATZ (Option GIO322).
- */
- mm_at_serial_port_queue_command (port, "E0", 2, NULL, NULL);
-
- /* Some phones (like Blackberries) don't support +CMEE=1, so make it
- * optional. It completely violates 3GPP TS 27.007 (9.1) but what can we do...
- */
- mm_at_serial_port_queue_command (port, "+CMEE=1", 2, NULL, NULL);
-
- g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_INIT_CMD_OPTIONAL, &cmd, NULL);
- mm_at_serial_port_queue_command (port, cmd, 2, NULL, NULL);
- g_free (cmd);
-
- /* Plugins can now check if they need the power up command or not */
- if (MM_GENERIC_GSM_GET_CLASS (info->modem)->do_enable_power_up_check_needed)
- MM_GENERIC_GSM_GET_CLASS (info->modem)->do_enable_power_up_check_needed (MM_GENERIC_GSM (info->modem),
- enable_power_up_check_needed_done,
- info);
- else
- enable_power_up_check_needed_done (info->modem, TRUE, NULL, info);
-}
-
-static void
-enable_flash_done (MMSerialPort *port, GError *error, gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- char *cmd = NULL;
-
- if (error) {
- mm_generic_gsm_enable_complete (MM_GENERIC_GSM (info->modem), error, info);
- return;
- }
-
- /* Send the init command twice; some devices (Nokia N900) appear to take a
- * few commands before responding correctly. Instead of penalizing them for
- * being stupid the first time by failing to enable the device, just
- * try again.
- */
- g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_INIT_CMD, &cmd, NULL);
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), cmd, 3, NULL, NULL);
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), cmd, 3, init_done, user_data);
- g_free (cmd);
-}
-
-static void
-real_do_enable (MMGenericGsm *self, MMModemFn callback, gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 100, FALSE, enable_flash_done, info);
-}
-
-static void
-enable (MMModem *modem,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- GError *error = NULL;
- const char *unlock;
-
- /* If the device needs a PIN, deal with that now, but we don't care
- * about SIM-PIN2/SIM-PUK2 since the device is operational without it.
- */
- unlock = mm_modem_base_get_unlock_required (MM_MODEM_BASE (modem));
- if (unlock && strcmp (unlock, "sim-puk2") && strcmp (unlock, "sim-pin2")) {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (modem, callback, user_data);
- info->error = error_for_unlock_required (unlock);
- mm_callback_info_schedule (info);
- return;
- }
-
- /* First, reset the previously used CID */
- priv->cid = -1;
-
- if (!mm_serial_port_open (MM_SERIAL_PORT (priv->primary), &error)) {
- MMCallbackInfo *info;
-
- g_assert (error);
- info = mm_callback_info_new (modem, callback, user_data);
- info->error = error;
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_modem_set_state (modem, MM_MODEM_STATE_ENABLING, MM_MODEM_STATE_REASON_NONE);
-
- g_assert (MM_GENERIC_GSM_GET_CLASS (modem)->do_enable);
- MM_GENERIC_GSM_GET_CLASS (modem)->do_enable (MM_GENERIC_GSM (modem), callback, user_data);
-}
-
-static void
-disable_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- MMGenericGsm *self = MM_GENERIC_GSM (info->modem);
-
- mm_serial_port_close_force (MM_SERIAL_PORT (port));
- mm_modem_set_state (MM_MODEM (info->modem),
- MM_MODEM_STATE_DISABLED,
- MM_MODEM_STATE_REASON_NONE);
-
- /* Clear out circuit-switched registration info... */
- reg_info_updated (self,
- TRUE, MM_GENERIC_GSM_REG_TYPE_CS, MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN,
- TRUE, NULL,
- TRUE, NULL);
- /* ...and packet-switched registration info */
- reg_info_updated (self,
- TRUE, MM_GENERIC_GSM_REG_TYPE_PS, MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN,
- TRUE, NULL,
- TRUE, NULL);
- }
- mm_callback_info_schedule (info);
-}
-
-static void
-disable_flash_done (MMSerialPort *port,
- GError *error,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv;
- MMCallbackInfo *info = user_data;
- MMModemState prev_state;
- char *cmd = NULL;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
-
- /* Reset old state since the operation failed */
- prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
- mm_modem_set_state (MM_MODEM (info->modem),
- prev_state,
- MM_MODEM_STATE_REASON_NONE);
-
- mm_callback_info_schedule (info);
- return;
- }
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- /* Disable unsolicited messages */
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "+CREG=0", 3, NULL, NULL);
- if (ps_network_supported (MM_GENERIC_GSM (info->modem)))
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "+CGREG=0", 3, NULL, NULL);
-
- if (priv->ussd_enabled) {
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "+CUSD=0", 3, NULL, NULL);
- priv->ussd_enabled = FALSE;
- }
-
- if (priv->cmer_enabled) {
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "+CMER=0", 3, NULL, NULL);
-
- /* And on the secondary port */
- if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary)))
- mm_at_serial_port_queue_command (priv->secondary, "+CMER=0", 3, NULL, NULL);
-
- priv->cmer_enabled = FALSE;
- }
-
- g_object_get (G_OBJECT (info->modem), MM_GENERIC_GSM_POWER_DOWN_CMD, &cmd, NULL);
- if (cmd && strlen (cmd))
- mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), cmd, 5, disable_done, user_data);
- else
- disable_done (MM_AT_SERIAL_PORT (port), NULL, NULL, user_data);
- g_free (cmd);
-}
-
-static void
-mark_disabled (gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- mm_modem_set_state (MM_MODEM (info->modem),
- MM_MODEM_STATE_DISABLING,
- MM_MODEM_STATE_REASON_NONE);
-
- if (mm_port_get_connected (MM_PORT (priv->primary)))
- mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, TRUE, disable_flash_done, info);
- else
- disable_flash_done (MM_SERIAL_PORT (priv->primary), NULL, info);
-}
-
-static void
-secondary_unsolicited_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- mm_serial_port_close_force (MM_SERIAL_PORT (port));
- mark_disabled (user_data);
-}
-
-static void
-disable (MMModem *modem,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMCallbackInfo *info;
- MMModemState state;
-
- /* First, reset the previously used CID and clean up registration */
- g_warn_if_fail (priv->cid == -1);
- priv->cid = -1;
-
- mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (modem));
-
- mm_generic_gsm_ussd_cleanup (MM_GENERIC_GSM (modem));
-
- if (priv->poll_id) {
- g_source_remove (priv->poll_id);
- priv->poll_id = 0;
- }
-
- if (priv->signal_quality_id) {
- g_source_remove (priv->signal_quality_id);
- priv->signal_quality_id = 0;
- }
-
- if (priv->pin_check_timeout) {
- g_source_remove (priv->pin_check_timeout);
- priv->pin_check_timeout = 0;
- }
-
- update_lac_ci (self, 0, 0, 0);
- update_lac_ci (self, 0, 0, 1);
- _internal_update_access_technology (self, MM_MODEM_GSM_ACCESS_TECH_UNKNOWN);
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- /* Cache the previous state so we can reset it if the operation fails */
- state = mm_modem_get_state (modem);
- mm_callback_info_set_data (info,
- MM_GENERIC_GSM_PREV_STATE_TAG,
- GUINT_TO_POINTER (state),
- NULL);
-
- /* Clean up the secondary port if it's open */
- if (priv->secondary && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) {
- mm_dbg("Shutting down secondary port");
- mm_at_serial_port_queue_command (priv->secondary, "+CREG=0", 3, NULL, NULL);
- mm_at_serial_port_queue_command (priv->secondary, "+CGREG=0", 3, NULL, NULL);
- mm_at_serial_port_queue_command (priv->secondary, "+CMER=0", 3, secondary_unsolicited_done, info);
- } else
- mark_disabled (info);
-}
-
-static void
-get_string_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else
- mm_callback_info_set_result (info, g_strdup (response->str), g_free);
-
- mm_callback_info_schedule (info);
-}
-
-static void
-get_mnc_length_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- int sw1, sw2;
- const char *imsi;
- gboolean success = FALSE;
- char hex[51];
- char *bin;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- goto done;
- }
-
- memset (hex, 0, sizeof (hex));
- if (sscanf (response->str, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3)
- success = TRUE;
- else {
- /* May not include quotes... */
- if (sscanf (response->str, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3)
- success = TRUE;
- }
-
- if (!success) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse the CRSM response");
- goto done;
- }
-
- if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x91) || (sw1 == 0x92) || (sw1 == 0x9f)) {
- gsize buflen = 0;
- guint32 mnc_len;
-
- /* Make sure the buffer is only hex characters */
- while (buflen < sizeof (hex) && hex[buflen]) {
- if (!isxdigit (hex[buflen])) {
- hex[buflen] = 0x0;
- break;
- }
- buflen++;
- }
-
- /* Convert hex string to binary */
- bin = utils_hexstr2bin (hex, &buflen);
- if (!bin || buflen < 4) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "SIM returned malformed response '%s'",
- hex);
- g_free (bin);
- goto done;
- }
-
- /* MNC length is byte 4 of this SIM file */
- mnc_len = bin[3] & 0xFF;
- if (mnc_len == 2 || mnc_len == 3) {
- imsi = mm_callback_info_get_data (info, "imsi");
- mm_callback_info_set_result (info, g_strndup (imsi, 3 + mnc_len), g_free);
- } else {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "SIM returned invalid MNC length %d (should be either 2 or 3)",
- mnc_len);
- }
- g_free (bin);
- } else {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
- sw1, sw2);
- }
-
-done:
- mm_callback_info_schedule (info);
-}
-
-static void
-get_operator_id_imsi_done (MMModem *modem,
- const char *result,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMAtSerialPort *port;
-
- if (error) {
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
- }
-
- g_clear_error (&info->error);
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_callback_info_set_data (info, "imsi", g_strdup (result), g_free);
-
- /* READ BINARY of EFad (Administrative Data) ETSI 51.011 section 10.3.18 */
- mm_at_serial_port_queue_command_cached (port,
- "+CRSM=176,28589,0,0,4",
- 3,
- get_mnc_length_done,
- info);
-}
-
-static void
-get_spn_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- int sw1, sw2;
- gboolean success = FALSE;
- char hex[51];
- char *bin, *utf8;
-
- if (error) {
- info->error = g_error_copy (error);
- goto done;
- }
-
- memset (hex, 0, sizeof (hex));
- if (sscanf (response->str, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3)
- success = TRUE;
- else {
- /* May not include quotes... */
- if (sscanf (response->str, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3)
- success = TRUE;
- }
-
- if (!success) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse the CRSM response");
- goto done;
- }
-
- if ((sw1 == 0x90 && sw2 == 0x00) || (sw1 == 0x91) || (sw1 == 0x92) || (sw1 == 0x9f)) {
- gsize buflen = 0;
-
- /* Make sure the buffer is only hex characters */
- while (buflen < sizeof (hex) && hex[buflen]) {
- if (!isxdigit (hex[buflen])) {
- hex[buflen] = 0x0;
- break;
- }
- buflen++;
- }
-
- /* Convert hex string to binary */
- bin = utils_hexstr2bin (hex, &buflen);
- if (!bin) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "SIM returned malformed response '%s'",
- hex);
- goto done;
- }
-
- /* Remove the FF filler at the end */
- while (buflen > 1 && bin[buflen - 1] == (char)0xff)
- buflen--;
-
- /* First byte is metadata; remainder is GSM-7 unpacked into octets; convert to UTF8 */
- utf8 = (char *)mm_charset_gsm_unpacked_to_utf8 ((guint8 *)bin + 1, buflen - 1);
- g_free(bin);
- mm_callback_info_set_result(info, utf8, g_free);
- } else {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
- sw1, sw2);
- }
-
-done:
- mm_callback_info_schedule (info);
-}
-
-
-static void
-get_imei (MMModemGsmCard *modem,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port)
- mm_callback_info_schedule (info);
- else {
- g_clear_error (&info->error);
- mm_at_serial_port_queue_command_cached (port, "+CGSN", 3, get_string_done, info);
- }
-}
-
-static void
-get_imsi (MMModemGsmCard *modem,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port)
- mm_callback_info_schedule (info);
- else {
- g_clear_error (&info->error);
- mm_at_serial_port_queue_command_cached (port, "+CIMI", 3, get_string_done, info);
- }
-}
-
-static void
-get_operator_id (MMModemGsmCard *modem,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
- mm_modem_gsm_card_get_imsi (MM_MODEM_GSM_CARD (modem),
- get_operator_id_imsi_done,
- info);
-}
-
-static void
-get_spn (MMModemGsmCard *modem,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port)
- mm_callback_info_schedule (info);
- else {
- g_clear_error (&info->error);
-
- /* READ BINARY of EFspn (Service Provider Name) ETSI 51.011 section 10.3.11 */
- mm_at_serial_port_queue_command_cached (port,
- "+CRSM=176,28486,0,0,17",
- 3,
- get_spn_done,
- info);
- }
-}
-
-static void
-get_card_info (MMModem *modem,
- MMModemInfoFn callback,
- gpointer user_data)
-{
- MMAtSerialPort *port;
- GError *error = NULL;
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &error);
- mm_modem_base_get_card_info (MM_MODEM_BASE (modem), port, error, callback, user_data);
- g_clear_error (&error);
-}
-
-#define PIN_PORT_TAG "pin-port"
-#define SAVED_ERROR_TAG "error"
-
-static void
-pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data);
-
-static gboolean
-pin_puk_recheck_again (gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- MM_GENERIC_GSM_GET_PRIVATE (info->modem)->pin_check_timeout = 0;
- check_pin (MM_GENERIC_GSM (info->modem), pin_puk_recheck_done, info);
- return FALSE;
-}
-
-static void
-pin_puk_recheck_done (MMModem *modem, GError *error, gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
- MMSerialPort *port;
- GError *saved_error;
-
- /* Do nothing if modem removed */
- if (!modem || mm_callback_info_check_modem_removed (info))
- return;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- /* Clear the pin check timeout to ensure that it won't ever get a
- * stale MMCallbackInfo if the modem got removed. We'll reschedule it here
- * anyway if needed.
- */
- if (priv->pin_check_timeout)
- g_source_remove (priv->pin_check_timeout);
- priv->pin_check_timeout = 0;
-
- /* Propagate the error to the info */
- if (error)
- info->error = g_error_copy (error);
-
- /* If the modem wasn't removed, and the modem isn't ready yet, ask it for
- * the current PIN status a few times since some devices take a bit to fully
- * enable themselves after a SIM PIN/PUK unlock.
- */
- if (info->error && !g_error_matches (info->error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED)) {
- if (priv->pin_check_tries < 4) {
- g_clear_error (&info->error);
- priv->pin_check_tries++;
- priv->pin_check_timeout = g_timeout_add_seconds (2, pin_puk_recheck_again, info);
- return;
- }
- }
-
- /* Otherwise, clean up and return the PIN check result */
- port = mm_callback_info_get_data (info, PIN_PORT_TAG);
- if (port)
- mm_serial_port_close (port);
-
- /* If we have a saved error from sending PIN/PUK, return that to callers */
- saved_error = mm_callback_info_get_data (info, SAVED_ERROR_TAG);
- if (saved_error) {
- if (!mm_modem_base_get_unlock_required (MM_MODEM_BASE (info->modem))) {
- /* Original unlock failed but the modem is actually unlocked, so
- * return success. Sometimes happens if the modem doesn't allow
- * CPIN="xxxx" when it's already unlocked and returns an error.
- * Do nothing.
- */
- } else {
- /* Unlock failed after recheck, return original error */
- g_clear_error (&info->error);
- info->error = g_error_copy (saved_error);
- }
- }
-
- mm_callback_info_schedule (info);
-}
-
-/* Following an operation other than unlock that requires
- * a pin, refetch the retry count, which may have changed
- * if an incorrect PIN was supplied. Check also for a SIM_PUK
- * error, which occurs if PIN retries has reached zero. */
-static void
-update_pin_puk_status (MMModem *modem, GError *error)
-{
- if (error) {
- if (error->domain != MM_MOBILE_ERROR)
- return;
- if (error->code == MM_MOBILE_ERROR_SIM_PUK) {
- mm_modem_base_set_unlock_required (MM_MODEM_BASE (modem),
- "sim-puk");
- } else if (error->code != MM_MOBILE_ERROR_WRONG_PASSWORD) {
- return;
- }
- }
- mm_modem_gsm_card_get_unlock_retries (MM_MODEM_GSM_CARD (modem),
- get_unlock_retries_cb,
- NULL);
-}
-
-static void
-send_pin_puk_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- if (error->domain != MM_MOBILE_ERROR) {
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- mm_serial_port_close (MM_SERIAL_PORT (port));
- return;
- } else {
- /* Keep the real error around so we can send it back
- * when we're done rechecking CPIN status.
- */
- mm_callback_info_set_data (info, SAVED_ERROR_TAG,
- g_error_copy (error),
- (GDestroyNotify) g_error_free);
- }
- }
-
- /* Get latest PIN status */
- MM_GENERIC_GSM_GET_PRIVATE (info->modem)->pin_check_tries = 0;
- check_pin (MM_GENERIC_GSM (info->modem), pin_puk_recheck_done, info);
-}
-
-static void
-send_puk (MMModemGsmCard *modem,
- const char *puk,
- const char *pin,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- char *command;
- MMAtSerialPort *port;
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
-
- /* Ensure we have a usable port to use for the unlock */
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- /* Modem may not be enabled yet, which sometimes can't be done until
- * the device has been unlocked. In this case we have to open the port
- * ourselves.
- */
- if (!mm_serial_port_open (MM_SERIAL_PORT (port), &info->error)) {
- mm_callback_info_schedule (info);
- return;
- }
- mm_callback_info_set_data (info, PIN_PORT_TAG, port, NULL);
-
- command = g_strdup_printf ("+CPIN=\"%s\",\"%s\"", puk, pin);
- mm_at_serial_port_queue_command (port, command, 3, send_pin_puk_done, info);
- g_free (command);
-}
-
-static void
-send_pin (MMModemGsmCard *modem,
- const char *pin,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- char *command;
- MMAtSerialPort *port;
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
-
- /* Ensure we have a usable port to use for the unlock */
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- /* Modem may not be enabled yet, which sometimes can't be done until
- * the device has been unlocked. In this case we have to open the port
- * ourselves.
- */
- if (!mm_serial_port_open (MM_SERIAL_PORT (port), &info->error)) {
- mm_callback_info_schedule (info);
- return;
- }
- mm_callback_info_set_data (info, PIN_PORT_TAG, port, NULL);
-
- command = g_strdup_printf ("+CPIN=\"%s\"", pin);
- mm_at_serial_port_queue_command (port, command, 3, send_pin_puk_done, info);
- g_free (command);
-}
-
-#define ENABLED_FACILITY_TAG "enabled-facility"
-#define ENABLED_TAG "enabled"
-
-static void
-pin_operation_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
- MMModem *modem;
- MMModemGsmFacility facility;
- gboolean enabled;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- modem = info->modem;
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- if (!error) {
- facility = GPOINTER_TO_UINT (mm_callback_info_get_data (info, ENABLED_FACILITY_TAG));
- enabled = GPOINTER_TO_UINT (mm_callback_info_get_data (info, ENABLED_TAG));
- if (facility != MM_MODEM_GSM_FACILITY_NONE) {
- MMModemGsmFacility old = priv->enabled_facilities;
- if (enabled)
- priv->enabled_facilities |= facility;
- else
- priv->enabled_facilities &= ~facility;
- if (priv->enabled_facilities != old)
- g_object_notify (G_OBJECT (modem),
- MM_MODEM_GSM_CARD_ENABLED_FACILITY_LOCKS);
- }
- }
- update_pin_puk_status (modem, error);
- if (error)
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
-}
-
-static void
-enable_pin (MMModemGsmCard *modem,
- const char *pin,
- gboolean enabled,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- char *command;
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
- command = g_strdup_printf ("+CLCK=\"SC\",%d,\"%s\"", enabled ? 1 : 0, pin);
- mm_callback_info_set_data (info, ENABLED_FACILITY_TAG, GUINT_TO_POINTER (MM_MODEM_GSM_FACILITY_SIM), NULL);
- mm_callback_info_set_data (info, ENABLED_TAG, GUINT_TO_POINTER (enabled), NULL);
- mm_at_serial_port_queue_command (priv->primary, command, 3, pin_operation_done, info);
- g_free (command);
-}
-
-static void
-change_pin (MMModemGsmCard *modem,
- const char *old_pin,
- const char *new_pin,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- char *command;
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
- command = g_strdup_printf ("+CPWD=\"SC\",\"%s\",\"%s\"", old_pin, new_pin);
- mm_at_serial_port_queue_command (priv->primary, command, 3, pin_operation_done, info);
- g_free (command);
-}
-
-static void
-get_unlock_retries (MMModemGsmCard *modem,
- MMModemArrayFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info = mm_callback_info_array_new (MM_MODEM (modem), callback, user_data);
-
- mm_callback_info_set_result (info, NULL, NULL);
- mm_callback_info_schedule (info);
-}
-
-static void
-reg_info_updated (MMGenericGsm *self,
- gboolean update_rs,
- MMGenericGsmRegType rs_type,
- MMModemGsmNetworkRegStatus status,
- gboolean update_code,
- const char *oper_code,
- gboolean update_name,
- const char *oper_name)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMModemGsmNetworkRegStatus old_status;
- gboolean changed = FALSE;
-
- if (update_rs) {
- g_return_if_fail ( rs_type == MM_GENERIC_GSM_REG_TYPE_CS
- || rs_type == MM_GENERIC_GSM_REG_TYPE_PS);
-
- old_status = gsm_reg_status (self, NULL);
- priv->reg_status[rs_type - 1] = status;
- if (gsm_reg_status (self, NULL) != old_status)
- changed = TRUE;
- }
-
- /* Don't clear oper code or oper num if at least one of CS or PS state
- * is home or roaming.
- */
- if ( priv->reg_status[0] == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME
- || priv->reg_status[0] == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING
- || priv->reg_status[1] == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME
- || priv->reg_status[1] == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING) {
- if (update_code && oper_code == NULL)
- update_code = FALSE;
- if (update_name && oper_name == NULL)
- update_name = FALSE;
- }
-
- if (update_code) {
- if (g_strcmp0 (oper_code, priv->oper_code) != 0) {
- g_free (priv->oper_code);
- priv->oper_code = g_strdup (oper_code);
- changed = TRUE;
- }
- }
-
- if (update_name) {
- if (g_strcmp0 (oper_name, priv->oper_name) != 0) {
- g_free (priv->oper_name);
- priv->oper_name = g_strdup (oper_name);
- changed = TRUE;
- }
- }
-
- if (changed) {
- mm_modem_gsm_network_registration_info (MM_MODEM_GSM_NETWORK (self),
- gsm_reg_status (self, NULL),
- priv->oper_code,
- priv->oper_name);
- }
-}
-
-static void
-get_operator_name_done (MMModem *self,
- const char *operator_name,
- GError *error,
- gpointer user_data)
-{
- if (!error && operator_name)
- reg_info_updated (MM_GENERIC_GSM (self), FALSE, MM_GENERIC_GSM_REG_TYPE_UNKNOWN, 0,
- FALSE, NULL,
- TRUE, operator_name);
-}
-
-static void
-get_operator_code_done (MMModem *self,
- const char *operator_code,
- GError *error,
- gpointer user_data)
-{
- if (!error && operator_code)
- reg_info_updated (MM_GENERIC_GSM (self), FALSE, MM_GENERIC_GSM_REG_TYPE_UNKNOWN, 0,
- TRUE, operator_code,
- FALSE, NULL);
-}
-
-static char *
-parse_operator (const char *reply, MMModemCharset cur_charset)
-{
- char *operator = NULL;
-
- if (reply && !strncmp (reply, "+COPS: ", 7)) {
- /* Got valid reply */
- GRegex *r;
- GMatchInfo *match_info;
-
- reply += 7;
- r = g_regex_new ("(\\d),(\\d),\"(.+)\"", G_REGEX_UNGREEDY, 0, NULL);
- if (!r)
- return NULL;
-
- g_regex_match (r, reply, 0, &match_info);
- if (g_match_info_matches (match_info))
- operator = g_match_info_fetch (match_info, 3);
-
- g_match_info_free (match_info);
- g_regex_unref (r);
- }
-
- if (operator) {
- /* Some modems (Option & HSO) return the operator name as a hexadecimal
- * string of the bytes of the operator name as encoded by the current
- * character set.
- */
- if (cur_charset == MM_MODEM_CHARSET_UCS2)
- operator = mm_charset_take_and_convert_to_utf8 (operator, MM_MODEM_CHARSET_UCS2);
-
- /* Ensure the operator name is valid UTF-8 so that we can send it
- * through D-Bus and such.
- */
- if (!g_utf8_validate (operator, -1, NULL)) {
- g_free (operator);
- operator = NULL;
- }
- }
-
- return operator;
-}
-
-static void
-real_get_operator_code_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- char *oper;
-
- /* Note that parse_operator() returns a newly allocated string */
- oper = parse_operator (response->str, MM_MODEM_CHARSET_UNKNOWN);
- if (oper)
- mm_callback_info_set_result (info, oper, g_free);
- else
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse the +COPS response");
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-real_get_operator_name_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- char *oper;
-
- /* Note that parse_operator() returns a newly allocated string */
- oper = parse_operator (response->str, priv->cur_charset);
- if (oper)
- mm_callback_info_set_result (info, oper, g_free);
- else
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse the +COPS response");
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-real_get_operator_name (MMGenericGsm *self,
- MMModemStringFn callback,
- gpointer callback_data)
-{
- MMAtSerialPort *port;
- MMCallbackInfo *info;
-
- info = mm_callback_info_string_new (MM_MODEM (self), callback, callback_data);
-
- port = mm_generic_gsm_get_best_at_port (self, &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_at_serial_port_queue_command (port, "+COPS=3,0;+COPS?", 3, real_get_operator_name_done, info);
-}
-
-static void
-real_get_operator_code (MMGenericGsm *self,
- MMModemStringFn callback,
- gpointer callback_data)
-{
- MMAtSerialPort *port;
- MMCallbackInfo *info;
-
- info = mm_callback_info_string_new (MM_MODEM (self), callback, callback_data);
-
- port = mm_generic_gsm_get_best_at_port (self, &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_at_serial_port_queue_command (port, "+COPS=3,2;+COPS?", 3, real_get_operator_code_done, info);
-}
-
-/* Registration */
-#define REG_STATUS_AGAIN_TAG "reg-status-again"
-
-void
-mm_generic_gsm_pending_registration_stop (MMGenericGsm *modem)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- if (priv->pending_reg_id) {
- /* Clear the registration timeout handler */
- g_source_remove (priv->pending_reg_id);
- priv->pending_reg_id = 0;
- }
-
- if (priv->pending_reg_info) {
- /* Clear any ongoing registration status callback */
- mm_callback_info_set_data (priv->pending_reg_info, REG_STATUS_AGAIN_TAG, NULL, NULL);
-
- /* And schedule the callback */
- mm_callback_info_schedule (priv->pending_reg_info);
- priv->pending_reg_info = NULL;
- }
-}
-
-static void
-got_signal_quality (MMModem *modem,
- guint32 quality,
- GError *error,
- gpointer user_data)
-{
- mm_generic_gsm_update_signal_quality (MM_GENERIC_GSM (modem), quality);
-}
-
-static void
-roam_disconnect_done (MMModem *modem,
- GError *error,
- gpointer user_data)
-{
- mm_info ("Disconnected because roaming is not allowed");
-}
-
-static void
-get_reg_act_done (MMModem *modem,
- guint32 act,
- GError *error,
- gpointer user_data)
-{
- if (modem && !error && act)
- mm_generic_gsm_update_access_technology (MM_GENERIC_GSM (modem), act);
-}
-
-void
-mm_generic_gsm_set_reg_status (MMGenericGsm *self,
- MMGenericGsmRegType rs_type,
- MMModemGsmNetworkRegStatus status)
-{
- MMGenericGsmPrivate *priv;
- MMAtSerialPort *port;
-
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
-
- g_return_if_fail ( rs_type == MM_GENERIC_GSM_REG_TYPE_CS
- || rs_type == MM_GENERIC_GSM_REG_TYPE_PS);
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (priv->reg_status[rs_type - 1] == status)
- return;
-
- mm_dbg ("%s registration state changed: %d",
- (rs_type == MM_GENERIC_GSM_REG_TYPE_CS) ? "CS" : "PS",
- status);
- priv->reg_status[rs_type - 1] = status;
-
- port = mm_generic_gsm_get_best_at_port (self, NULL);
-
- if (status == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME ||
- status == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING) {
-
- /* If we're connected and we're not supposed to roam, but the device
- * just roamed, disconnect the connection to avoid charging the user
- * loads of money.
- */
- if ( (status == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING)
- && (mm_modem_get_state (MM_MODEM (self)) == MM_MODEM_STATE_CONNECTED)
- && (priv->roam_allowed == FALSE)) {
- mm_modem_disconnect (MM_MODEM (self), roam_disconnect_done, NULL);
- } else {
- /* Grab the new operator name and MCC/MNC */
- if (port) {
- g_assert (MM_GENERIC_GSM_GET_CLASS (self)->get_operator_name);
- MM_GENERIC_GSM_GET_CLASS (self)->get_operator_name (self, get_operator_name_done, NULL);
- g_assert (MM_GENERIC_GSM_GET_CLASS (self)->get_operator_code);
- MM_GENERIC_GSM_GET_CLASS (self)->get_operator_code (self, get_operator_code_done, NULL);
- }
-
- /* And update signal quality and access technology */
- mm_modem_gsm_network_get_signal_quality (MM_MODEM_GSM_NETWORK (self), got_signal_quality, NULL);
- if (MM_GENERIC_GSM_GET_CLASS (self)->get_access_technology)
- MM_GENERIC_GSM_GET_CLASS (self)->get_access_technology (self, get_reg_act_done, NULL);
- }
- } else
- reg_info_updated (self, FALSE, rs_type, 0, TRUE, NULL, TRUE, NULL);
-
- mm_generic_gsm_update_enabled_state (self, TRUE, MM_MODEM_STATE_REASON_NONE);
-}
-
-/* Returns TRUE if the modem is "done", ie has registered or been denied */
-static gboolean
-reg_status_updated (MMGenericGsm *self,
- MMGenericGsmRegType rs_type,
- int new_value,
- GError **error)
-{
- MMModemGsmNetworkRegStatus status;
- gboolean status_done = FALSE;
-
- switch (new_value) {
- case 0:
- status = MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE;
- break;
- case 1:
- status = MM_MODEM_GSM_NETWORK_REG_STATUS_HOME;
- break;
- case 2:
- status = MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING;
- break;
- case 3:
- status = MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED;
- break;
- case 4:
- status = MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN;
- break;
- case 5:
- status = MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING;
- break;
- default:
- status = MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN;
- break;
- }
-
- mm_generic_gsm_set_reg_status (self, rs_type, status);
-
- /* Registration has either completed successfully or completely failed */
- switch (status) {
- case MM_MODEM_GSM_NETWORK_REG_STATUS_HOME:
- case MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING:
- /* Successfully registered - stop registration */
- status_done = TRUE;
- break;
- case MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED:
- /* registration failed - stop registration */
- if (error)
- *error = mm_mobile_error_for_code (MM_MOBILE_ERROR_NETWORK_NOT_ALLOWED);
- status_done = TRUE;
- break;
- case MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING:
- if (error)
- *error = mm_mobile_error_for_code (MM_MOBILE_ERROR_NETWORK_TIMEOUT);
- break;
- case MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE:
- if (error)
- *error = mm_mobile_error_for_code (MM_MOBILE_ERROR_NO_NETWORK);
- break;
- default:
- if (error)
- *error = mm_mobile_error_for_code (MM_MOBILE_ERROR_UNKNOWN);
- break;
- }
- return status_done;
-}
-
-static MMGenericGsmRegType
-cgreg_to_reg_type (gboolean cgreg)
-{
- return (cgreg ? MM_GENERIC_GSM_REG_TYPE_PS : MM_GENERIC_GSM_REG_TYPE_CS);
-}
-
-static void
-reg_state_changed (MMAtSerialPort *port,
- GMatchInfo *match_info,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- guint32 state = 0;
- gulong lac = 0, cell_id = 0;
- gint act = -1;
- gboolean cgreg = FALSE;
- GError *error = NULL;
-
- if (!mm_gsm_parse_creg_response (match_info, &state, &lac, &cell_id, &act, &cgreg, &error)) {
- mm_warn ("error parsing unsolicited registration: %s",
- error && error->message ? error->message : "(unknown)");
- return;
- }
-
- if (cgreg && !ps_network_supported (self))
- mm_warn ("shouldn't get PS registration status if PS not supported");
-
- if (reg_status_updated (self, cgreg_to_reg_type (cgreg), state, NULL)) {
- /* If registration is finished (either registered or failed) but the
- * registration query hasn't completed yet, just remove the timeout and
- * let the registration query complete.
- */
- if (priv->pending_reg_id) {
- g_source_remove (priv->pending_reg_id);
- priv->pending_reg_id = 0;
- }
- }
-
- update_lac_ci (self, lac, cell_id, cgreg ? 1 : 0);
-
- /* Only update access technology if it appeared in the CREG/CGREG response */
- if (act != -1)
- mm_generic_gsm_update_access_technology (self, etsi_act_to_mm_act (act));
-}
-
-static gboolean
-reg_status_again (gpointer data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) data;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- g_warn_if_fail (info == priv->pending_reg_info);
-
- if (priv->pending_reg_info)
- get_registration_status (priv->primary, info);
-
- return FALSE;
-}
-
-static void
-reg_status_again_remove (gpointer data)
-{
- guint id = GPOINTER_TO_UINT (data);
-
- /* Technically the GSource ID can be 0, but in practice it won't be */
- if (id > 0)
- g_source_remove (id);
-}
-
-static gboolean
-handle_reg_status_response (MMGenericGsm *self,
- GString *response,
- GError **error)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- GMatchInfo *match_info;
- guint32 status = 0;
- gulong lac = 0, ci = 0;
- gint act = -1;
- gboolean cgreg = FALSE, parsed;
- guint i;
-
- /* Try to match the response */
- for (i = 0; i < priv->reg_regex->len; i++) {
- GRegex *r = g_ptr_array_index (priv->reg_regex, i);
-
- if (g_regex_match (r, response->str, 0, &match_info))
- break;
- g_match_info_free (match_info);
- match_info = NULL;
- }
-
- if (!match_info) {
- g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Unknown registration status response");
- return FALSE;
- }
-
- /* And parse it */
- parsed = mm_gsm_parse_creg_response (match_info, &status, &lac, &ci, &act, &cgreg, error);
- g_match_info_free (match_info);
- if (parsed) {
- if (cgreg && !ps_network_supported (self))
- mm_warn ("shouldn't get PS registration status if PS not supported");
-
- /* Success; update cached location information */
- update_lac_ci (self, lac, ci, cgreg ? 1 : 0);
-
- /* Only update access technology if it appeared in the CREG/CGREG response */
- if (act != -1)
- mm_generic_gsm_update_access_technology (self, etsi_act_to_mm_act (act));
-
- /* Update cached registration status */
- reg_status_updated (self, cgreg_to_reg_type (cgreg), status, NULL);
- }
-
- return parsed;
-}
-
-#define CS_ERROR_TAG "cs-error"
-#define CS_DONE_TAG "cs-complete"
-#define PS_ERROR_TAG "ps-error"
-#define PS_DONE_TAG "ps-complete"
-
-static void
-check_reg_status_done (MMCallbackInfo *info)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (info->modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- GError *cs_error, *ps_error;
- MMModemGsmNetworkRegStatus status;
- guint id;
-
- /* This function should only get called during the connect sequence when
- * polling for registration state, since explicit registration requests
- * from D-Bus clients are filled from the cached registration state.
- */
- g_return_if_fail (info == priv->pending_reg_info);
-
- /* Only process when both CS and PS checks are both done */
- if ( !mm_callback_info_get_data (info, CS_DONE_TAG)
- || ( ps_network_supported (self)
- && !mm_callback_info_get_data (info, PS_DONE_TAG)))
- return;
-
- /* The unsolicited registration state handlers will intercept the CREG
- * response and update the cached registration state for us, so we usually
- * just need to check the cached state here.
- */
-
- /* If both CS and PS registration checks returned errors we fail */
- cs_error = mm_callback_info_get_data (info, CS_ERROR_TAG);
- ps_error = mm_callback_info_get_data (info, PS_ERROR_TAG);
- if (cs_error && ps_error) {
- /* Prefer the PS error */
- info->error = g_error_copy (ps_error);
- goto reg_done;
- }
-
- status = gsm_reg_status (self, NULL);
- if ( status != MM_MODEM_GSM_NETWORK_REG_STATUS_HOME
- && status != MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING
- && status != MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED) {
-
- /* Clear state that should be reset every poll */
- mm_callback_info_set_data (info, CS_DONE_TAG, NULL, NULL);
- mm_callback_info_set_data (info, CS_ERROR_TAG, NULL, NULL);
- mm_callback_info_set_data (info, PS_DONE_TAG, NULL, NULL);
- mm_callback_info_set_data (info, PS_ERROR_TAG, NULL, NULL);
-
- /* If we're still waiting for automatic registration to complete or
- * fail, check again in a few seconds.
- */
- id = g_timeout_add_seconds (1, reg_status_again, info);
- mm_callback_info_set_data (info, REG_STATUS_AGAIN_TAG,
- GUINT_TO_POINTER (id),
- reg_status_again_remove);
- return;
- }
-
-reg_done:
- /* This will schedule the pending registration's the callback for us */
- mm_generic_gsm_pending_registration_stop (self);
-}
-
-static void
-generic_reg_status_done (MMCallbackInfo *info,
- GString *response,
- GError *error,
- const char *error_tag,
- const char *done_tag)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (info->modem);
- GError *local = NULL;
-
- if (error)
- local = g_error_copy (error);
- else if (response && strlen (response->str)) {
- /* Unsolicited registration status handlers will usually process the
- * response for us, but just in case they don't, do that here.
- */
- if (handle_reg_status_response (self, response, &local) == TRUE)
- g_assert_no_error (local);
- }
-
- if (local)
- mm_callback_info_set_data (info, error_tag, local, (GDestroyNotify) g_error_free);
- mm_callback_info_set_data (info, done_tag, GUINT_TO_POINTER (1), NULL);
-}
-
-static void
-get_ps_reg_status_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- if (mm_callback_info_check_modem_removed (info) == FALSE) {
- generic_reg_status_done (info, response, error, PS_ERROR_TAG, PS_DONE_TAG);
- check_reg_status_done (info);
- }
-}
-
-static void
-get_cs_reg_status_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- if (mm_callback_info_check_modem_removed (info) == FALSE) {
- generic_reg_status_done (info, response, error, CS_ERROR_TAG, CS_DONE_TAG);
- check_reg_status_done (info);
- }
-}
-
-static void
-get_registration_status (MMAtSerialPort *port, MMCallbackInfo *info)
-{
- mm_at_serial_port_queue_command (port, "+CREG?", 10, get_cs_reg_status_done, info);
- if (ps_network_supported (MM_GENERIC_GSM (info->modem)))
- mm_at_serial_port_queue_command (port, "+CGREG?", 10, get_ps_reg_status_done, info);
- else
- generic_reg_status_done (info, NULL, NULL, PS_ERROR_TAG, PS_DONE_TAG);
-}
-
-static void
-register_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMGenericGsmPrivate *priv;
-
- mm_callback_info_unref (info);
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- /* If the registration timed out (and thus pending_reg_info will be NULL)
- * and the modem eventually got around to sending the response for the
- * registration request then just ignore the response since the callback is
- * already called.
- */
-
- if (priv->pending_reg_info) {
- g_warn_if_fail (info == priv->pending_reg_info);
- if (error) {
- g_clear_error (&info->error);
- info->error = g_error_copy (error);
- }
-
- /* Don't use cached registration state here since it could be up to
- * 30 seconds old. Get fresh registration state.
- */
- get_registration_status (port, info);
- }
-}
-
-static gboolean
-registration_timed_out (gpointer data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) data;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- g_warn_if_fail (info == priv->pending_reg_info);
-
- /* Clear out circuit-switched registration info... */
- reg_info_updated (MM_GENERIC_GSM (info->modem),
- TRUE, MM_GENERIC_GSM_REG_TYPE_CS, MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE,
- TRUE, NULL,
- TRUE, NULL);
- /* ... and packet-switched registration info */
- reg_info_updated (MM_GENERIC_GSM (info->modem),
- TRUE, MM_GENERIC_GSM_REG_TYPE_PS, MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE,
- TRUE, NULL,
- TRUE, NULL);
-
- info->error = mm_mobile_error_for_code (MM_MOBILE_ERROR_NETWORK_TIMEOUT);
- mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (info->modem));
-
- return FALSE;
-}
-
-static gboolean
-reg_is_idle (MMModemGsmNetworkRegStatus status)
-{
- if ( status == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME
- || status == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING
- || status == MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING)
- return FALSE;
- return TRUE;
-}
-
-static void
-do_register (MMModemGsmNetwork *modem,
- const char *network_id,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMCallbackInfo *info;
- char *command = NULL;
-
- /* Clear any previous registration */
- mm_generic_gsm_pending_registration_stop (self);
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
-
- priv->pending_reg_id = g_timeout_add_seconds (60, registration_timed_out, info);
- priv->pending_reg_info = info;
-
- /* If the user sent a specific network to use, lock it in. If no specific
- * network was given, and the modem is not registered and not searching,
- * kick it to search for a network. Also do auto registration if the modem
- * had been set to manual registration last time but now is not.
- */
- if (network_id) {
- command = g_strdup_printf ("+COPS=1,2,\"%s\"", network_id);
- priv->manual_reg = TRUE;
- } else if (reg_is_idle (gsm_reg_status (self, NULL)) || priv->manual_reg) {
- command = g_strdup ("+COPS=0,,");
- priv->manual_reg = FALSE;
- }
-
- /* Ref the callback info to ensure it stays alive for register_done() even
- * if the timeout triggers and ends registration (which calls the callback
- * and unrefs the callback info). Some devices (hso) will delay the
- * registration response until the registration is done (and thus
- * unsolicited registration responses will arrive before the +COPS is
- * complete). Most other devices will return the +COPS response immediately
- * and the unsolicited response (if any) at a later time.
- *
- * To handle both these cases, unsolicited registration responses will just
- * remove the pending registration timeout but we let the +COPS command
- * complete. For those devices that delay the +COPS response (hso) the
- * callback will be called from register_done(). For those devices that
- * return the +COPS response immediately, we'll poll the registration state
- * and call the callback from get_[cs|ps]_reg_status_done() in response to
- * the polled response. The registration timeout will only be triggered
- * when the +COPS response is never received.
- */
- mm_callback_info_ref (info);
-
- if (command) {
- mm_at_serial_port_queue_command (priv->primary, command, 120, register_done, info);
- g_free (command);
- } else
- register_done (priv->primary, NULL, NULL, info);
-}
-
-static void
-gsm_network_reg_info_invoke (MMCallbackInfo *info)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- MMModemGsmNetworkRegInfoFn callback = (MMModemGsmNetworkRegInfoFn) info->callback;
-
- callback (MM_MODEM_GSM_NETWORK (info->modem),
- gsm_reg_status (MM_GENERIC_GSM (info->modem), NULL),
- priv->oper_code,
- priv->oper_name,
- info->error,
- info->user_data);
-}
-
-static void
-get_registration_info (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegInfoFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self),
- gsm_network_reg_info_invoke,
- G_CALLBACK (callback),
- user_data);
- /* Registration info updates are handled internally either by unsolicited
- * updates or by polling. Thus just return the cached registration state.
- */
- mm_callback_info_schedule (info);
-}
-
-void
-mm_generic_gsm_connect_complete (MMGenericGsm *modem,
- GError *error,
- MMCallbackInfo *info)
-{
- MMGenericGsmPrivate *priv;
-
- g_return_if_fail (modem != NULL);
- g_return_if_fail (MM_IS_GENERIC_GSM (modem));
- g_return_if_fail (info != NULL);
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- if (error) {
- mm_generic_gsm_update_enabled_state (modem, FALSE, MM_MODEM_STATE_REASON_NONE);
- info->error = g_error_copy (error);
- } else {
- /* Modem is connected; update the state */
- mm_port_set_connected (priv->data, TRUE);
- mm_modem_set_state (MM_MODEM (modem),
- MM_MODEM_STATE_CONNECTED,
- MM_MODEM_STATE_REASON_NONE);
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-connect_report_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- GError *real_error;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- /* If the CEER command was successful, copy that error reason into the
- * callback's error. If not, use the original error.
- */
-
- /* Have to do this little dance since mm_generic_gsm_connect_complete()
- * copies the provided error into the callback info.
- */
- real_error = info->error;
- info->error = NULL;
-
- if ( !error
- && g_str_has_prefix (response->str, "+CEER: ")
- && (strlen (response->str) > 7)) {
- /* copy the connect failure reason into the error */
- g_free (real_error->message);
- real_error->message = g_strdup (response->str + 7); /* skip the "+CEER: " */
- }
-
- mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), real_error, info);
- g_error_free (real_error);
-}
-
-static void
-connect_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- if (error) {
- info->error = g_error_copy (error);
- /* Try to get more information why it failed */
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- mm_at_serial_port_queue_command (priv->primary, "+CEER", 3, connect_report_done, info);
- } else
- mm_generic_gsm_connect_complete (MM_GENERIC_GSM (info->modem), NULL, info);
-}
-
-static void
-connect (MMModem *modem,
- const char *number,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- char *command;
- gint cid = mm_generic_gsm_get_cid (MM_GENERIC_GSM (modem));
- MMAtSerialPort *dial_port;
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- /* Dial port might not be the primary port*/
- priv->data_opened_at_connect = FALSE;
- dial_port = priv->primary;
- if (MM_IS_AT_SERIAL_PORT (priv->data)) {
- dial_port = MM_AT_SERIAL_PORT (priv->data);
-
- if (!mm_serial_port_open (MM_SERIAL_PORT (dial_port), &info->error)) {
- g_warning ("%s: failed to open dial port: (%d) %s",
- __func__,
- info->error ? info->error->code : -1,
- info->error && info->error->message ? info->error->message : "(unknown)");
- mm_callback_info_schedule (info);
- return;
- }
- priv->data_opened_at_connect = TRUE;
- }
-
- mm_modem_set_state (modem, MM_MODEM_STATE_CONNECTING, MM_MODEM_STATE_REASON_NONE);
-
- if (cid > 0) {
- GString *str;
-
- str = g_string_new ("D");
- if (g_str_has_suffix (number, "#"))
- str = g_string_append_len (str, number, strlen (number) - 1);
- else
- str = g_string_append (str, number);
-
- g_string_append_printf (str, "***%d#", cid);
- command = g_string_free (str, FALSE);
- } else
- command = g_strconcat ("DT", number, NULL);
-
- mm_at_serial_port_queue_command (dial_port, command, 60, connect_done, info);
- g_free (command);
-}
-
-static void
-disconnect_done (MMModem *modem,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMModemState prev_state;
- MMGenericGsmPrivate *priv;
-
- /* Do nothing if modem removed */
- if (!modem || mm_callback_info_check_modem_removed (info))
- return;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- if (error) {
- info->error = g_error_copy (error);
- /* Reset old state since the operation failed */
- prev_state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, MM_GENERIC_GSM_PREV_STATE_TAG));
- mm_modem_set_state (MM_MODEM (info->modem),
- prev_state,
- MM_MODEM_STATE_REASON_NONE);
- } else {
- mm_port_set_connected (priv->data, FALSE);
- priv->cid = -1;
- mm_generic_gsm_update_enabled_state (MM_GENERIC_GSM (modem), FALSE, MM_MODEM_STATE_REASON_NONE);
- }
-
- /* Balance any open from connect(); subclasses may not use the generic
- * class' connect function and so the dial port may not have been
- * opened at all.
- */
- if (priv->data_opened_at_connect) {
- if (MM_IS_AT_SERIAL_PORT (priv->data))
- mm_serial_port_close (MM_SERIAL_PORT (priv->data));
- priv->data_opened_at_connect = FALSE;
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-disconnect_all_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *)user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- mm_callback_info_schedule (info);
-}
-
-static void
-disconnect_send_cgact (MMAtSerialPort *port,
- gint cid,
- MMAtSerialResponseFn callback,
- gpointer user_data)
-{
- char *command;
-
- if (cid >= 0)
- command = g_strdup_printf ("+CGACT=0,%d", cid);
- else {
- /* Disable all PDP contexts */
- command = g_strdup_printf ("+CGACT=0");
- }
-
- mm_at_serial_port_queue_command (port, command, 3, callback, user_data);
- g_free (command);
-}
-
-#define DISCONNECT_CGACT_DONE_TAG "disconnect-cgact-done"
-
-static void
-disconnect_flash_done (MMSerialPort *port,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- /* Ignore "NO CARRIER" response when modem disconnects and any flash
- * failures we might encounter. Other errors are hard errors.
- */
- if ( !g_error_matches (error, MM_MODEM_CONNECT_ERROR, MM_MODEM_CONNECT_ERROR_NO_CARRIER)
- && !g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_FLASH_FAILED)) {
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
- }
- }
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- mm_port_set_connected (priv->data, FALSE);
-
- /* Don't bother doing the CGACT again if it was done on a secondary port,
- * or if no GPRS activation was done before. */
- if ( mm_callback_info_get_data (info, DISCONNECT_CGACT_DONE_TAG)
- || !ps_network_supported (MM_GENERIC_GSM (info->modem)))
- disconnect_all_done (MM_AT_SERIAL_PORT (priv->primary), NULL, NULL, info);
- else {
- disconnect_send_cgact (MM_AT_SERIAL_PORT (priv->primary),
- priv->cid,
- disconnect_all_done,
- info);
- }
-}
-
-static void
-disconnect_secondary_cgact_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
- MMGenericGsm *self;
- MMGenericGsmPrivate *priv;
- MMSerialPort *dial_port;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- self = MM_GENERIC_GSM (info->modem);
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- /* Now that we've tried deactivating the PDP context on the secondary
- * port, continue with flashing the primary port.
- */
- if (!error)
- mm_callback_info_set_data (info, DISCONNECT_CGACT_DONE_TAG, GUINT_TO_POINTER (TRUE), NULL);
-
- dial_port = MM_SERIAL_PORT (priv->primary);
- if (MM_IS_AT_SERIAL_PORT (priv->data))
- dial_port = MM_SERIAL_PORT (priv->data);
-
- mm_serial_port_flash (dial_port, 1000, TRUE, disconnect_flash_done, info);
-}
-
-static void
-real_do_disconnect (MMGenericGsm *self,
- gint cid,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMCallbackInfo *info;
- MMSerialPort *dial_port;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
-
- /* If the primary port is connected (with PPP) then try sending the PDP
- * context deactivation on the secondary port because not all modems will
- * respond to flashing (since either the modem or the kernel's serial
- * driver doesn't support it).
- */
- if ( mm_port_get_connected (MM_PORT (priv->primary))
- && priv->secondary
- && mm_serial_port_is_open (MM_SERIAL_PORT (priv->secondary))) {
- disconnect_send_cgact (MM_AT_SERIAL_PORT (priv->secondary),
- priv->cid,
- disconnect_secondary_cgact_done,
- info);
- } else {
- /* Just flash the dial port */
- dial_port = MM_SERIAL_PORT (priv->primary);
- if (MM_IS_AT_SERIAL_PORT (priv->data))
- dial_port = MM_SERIAL_PORT (priv->data);
-
- mm_serial_port_flash (dial_port, 1000, TRUE, disconnect_flash_done, info);
- }
-}
-
-static void
-disconnect (MMModem *modem,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMCallbackInfo *info;
- MMModemState state;
-
- priv->roam_allowed = TRUE;
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- /* Cache the previous state so we can reset it if the operation fails */
- state = mm_modem_get_state (modem);
- mm_callback_info_set_data (info,
- MM_GENERIC_GSM_PREV_STATE_TAG,
- GUINT_TO_POINTER (state),
- NULL);
-
- mm_modem_set_state (modem, MM_MODEM_STATE_DISCONNECTING, MM_MODEM_STATE_REASON_NONE);
-
- g_assert (MM_GENERIC_GSM_GET_CLASS (self)->do_disconnect);
- MM_GENERIC_GSM_GET_CLASS (self)->do_disconnect (self, priv->cid, disconnect_done, info);
-}
-
-static void
-gsm_network_scan_invoke (MMCallbackInfo *info)
-{
- MMModemGsmNetworkScanFn callback = (MMModemGsmNetworkScanFn) info->callback;
-
- callback (MM_MODEM_GSM_NETWORK (info->modem),
- (GPtrArray *) mm_callback_info_get_data (info, "scan-results"),
- info->error,
- info->user_data);
-}
-
-static void
-scan_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- GPtrArray *results;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- results = mm_gsm_parse_scan_response (response->str, &info->error);
- if (results)
- mm_callback_info_set_data (info, "scan-results", results, mm_gsm_destroy_scan_data);
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-scan (MMModemGsmNetwork *modem,
- MMModemGsmNetworkScanFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (modem),
- gsm_network_scan_invoke,
- G_CALLBACK (callback),
- user_data);
-
- mm_at_serial_port_queue_command (priv->primary, "+COPS=?", 120, scan_done, info);
-}
-
-/* SetApn */
-
-#define APN_CID_TAG "generic-gsm-cid"
-
-static void
-set_apn_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- priv->cid = GPOINTER_TO_INT (mm_callback_info_get_data (info, APN_CID_TAG));
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-cid_range_read (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- guint32 cid = 0;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else if (g_str_has_prefix (response->str, "+CGDCONT:")) {
- GRegex *r;
- GMatchInfo *match_info;
-
- r = g_regex_new ("\\+CGDCONT:\\s*\\((\\d+)-(\\d+)\\),\\(?\"(\\S+)\"",
- G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
- 0, &info->error);
- if (r) {
- g_regex_match_full (r, response->str, response->len, 0, 0, &match_info, &info->error);
- while (cid == 0 && g_match_info_matches (match_info)) {
- char *tmp;
-
- tmp = g_match_info_fetch (match_info, 3);
- if (!strcmp (tmp, "IP")) {
- int max_cid;
- int highest_cid = GPOINTER_TO_INT (mm_callback_info_get_data (info, "highest-cid"));
-
- g_free (tmp);
-
- tmp = g_match_info_fetch (match_info, 2);
- max_cid = atoi (tmp);
-
- if (highest_cid < max_cid)
- cid = highest_cid + 1;
- else
- cid = highest_cid;
- }
-
- g_free (tmp);
- g_match_info_next (match_info, NULL);
- }
-
- if (cid == 0) {
- /* Choose something */
- cid = 1;
- }
-
- g_match_info_free (match_info);
- g_regex_unref (r);
- }
- } else
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse the response");
-
- if (info->error)
- mm_callback_info_schedule (info);
- else {
- const char *apn = (const char *) mm_callback_info_get_data (info, "apn");
- char *command;
-
- mm_callback_info_set_data (info, APN_CID_TAG, GINT_TO_POINTER (cid), NULL);
-
- command = g_strdup_printf ("+CGDCONT=%d,\"IP\",\"%s\"", cid, apn);
- mm_at_serial_port_queue_command (port, command, 3, set_apn_done, info);
- g_free (command);
- }
-}
-
-static void
-existing_apns_read (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- gboolean found = FALSE;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- /* Some Android phones don't support querying existing PDP contexts,
- * but will accept setting the APN. So if CGDCONT? isn't supported,
- * just ignore that error and hope for the best. (bgo #637327)
- */
- if (g_error_matches (error, MM_MOBILE_ERROR, MM_MOBILE_ERROR_NOT_SUPPORTED) == FALSE)
- info->error = g_error_copy (error);
- } else if (g_str_has_prefix (response->str, "+CGDCONT:")) {
- GRegex *r;
- GMatchInfo *match_info;
-
- r = g_regex_new ("\\+CGDCONT:\\s*(\\d+)\\s*,\"(\\S+)\",\"(\\S+)\",\"(\\S*)\"",
- G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
- 0, &info->error);
- if (r) {
- const char *new_apn = (const char *) mm_callback_info_get_data (info, "apn");
-
- g_regex_match_full (r, response->str, response->len, 0, 0, &match_info, &info->error);
- while (!found && g_match_info_matches (match_info)) {
- char *cid;
- char *pdp_type;
- char *apn;
- int num_cid;
-
- cid = g_match_info_fetch (match_info, 1);
- num_cid = atoi (cid);
- pdp_type = g_match_info_fetch (match_info, 2);
- apn = g_match_info_fetch (match_info, 3);
-
- if (!strcmp (apn, new_apn)) {
- MM_GENERIC_GSM_GET_PRIVATE (info->modem)->cid = num_cid;
- found = TRUE;
- }
-
- if (!found && !strcmp (pdp_type, "IP")) {
- int highest_cid;
-
- highest_cid = GPOINTER_TO_INT (mm_callback_info_get_data (info, "highest-cid"));
- if (num_cid > highest_cid)
- mm_callback_info_set_data (info, "highest-cid", GINT_TO_POINTER (num_cid), NULL);
- }
-
- g_free (cid);
- g_free (pdp_type);
- g_free (apn);
- g_match_info_next (match_info, NULL);
- }
-
- g_match_info_free (match_info);
- g_regex_unref (r);
- }
- } else if (strlen (response->str) == 0) {
- /* No APNs configured, just don't set error */
- } else
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Could not parse the response");
-
- if (found || info->error)
- mm_callback_info_schedule (info);
- else {
- /* APN not configured on the card. Get the allowed CID range */
- mm_at_serial_port_queue_command_cached (port, "+CGDCONT=?", 3, cid_range_read, info);
- }
-}
-
-static void
-set_apn (MMModemGsmNetwork *modem,
- const char *apn,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
- mm_callback_info_set_data (info, "apn", g_strdup (apn), g_free);
-
- /* Start by searching if the APN is already in card */
- mm_at_serial_port_queue_command (priv->primary, "+CGDCONT?", 3, existing_apns_read, info);
-}
-
-/* GetSignalQuality */
-
-static gboolean
-emit_signal_quality_change (gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- priv->signal_quality_id = 0;
- priv->signal_emit_timestamp = time (NULL);
- mm_modem_gsm_network_signal_quality (MM_MODEM_GSM_NETWORK (self), priv->signal_quality);
- return FALSE;
-}
-
-void
-mm_generic_gsm_update_signal_quality (MMGenericGsm *self, guint32 quality)
-{
- MMGenericGsmPrivate *priv;
- guint delay = 0;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
- g_return_if_fail (quality <= 100);
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- priv->signal_update_timestamp = time (NULL);
-
- if (priv->signal_quality == quality)
- return;
-
- priv->signal_quality = quality;
-
- /* Some modems will send unsolcited signal quality changes quite often,
- * so rate-limit them to every few seconds. Track the last time we
- * emitted signal quality so that we send the signal immediately if there
- * haven't been any updates in a while.
- */
- if (!priv->signal_quality_id) {
- if (priv->signal_emit_timestamp > 0) {
- time_t curtime;
- long int diff;
-
- curtime = time (NULL);
- diff = curtime - priv->signal_emit_timestamp;
- if (diff == 0) {
- /* If the device is sending more than one update per second,
- * make sure we don't spam clients with signals.
- */
- delay = 3;
- } else if ((diff > 0) && (diff <= 3)) {
- /* Emitted an update less than 3 seconds ago; schedule an update
- * 3 seconds after the previous one.
- */
- delay = (guint) diff;
- } else {
- /* Otherwise, we haven't emitted an update in the last 3 seconds,
- * or the user turned their clock back, or something like that.
- */
- delay = 0;
- }
- }
-
- priv->signal_quality_id = g_timeout_add_seconds (delay,
- emit_signal_quality_change,
- self);
- }
-}
-
-#define CIND_TAG "+CIND:"
-
-static void
-get_cind_signal_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
- GByteArray *indicators;
- guint quality;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- indicators = mm_parse_cind_query_response (response->str, &info->error);
- if (indicators) {
- if (indicators->len >= priv->signal_ind) {
- quality = g_array_index (indicators, guint8, priv->signal_ind);
- quality = CLAMP (quality, 0, 5) * 20;
- mm_generic_gsm_update_signal_quality (MM_GENERIC_GSM (info->modem), quality);
- mm_callback_info_set_result (info, GUINT_TO_POINTER (quality), NULL);
- }
- g_byte_array_free (indicators, TRUE);
- }
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-get_csq_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- char *reply;
- gboolean parsed = FALSE;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- goto done;
- }
-
- reply = response->str;
- if (!strncmp (reply, "+CSQ: ", 6)) {
- /* Got valid reply */
- int quality;
- int ber;
-
- if (sscanf (reply + 6, "%d, %d", &quality, &ber)) {
- /* 99 means unknown */
- if (quality == 99) {
- info->error = g_error_new_literal (MM_MOBILE_ERROR,
- MM_MOBILE_ERROR_NO_NETWORK,
- "No service");
- } else {
- /* Normalize the quality */
- quality = CLAMP (quality, 0, 31) * 100 / 31;
-
- mm_generic_gsm_update_signal_quality (MM_GENERIC_GSM (info->modem), quality);
- mm_callback_info_set_result (info, GUINT_TO_POINTER (quality), NULL);
- }
- parsed = TRUE;
- }
- }
-
- if (!parsed && !info->error) {
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Could not parse signal quality results");
- }
-
-done:
- mm_callback_info_schedule (info);
-}
-
-static void
-get_signal_quality (MMModemGsmNetwork *modem,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data);
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), NULL);
- if (port) {
- /* Prefer +CIND if the modem supports it, fall back to +CSQ otherwise */
- if (priv->signal_ind)
- mm_at_serial_port_queue_command (port, "+CIND?", 3, get_cind_signal_done, info);
- else
- mm_at_serial_port_queue_command (port, "+CSQ", 3, get_csq_done, info);
- } else {
- /* Use cached signal quality */
- mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->signal_quality), NULL);
- mm_callback_info_schedule (info);
- }
-}
-
-/*****************************************************************************/
-
-typedef struct {
- MMModemGsmAccessTech mm_act;
- gint etsi_act;
-} ModeEtsi;
-
-static ModeEtsi modes_table[] = {
- { MM_MODEM_GSM_ACCESS_TECH_GSM, 0 },
- { MM_MODEM_GSM_ACCESS_TECH_GSM_COMPACT, 1 },
- { MM_MODEM_GSM_ACCESS_TECH_UMTS, 2 },
- { MM_MODEM_GSM_ACCESS_TECH_EDGE, 3 },
- { MM_MODEM_GSM_ACCESS_TECH_HSDPA, 4 },
- { MM_MODEM_GSM_ACCESS_TECH_HSUPA, 5 },
- { MM_MODEM_GSM_ACCESS_TECH_HSPA, 6 },
- { MM_MODEM_GSM_ACCESS_TECH_HSPA, 7 }, /* E-UTRAN/LTE => HSPA for now */
- { MM_MODEM_GSM_ACCESS_TECH_UNKNOWN, -1 },
-};
-
-static MMModemGsmAccessTech
-etsi_act_to_mm_act (gint act)
-{
- ModeEtsi *iter = &modes_table[0];
-
- while (iter->mm_act != MM_MODEM_GSM_ACCESS_TECH_UNKNOWN) {
- if (iter->etsi_act == act)
- return iter->mm_act;
- iter++;
- }
- return MM_MODEM_GSM_ACCESS_TECH_UNKNOWN;
-}
-
-static void
-_internal_update_access_technology (MMGenericGsm *modem,
- MMModemGsmAccessTech act)
-{
- MMGenericGsmPrivate *priv;
-
- g_return_if_fail (modem != NULL);
- g_return_if_fail (MM_IS_GENERIC_GSM (modem));
- g_return_if_fail (act >= MM_MODEM_GSM_ACCESS_TECH_UNKNOWN &&
- act <= MM_MODEM_GSM_ACCESS_TECH_LTE);
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- if (act != priv->act) {
- MMModemGsmNetworkDeprecatedMode old_mode;
-
- priv->act = act;
- g_object_notify (G_OBJECT (modem), MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY);
-
- /* Deprecated value */
- old_mode = mm_modem_gsm_network_act_to_old_mode (act);
- g_signal_emit_by_name (G_OBJECT (modem), "network-mode", old_mode);
- }
-}
-
-void
-mm_generic_gsm_update_access_technology (MMGenericGsm *self,
- MMModemGsmAccessTech act)
-{
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
-
- /* For plugins, don't update the access tech when the modem isn't enabled */
- if (mm_modem_get_state (MM_MODEM (self)) >= MM_MODEM_STATE_ENABLED)
- _internal_update_access_technology (self, act);
-}
-
-void
-mm_generic_gsm_update_allowed_mode (MMGenericGsm *self,
- MMModemGsmAllowedMode mode)
-{
- MMGenericGsmPrivate *priv;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_GENERIC_GSM (self));
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (mode != priv->allowed_mode) {
- priv->allowed_mode = mode;
- g_object_notify (G_OBJECT (self), MM_MODEM_GSM_NETWORK_ALLOWED_MODE);
- }
-}
-
-static void
-set_allowed_mode_done (MMModem *modem, GError *error, gpointer user_data)
-{
- MMCallbackInfo *info = user_data;
-
- /* Do nothing if modem removed */
- if (!modem || mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
- else {
- MMModemGsmAllowedMode mode = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "mode"));
-
- mm_generic_gsm_update_allowed_mode (MM_GENERIC_GSM (info->modem), mode);
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-set_allowed_mode (MMModemGsmNetwork *net,
- MMModemGsmAllowedMode mode,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (net);
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
-
- switch (mode) {
- case MM_MODEM_GSM_ALLOWED_MODE_ANY:
- case MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED:
- case MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED:
- case MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY:
- case MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY:
- if (!MM_GENERIC_GSM_GET_CLASS (self)->set_allowed_mode) {
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- } else {
- mm_callback_info_set_data (info, "mode", GUINT_TO_POINTER (mode), NULL);
- MM_GENERIC_GSM_GET_CLASS (self)->set_allowed_mode (self, mode, set_allowed_mode_done, info);
- }
- break;
- default:
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Invalid mode.");
- break;
- }
-
- if (info->error)
- mm_callback_info_schedule (info);
-}
-
-/*****************************************************************************/
-/* Charset stuff */
-
-static void
-get_charsets_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
- }
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- priv->charsets = MM_MODEM_CHARSET_UNKNOWN;
- if (!mm_gsm_parse_cscs_support_response (response->str, &priv->charsets)) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Failed to parse the supported character sets response");
- } else
- mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->charsets), NULL);
-
- mm_callback_info_schedule (info);
-}
-
-static void
-get_supported_charsets (MMModem *modem,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data);
-
- /* Use cached value if we have one */
- if (priv->charsets) {
- mm_callback_info_set_result (info, GUINT_TO_POINTER (priv->charsets), NULL);
- mm_callback_info_schedule (info);
- return;
- }
-
- /* Otherwise hit up the modem */
- port = mm_generic_gsm_get_best_at_port (self, &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_at_serial_port_queue_command (port, "+CSCS=?", 3, get_charsets_done, info);
-}
-
-static void
-set_get_charset_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
- MMModemCharset tried_charset;
- const char *p;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
- }
-
- p = response->str;
- if (g_str_has_prefix (p, "+CSCS:"))
- p += 6;
- while (*p == ' ')
- p++;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- priv->cur_charset = mm_modem_charset_from_string (p);
-
- tried_charset = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "charset"));
-
- if (tried_charset != priv->cur_charset) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_UNSUPPORTED_CHARSET,
- "Modem failed to change character set to %s",
- mm_modem_charset_to_string (tried_charset));
- }
-
- mm_callback_info_schedule (info);
-}
-
-#define TRIED_NO_QUOTES_TAG "tried-no-quotes"
-
-static void
-set_charset_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- gboolean tried_no_quotes = !!mm_callback_info_get_data (info, TRIED_NO_QUOTES_TAG);
- MMModemCharset charset = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "charset"));
- char *command;
-
- if (tried_no_quotes) {
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
- }
-
- /* Some modems puke if you include the quotes around the character
- * set name, so lets try it again without them.
- */
- mm_callback_info_set_data (info, TRIED_NO_QUOTES_TAG, GUINT_TO_POINTER (TRUE), NULL);
- command = g_strdup_printf ("+CSCS=%s", mm_modem_charset_to_string (charset));
- mm_at_serial_port_queue_command (port, command, 3, set_charset_done, info);
- g_free (command);
- } else
- mm_at_serial_port_queue_command (port, "+CSCS?", 3, set_get_charset_done, info);
-}
-
-static void
-set_charset (MMModem *modem,
- MMModemCharset charset,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMCallbackInfo *info;
- const char *str;
- char *command;
- MMAtSerialPort *port;
-
- info = mm_callback_info_new (modem, callback, user_data);
-
- if (!(priv->charsets & charset) || !utils_check_for_single_value (charset)) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_UNSUPPORTED_CHARSET,
- "Character set 0x%X not supported",
- charset);
- mm_callback_info_schedule (info);
- return;
- }
-
- str = mm_modem_charset_to_string (charset);
- if (!str) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_UNSUPPORTED_CHARSET,
- "Unhandled character set 0x%X",
- charset);
- mm_callback_info_schedule (info);
- return;
- }
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_callback_info_set_data (info, "charset", GUINT_TO_POINTER (charset), NULL);
-
- command = g_strdup_printf ("+CSCS=\"%s\"", str);
- mm_at_serial_port_queue_command (port, command, 3, set_charset_done, info);
- g_free (command);
-}
-
-MMModemCharset
-mm_generic_gsm_get_charset (MMGenericGsm *self)
-{
- g_return_val_if_fail (self != NULL, MM_MODEM_CHARSET_UNKNOWN);
- g_return_val_if_fail (MM_IS_GENERIC_GSM (self), MM_MODEM_CHARSET_UNKNOWN);
-
- return MM_GENERIC_GSM_GET_PRIVATE (self)->cur_charset;
-}
-
-/*****************************************************************************/
-/* MMModemGsmSms interface */
-
-static void
-sms_send_invoke (MMCallbackInfo *info)
-{
- MMModemGsmSmsSendFn callback = (MMModemGsmSmsSendFn) info->callback;
-
- callback (MM_MODEM_GSM_SMS (info->modem),
- mm_callback_info_get_data (info, "indexes"),
- info->error,
- info->user_data);
-}
-
-static void
-free_indexes (gpointer data)
-{
- g_array_free ((GArray *) data, TRUE);
-}
-
-static void
-sms_send_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- const char *p, *pdu;
- unsigned long num;
- GArray *indexes = NULL;
- guint32 idx = 0;
- guint cmgs_pdu_size;
- char *command;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- /* If there was an error sending in text mode the retry with the PDU;
- * text mode is pretty dumb on most devices and often fails. Later we'll
- * just use text mode exclusively.
- */
- pdu = mm_callback_info_get_data (info, "pdu");
- if (priv->sms_pdu_mode == FALSE && priv->sms_pdu_supported && pdu) {
- cmgs_pdu_size = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "cmgs-pdu-size"));
- g_assert (cmgs_pdu_size);
- command = g_strdup_printf ("+CMGS=%d\r%s\x1a", cmgs_pdu_size, pdu);
- mm_at_serial_port_queue_command (port, command, 10, sms_send_done, info);
- g_free (command);
-
- /* Clear the PDU data so we don't keep getting here */
- mm_callback_info_set_data (info, "pdu", NULL, NULL);
- return;
- }
-
- /* Otherwise it's a hard error */
- info->error = g_error_copy (error);
- } else {
- /* If the response happens to have a ">" in it from the interactive
- * handling of the CMGS command, skip it.
- */
- p = strchr (response->str, '+');
- if (p && *p) {
- /* Check for the message index */
- p = mm_strip_tag (p, "+CMGS:");
- if (p && *p) {
- errno = 0;
- num = strtoul (p, NULL, 10);
- if ((num < G_MAXUINT32) && (errno == 0))
- idx = (guint32) num;
- }
- }
- indexes = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 1);
- g_array_append_val (indexes, idx);
- mm_callback_info_set_data (info, "indexes", indexes, free_indexes);
- }
- mm_callback_info_schedule (info);
-}
-
-static void
-sms_send (MMModemGsmSms *modem,
- const char *number,
- const char *text,
- const char *smsc,
- guint validity,
- guint class,
- MMModemGsmSmsSendFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMGenericGsm *self = MM_GENERIC_GSM (modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- char *command;
- MMAtSerialPort *port;
- guint8 *pdu;
- guint pdulen = 0, msgstart = 0;
- char *hex;
-
- info = mm_callback_info_new_full (MM_MODEM (modem),
- sms_send_invoke,
- G_CALLBACK (callback),
- user_data);
-
- port = mm_generic_gsm_get_best_at_port (self, &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- /* Always create a PDU since we might need it for fallback from text mode */
- pdu = sms_create_submit_pdu (number, text, smsc, validity, class, &pdulen, &msgstart, &info->error);
- if (!pdu) {
- mm_callback_info_schedule (info);
- return;
- }
-
- hex = utils_bin2hexstr (pdu, pdulen);
- g_free (pdu);
- if (hex == NULL) {
- g_set_error_literal (&info->error,
- MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Not enough memory to send SMS PDU");
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_callback_info_set_data (info, "pdu", hex, g_free);
- mm_callback_info_set_data (info, "cmgs-pdu-size", GUINT_TO_POINTER (pdulen - msgstart), NULL);
- if (priv->sms_pdu_mode) {
- /* CMGS length is the size of the PDU without SMSC information */
- command = g_strdup_printf ("+CMGS=%d\r%s\x1a", pdulen - msgstart, hex);
- } else
- command = g_strdup_printf ("+CMGS=\"%s\"\r%s\x1a", number, text);
-
- mm_at_serial_port_queue_command (port, command, 10, sms_send_done, info);
- g_free (command);
-}
-
-static void
-sms_get_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
- GHashTable *properties;
- int rv, status, tpdu_len;
- guint idx;
- char pdu[SMS_MAX_PDU_LEN + 1];
- gboolean look_for_complete;
-
- idx = priv->sms_fetch_pending;
- priv->sms_fetch_pending = 0;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- goto out;
- }
-
- /* 344 == SMS_MAX_PDU_LEN */
- rv = sscanf (response->str, "+CMGR: %d,,%d %344s",
- &status, &tpdu_len, pdu);
- if (rv != 3) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Failed to parse CMGR response (parsed %d items)",
- rv);
- goto out;
- }
-
- properties = sms_parse_pdu (pdu, &info->error);
- if (!properties) {
- goto out;
- }
-
- g_hash_table_insert (properties, "index", simple_uint_value (idx));
- sms_cache_insert (info->modem, properties, idx);
-
- look_for_complete = GPOINTER_TO_UINT (mm_callback_info_get_data(info,
- "complete-sms-only"));
-
- if (look_for_complete == TRUE) {
- /*
- * If this is a standalone message, or the key part of a
- * multipart message, pass it along, otherwise report that there's
- * no such message.
- */
- properties = sms_cache_lookup_full (info->modem, properties,
- &info->error);
- }
- if (properties)
- mm_callback_info_set_data (info, GS_HASH_TAG, properties,
- (GDestroyNotify) g_hash_table_unref);
-
-out:
- mm_callback_info_schedule (info);
-}
-
-static void
-sms_get_invoke (MMCallbackInfo *info)
-{
- MMModemGsmSmsGetFn callback = (MMModemGsmSmsGetFn) info->callback;
-
- callback (MM_MODEM_GSM_SMS (info->modem),
- (GHashTable *) mm_callback_info_get_data (info, GS_HASH_TAG),
- info->error, info->user_data);
-}
-
-static void
-sms_get (MMModemGsmSms *modem,
- guint idx,
- MMModemGsmSmsGetFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- char *command;
- MMAtSerialPort *port;
- MMGenericGsmPrivate *priv =
- MM_GENERIC_GSM_GET_PRIVATE (MM_GENERIC_GSM (modem));
- GHashTable *properties;
- GError *error = NULL;
-
- properties = g_hash_table_lookup (priv->sms_contents, GUINT_TO_POINTER (idx));
- if (properties != NULL) {
- g_hash_table_ref (properties);
- properties = sms_cache_lookup_full (MM_MODEM (modem), properties, &error);
- if (properties == NULL) {
- error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "No SMS found");
- }
- callback (modem, properties, error, user_data);
- if (properties != NULL)
- g_hash_table_unref (properties);
- g_error_free (error);
- return;
- }
-
- info = mm_callback_info_new_full (MM_MODEM (modem),
- sms_get_invoke,
- G_CALLBACK (callback),
- user_data);
- mm_callback_info_set_data (info,
- "complete-sms-only",
- GUINT_TO_POINTER (TRUE),
- NULL);
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- command = g_strdup_printf ("+CMGR=%d", idx);
- priv->sms_fetch_pending = idx;
- mm_at_serial_port_queue_command (port, command, 10, sms_get_done, info);
-}
-
-typedef struct {
- MMGenericGsmPrivate *priv;
- MMCallbackInfo *info;
- SMSMultiPartMessage *mpm;
- int deleting;
-} SMSDeleteProgress;
-
-static void
-sms_delete_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
-
- mm_callback_info_schedule (info);
-}
-
-static void
-sms_delete_multi_next (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- SMSDeleteProgress *progress = (SMSDeleteProgress *)user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (progress->info))
- goto done;
-
- if (error)
- progress->info->error = g_error_copy (error);
-
- for (progress->deleting++ ;
- progress->deleting < progress->mpm->numparts ;
- progress->deleting++)
- if (progress->mpm->parts[progress->deleting] != 0)
- break;
- if (progress->deleting < progress->mpm->numparts) {
- GHashTable *properties;
- char *command;
- guint idx;
-
- idx = progress->mpm->parts[progress->deleting];
- command = g_strdup_printf ("+CMGD=%d", idx);
- mm_at_serial_port_queue_command (port, command, 10,
- sms_delete_multi_next, progress);
- properties = g_hash_table_lookup (progress->priv->sms_contents, GUINT_TO_POINTER (idx));
- g_hash_table_remove (progress->priv->sms_contents, GUINT_TO_POINTER (idx));
- g_hash_table_remove (progress->priv->sms_present, GUINT_TO_POINTER (idx));
- g_hash_table_unref (properties);
- return;
- }
-
- mm_callback_info_schedule (progress->info);
-done:
- g_free (progress->mpm->parts);
- g_free (progress->mpm);
- g_free (progress);
-}
-
-static void
-sms_delete (MMModemGsmSms *modem,
- guint idx,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- char *command;
- MMAtSerialPort *port;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (MM_GENERIC_GSM (modem));
- GHashTable *properties;
- MMAtSerialResponseFn next_callback;
- GValue *ref;
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
-
- properties = g_hash_table_lookup (priv->sms_contents, GINT_TO_POINTER (idx));
- if (properties == NULL) {
- /*
- * TODO(njw): This assumes our cache is valid. If we doubt this, we should just
- * run the delete anyway and let that return the nonexistent-message error.
- */
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "No SMS to delete");
- mm_callback_info_schedule (info);
- return;
- }
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- g_hash_table_remove (priv->sms_contents, GINT_TO_POINTER (idx));
- g_hash_table_unref (properties);
- return;
- }
-
- user_data = info;
- next_callback = sms_delete_done;
- ref = g_hash_table_lookup (properties, "concat-reference");
- if (ref != NULL) {
- SMSMultiPartMessage *mpm;
- SMSDeleteProgress *progress;
- guint refnum;
-
- refnum = g_value_get_uint (ref);
- mpm = g_hash_table_lookup (priv->sms_parts, GUINT_TO_POINTER (refnum));
- if (mpm == NULL) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Internal error - no part array for multipart SMS");
- mm_callback_info_schedule (info);
- g_hash_table_remove (priv->sms_contents, GINT_TO_POINTER (idx));
- g_hash_table_unref (properties);
- return;
- }
- /* Only allow the delete operation on the main index number. */
- if (idx != mpm->index) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "No SMS to delete");
- mm_callback_info_schedule (info);
- return;
- }
-
- g_hash_table_remove (priv->sms_parts, GUINT_TO_POINTER (refnum));
- progress = g_malloc0 (sizeof(*progress));
- progress->priv = priv;
- progress->info = info;
- progress->mpm = mpm;
- for (progress->deleting = 0 ;
- progress->deleting < mpm->numparts ;
- progress->deleting++)
- if (mpm->parts[progress->deleting] != 0)
- break;
- user_data = progress;
- next_callback = sms_delete_multi_next;
- idx = progress->mpm->parts[progress->deleting];
- properties = g_hash_table_lookup (priv->sms_contents, GINT_TO_POINTER (idx));
- }
- g_hash_table_remove (priv->sms_contents, GUINT_TO_POINTER (idx));
- g_hash_table_remove (priv->sms_present, GUINT_TO_POINTER (idx));
- g_hash_table_unref (properties);
-
- command = g_strdup_printf ("+CMGD=%d", idx);
- mm_at_serial_port_queue_command (port, command, 10, next_callback,
- user_data);
-}
-
-static gboolean
-pdu_parse_cmgl (MMGenericGsm *self, const char *response, GError **error)
-{
- int rv, status, tpdu_len, offset;
- GHashTable *properties;
-
- while (*response) {
- int idx;
- char pdu[SMS_MAX_PDU_LEN + 1];
-
- rv = sscanf (response, "+CMGL: %d,%d,,%d %344s %n",
- &idx, &status, &tpdu_len, pdu, &offset);
- if (4 != rv) {
- g_set_error (error,
- MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Failed to parse CMGL response: expected 4 results got %d", rv);
- mm_err("Couldn't parse response to SMS LIST (%d)", rv);
- return FALSE;
- }
- response += offset;
-
- properties = sms_parse_pdu (pdu, NULL);
- if (properties) {
- g_hash_table_insert (properties, "index", simple_uint_value (idx));
- sms_cache_insert (MM_MODEM (self), properties, idx);
- /* The cache holds a reference, so we don't need it anymore */
- g_hash_table_unref (properties);
- }
- }
-
- return TRUE;
-}
-
-static gboolean
-get_match_uint (GMatchInfo *m, guint match_index, guint *out_val)
-{
- char *s;
- unsigned long num;
-
- g_return_val_if_fail (out_val != NULL, FALSE);
-
- s = g_match_info_fetch (m, match_index);
- g_return_val_if_fail (s != NULL, FALSE);
-
- errno = 0;
- num = strtoul (s, NULL, 10);
- g_free (s);
-
- if (num <= 1000 && errno == 0) {
- *out_val = (guint) num;
- return TRUE;
- }
- return FALSE;
-}
-
-static char *
-get_match_string_unquoted (GMatchInfo *m, guint match_index)
-{
- char *s, *p, *q, *ret = NULL;
-
- q = s = g_match_info_fetch (m, match_index);
- g_return_val_if_fail (s != NULL, FALSE);
-
- /* remove quotes */
- if (*q == '"')
- q++;
- p = strchr (q, '"');
- if (p)
- *p = '\0';
- if (*q)
- ret = g_strdup (q);
- g_free (s);
- return ret;
-}
-
-static gboolean
-text_parse_cmgl (MMGenericGsm *self, const char *response, GError **error)
-{
- MMGenericGsmPrivate *priv;
- GRegex *r;
- GMatchInfo *match_info = NULL;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- /* +CMGL: <index>,<stat>,<oa/da>,[alpha],<scts><CR><LF><data><CR><LF> */
- r = g_regex_new ("\\+CMGL:\\s*(\\d+)\\s*,\\s*([^,]*),\\s*([^,]*),\\s*([^,]*),\\s*([^\\r\\n]*)\\r\\n([^\\r\\n]*)", 0, 0, NULL);
- g_assert (r);
-
- if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, NULL)) {
- g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Failed to parse CMGL response");
- mm_err("Couldn't parse response to SMS LIST");
- g_regex_unref (r);
- return FALSE;
- }
-
- while (g_match_info_matches (match_info)) {
- GHashTable *properties;
- guint matches, idx;
- char *number = NULL, *timestamp, *text, *ucs2_text;
- gsize ucs2_len = 0;
- GByteArray *data;
-
- matches = g_match_info_get_match_count (match_info);
- if (matches != 7) {
- mm_dbg ("Failed to match entire CMGL response (count %d)", matches);
- goto next;
- }
-
- if (!get_match_uint (match_info, 1, &idx)) {
- mm_dbg ("Failed to convert message index");
- goto next;
- }
-
- /* <stat is ignored for now> */
-
- /* Get and parse number */
- number = get_match_string_unquoted (match_info, 3);
- if (!number) {
- mm_dbg ("Failed to get message sender number");
- goto next;
- }
- number = mm_charset_take_and_convert_to_utf8 (number,
- priv->cur_charset);
-
- /* Get and parse timestamp (always expected in ASCII) */
- timestamp = get_match_string_unquoted (match_info, 5);
-
- /* Get and parse text */
- text = mm_charset_take_and_convert_to_utf8 (g_match_info_fetch (match_info, 6),
- priv->cur_charset);
-
- /* The raw SMS data can only be GSM, UCS2, or unknown (8-bit), so we
- * need to convert to UCS2 here.
- */
- ucs2_text = g_convert (text, -1, "UCS-2BE//TRANSLIT", "UTF-8", NULL, &ucs2_len, NULL);
- g_assert (ucs2_text);
- data = g_byte_array_sized_new (ucs2_len);
- g_byte_array_append (data, (const guint8 *) ucs2_text, ucs2_len);
- g_free (ucs2_text);
-
- properties = sms_properties_hash_new (NULL,
- number,
- timestamp,
- text,
- data,
- 2, /* DCS = UCS2 */
- 0); /* class */
- g_assert (properties);
-
- g_free (number);
- g_free (timestamp);
- g_free (text);
- g_byte_array_free (data, TRUE);
-
- g_hash_table_insert (properties, "index", simple_uint_value (idx));
- sms_cache_insert (MM_MODEM (self), properties, idx);
- /* The cache holds a reference, so we don't need it anymore */
- g_hash_table_unref (properties);
-
-next:
- g_match_info_next (match_info, NULL);
- }
- g_match_info_free (match_info);
-
- g_regex_unref (r);
- return TRUE;
-}
-
-static void
-free_list_results (gpointer data)
-{
- GPtrArray *results = (GPtrArray *) data;
-
- g_ptr_array_foreach (results, (GFunc) g_hash_table_unref, NULL);
- g_ptr_array_free (results, TRUE);
-}
-
-static void
-sms_list_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsm *self = MM_GENERIC_GSM (info->modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- GHashTableIter iter;
- GHashTable *properties = NULL;
- GPtrArray *results = NULL;
- gboolean success;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- mm_callback_info_schedule (info);
- return;
- }
-
- if (priv->sms_pdu_mode)
- success = pdu_parse_cmgl (self, response->str, &info->error);
- else
- success = text_parse_cmgl (self, response->str, &info->error);
-
- if (success) {
- results = g_ptr_array_new ();
-
- /* Add all the complete messages to the results */
- g_hash_table_iter_init (&iter, priv->sms_contents);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &properties)) {
- g_hash_table_ref (properties);
- g_clear_error (&info->error);
- properties = sms_cache_lookup_full (info->modem, properties, NULL);
- if (properties)
- g_ptr_array_add (results, properties);
- }
-
- if (results)
- mm_callback_info_set_data (info, "list-sms", results, free_list_results);
- }
-
- mm_callback_info_schedule (info);
-}
-
-static void
-sms_list_invoke (MMCallbackInfo *info)
-{
- MMModemGsmSmsListFn callback = (MMModemGsmSmsListFn) info->callback;
-
- callback (MM_MODEM_GSM_SMS (info->modem),
- (GPtrArray *) mm_callback_info_get_data (info, "list-sms"),
- info->error, info->user_data);
-}
-
-static void
-sms_list (MMModemGsmSms *modem,
- MMModemGsmSmsListFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- char *command;
- MMAtSerialPort *port;
-
- info = mm_callback_info_new_full (MM_MODEM (modem),
- sms_list_invoke,
- G_CALLBACK (callback),
- user_data);
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- if (MM_GENERIC_GSM_GET_PRIVATE (modem)->sms_pdu_mode)
- command = g_strdup_printf ("+CMGL=4");
- else
- command = g_strdup_printf ("+CMGL=\"ALL\"");
- mm_at_serial_port_queue_command (port, command, 10, sms_list_done, info);
-}
-
-MMAtSerialPort *
-mm_generic_gsm_get_at_port (MMGenericGsm *modem,
- MMAtPortFlags flag)
-{
- MMGenericGsmPrivate *priv;
-
- g_return_val_if_fail (MM_IS_GENERIC_GSM (modem), NULL);
-
- /* We only search for a single value even though it's a bitfield */
- g_return_val_if_fail ( flag == MM_AT_PORT_FLAG_NONE
- || flag == MM_AT_PORT_FLAG_PRIMARY
- || flag == MM_AT_PORT_FLAG_SECONDARY
- || flag == MM_AT_PORT_FLAG_PPP, NULL);
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- if (flag == MM_AT_PORT_FLAG_SECONDARY)
- return priv->secondary;
- else if (flag == MM_AT_PORT_FLAG_PRIMARY)
- return priv->primary;
- else if ((flag == MM_AT_PORT_FLAG_PPP) && MM_IS_AT_SERIAL_PORT (priv->data))
- return MM_AT_SERIAL_PORT (priv->data);
-
- return NULL;
-}
-
-MMAtSerialPort *
-mm_generic_gsm_get_best_at_port (MMGenericGsm *self, GError **error)
-{
- MMGenericGsmPrivate *priv;
-
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_GENERIC_GSM (self), NULL);
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (!mm_port_get_connected (MM_PORT (priv->primary)))
- return priv->primary;
-
- if (!priv->secondary) {
- g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_CONNECTED,
- "Cannot perform this operation while connected");
- }
-
- return priv->secondary;
-}
-
-/*****************************************************************************/
-/* MMModemGsmUssd interface */
-
-static void
-ussd_update_state (MMGenericGsm *self, MMModemGsmUssdState new_state)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (new_state != priv->ussd_state) {
- priv->ussd_state = new_state;
- g_object_notify (G_OBJECT (self), MM_MODEM_GSM_USSD_STATE);
- }
-}
-
-void
-mm_generic_gsm_ussd_cleanup (MMGenericGsm *self)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- if (priv->pending_ussd_info) {
- /* And schedule the callback */
- g_clear_error (&priv->pending_ussd_info->error);
- priv->pending_ussd_info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "USSD session terminated without reply.");
- mm_callback_info_schedule (priv->pending_ussd_info);
- priv->pending_ussd_info = NULL;
- }
-
- ussd_update_state (self, MM_MODEM_GSM_USSD_STATE_IDLE);
-
- g_free (priv->ussd_network_request);
- priv->ussd_network_request = NULL;
- g_object_notify (G_OBJECT (self), MM_MODEM_GSM_USSD_NETWORK_REQUEST);
-
- g_free (priv->ussd_network_notification);
- priv->ussd_network_notification = NULL;
- g_object_notify (G_OBJECT (self), MM_MODEM_GSM_USSD_NETWORK_NOTIFICATION);
-}
-
-static char *
-decode_ussd_response (MMGenericGsm *self,
- const char *reply,
- MMModemCharset cur_charset)
-{
- char **items, **iter, *p;
- char *str = NULL;
- gint encoding = -1;
- char *decoded;
-
- /* Look for the first ',' */
- p = strchr (reply, ',');
- if (p == NULL)
- return NULL;
-
- items = g_strsplit_set (p + 1, " ,", -1);
- for (iter = items; iter && *iter; iter++) {
- if (*iter[0] == '\0')
- continue;
- if (str == NULL)
- str = *iter;
- else if (encoding == -1) {
- encoding = atoi (*iter);
- mm_dbg ("USSD data coding scheme %d", encoding);
- break; /* All done */
- }
- }
-
- if (!str)
- return NULL;
-
- /* Strip quotes */
- if (str[0] == '"')
- str++;
- p = strchr (str, '"');
- if (p)
- *p = '\0';
-
- decoded = mm_modem_gsm_ussd_decode (MM_MODEM_GSM_USSD (self), str, cur_charset);
- g_strfreev (items);
- return decoded;
-}
-
-static char*
-ussd_encode (MMModemGsmUssd *modem, const char* command, guint *scheme)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- GByteArray *ussd_command = g_byte_array_new();
- gboolean success;
- char *hex = NULL;
-
- /* encode to cur_charset */
- success = mm_modem_charset_byte_array_append (ussd_command, command, FALSE,
- priv->cur_charset);
- g_warn_if_fail (success == TRUE);
- if (!success)
- goto out;
-
- *scheme = MM_MODEM_GSM_USSD_SCHEME_7BIT;
- /* convert to hex representation */
- hex = utils_bin2hexstr (ussd_command->data, ussd_command->len);
-
- out:
- g_byte_array_free (ussd_command, TRUE);
- return hex;
-}
-
-static char*
-ussd_decode (MMModemGsmUssd *modem, const char* reply, guint scheme)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- char *converted;
-
- converted = mm_modem_charset_hex_to_utf8 (reply, priv->cur_charset);
- return converted;
-}
-
-static void
-cusd_received (MMAtSerialPort *port,
- GMatchInfo *info,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (user_data);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- GError *error = NULL;
- gint status;
- MMModemGsmUssdState ussd_state = MM_MODEM_GSM_USSD_STATE_IDLE;
- char *reply = NULL, *converted;
-
- reply = g_match_info_fetch (info, 1);
- if (!reply || !isdigit (*reply)) {
- mm_warn ("Recieved invalid USSD response: '%s'", reply ? reply : "(none)");
- g_free (reply);
- return;
- }
-
- status = g_ascii_digit_value (*reply);
- switch (status) {
- case 0: /* no further action required */
- converted = decode_ussd_response (self, reply, priv->cur_charset);
- if (priv->pending_ussd_info) {
- /* Response to the user's request */
- mm_callback_info_set_result (priv->pending_ussd_info, converted, g_free);
- } else {
- /* Network-initiated USSD-Notify */
- g_free (priv->ussd_network_notification);
- priv->ussd_network_notification = converted;
- g_object_notify (G_OBJECT (self), MM_MODEM_GSM_USSD_NETWORK_NOTIFICATION);
- }
- break;
- case 1: /* further action required */
- ussd_state = MM_MODEM_GSM_USSD_STATE_USER_RESPONSE;
- converted = decode_ussd_response (self, reply, priv->cur_charset);
- if (priv->pending_ussd_info) {
- mm_callback_info_set_result (priv->pending_ussd_info, converted, g_free);
- } else {
- /* Network-initiated USSD-Request */
- g_free (priv->ussd_network_request);
- priv->ussd_network_request = converted;
- g_object_notify (G_OBJECT (self), MM_MODEM_GSM_USSD_NETWORK_REQUEST);
- }
- break;
- case 2:
- error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "USSD terminated by network.");
- break;
- case 4:
- error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Operation not supported.");
- break;
- default:
- error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Unhandled USSD reply %d", status);
- break;
- }
-
- ussd_update_state (self, ussd_state);
-
- if (priv->pending_ussd_info) {
- if (error)
- priv->pending_ussd_info->error = g_error_copy (error);
- mm_callback_info_schedule (priv->pending_ussd_info);
- priv->pending_ussd_info = NULL;
- }
-
- g_clear_error (&error);
- g_free (reply);
-}
-
-static void
-ussd_send_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
-
- if (error) {
- /* Some immediate error happened when sending the USSD request */
- info->error = g_error_copy (error);
- priv->pending_ussd_info = NULL;
- mm_callback_info_schedule (info);
-
- ussd_update_state (MM_GENERIC_GSM (info->modem), MM_MODEM_GSM_USSD_STATE_IDLE);
- }
-
- /* Otherwise if no error wait for the response to show up via the
- * unsolicited response code.
- */
-}
-
-static void
-ussd_send (MMModemGsmUssd *modem,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- char *atc_command;
- char *hex;
- guint scheme = 0;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
- MMAtSerialPort *port;
-
- g_warn_if_fail (priv->pending_ussd_info == NULL);
-
- info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- /* Cache the callback info since the response is an unsolicited one */
- priv->pending_ussd_info = info;
-
- hex = mm_modem_gsm_ussd_encode (MM_MODEM_GSM_USSD (modem), command, &scheme);
- if (!hex) {
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "Failed to encode USSD command '%s'",
- command);
- mm_callback_info_schedule (info);
- return;
- }
- atc_command = g_strdup_printf ("+CUSD=1,\"%s\",%d", hex, scheme);
- g_free (hex);
-
- mm_at_serial_port_queue_command (port, atc_command, 10, ussd_send_done, info);
- g_free (atc_command);
-
- ussd_update_state (MM_GENERIC_GSM (modem), MM_MODEM_GSM_USSD_STATE_ACTIVE);
-}
-
-static void
-ussd_initiate (MMModemGsmUssd *modem,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- if (priv->ussd_state != MM_MODEM_GSM_USSD_STATE_IDLE) {
- info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "USSD session already active.");
- mm_callback_info_schedule (info);
- } else {
- ussd_send (modem, command, callback, user_data);
- }
-}
-
-static void
-ussd_respond (MMModemGsmUssd *modem,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- if (priv->ussd_state != MM_MODEM_GSM_USSD_STATE_USER_RESPONSE) {
- info = mm_callback_info_string_new (MM_MODEM (modem), callback, user_data);
- info->error = g_error_new (MM_MODEM_ERROR,
- MM_MODEM_ERROR_GENERAL,
- "No active USSD session, cannot respond.");
- mm_callback_info_schedule (info);
- } else {
- ussd_send (modem, command, callback, user_data);
- }
-}
-
-static void
-ussd_cancel_done (MMAtSerialPort *port,
- GString *response,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
-
- /* If the modem has already been removed, return without
- * scheduling callback */
- if (mm_callback_info_check_modem_removed (info))
- return;
-
- if (error)
- info->error = g_error_copy (error);
-
- mm_callback_info_schedule (info);
-
- ussd_update_state (MM_GENERIC_GSM (info->modem), MM_MODEM_GSM_USSD_STATE_IDLE);
-}
-
-static void
-ussd_cancel (MMModemGsmUssd *modem,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- MMAtSerialPort *port;
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
-
- port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &info->error);
- if (!port) {
- mm_callback_info_schedule (info);
- return;
- }
-
- mm_at_serial_port_queue_command (port, "+CUSD=2", 10, ussd_cancel_done, info);
-}
-
-/*****************************************************************************/
-/* MMModemSimple interface */
-
-typedef enum {
- SIMPLE_STATE_CHECK_PIN = 0,
- SIMPLE_STATE_ENABLE,
- SIMPLE_STATE_ALLOWED_MODE,
- SIMPLE_STATE_REGISTER,
- SIMPLE_STATE_SET_APN,
- SIMPLE_STATE_CONNECT,
- SIMPLE_STATE_DONE
-} SimpleState;
-
-/* Looks a value up in the simple connect properties dictionary. If the
- * requested key is not present in the dict, NULL is returned. If the
- * requested key is present but is not a string, an error is returned.
- */
-static gboolean
-simple_get_property (MMCallbackInfo *info,
- const char *name,
- GType expected_type,
- const char **out_str,
- guint32 *out_num,
- gboolean *out_bool,
- GError **error)
-{
- GHashTable *properties = (GHashTable *) mm_callback_info_get_data (info, "simple-connect-properties");
- GValue *value;
- gint foo;
-
- g_return_val_if_fail (properties != NULL, FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
- if (out_str)
- g_return_val_if_fail (*out_str == NULL, FALSE);
-
- value = (GValue *) g_hash_table_lookup (properties, name);
- if (!value)
- return FALSE;
-
- if ((expected_type == G_TYPE_STRING) && G_VALUE_HOLDS_STRING (value)) {
- *out_str = g_value_get_string (value);
- return TRUE;
- } else if (expected_type == G_TYPE_UINT) {
- if (G_VALUE_HOLDS_UINT (value)) {
- *out_num = g_value_get_uint (value);
- return TRUE;
- } else if (G_VALUE_HOLDS_INT (value)) {
- /* handle ints for convenience, but only if they are >= 0 */
- foo = g_value_get_int (value);
- if (foo >= 0) {
- *out_num = (guint) foo;
- return TRUE;
- }
- }
- } else if (expected_type == G_TYPE_BOOLEAN && G_VALUE_HOLDS_BOOLEAN (value)) {
- *out_bool = g_value_get_boolean (value);
- return TRUE;
- }
-
- g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Invalid property type for '%s': %s (%s expected)",
- name, G_VALUE_TYPE_NAME (value), g_type_name (expected_type));
-
- return FALSE;
-}
-
-static const char *
-simple_get_string_property (MMCallbackInfo *info, const char *name, GError **error)
-{
- const char *str = NULL;
-
- simple_get_property (info, name, G_TYPE_STRING, &str, NULL, NULL, error);
- return str;
-}
-
-static gboolean
-simple_get_uint_property (MMCallbackInfo *info, const char *name, guint32 *out_val, GError **error)
-{
- return simple_get_property (info, name, G_TYPE_UINT, NULL, out_val, NULL, error);
-}
-
-static gboolean
-simple_get_bool_property (MMCallbackInfo *info, const char *name, gboolean *out_val, GError **error)
-{
- return simple_get_property (info, name, G_TYPE_BOOLEAN, NULL, NULL, out_val, error);
-}
-
-static gboolean
-simple_get_allowed_mode (MMCallbackInfo *info,
- MMModemGsmAllowedMode *out_mode,
- GError **error)
-{
- MMModemGsmNetworkDeprecatedMode old_mode = MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY;
- MMModemGsmAllowedMode allowed_mode = MM_MODEM_GSM_ALLOWED_MODE_ANY;
- GError *tmp_error = NULL;
-
- /* check for new allowed mode first */
- if (simple_get_uint_property (info, "allowed_mode", &allowed_mode, &tmp_error)) {
- if (allowed_mode > MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY) {
- g_set_error (&tmp_error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Invalid allowed mode %d", old_mode);
- } else {
- *out_mode = allowed_mode;
- return TRUE;
- }
- } else if (!tmp_error) {
- /* and if not, the old allowed mode */
- if (simple_get_uint_property (info, "network_mode", &old_mode, &tmp_error)) {
- if (old_mode > MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA) {
- g_set_error (&tmp_error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Invalid allowed mode %d", old_mode);
- } else {
- *out_mode = mm_modem_gsm_network_old_mode_to_allowed (old_mode);
- return TRUE;
- }
- }
- }
-
- if (error)
- *error = tmp_error;
- return FALSE;
-}
-
-static void
-simple_state_machine (MMModem *modem, GError *error, gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- MMGenericGsmPrivate *priv;
- const char *str, *unlock = NULL;
- SimpleState state = GPOINTER_TO_UINT (mm_callback_info_get_data (info, "simple-connect-state"));
- SimpleState next_state = state;
- gboolean done = FALSE;
- MMModemGsmAllowedMode allowed_mode;
- gboolean home_only = FALSE;
- char *data_device;
-
- /* Do nothing if modem removed */
- if (!modem || mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- info->error = g_error_copy (error);
- goto out;
- }
-
- priv = MM_GENERIC_GSM_GET_PRIVATE (modem);
-
- g_object_get (G_OBJECT (modem), MM_MODEM_DATA_DEVICE, &data_device, NULL);
- mm_dbg ("(%s): simple connect state %d", data_device, state);
- g_free (data_device);
-
- switch (state) {
- case SIMPLE_STATE_CHECK_PIN:
- next_state = SIMPLE_STATE_ENABLE;
-
- /* If we need a PIN, send it now, but we don't care about SIM-PIN2/SIM-PUK2
- * since the device is operational without it.
- */
- unlock = mm_modem_base_get_unlock_required (MM_MODEM_BASE (modem));
- if (unlock && strcmp (unlock, "sim-puk2") && strcmp (unlock, "sim-pin2")) {
- gboolean success = FALSE;
-
- if (!strcmp (unlock, "sim-pin")) {
- str = simple_get_string_property (info, "pin", &info->error);
- if (str) {
- mm_modem_gsm_card_send_pin (MM_MODEM_GSM_CARD (modem), str, simple_state_machine, info);
- success = TRUE;
- }
- }
- if (!success && !info->error)
- info->error = error_for_unlock_required (unlock);
- break;
- }
- /* Fall through if no PIN required */
- case SIMPLE_STATE_ENABLE:
- next_state = SIMPLE_STATE_ALLOWED_MODE;
- mm_modem_enable (modem, simple_state_machine, info);
- break;
- case SIMPLE_STATE_ALLOWED_MODE:
- next_state = SIMPLE_STATE_REGISTER;
- if ( simple_get_allowed_mode (info, &allowed_mode, &info->error)
- && (allowed_mode != priv->allowed_mode)) {
- mm_modem_gsm_network_set_allowed_mode (MM_MODEM_GSM_NETWORK (modem),
- allowed_mode,
- simple_state_machine,
- info);
- break;
- } else if (info->error)
- break;
- /* otherwise fall through as no allowed mode was sent */
- case SIMPLE_STATE_REGISTER:
- next_state = SIMPLE_STATE_SET_APN;
- str = simple_get_string_property (info, "network_id", &info->error);
- if (info->error)
- str = NULL;
- mm_modem_gsm_network_register (MM_MODEM_GSM_NETWORK (modem), str, simple_state_machine, info);
- break;
- case SIMPLE_STATE_SET_APN:
- next_state = SIMPLE_STATE_CONNECT;
- str = simple_get_string_property (info, "apn", &info->error);
- if (str || info->error) {
- if (str)
- mm_modem_gsm_network_set_apn (MM_MODEM_GSM_NETWORK (modem), str, simple_state_machine, info);
- break;
- }
- /* Fall through if no APN or no 'apn' property error */
- case SIMPLE_STATE_CONNECT:
- next_state = SIMPLE_STATE_DONE;
- str = simple_get_string_property (info, "number", &info->error);
- if (!info->error) {
- if (simple_get_bool_property (info, "home_only", &home_only, &info->error)) {
- MMModemGsmNetworkRegStatus status;
-
- priv->roam_allowed = !home_only;
-
- /* Don't connect if we're not supposed to be roaming */
- status = gsm_reg_status (MM_GENERIC_GSM (modem), NULL);
- if (home_only && (status == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING)) {
- info->error = g_error_new_literal (MM_MOBILE_ERROR,
- MM_MOBILE_ERROR_GPRS_ROAMING_NOT_ALLOWED,
- "Roaming is not allowed.");
- break;
- }
- } else if (info->error)
- break;
-
- mm_modem_connect (modem, str, simple_state_machine, info);
- }
- break;
- case SIMPLE_STATE_DONE:
- done = TRUE;
- break;
- }
-
- out:
- if (info->error || done)
- mm_callback_info_schedule (info);
- else
- mm_callback_info_set_data (info, "simple-connect-state", GUINT_TO_POINTER (next_state), NULL);
-}
-
-static void
-simple_connect (MMModemSimple *simple,
- GHashTable *properties,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
- GHashTableIter iter;
- gpointer key, value;
- char *data_device;
-
- /* List simple connect properties when debugging */
- g_object_get (G_OBJECT (simple), MM_MODEM_DATA_DEVICE, &data_device, NULL);
- g_hash_table_iter_init (&iter, properties);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- char *val_str;
-
- val_str = g_strdup_value_contents ((GValue *) value);
- mm_dbg ("(%s): %s => %s", data_device, (const char *) key, val_str);
- g_free (val_str);
- }
- g_free (data_device);
-
- info = mm_callback_info_new (MM_MODEM (simple), callback, user_data);
- mm_callback_info_set_data (info, "simple-connect-properties",
- g_hash_table_ref (properties),
- (GDestroyNotify) g_hash_table_unref);
-
- simple_state_machine (MM_MODEM (simple), NULL, info);
-}
-
-static void
-simple_free_gvalue (gpointer data)
-{
- g_value_unset ((GValue *) data);
- g_slice_free (GValue, data);
-}
-
-static GValue *
-simple_uint_value (guint32 i)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_UINT);
- g_value_set_uint (val, i);
-
- return val;
-}
-
-static GValue *
-simple_string_value (const char *str)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_STRING);
- g_value_set_string (val, str);
-
- return val;
-}
-
-#define SS_HASH_TAG "simple-get-status"
-
-static void
-simple_status_got_signal_quality (MMModem *modem,
- guint32 result,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- GHashTable *properties;
- gboolean error_no_network = FALSE;
-
- /* Treat "no network" as zero strength */
- if (g_error_matches (error, MM_MOBILE_ERROR, MM_MOBILE_ERROR_NO_NETWORK)) {
- error_no_network = TRUE;
- result = 0;
- }
-
- if (!error || error_no_network) {
- properties = (GHashTable *) mm_callback_info_get_data (info, SS_HASH_TAG);
- g_hash_table_insert (properties, "signal_quality", simple_uint_value (result));
- } else {
- g_clear_error (&info->error);
- info->error = g_error_copy (error);
- }
- mm_callback_info_chain_complete_one (info);
-}
-
-static void
-simple_status_got_band (MMModem *modem,
- guint32 result,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- GHashTable *properties;
-
- if (!error) {
- properties = (GHashTable *) mm_callback_info_get_data (info, SS_HASH_TAG);
- g_hash_table_insert (properties, "band", simple_uint_value (result));
- } else {
- g_clear_error (&info->error);
- info->error = g_error_copy (error);
- }
- mm_callback_info_chain_complete_one (info);
-}
-
-static void
-simple_status_got_reg_info (MMModemGsmNetwork *modem,
- MMModemGsmNetworkRegStatus status,
- const char *oper_code,
- const char *oper_name,
- GError *error,
- gpointer user_data)
-{
- MMCallbackInfo *info = (MMCallbackInfo *) user_data;
- GHashTable *properties;
-
- /* Do nothing if modem removed */
- if (!modem || mm_callback_info_check_modem_removed (info))
- return;
-
- if (error) {
- g_clear_error (&info->error);
- info->error = g_error_copy (error);
- } else {
- properties = (GHashTable *) mm_callback_info_get_data (info, SS_HASH_TAG);
-
- g_hash_table_insert (properties, "registration_status", simple_uint_value (status));
- g_hash_table_insert (properties, "operator_code", simple_string_value (oper_code));
- g_hash_table_insert (properties, "operator_name", simple_string_value (oper_name));
- }
- mm_callback_info_chain_complete_one (info);
-}
-
-static void
-simple_get_status_invoke (MMCallbackInfo *info)
-{
- MMModemSimpleGetStatusFn callback = (MMModemSimpleGetStatusFn) info->callback;
-
- callback (MM_MODEM_SIMPLE (info->modem),
- (GHashTable *) mm_callback_info_get_data (info, SS_HASH_TAG),
- info->error, info->user_data);
-}
-
-static void
-simple_get_status (MMModemSimple *simple,
- MMModemSimpleGetStatusFn callback,
- gpointer user_data)
-{
- MMModemGsmNetwork *gsm = MM_MODEM_GSM_NETWORK (simple);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (simple);
- GHashTable *properties;
- MMCallbackInfo *info;
- MMModemGsmNetworkDeprecatedMode old_mode;
-
- info = mm_callback_info_new_full (MM_MODEM (simple),
- simple_get_status_invoke,
- G_CALLBACK (callback),
- user_data);
-
- properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, simple_free_gvalue);
- mm_callback_info_set_data (info, SS_HASH_TAG, properties, (GDestroyNotify) g_hash_table_unref);
-
- mm_callback_info_chain_start (info, 3);
- mm_modem_gsm_network_get_signal_quality (gsm, simple_status_got_signal_quality, info);
- mm_modem_gsm_network_get_band (gsm, simple_status_got_band, info);
- mm_modem_gsm_network_get_registration_info (gsm, simple_status_got_reg_info, info);
-
- if (priv->act > -1) {
- /* Deprecated key */
- old_mode = mm_modem_gsm_network_act_to_old_mode (priv->act);
- g_hash_table_insert (properties, "network_mode", simple_uint_value (old_mode));
-
- /* New key */
- g_hash_table_insert (properties, "access_technology", simple_uint_value (priv->act));
- }
-}
-
-/*****************************************************************************/
-
-static gboolean
-gsm_lac_ci_available (MMGenericGsm *self, guint32 *out_idx)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMModemGsmNetworkRegStatus status;
- guint idx;
-
- /* Must be registered, and have operator code, LAC and CI before GSM_LAC_CI is valid */
- status = gsm_reg_status (self, &idx);
- if (out_idx)
- *out_idx = idx;
-
- if ( status != MM_MODEM_GSM_NETWORK_REG_STATUS_HOME
- && status != MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING)
- return FALSE;
-
- if (!priv->oper_code || !strlen (priv->oper_code))
- return FALSE;
-
- if (!priv->lac[idx] || !priv->cell_id[idx])
- return FALSE;
-
- return TRUE;
-}
-
-static void
-update_lac_ci (MMGenericGsm *self, gulong lac, gulong ci, guint idx)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- gboolean changed = FALSE;
-
- if (lac != priv->lac[idx]) {
- priv->lac[idx] = lac;
- changed = TRUE;
- }
-
- if (ci != priv->cell_id[idx]) {
- priv->cell_id[idx] = ci;
- changed = TRUE;
- }
-
- if (changed && gsm_lac_ci_available (self, NULL) && priv->loc_enabled && priv->loc_signal)
- g_object_notify (G_OBJECT (self), MM_MODEM_LOCATION_LOCATION);
-}
-
-static void
-destroy_gvalue (gpointer data)
-{
- GValue *value = (GValue *) data;
-
- g_value_unset (value);
- g_slice_free (GValue, value);
-}
-
-static GHashTable *
-make_location_hash (MMGenericGsm *self, GError **error)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- GHashTable *locations = NULL;
- guint32 reg_idx = 0;
- GValue *val;
- char mcc[4] = { 0, 0, 0, 0 };
- char mnc[4] = { 0, 0, 0, 0 };
-
- if (priv->loc_caps == MM_MODEM_LOCATION_CAPABILITY_UNKNOWN) {
- g_set_error_literal (error,
- MM_MODEM_ERROR,
- MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Modem has no location capabilities");
- return NULL;
- }
-
- locations = g_hash_table_new_full (g_direct_hash, g_direct_equal,
- NULL, destroy_gvalue);
-
- if (!gsm_lac_ci_available (self, &reg_idx))
- return locations;
-
- memcpy (mcc, priv->oper_code, 3);
- /* Not all modems report 6-digit MNCs */
- memcpy (mnc, priv->oper_code + 3, 2);
- if (strlen (priv->oper_code) == 6)
- mnc[2] = priv->oper_code[5];
-
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_STRING);
- g_value_take_string (val, g_strdup_printf ("%s,%s,%lX,%lX",
- mcc,
- mnc,
- priv->lac[reg_idx],
- priv->cell_id[reg_idx]));
- g_hash_table_insert (locations,
- GUINT_TO_POINTER (MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI),
- val);
-
- return locations;
-}
-
-static void
-location_enable (MMModemLocation *modem,
- gboolean loc_enable,
- gboolean signal_location,
- MMModemFn callback,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMCallbackInfo *info;
-
- if (loc_enable != priv->loc_enabled) {
- priv->loc_enabled = loc_enable;
- g_object_notify (G_OBJECT (modem), MM_MODEM_LOCATION_ENABLED);
- }
-
- if (signal_location != priv->loc_signal) {
- priv->loc_signal = signal_location;
- g_object_notify (G_OBJECT (modem), MM_MODEM_LOCATION_SIGNALS_LOCATION);
- }
-
- if (loc_enable && signal_location && gsm_lac_ci_available (self, NULL))
- g_object_notify (G_OBJECT (modem), MM_MODEM_LOCATION_LOCATION);
-
- info = mm_callback_info_new (MM_MODEM (modem), callback, user_data);
- mm_callback_info_schedule (info);
-}
-
-static void
-location_get (MMModemLocation *modem,
- MMModemLocationGetFn callback,
- gpointer user_data)
-{
- MMGenericGsm *self = MM_GENERIC_GSM (modem);
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- GHashTable *locations = NULL;
- GError *error = NULL;
-
- if (priv->loc_caps == MM_MODEM_LOCATION_CAPABILITY_UNKNOWN) {
- error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Modem has no location capabilities");
- } else if (priv->loc_enabled)
- locations = make_location_hash (self, &error);
- else
- locations = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- callback (modem, locations, error, user_data);
- if (locations)
- g_hash_table_destroy (locations);
- g_clear_error (&error);
-}
-
-/*****************************************************************************/
-
-static void
-modem_state_changed (MMGenericGsm *self, GParamSpec *pspec, gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
- MMModemState state;
-
- /* Start polling registration status and signal quality when enabled */
-
- state = mm_modem_get_state (MM_MODEM (self));
- if (state >= MM_MODEM_STATE_ENABLED) {
- if (!priv->poll_id)
- priv->poll_id = g_timeout_add_seconds (30, periodic_poll_cb, self);
- } else {
- if (priv->poll_id)
- g_source_remove (priv->poll_id);
- priv->poll_id = 0;
- }
-}
-
-static void
-unlock_required_changed (MMGenericGsm *self, GParamSpec *pspec, gpointer user_data)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- /* Some modems don't allow most commands when they're PIN locked so
- * when they get unlocked we have to recheck various stuff.
- */
- if (priv->enabled_facilities == 0)
- initial_facility_lock_check (self);
-}
-
-/*****************************************************************************/
-
-static void
-modem_init (MMModem *modem_class)
-{
- modem_class->owns_port = owns_port;
- modem_class->organize_ports = organize_ports;
- modem_class->release_port = release_port;
- modem_class->enable = enable;
- modem_class->disable = disable;
- modem_class->connect = connect;
- modem_class->disconnect = disconnect;
- modem_class->get_info = get_card_info;
- modem_class->get_supported_charsets = get_supported_charsets;
- modem_class->set_charset = set_charset;
-}
-
-static void
-modem_location_init (MMModemLocation *class)
-{
- class->enable = location_enable;
- class->get_location = location_get;
-}
-
-static void
-modem_gsm_card_init (MMModemGsmCard *class)
-{
- class->get_imei = get_imei;
- class->get_imsi = get_imsi;
- class->get_operator_id = get_operator_id;
- class->get_spn = get_spn;
- class->send_pin = send_pin;
- class->send_puk = send_puk;
- class->enable_pin = enable_pin;
- class->change_pin = change_pin;
- class->get_unlock_retries = get_unlock_retries;
-}
-
-static void
-modem_gsm_network_init (MMModemGsmNetwork *class)
-{
- class->do_register = do_register;
- class->get_registration_info = get_registration_info;
- class->set_allowed_mode = set_allowed_mode;
- class->set_apn = set_apn;
- class->scan = scan;
- class->get_signal_quality = get_signal_quality;
-}
-
-static void
-modem_gsm_sms_init (MMModemGsmSms *class)
-{
- class->send = sms_send;
- class->get = sms_get;
- class->delete = sms_delete;
- class->list = sms_list;
-}
-
-static void
-modem_gsm_ussd_init (MMModemGsmUssd *class)
-{
- class->initiate = ussd_initiate;
- class->respond = ussd_respond;
- class->cancel = ussd_cancel;
- class->encode = ussd_encode;
- class->decode = ussd_decode;
-}
-
-static void
-modem_simple_init (MMModemSimple *class)
-{
- class->connect = simple_connect;
- class->get_status = simple_get_status;
-}
-
-static void
-mm_generic_gsm_init (MMGenericGsm *self)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (self);
-
- priv->act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN;
- priv->reg_regex = mm_gsm_creg_regex_get (TRUE);
- priv->roam_allowed = TRUE;
- priv->sms_present = g_hash_table_new (g_direct_hash, g_direct_equal);
- priv->sms_contents = g_hash_table_new (g_direct_hash, g_direct_equal);
- priv->sms_parts = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_GSM_NETWORK_ALLOWED_MODE,
- NULL,
- MM_MODEM_GSM_NETWORK_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY,
- NULL,
- MM_MODEM_GSM_NETWORK_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_GSM_CARD_ENABLED_FACILITY_LOCKS,
- NULL,
- MM_MODEM_GSM_CARD_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_LOCATION_CAPABILITIES,
- "Capabilities",
- MM_MODEM_LOCATION_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_LOCATION_ENABLED,
- "Enabled",
- MM_MODEM_LOCATION_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_LOCATION_SIGNALS_LOCATION,
- NULL,
- MM_MODEM_LOCATION_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_LOCATION_LOCATION,
- NULL,
- MM_MODEM_LOCATION_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_GSM_USSD_STATE,
- "State",
- MM_MODEM_GSM_USSD_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_GSM_USSD_NETWORK_NOTIFICATION,
- "NetworkNotification",
- MM_MODEM_GSM_USSD_DBUS_INTERFACE);
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_GSM_USSD_NETWORK_REQUEST,
- "NetworkRequest",
- MM_MODEM_GSM_USSD_DBUS_INTERFACE);
-
- g_signal_connect (self, "notify::" MM_MODEM_STATE,
- G_CALLBACK (modem_state_changed), NULL);
-
- g_signal_connect (self, "notify::" MM_MODEM_UNLOCK_REQUIRED,
- G_CALLBACK (unlock_required_changed), NULL);
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- switch (prop_id) {
- case MM_MODEM_PROP_TYPE:
- case MM_GENERIC_GSM_PROP_POWER_UP_CMD:
- case MM_GENERIC_GSM_PROP_POWER_DOWN_CMD:
- case MM_GENERIC_GSM_PROP_INIT_CMD:
- case MM_GENERIC_GSM_PROP_INIT_CMD_OPTIONAL:
- case MM_GENERIC_GSM_PROP_SUPPORTED_BANDS:
- case MM_GENERIC_GSM_PROP_SUPPORTED_MODES:
- case MM_GENERIC_GSM_PROP_ALLOWED_MODE:
- case MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY:
- case MM_GENERIC_GSM_PROP_SIM_IDENTIFIER:
- case MM_GENERIC_GSM_PROP_ENABLED_FACILITY_LOCKS:
- case MM_GENERIC_GSM_PROP_LOC_CAPABILITIES:
- case MM_GENERIC_GSM_PROP_LOC_ENABLED:
- case MM_GENERIC_GSM_PROP_LOC_SIGNAL:
- case MM_GENERIC_GSM_PROP_LOC_LOCATION:
- case MM_GENERIC_GSM_PROP_USSD_STATE:
- case MM_GENERIC_GSM_PROP_USSD_NETWORK_REQUEST:
- case MM_GENERIC_GSM_PROP_USSD_NETWORK_NOTIFICATION:
- case MM_GENERIC_GSM_PROP_FLOW_CONTROL_CMD:
- case MM_GENERIC_GSM_PROP_SMS_INDICATION_ENABLE_CMD:
- case MM_GENERIC_GSM_PROP_SMS_STORAGE_LOCATION_CMD:
- case MM_GENERIC_GSM_PROP_CMER_ENABLE_CMD:
- case MM_GENERIC_GSM_PROP_PS_NETWORK_SUPPORTED:
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static const char *
-ussd_state_to_string (MMModemGsmUssdState ussd_state)
-{
- switch (ussd_state) {
- case MM_MODEM_GSM_USSD_STATE_IDLE:
- return "idle";
- case MM_MODEM_GSM_USSD_STATE_ACTIVE:
- return "active";
- case MM_MODEM_GSM_USSD_STATE_USER_RESPONSE:
- return "user-response";
- default:
- break;
- }
-
- g_warning ("Unknown GSM USSD state %d", ussd_state);
- return "unknown";
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (object);
- GHashTable *locations = NULL;
-
- switch (prop_id) {
- case MM_MODEM_PROP_DATA_DEVICE:
- if (priv->data)
- g_value_set_string (value, mm_port_get_device (priv->data));
- else
- g_value_set_string (value, NULL);
- break;
- case MM_MODEM_PROP_TYPE:
- g_value_set_uint (value, MM_MODEM_TYPE_GSM);
- break;
- case MM_GENERIC_GSM_PROP_POWER_UP_CMD:
- g_value_set_string (value, "+CFUN=1");
- break;
- case MM_GENERIC_GSM_PROP_POWER_DOWN_CMD:
- /* CFUN=0 is dangerous and often will shoot devices in the head (that's
- * what it's supposed to do). So don't use CFUN=0 by default, but let
- * specific plugins use it when they know it's safe to do so. For
- * example, CFUN=0 will often make phones turn themselves off, but some
- * dedicated devices (ex Sierra WWAN cards) will just turn off their
- * radio but otherwise still work.
- */
- g_value_set_string (value, "");
- break;
- case MM_GENERIC_GSM_PROP_INIT_CMD:
- g_value_set_string (value, "Z E0 V1");
- break;
- case MM_GENERIC_GSM_PROP_INIT_CMD_OPTIONAL:
- g_value_set_string (value, "X4 &C1");
- break;
- case MM_GENERIC_GSM_PROP_SUPPORTED_BANDS:
- g_value_set_uint (value, 0);
- break;
- case MM_GENERIC_GSM_PROP_SUPPORTED_MODES:
- g_value_set_uint (value, 0);
- break;
- case MM_GENERIC_GSM_PROP_ALLOWED_MODE:
- g_value_set_uint (value, priv->allowed_mode);
- break;
- case MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY:
- if (mm_modem_get_state (MM_MODEM (object)) >= MM_MODEM_STATE_ENABLED)
- g_value_set_uint (value, priv->act);
- else
- g_value_set_uint (value, MM_MODEM_GSM_ACCESS_TECH_UNKNOWN);
- break;
- case MM_GENERIC_GSM_PROP_SIM_IDENTIFIER:
- g_value_set_string (value, priv->simid);
- break;
- case MM_GENERIC_GSM_PROP_ENABLED_FACILITY_LOCKS:
- g_value_set_uint (value, priv->enabled_facilities);
- break;
- case MM_GENERIC_GSM_PROP_LOC_CAPABILITIES:
- g_value_set_uint (value, priv->loc_caps);
- break;
- case MM_GENERIC_GSM_PROP_LOC_ENABLED:
- g_value_set_boolean (value, priv->loc_enabled);
- break;
- case MM_GENERIC_GSM_PROP_LOC_SIGNAL:
- g_value_set_boolean (value, priv->loc_signal);
- break;
- case MM_GENERIC_GSM_PROP_LOC_LOCATION:
- /* We don't allow property accesses unless location change signalling
- * is enabled, for security reasons.
- */
- if (priv->loc_enabled && priv->loc_signal)
- locations = make_location_hash (MM_GENERIC_GSM (object), NULL);
- else
- locations = g_hash_table_new (g_direct_hash, g_direct_equal);
- g_value_take_boxed (value, locations);
- break;
- case MM_GENERIC_GSM_PROP_USSD_STATE:
- g_value_set_string (value, ussd_state_to_string (priv->ussd_state));
- break;
- case MM_GENERIC_GSM_PROP_USSD_NETWORK_REQUEST:
- g_value_set_string (value, priv->ussd_network_request);
- break;
- case MM_GENERIC_GSM_PROP_USSD_NETWORK_NOTIFICATION:
- g_value_set_string (value, priv->ussd_network_notification);
- break;
- case MM_GENERIC_GSM_PROP_FLOW_CONTROL_CMD:
- /* By default, try to set XOFF/XON flow control */
- g_value_set_string (value, "+IFC=1,1");
- break;
- case MM_GENERIC_GSM_PROP_SMS_INDICATION_ENABLE_CMD:
- /* Enable SMS notifications */
- g_value_set_string (value, "+CNMI=2,1,2,1,0");
- break;
- case MM_GENERIC_GSM_PROP_SMS_STORAGE_LOCATION_CMD:
- /* Use always ME to store SMS */
- g_value_set_string (value, "+CPMS=\"ME\",\"ME\",\"ME\"");
- break;
- case MM_GENERIC_GSM_PROP_CMER_ENABLE_CMD:
- g_value_set_string (value, "+CMER=3,0,0,1");
- break;
- case MM_GENERIC_GSM_PROP_PS_NETWORK_SUPPORTED:
- g_value_set_boolean (value, TRUE);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-finalize (GObject *object)
-{
- MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (object);
-
- mm_generic_gsm_pending_registration_stop (MM_GENERIC_GSM (object));
- mm_generic_gsm_ussd_cleanup (MM_GENERIC_GSM (object));
-
- if (priv->pin_check_timeout) {
- g_source_remove (priv->pin_check_timeout);
- priv->pin_check_timeout = 0;
- }
-
- if (priv->poll_id) {
- g_source_remove (priv->poll_id);
- priv->poll_id = 0;
- }
-
- if (priv->signal_quality_id) {
- g_source_remove (priv->signal_quality_id);
- priv->signal_quality_id = 0;
- }
-
- mm_gsm_creg_regex_destroy (priv->reg_regex);
-
- g_free (priv->oper_code);
- g_free (priv->oper_name);
- g_free (priv->simid);
- g_hash_table_destroy (priv->sms_present);
- g_hash_table_destroy (priv->sms_contents);
- g_hash_table_destroy (priv->sms_parts);
-
- G_OBJECT_CLASS (mm_generic_gsm_parent_class)->finalize (object);
-}
-
-static void
-mm_generic_gsm_class_init (MMGenericGsmClass *generic_class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (generic_class);
- MMModemBaseClass *base_class = MM_MODEM_BASE_CLASS (generic_class);
-
- mm_generic_gsm_parent_class = g_type_class_peek_parent (generic_class);
- g_type_class_add_private (object_class, sizeof (MMGenericGsmPrivate));
-
- /* Virtual methods */
- object_class->set_property = set_property;
- object_class->get_property = get_property;
- object_class->finalize = finalize;
-
- base_class->port_grabbed = port_grabbed;
-
- generic_class->do_enable = real_do_enable;
- generic_class->do_enable_power_up_done = real_do_enable_power_up_done;
- generic_class->do_disconnect = real_do_disconnect;
- generic_class->get_sim_iccid = real_get_sim_iccid;
- generic_class->get_operator_name = real_get_operator_name;
- generic_class->get_operator_code = real_get_operator_code;
-
- /* Properties */
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_DATA_DEVICE,
- MM_MODEM_DATA_DEVICE);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_TYPE,
- MM_MODEM_TYPE);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_SUPPORTED_BANDS,
- MM_MODEM_GSM_CARD_SUPPORTED_BANDS);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_SUPPORTED_MODES,
- MM_MODEM_GSM_CARD_SUPPORTED_MODES);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_ENABLED_FACILITY_LOCKS,
- MM_MODEM_GSM_CARD_ENABLED_FACILITY_LOCKS);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_ALLOWED_MODE,
- MM_MODEM_GSM_NETWORK_ALLOWED_MODE);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY,
- MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_SIM_IDENTIFIER,
- MM_MODEM_GSM_CARD_SIM_IDENTIFIER);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_LOC_CAPABILITIES,
- MM_MODEM_LOCATION_CAPABILITIES);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_LOC_ENABLED,
- MM_MODEM_LOCATION_ENABLED);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_LOC_SIGNAL,
- MM_MODEM_LOCATION_SIGNALS_LOCATION);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_LOC_LOCATION,
- MM_MODEM_LOCATION_LOCATION);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_USSD_STATE,
- MM_MODEM_GSM_USSD_STATE);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_USSD_NETWORK_NOTIFICATION,
- MM_MODEM_GSM_USSD_NETWORK_NOTIFICATION);
-
- g_object_class_override_property (object_class,
- MM_GENERIC_GSM_PROP_USSD_NETWORK_REQUEST,
- MM_MODEM_GSM_USSD_NETWORK_REQUEST);
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_POWER_UP_CMD,
- g_param_spec_string (MM_GENERIC_GSM_POWER_UP_CMD,
- "PowerUpCommand",
- "Power up command",
- "+CFUN=1",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_POWER_DOWN_CMD,
- g_param_spec_string (MM_GENERIC_GSM_POWER_DOWN_CMD,
- "PowerDownCommand",
- "Power down command",
- "+CFUN=0",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_INIT_CMD,
- g_param_spec_string (MM_GENERIC_GSM_INIT_CMD,
- "InitCommand",
- "Initialization command",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_INIT_CMD_OPTIONAL,
- g_param_spec_string (MM_GENERIC_GSM_INIT_CMD_OPTIONAL,
- "InitCommandOptional",
- "Optional initialization command (errors ignored)",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_FLOW_CONTROL_CMD,
- g_param_spec_string (MM_GENERIC_GSM_FLOW_CONTROL_CMD,
- "FlowControlCommand",
- "Flow control configuration command (errors ignored)",
- "+IFC=1,1",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_SMS_INDICATION_ENABLE_CMD,
- g_param_spec_string (MM_GENERIC_GSM_SMS_INDICATION_ENABLE_CMD,
- "SmsIndicationEnableCommand",
- "SMS indication enable command (errors ignored)",
- "+CNMI=2,1,2,1,0",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_SMS_STORAGE_LOCATION_CMD,
- g_param_spec_string (MM_GENERIC_GSM_SMS_STORAGE_LOCATION_CMD,
- "SmsStorageLocationCommand",
- "SMS storage location command (errors ignored)",
- "+CPMS=\"ME\",\"ME\",\"ME\"",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_CMER_ENABLE_CMD,
- g_param_spec_string (MM_GENERIC_GSM_CMER_ENABLE_CMD,
- "CmerEnableCommand",
- "CMER enable command",
- "+CMER=3,0,0,1",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property
- (object_class, MM_GENERIC_GSM_PROP_PS_NETWORK_SUPPORTED,
- g_param_spec_boolean (MM_GENERIC_GSM_PS_NETWORK_SUPPORTED,
- "PSNetworkSupported",
- "Flag identifying if PS network is supported",
- TRUE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
diff --git a/src/mm-generic-gsm.h b/src/mm-generic-gsm.h
deleted file mode 100644
index e0c3e6dd..00000000
--- a/src/mm-generic-gsm.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#ifndef MM_GENERIC_GSM_H
-#define MM_GENERIC_GSM_H
-
-#include <config.h>
-
-#include <ModemManager.h>
-#include "mm-modem-gsm-network.h"
-#include "mm-modem-base.h"
-#include "mm-at-serial-port.h"
-#include "mm-callback-info.h"
-#include "mm-charsets.h"
-
-#define MM_TYPE_GENERIC_GSM (mm_generic_gsm_get_type ())
-#define MM_GENERIC_GSM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_GENERIC_GSM, MMGenericGsm))
-#define MM_GENERIC_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_GENERIC_GSM, MMGenericGsmClass))
-#define MM_IS_GENERIC_GSM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_GENERIC_GSM))
-#define MM_IS_GENERIC_GSM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_GENERIC_GSM))
-#define MM_GENERIC_GSM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_GENERIC_GSM, MMGenericGsmClass))
-
-#define MM_GENERIC_GSM_POWER_UP_CMD "power-up-cmd"
-#define MM_GENERIC_GSM_POWER_DOWN_CMD "power-down-cmd"
-#define MM_GENERIC_GSM_INIT_CMD "init-cmd"
-#define MM_GENERIC_GSM_INIT_CMD_OPTIONAL "init-cmd-optional"
-#define MM_GENERIC_GSM_FLOW_CONTROL_CMD "flow-control-cmd"
-#define MM_GENERIC_GSM_SMS_INDICATION_ENABLE_CMD "sms-enable-cmd"
-#define MM_GENERIC_GSM_SMS_STORAGE_LOCATION_CMD "sms-storage-cmd"
-#define MM_GENERIC_GSM_CMER_ENABLE_CMD "cmer-enable-cmd"
-#define MM_GENERIC_GSM_PS_NETWORK_SUPPORTED "ps-network-supported"
-
-typedef enum {
- MM_GENERIC_GSM_PROP_FIRST = 0x2000,
-
- MM_GENERIC_GSM_PROP_POWER_UP_CMD,
- MM_GENERIC_GSM_PROP_POWER_DOWN_CMD,
- MM_GENERIC_GSM_PROP_INIT_CMD,
- MM_GENERIC_GSM_PROP_SUPPORTED_BANDS,
- MM_GENERIC_GSM_PROP_SUPPORTED_MODES,
- MM_GENERIC_GSM_PROP_INIT_CMD_OPTIONAL,
- MM_GENERIC_GSM_PROP_ALLOWED_MODE,
- MM_GENERIC_GSM_PROP_ACCESS_TECHNOLOGY,
- MM_GENERIC_GSM_PROP_LOC_CAPABILITIES,
- MM_GENERIC_GSM_PROP_LOC_ENABLED,
- MM_GENERIC_GSM_PROP_LOC_SIGNAL,
- MM_GENERIC_GSM_PROP_LOC_LOCATION,
- MM_GENERIC_GSM_PROP_SIM_IDENTIFIER,
- MM_GENERIC_GSM_PROP_USSD_STATE,
- MM_GENERIC_GSM_PROP_USSD_NETWORK_REQUEST,
- MM_GENERIC_GSM_PROP_USSD_NETWORK_NOTIFICATION,
- MM_GENERIC_GSM_PROP_FLOW_CONTROL_CMD,
- MM_GENERIC_GSM_PROP_SMS_INDICATION_ENABLE_CMD,
- MM_GENERIC_GSM_PROP_SMS_STORAGE_LOCATION_CMD,
- MM_GENERIC_GSM_PROP_CMER_ENABLE_CMD,
- MM_GENERIC_GSM_PROP_ENABLED_FACILITY_LOCKS,
- MM_GENERIC_GSM_PROP_PS_NETWORK_SUPPORTED
-} MMGenericGsmProp;
-
-typedef enum {
- MM_GENERIC_GSM_REG_TYPE_UNKNOWN = 0,
- MM_GENERIC_GSM_REG_TYPE_CS = 1,
- MM_GENERIC_GSM_REG_TYPE_PS = 2
-} MMGenericGsmRegType;
-
-typedef struct {
- MMModemBase parent;
-} MMGenericGsm;
-
-typedef struct {
- MMModemBaseClass parent;
-
- /* Called to allow subclasses to update port flags, attach unsolicited
- * result code handlers, change port attributes, etc. This is called
- * after the generic class has installed it's own handlers; if the
- * generic class' behavior is not desired, subclasses can override the
- * port_grabbed() method of MMModemBase.
- */
- void (*port_grabbed) (MMGenericGsm *self,
- MMPort *port,
- MMAtPortFlags at_pflags,
- gpointer user_data);
-
- /* Called after all ports have been organized to allow subclasses to
- * make changes to ports after we've assigned primary, secondary, and data
- * designations.
- */
- void (*ports_organized) (MMGenericGsm *self, MMAtSerialPort *primary);
-
- /* Called after opening the primary serial port and updating the modem's
- * state to ENABLING, but before sending any commands to the device. Modems
- * that need to perform custom initialization sequences or other setup should
- * generally override this method instead of the MMModem interface's enable()
- * method, unless the customization must happen *after* the generic init
- * sequence has completed. When the subclass' enable attempt is complete
- * the subclass should call mm_generic_gsm_enable_complete() with any error
- * encountered during the process and the MMCallbackInfo created from the
- * callback and user_data passed in here.
- */
- void (*do_enable) (MMGenericGsm *self,
- MMModemFn callback,
- gpointer user_data);
-
- /* Called before issuing the power-up command, to check whether it should
- * really be issued or not. */
- void (*do_enable_power_up_check_needed) (MMGenericGsm *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- /* Called after the generic class has attempted to power up the modem.
- * Subclasses can handle errors here if they know the device supports their
- * power up command. Will only be called if the device does *not* override
- * the MMModem enable() command or allows the generic class' do_enable()
- * handler to execute.
- */
- void (*do_enable_power_up_done) (MMGenericGsm *self,
- GString *response,
- GError *error,
- MMCallbackInfo *info);
-
- /* Called to terminate the active data call and deactivate the given PDP
- * context.
- */
- void (*do_disconnect) (MMGenericGsm *self,
- gint cid,
- MMModemFn callback,
- gpointer user_data);
-
- /* Called by the generic class to set the allowed operating mode of the device */
- void (*set_allowed_mode) (MMGenericGsm *self,
- MMModemGsmAllowedMode mode,
- MMModemFn callback,
- gpointer user_data);
-
- /* Called by the generic class to get the allowed operating mode of the device */
- void (*get_allowed_mode) (MMGenericGsm *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- /* Called by the generic class to the current radio access technology the
- * device is using while communicating with the base station.
- */
- void (*get_access_technology) (MMGenericGsm *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- /* Called by the generic class to get additional Location capabilities that
- * subclasses may implement. The MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI
- * capabilities is automatically provided by the generic class, and
- * subclasses should return a bitfield of additional location capabilities
- * they support in the callback here.
- */
- void (*loc_get_capabilities) (MMGenericGsm *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- /* Called by the generic class to retrieve the SIM's ICCID */
- void (*get_sim_iccid) (MMGenericGsm *self,
- MMModemStringFn callback,
- gpointer user_data);
-
- /* Called by the generic class to retrieve the Operator's name */
- void (*get_operator_name) (MMGenericGsm *self,
- MMModemStringFn callback,
- gpointer user_data);
-
- /* Called by the generic class to retrieve the Operator's code */
- void (*get_operator_code) (MMGenericGsm *self,
- MMModemStringFn callback,
- gpointer user_data);
-} MMGenericGsmClass;
-
-GType mm_generic_gsm_get_type (void);
-
-MMModem *mm_generic_gsm_new (const char *device,
- const char *driver,
- const char *plugin,
- guint vendor,
- guint product);
-
-/* Private, for subclasses */
-
-#define MM_GENERIC_GSM_PREV_STATE_TAG "prev-state"
-
-void mm_generic_gsm_pending_registration_stop (MMGenericGsm *modem);
-
-void mm_generic_gsm_ussd_cleanup (MMGenericGsm *modem);
-
-gint mm_generic_gsm_get_cid (MMGenericGsm *modem);
-
-void mm_generic_gsm_set_reg_status (MMGenericGsm *modem,
- MMGenericGsmRegType reg_type,
- MMModemGsmNetworkRegStatus status);
-
-MMModemCharset mm_generic_gsm_get_charset (MMGenericGsm *modem);
-
-/* Called to asynchronously update the current allowed operating mode that the
- * device is allowed to use when connecting to a network. This isn't the
- * specific access technology the device is currently using (see
- * mm_generic_gsm_set_access_technology() for that) but the mode the device is
- * allowed to choose from when connecting.
- */
-void mm_generic_gsm_update_allowed_mode (MMGenericGsm *modem,
- MMModemGsmAllowedMode mode);
-
-/* Called to asynchronously update the current access technology of the device;
- * this is NOT the 2G/3G mode preference, but the current radio access
- * technology being used to communicate with the base station.
- */
-void mm_generic_gsm_update_access_technology (MMGenericGsm *modem,
- MMModemGsmAccessTech act);
-
-/* Called to asynchronously update the current signal quality of the device;
- * 'quality' is a 0 - 100% quality.
- */
-void mm_generic_gsm_update_signal_quality (MMGenericGsm *modem, guint32 quality);
-
-/* Returns the first port (if any) which has the given flag */
-MMAtSerialPort *mm_generic_gsm_get_at_port (MMGenericGsm *modem,
- MMAtPortFlags flag);
-
-MMAtSerialPort *mm_generic_gsm_get_best_at_port (MMGenericGsm *modem,
- GError **error);
-
-/* stay_connected should be TRUE for unsolicited registration updates, otherwise
- * the registration update will clear connected/connecting/disconnecting state
- * which we don't want. stay_connected should be FALSE for other cases like
- * updating the state after disconnecting, or after a connect error occurs.
- */
-void mm_generic_gsm_update_enabled_state (MMGenericGsm *modem,
- gboolean stay_connected,
- MMModemStateReason reason);
-
-/* Called to complete the enable operation for custom enable() handling; if an
- * error is passed in, it copies the error to the callback info. This function
- * always schedules the callback info. It will also update the modem with the
- * correct state for both failure and success of the enable operation.
- */
-void mm_generic_gsm_enable_complete (MMGenericGsm *modem,
- GError *error,
- MMCallbackInfo *info);
-
-/* Called to complete the enable operation for custom connect() handling; if an
- * error is passed in, it copies the error to the callback info. This function
- * always schedules the callback info. It will also update the modem with the
- * correct state for both failure and success of the connect operation.
- */
-void mm_generic_gsm_connect_complete (MMGenericGsm *modem,
- GError *error,
- MMCallbackInfo *info);
-
-#endif /* MM_GENERIC_GSM_H */
diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c
deleted file mode 100644
index bd1943e7..00000000
--- a/src/mm-modem-base.c
+++ /dev/null
@@ -1,1323 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "mm-modem-base.h"
-#include "mm-modem.h"
-#include "mm-at-serial-port.h"
-#include "mm-qcdm-serial-port.h"
-#include "mm-errors.h"
-#include "mm-log.h"
-#include "mm-properties-changed-signal.h"
-#include "mm-callback-info.h"
-#include "mm-modem-helpers.h"
-#include "mm-modem-time.h"
-
-static void modem_init (MMModem *modem_class);
-static void pc_init (MMPropertiesChanged *pc_class);
-static void modem_time_init (MMModemTime *modem_time_class);
-
-G_DEFINE_TYPE_EXTENDED (MMModemBase, mm_modem_base,
- G_TYPE_OBJECT,
- G_TYPE_FLAG_VALUE_ABSTRACT,
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM, modem_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_PROPERTIES_CHANGED, pc_init)
- G_IMPLEMENT_INTERFACE (MM_TYPE_MODEM_TIME, modem_time_init))
-
-#define MM_MODEM_BASE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MODEM_BASE, MMModemBasePrivate))
-
-enum {
- PROP_0,
- PROP_MAX_TIMEOUTS,
- LAST_PROP
-};
-
-typedef struct {
- char *driver;
- char *plugin;
- char *device;
- char *equipment_ident;
- char *device_ident;
- char *unlock_required;
- guint32 unlock_retries;
- GArray *pin_retry_counts;
- guint32 ip_method;
- guint32 ip_timeout;
- gboolean valid;
- MMModemState state;
-
- guint vid;
- guint pid;
- char *manf;
- char *model;
- char *revision;
- char *ati;
- char *ati1;
- char *gsn;
-
- guint max_timeouts;
- guint set_invalid_unresponsive_modem_id;
-
- MMAuthProvider *authp;
-
- GHashTable *ports;
-
- GHashTable *tz_data;
- guint tz_poll_id;
- guint tz_poll_count;
-} MMModemBasePrivate;
-
-
-static char *
-get_hash_key (const char *subsys, const char *name)
-{
- return g_strdup_printf ("%s%s", subsys, name);
-}
-
-MMPort *
-mm_modem_base_get_port (MMModemBase *self,
- const char *subsys,
- const char *name)
-{
- MMPort *port;
- char *key;
-
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (subsys != NULL, NULL);
-
- g_return_val_if_fail (!strcmp (subsys, "net") || !strcmp (subsys, "tty"), NULL);
-
- key = get_hash_key (subsys, name);
- port = g_hash_table_lookup (MM_MODEM_BASE_GET_PRIVATE (self)->ports, key);
- g_free (key);
- return port;
-}
-
-GSList *
-mm_modem_base_get_ports (MMModemBase *self)
-{
- GHashTableIter iter;
- MMPort *port;
- GSList *list = NULL;
-
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL);
-
- g_hash_table_iter_init (&iter, MM_MODEM_BASE_GET_PRIVATE (self)->ports);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &port))
- list = g_slist_append (list, port);
-
- return list;
-}
-
-static gboolean
-set_invalid_unresponsive_modem_cb (MMModemBase *self)
-{
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- mm_modem_base_set_valid (self, FALSE);
- priv->set_invalid_unresponsive_modem_id = 0;
- return FALSE;
-}
-
-static void
-serial_port_timed_out_cb (MMSerialPort *port,
- guint n_consecutive_timeouts,
- gpointer user_data)
-{
- MMModemBase *self = (MM_MODEM_BASE (user_data));
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- if (priv->max_timeouts > 0 &&
- n_consecutive_timeouts >= priv->max_timeouts) {
- const gchar *dbus_path;
-
- dbus_path = (const gchar *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG);
- mm_warn ("Modem %s: Port (%s/%s) timed out %u times, marking modem as disabled",
- dbus_path,
- mm_port_type_to_name (mm_port_get_port_type (MM_PORT (port))),
- mm_port_get_device (MM_PORT (port)),
- n_consecutive_timeouts);
-
- /* Only set action to invalidate modem if not already done */
- if (!priv->set_invalid_unresponsive_modem_id)
- priv->set_invalid_unresponsive_modem_id =
- g_idle_add ((GSourceFunc)set_invalid_unresponsive_modem_cb, self);
- }
-}
-
-gboolean
-mm_modem_base_remove_port (MMModemBase *self, MMPort *port)
-{
- MMModemBasePrivate *priv;
- char *device, *key, *name;
- const char *type_name, *subsys;
- gboolean removed;
-
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), FALSE);
- g_return_val_if_fail (port != NULL, FALSE);
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- name = g_strdup (mm_port_get_device (port));
- subsys = mm_port_subsys_to_name (mm_port_get_subsys (port));
- type_name = mm_port_type_to_name (mm_port_get_port_type (port));
-
- key = get_hash_key (subsys, name);
- removed = g_hash_table_remove (priv->ports, key);
- if (removed) {
- /* Port may have already been destroyed by removal from the hash */
- device = mm_modem_get_device (MM_MODEM (self));
- mm_dbg ("(%s) type %s removed from %s", name, type_name, device);
- g_free (device);
- }
- g_free (key);
- g_free (name);
-
- return removed;
-}
-
-static inline void
-log_port (MMPort *port, const char *device, const char *desc)
-{
- if (port) {
- mm_dbg ("(%s) %s/%s %s",
- device,
- mm_port_subsys_to_name (mm_port_get_subsys (port)),
- mm_port_get_device (port),
- desc);
- }
-}
-
-gboolean
-mm_modem_base_organize_ports (MMModemBase *self,
- MMAtSerialPort **out_primary,
- MMAtSerialPort **out_secondary,
- MMPort **out_data,
- MMQcdmSerialPort **out_qcdm,
- GError **error)
-{
- GSList *ports, *iter;
- MMAtPortFlags flags;
- MMAtSerialPort *backup_primary = NULL;
- MMAtSerialPort *primary = NULL;
- MMAtSerialPort *secondary = NULL;
- MMAtSerialPort *backup_secondary = NULL;
- MMQcdmSerialPort *qcdm = NULL;
- MMPort *data = NULL;
- char *device;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (out_primary != NULL, FALSE);
- g_return_val_if_fail (out_secondary != NULL, FALSE);
- g_return_val_if_fail (out_data != NULL, FALSE);
-
- ports = mm_modem_base_get_ports (self);
- for (iter = ports; iter; iter = g_slist_next (iter)) {
- MMPort *candidate = iter->data;
- MMPortSubsys subsys = mm_port_get_subsys (candidate);
-
- if (MM_IS_AT_SERIAL_PORT (candidate)) {
- flags = mm_at_serial_port_get_flags (MM_AT_SERIAL_PORT (candidate));
-
- if (flags & MM_AT_PORT_FLAG_PRIMARY) {
- if (!primary)
- primary = MM_AT_SERIAL_PORT (candidate);
- else if (!backup_primary) {
- /* Just in case the plugin gave us more than one primary
- * and no secondaries, treat additional primary ports as
- * secondary.
- */
- backup_primary = MM_AT_SERIAL_PORT (candidate);
- }
- }
-
- if (!data && (flags & MM_AT_PORT_FLAG_PPP))
- data = candidate;
-
- /* Explicitly flagged secondary ports trump NONE ports for secondary */
- if (flags & MM_AT_PORT_FLAG_SECONDARY) {
- if (!secondary || !(mm_at_serial_port_get_flags (secondary) & MM_AT_PORT_FLAG_SECONDARY))
- secondary = MM_AT_SERIAL_PORT (candidate);
- }
-
- /* Fallback secondary */
- if (flags == MM_AT_PORT_FLAG_NONE) {
- if (!secondary)
- secondary = MM_AT_SERIAL_PORT (candidate);
- else if (!backup_secondary)
- backup_secondary = MM_AT_SERIAL_PORT (candidate);
- }
- } else if (MM_IS_QCDM_SERIAL_PORT (candidate)) {
- if (!qcdm)
- qcdm = MM_QCDM_SERIAL_PORT (candidate);
- } else if (subsys == MM_PORT_SUBSYS_NET) {
- /* Net device (if any) is the preferred data port */
- if (!data || MM_IS_AT_SERIAL_PORT (data))
- data = candidate;
- }
- }
- g_slist_free (ports);
-
- /* Fall back to a secondary port if we didn't find a primary port */
- if (!primary) {
- if (!secondary) {
- g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Failed to find primary port.");
- return FALSE;
- }
- primary = secondary;
- secondary = NULL;
- }
- g_assert (primary);
-
- /* If the plugin didn't give us any secondary ports, use any additional
- * primary ports or backup secondary ports as secondary.
- */
- if (!secondary)
- secondary = backup_primary ? backup_primary : backup_secondary;
-
- /* Data port defaults to primary AT port */
- if (!data)
- data = MM_PORT (primary);
- g_assert (data);
-
- /* Reset flags on all ports; clear data port first since it might also
- * be the primary or secondary port.
- */
- if (MM_IS_AT_SERIAL_PORT (data))
- mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (data), MM_AT_PORT_FLAG_NONE);
-
- mm_at_serial_port_set_flags (primary, MM_AT_PORT_FLAG_PRIMARY);
- if (secondary)
- mm_at_serial_port_set_flags (secondary, MM_AT_PORT_FLAG_SECONDARY);
-
- if (MM_IS_AT_SERIAL_PORT (data)) {
- flags = mm_at_serial_port_get_flags (MM_AT_SERIAL_PORT (data));
- mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (data), flags | MM_AT_PORT_FLAG_PPP);
- }
-
- device = mm_modem_get_device (MM_MODEM (self));
- log_port (MM_PORT (primary), device, "primary");
- log_port (MM_PORT (secondary), device, "secondary");
- log_port (MM_PORT (data), device, "data");
- log_port (MM_PORT (qcdm), device, "qcdm");
- g_free (device);
-
- *out_primary = primary;
- *out_secondary = secondary;
- *out_data = data;
- if (out_qcdm)
- *out_qcdm = qcdm;
-
- return TRUE;
-}
-
-void
-mm_modem_base_set_valid (MMModemBase *self, gboolean new_valid)
-{
- MMModemBasePrivate *priv;
-
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- if (priv->valid != new_valid) {
- priv->valid = new_valid;
-
- /* Modem starts off in disabled state, and jumps to disabled when
- * it's no longer valid.
- */
- mm_modem_set_state (MM_MODEM (self),
- MM_MODEM_STATE_DISABLED,
- MM_MODEM_STATE_REASON_NONE);
-
- g_object_notify (G_OBJECT (self), MM_MODEM_VALID);
- }
-}
-
-gboolean
-mm_modem_base_get_valid (MMModemBase *self)
-{
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), FALSE);
-
- return MM_MODEM_BASE_GET_PRIVATE (self)->valid;
-}
-
-const char *
-mm_modem_base_get_equipment_identifier (MMModemBase *self)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL);
-
- return MM_MODEM_BASE_GET_PRIVATE (self)->equipment_ident;
-}
-
-void
-mm_modem_base_set_equipment_identifier (MMModemBase *self, const char *ident)
-{
- MMModemBasePrivate *priv;
- const char *dbus_path;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- /* Only do something if the value changes */
- if ( (priv->equipment_ident == ident)
- || (priv->equipment_ident && ident && !strcmp (priv->equipment_ident, ident)))
- return;
-
- g_free (priv->equipment_ident);
- priv->equipment_ident = g_strdup (ident);
-
- dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG);
- if (dbus_path) {
- if (priv->equipment_ident)
- mm_info ("Modem %s: Equipment identifier set (%s)", dbus_path, priv->equipment_ident);
- else
- mm_warn ("Modem %s: Equipment identifier not set", dbus_path);
- }
-
- g_object_notify (G_OBJECT (self), MM_MODEM_EQUIPMENT_IDENTIFIER);
-}
-
-const char *
-mm_modem_base_get_unlock_required (MMModemBase *self)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL);
-
- return MM_MODEM_BASE_GET_PRIVATE (self)->unlock_required;
-}
-
-void
-mm_modem_base_set_unlock_required (MMModemBase *self, const char *unlock_required)
-{
- MMModemBasePrivate *priv;
- const char *dbus_path;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- /* Only do something if the value changes */
- if ( (priv->unlock_required == unlock_required)
- || ( priv->unlock_required
- && unlock_required
- && !strcmp (priv->unlock_required, unlock_required)))
- return;
-
- g_free (priv->unlock_required);
- priv->unlock_required = g_strdup (unlock_required);
-
- dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG);
- if (dbus_path) {
- if (priv->unlock_required)
- mm_info ("Modem %s: unlock required (%s)", dbus_path, priv->unlock_required);
- else
- mm_info ("Modem %s: unlock no longer required", dbus_path);
- }
-
- g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_REQUIRED);
-}
-
-void
-mm_modem_base_set_pin_retry_counts (MMModemBase *self, GArray *pin_retries)
-{
- MMModemBasePrivate *priv;
- GArray *old_retries;
- gboolean same;
- PinRetryCount *active = NULL;
- guint i, j;
- guint old_unlock_retries;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
- if (!pin_retries) {
- priv->unlock_retries = MM_MODEM_UNLOCK_RETRIES_NOT_SUPPORTED;
- return;
- }
-
- old_retries = priv->pin_retry_counts;
- old_unlock_retries = priv->unlock_retries;
-
- /* Only do something if one of the values changes */
- same = (old_retries != NULL) && (pin_retries->len == old_retries->len);
- for (i = 0; i < pin_retries->len; ++i) {
- PinRetryCount *newur = &g_array_index (pin_retries, PinRetryCount, i);
-
- if (!g_strcmp0 (newur->name, priv->unlock_required))
- active = newur;
-
- if (old_retries) {
- for (j = 0; j < old_retries->len; ++j) {
- PinRetryCount *oldur = &g_array_index (old_retries, PinRetryCount, i);
-
- if (!g_strcmp0 (oldur->name, newur->name)) {
- if (oldur->count != newur->count)
- same = FALSE;
- break;
- }
- }
- }
- }
-
- if (priv->pin_retry_counts)
- g_array_unref (priv->pin_retry_counts);
-
- priv->pin_retry_counts = pin_retries;
-
- if (priv->unlock_required) {
- g_assert (active);
- priv->unlock_retries = active->count;
- } else
- priv->unlock_retries = 0;
-
- if (old_unlock_retries != priv->unlock_retries)
- g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_RETRIES);
- if (!same)
- g_object_notify (G_OBJECT (self), MM_MODEM_PIN_RETRY_COUNTS);
-}
-
-const char *
-mm_modem_base_get_manf (MMModemBase *self)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL);
-
- return MM_MODEM_BASE_GET_PRIVATE (self)->manf;
-}
-
-void
-mm_modem_base_set_manf (MMModemBase *self, const char *manf)
-{
- MMModemBasePrivate *priv;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
- g_free (priv->manf);
- priv->manf = g_strdup (manf);
-}
-
-const char *
-mm_modem_base_get_model (MMModemBase *self)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL);
-
- return MM_MODEM_BASE_GET_PRIVATE (self)->model;
-}
-
-void
-mm_modem_base_set_model (MMModemBase *self, const char *model)
-{
- MMModemBasePrivate *priv;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
- g_free (priv->model);
- priv->model = g_strdup (model);
-}
-
-const char *
-mm_modem_base_get_revision (MMModemBase *self)
-{
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL);
-
- return MM_MODEM_BASE_GET_PRIVATE (self)->revision;
-}
-
-void
-mm_modem_base_set_revision (MMModemBase *self, const char *revision)
-{
- MMModemBasePrivate *priv;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
- g_free (priv->revision);
- priv->revision = g_strdup (revision);
-}
-
-static GValue *
-int_to_gvalue (gint i)
-{
- GValue *v = g_slice_new0 (GValue);
- g_value_init (v, G_TYPE_INT);
- g_value_set_int (v, i);
- return v;
-}
-
-static void
-value_destroy (gpointer data)
-{
- GValue *v = (GValue *) data;
- g_value_unset (v);
- g_slice_free (GValue, v);
-}
-
-static void
-timezone_poll_done (MMModem *modem, GError *error, gpointer user_data)
-{
- /* do nothing; modem will call mm_modem_base_set_network_timezone if
- it has timezone data, and then we will stop nagging it. */
-}
-
-static gboolean
-timezone_poll_callback (gpointer data)
-{
- MMModemBase *self = (MMModemBase *) data;
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
- gboolean result;
-
- if (priv->tz_poll_count == 0)
- goto stop_polling;
-
- priv->tz_poll_count--;
- result = mm_modem_time_poll_network_timezone (MM_MODEM_TIME (self),
- timezone_poll_done,
- NULL);
- if (!result)
- goto stop_polling;
-
- return TRUE;
-
-stop_polling:
- mm_modem_base_set_network_timezone (self, NULL, NULL, NULL);
- priv->tz_poll_id = 0;
- return FALSE;
-}
-
-#define TIMEZONE_POLL_INTERVAL_SEC 5
-#define TIMEZONE_POLL_RETRIES 6
-
-void
-mm_modem_base_set_network_timezone_polling (MMModemBase *self,
- gboolean should_poll)
-{
- MMModemBasePrivate *priv;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- if (should_poll == !!priv->tz_poll_id)
- return;
-
- if (should_poll) {
- priv->tz_poll_count = TIMEZONE_POLL_RETRIES;
- priv->tz_poll_id = g_timeout_add_seconds (TIMEZONE_POLL_INTERVAL_SEC,
- timezone_poll_callback,
- self);
- } else {
- g_source_remove (priv->tz_poll_id);
- priv->tz_poll_id = 0;
- }
-}
-
-static void
-modem_state_changed (MMModemBase *self, GParamSpec *pspec, gpointer user_data)
-{
- MMModemState state;
- gboolean registered;
-
- state = mm_modem_get_state (MM_MODEM (self));
- registered = (state >= MM_MODEM_STATE_REGISTERED);
-
- mm_modem_base_set_network_timezone_polling (self, registered);
-
- if (!registered)
- mm_modem_base_set_network_timezone (self, NULL, NULL, NULL);
-}
-
-void
-mm_modem_base_set_network_timezone (MMModemBase *self, gint *offset,
- gint *dst_offset, gint *leap_seconds)
-{
- MMModemBasePrivate *priv;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- if (offset)
- g_hash_table_replace (priv->tz_data, "offset", int_to_gvalue (*offset));
- else
- g_hash_table_remove (priv->tz_data, "offset");
-
- if (dst_offset)
- g_hash_table_replace (priv->tz_data, "dst_offset", int_to_gvalue (*dst_offset));
- else
- g_hash_table_remove (priv->tz_data, "dst_offset");
-
- if (leap_seconds)
- g_hash_table_replace (priv->tz_data, "leap_seconds", int_to_gvalue (*leap_seconds));
- else
- g_hash_table_remove (priv->tz_data, "leap_seconds");
-
- g_object_notify (G_OBJECT (self), MM_MODEM_TIME_NETWORK_TIMEZONE);
-
- mm_modem_base_set_network_timezone_polling (self, FALSE);
-}
-
-/*************************************************************************/
-static void
-card_info_simple_invoke (MMCallbackInfo *info)
-{
- MMModemBase *self = MM_MODEM_BASE (info->modem);
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
- MMModemInfoFn callback = (MMModemInfoFn) info->callback;
-
- callback (info->modem, priv->manf, priv->model, priv->revision, info->error, info->user_data);
-}
-
-static void
-card_info_cache_invoke (MMCallbackInfo *info)
-{
- MMModemBase *self = MM_MODEM_BASE (info->modem);
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
- MMModemInfoFn callback = (MMModemInfoFn) info->callback;
- const char *manf, *cmanf, *model, *cmodel, *rev, *crev, *ati, *ati1, *gsn, *cgsn;
-
- manf = mm_callback_info_get_data (info, "card-info-manf");
- cmanf = mm_callback_info_get_data (info, "card-info-c-manf");
-
- model = mm_callback_info_get_data (info, "card-info-model");
- cmodel = mm_callback_info_get_data (info, "card-info-c-model");
-
- rev = mm_callback_info_get_data (info, "card-info-revision");
- crev = mm_callback_info_get_data (info, "card-info-c-revision");
-
- /* Prefer the 'C' responses over the plain responses */
- g_free (priv->manf);
- priv->manf = g_strdup (cmanf ? cmanf : manf);
- g_free (priv->model);
- priv->model = g_strdup (cmodel ? cmodel : model);
- g_free (priv->revision);
- priv->revision = g_strdup (crev ? crev : rev);
-
- ati = mm_callback_info_get_data (info, "card-info-ati");
- g_free (priv->ati);
- priv->ati = g_strdup (ati);
-
- ati1 = mm_callback_info_get_data (info, "card-info-ati1");
- g_free (priv->ati1);
- priv->ati1 = g_strdup (ati1);
-
- gsn = mm_callback_info_get_data (info, "card-info-gsn");
- cgsn = mm_callback_info_get_data (info, "card-info-c-gsn");
- g_free (priv->gsn);
- priv->gsn = g_strdup (cgsn ? cgsn : gsn);
-
- /* Build up the device identifier */
- g_free (priv->device_ident);
- priv->device_ident = mm_create_device_identifier (priv->vid,
- priv->pid,
- priv->ati,
- priv->ati1,
- priv->gsn,
- priv->revision,
- priv->model,
- priv->manf);
- g_object_notify (G_OBJECT (self), MM_MODEM_DEVICE_IDENTIFIER);
-
- callback (info->modem, priv->manf, priv->model, priv->revision, info->error, info->user_data);
-}
-
-static void
-info_item_done (MMCallbackInfo *info,
- GString *response,
- GError *error,
- const char *tag,
- const char *tag2,
- const char *desc)
-{
- const char *p;
-
- if (!error) {
- p = response->str;
- if (tag)
- p = mm_strip_tag (p, tag);
- if (tag2)
- p = mm_strip_tag (p, tag2);
- mm_callback_info_set_data (info, desc, strlen (p) ? g_strdup (p) : NULL, g_free);
- }
-
- mm_callback_info_chain_complete_one (info);
-}
-
-#define GET_INFO_RESP_FN(func_name, tag, tag2, desc) \
- static void \
- func_name (MMAtSerialPort *port, \
- GString *response, \
- GError *error, \
- gpointer user_data) \
- { \
- if (mm_callback_info_check_modem_removed ((MMCallbackInfo *) user_data)) \
- return; \
- info_item_done ((MMCallbackInfo *) user_data, response, error, tag, tag2, desc ); \
- }
-
-GET_INFO_RESP_FN(get_revision_done, "+GMR:", "AT+GMR", "card-info-revision")
-GET_INFO_RESP_FN(get_model_done, "+GMM:", "AT+GMM", "card-info-model")
-GET_INFO_RESP_FN(get_manf_done, "+GMI:", "AT+GMI", "card-info-manf")
-
-GET_INFO_RESP_FN(get_c_revision_done, "+CGMR:", "AT+CGMR", "card-info-c-revision")
-GET_INFO_RESP_FN(get_c_model_done, "+CGMM:", "AT+CGMM", "card-info-c-model")
-GET_INFO_RESP_FN(get_c_manf_done, "+CGMI:", "AT+CGMI", "card-info-c-manf")
-
-GET_INFO_RESP_FN(get_ati_done, NULL, "ATI", "card-info-ati")
-GET_INFO_RESP_FN(get_ati1_done, NULL, "ATI1", "card-info-ati1")
-GET_INFO_RESP_FN(get_gsn_done, "+GSN:", "AT+GSN", "card-info-gsn")
-GET_INFO_RESP_FN(get_cgsn_done, "+CGSN:", "AT+CGSN", "card-info-c-gsn")
-
-void
-mm_modem_base_get_card_info (MMModemBase *self,
- MMAtSerialPort *port,
- GError *port_error,
- MMModemInfoFn callback,
- gpointer user_data)
-{
- MMModemBasePrivate *priv;
- MMCallbackInfo *info;
- gboolean cached = FALSE;
- GError *error = NULL;
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM_BASE (self));
- /* Either we get a proper AT port, or we get a port_error */
- g_return_if_fail ((port != NULL && MM_IS_AT_SERIAL_PORT (port)) || port_error != NULL);
- g_return_if_fail (callback != NULL);
-
- priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- /* Cached info and errors schedule the callback immediately and do
- * not hit up the card for it's model information.
- */
- if (priv->manf || priv->model || priv->revision)
- cached = TRUE;
- else if (port_error)
- error = g_error_copy (port_error);
-
- /* If we have cached info or an error, don't hit up the card */
- if (cached || error) {
- info = mm_callback_info_new_full (MM_MODEM (self),
- card_info_simple_invoke,
- G_CALLBACK (callback),
- user_data);
- info->error = error;
- mm_callback_info_schedule (info);
- return;
- }
-
- /* Otherwise, ask the card */
- info = mm_callback_info_new_full (MM_MODEM (self),
- card_info_cache_invoke,
- G_CALLBACK (callback),
- user_data);
-
- mm_callback_info_chain_start (info, 10);
-
- mm_at_serial_port_queue_command_cached (port, "+GMI", 3, get_manf_done, info);
- mm_at_serial_port_queue_command_cached (port, "+GMM", 3, get_model_done, info);
- mm_at_serial_port_queue_command_cached (port, "+GMR", 3, get_revision_done, info);
- mm_at_serial_port_queue_command_cached (port, "+CGMI", 3, get_c_manf_done, info);
- mm_at_serial_port_queue_command_cached (port, "+CGMM", 3, get_c_model_done, info);
- mm_at_serial_port_queue_command_cached (port, "+CGMR", 3, get_c_revision_done, info);
-
- mm_at_serial_port_queue_command_cached (port, "I", 3, get_ati_done, info);
- mm_at_serial_port_queue_command_cached (port, "I1", 3, get_ati1_done, info);
- mm_at_serial_port_queue_command_cached (port, "+GSN", 3, get_gsn_done, info);
- mm_at_serial_port_queue_command_cached (port, "+CGSN", 3, get_cgsn_done, info);
-}
-
-/*****************************************************************************/
-
-static gboolean
-grab_port (MMModem *modem,
- const char *subsys,
- const char *name,
- MMPortType ptype,
- MMAtPortFlags at_pflags,
- gpointer user_data,
- GError **error)
-{
- MMModemBase *self = MM_MODEM_BASE (modem);
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
- MMPort *port = NULL;
- char *key, *device;
-
- g_return_val_if_fail (MM_IS_MODEM_BASE (self), FALSE);
- g_return_val_if_fail (subsys != NULL, FALSE);
- g_return_val_if_fail (name != NULL, FALSE);
-
- g_return_val_if_fail (!strcmp (subsys, "net") || !strcmp (subsys, "tty"), FALSE);
-
- key = get_hash_key (subsys, name);
- port = g_hash_table_lookup (priv->ports, key);
- g_free (key);
- g_return_val_if_fail (port == NULL, FALSE);
-
- if (!strcmp (subsys, "tty")) {
- if (ptype == MM_PORT_TYPE_QCDM)
- port = MM_PORT (mm_qcdm_serial_port_new (name));
- else if (ptype == MM_PORT_TYPE_AT)
- port = MM_PORT (mm_at_serial_port_new (name));
-
- /* For serial ports, enable port timeout checks */
- if (port) {
- g_signal_connect (port,
- "timed-out",
- G_CALLBACK (serial_port_timed_out_cb),
- self);
- }
- } else if (!strcmp (subsys, "net")) {
- port = MM_PORT (g_object_new (MM_TYPE_PORT,
- MM_PORT_DEVICE, name,
- MM_PORT_SUBSYS, MM_PORT_SUBSYS_NET,
- NULL));
- }
-
- if (!port) {
- g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Failed to grab port %s/%s: unknown type?",
- subsys, name);
- mm_dbg ("(%s/%s): failed to create %s port",
- subsys, name, mm_port_type_to_name (ptype));
- return FALSE;
- }
-
- device = mm_modem_get_device (MM_MODEM (self));
- mm_dbg ("(%s) type %s claimed by %s",
- name,
- mm_port_type_to_name (ptype),
- device);
- g_free (device);
-
- key = get_hash_key (subsys, name);
- g_hash_table_insert (priv->ports, key, port);
-
- /* Let subclasses know we've grabbed it */
- if (MM_MODEM_BASE_GET_CLASS (self)->port_grabbed)
- MM_MODEM_BASE_GET_CLASS (self)->port_grabbed (self, port, at_pflags, user_data);
-
- return TRUE;
-}
-
-static gboolean
-modem_auth_request (MMModem *modem,
- const char *authorization,
- DBusGMethodInvocation *context,
- MMAuthRequestCb callback,
- gpointer callback_data,
- GDestroyNotify notify,
- GError **error)
-{
- MMModemBase *self = MM_MODEM_BASE (modem);
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- g_assert (priv->authp);
- return !!mm_auth_provider_request_auth (priv->authp,
- authorization,
- G_OBJECT (self),
- context,
- callback,
- callback_data,
- notify,
- error);
-}
-
-static gboolean
-modem_auth_finish (MMModem *modem, MMAuthRequest *req, GError **error)
-{
- if (mm_auth_request_get_result (req) != MM_AUTH_RESULT_AUTHORIZED) {
- g_set_error (error, MM_MODEM_ERROR, MM_MODEM_ERROR_AUTHORIZATION_REQUIRED,
- "This request requires the '%s' authorization",
- mm_auth_request_get_authorization (req));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*****************************************************************************/
-
-static void
-mm_modem_base_init (MMModemBase *self)
-{
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- priv->authp = mm_auth_provider_get ();
-
- priv->ports = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
- priv->tz_data = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, value_destroy);
- priv->tz_poll_id = 0;
-
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_ENABLED,
- NULL,
- MM_DBUS_INTERFACE_MODEM);
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_EQUIPMENT_IDENTIFIER,
- NULL,
- MM_DBUS_INTERFACE_MODEM);
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_DEVICE_IDENTIFIER,
- NULL,
- MM_DBUS_INTERFACE_MODEM);
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_UNLOCK_REQUIRED,
- NULL,
- MM_DBUS_INTERFACE_MODEM);
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_UNLOCK_RETRIES,
- NULL,
- MM_DBUS_INTERFACE_MODEM);
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_PIN_RETRY_COUNTS,
- NULL,
- MM_DBUS_INTERFACE_MODEM);
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_IP_METHOD,
- NULL,
- MM_DBUS_INTERFACE_MODEM);
- mm_properties_changed_signal_register_property (G_OBJECT (self),
- MM_MODEM_TIME_NETWORK_TIMEZONE,
- NULL,
- MM_DBUS_INTERFACE_MODEM_TIME);
-
- g_signal_connect (self,
- "notify::" MM_MODEM_STATE,
- G_CALLBACK (modem_state_changed),
- NULL);
-}
-
-static void
-modem_init (MMModem *modem_class)
-{
- modem_class->grab_port = grab_port;
- modem_class->auth_request = modem_auth_request;
- modem_class->auth_finish = modem_auth_finish;
-}
-
-static void
-pc_init (MMPropertiesChanged *pc_class)
-{
-}
-
-static void
-modem_time_init (MMModemTime *modem_time_class)
-{
-}
-
-static gboolean
-is_enabled (MMModemState state)
-{
- return (state >= MM_MODEM_STATE_ENABLED);
-}
-
-static void
-set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (object);
- gboolean old_enabled;
-
- switch (prop_id) {
- case MM_MODEM_PROP_STATE:
- /* Ensure we update the 'enabled' property when the state changes */
- old_enabled = is_enabled (priv->state);
- priv->state = g_value_get_uint (value);
- if (old_enabled != is_enabled (priv->state))
- g_object_notify (object, MM_MODEM_ENABLED);
- break;
- case MM_MODEM_PROP_DRIVER:
- /* Construct only */
- priv->driver = g_value_dup_string (value);
- break;
- case MM_MODEM_PROP_PLUGIN:
- /* Construct only */
- priv->plugin = g_value_dup_string (value);
- break;
- case MM_MODEM_PROP_MASTER_DEVICE:
- /* Construct only */
- priv->device = g_value_dup_string (value);
- break;
- case MM_MODEM_PROP_IP_METHOD:
- priv->ip_method = g_value_get_uint (value);
- break;
- case MM_MODEM_PROP_IP_TIMEOUT:
- priv->ip_timeout = g_value_get_uint (value);
- break;
- case MM_MODEM_PROP_VALID:
- case MM_MODEM_PROP_TYPE:
- case MM_MODEM_PROP_ENABLED:
- case MM_MODEM_PROP_EQUIPMENT_IDENTIFIER:
- case MM_MODEM_PROP_DEVICE_IDENTIFIER:
- case MM_MODEM_PROP_UNLOCK_REQUIRED:
- case MM_MODEM_PROP_UNLOCK_RETRIES:
- case MM_MODEM_PROP_PIN_RETRY_COUNTS:
- case MM_MODEM_PROP_NETWORK_TIMEZONE:
- break;
- case MM_MODEM_PROP_HW_VID:
- /* Construct only */
- priv->vid = g_value_get_uint (value);
- break;
- case MM_MODEM_PROP_HW_PID:
- /* Construct only */
- priv->pid = g_value_get_uint (value);
- break;
- case PROP_MAX_TIMEOUTS:
- priv->max_timeouts = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static GHashTable *
-get_retry_counts (GArray *counts)
-{
- GHashTable *map;
- int i;
-
- map = g_hash_table_new (g_str_hash, g_str_equal);
-
- if (counts) {
- for (i = 0; i < counts->len; ++i) {
- PinRetryCount *ur = (PinRetryCount *) &g_array_index (counts, PinRetryCount, i);
- g_hash_table_insert (map, (char *) ur->name, GUINT_TO_POINTER (ur->count));
- }
- }
- return map;
-}
-
-static void
-get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (object);
-
- switch (prop_id) {
- case MM_MODEM_PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- case MM_MODEM_PROP_MASTER_DEVICE:
- g_value_set_string (value, priv->device);
- break;
- case MM_MODEM_PROP_DATA_DEVICE:
- g_value_set_string (value, NULL);
- break;
- case MM_MODEM_PROP_DRIVER:
- g_value_set_string (value, priv->driver);
- break;
- case MM_MODEM_PROP_PLUGIN:
- g_value_set_string (value, priv->plugin);
- break;
- case MM_MODEM_PROP_TYPE:
- g_value_set_uint (value, MM_MODEM_TYPE_UNKNOWN);
- break;
- case MM_MODEM_PROP_IP_METHOD:
- g_value_set_uint (value, priv->ip_method);
- break;
- case MM_MODEM_PROP_IP_TIMEOUT:
- g_value_set_uint (value, priv->ip_timeout);
- break;
- case MM_MODEM_PROP_VALID:
- g_value_set_boolean (value, priv->valid);
- break;
- case MM_MODEM_PROP_ENABLED:
- g_value_set_boolean (value, is_enabled (priv->state));
- break;
- case MM_MODEM_PROP_EQUIPMENT_IDENTIFIER:
- g_value_set_string (value, priv->equipment_ident);
- break;
- case MM_MODEM_PROP_DEVICE_IDENTIFIER:
- g_value_set_string (value, priv->device_ident);
- break;
- case MM_MODEM_PROP_UNLOCK_REQUIRED:
- g_value_set_string (value, priv->unlock_required);
- break;
- case MM_MODEM_PROP_UNLOCK_RETRIES:
- g_value_set_uint (value, priv->unlock_retries);
- break;
- case MM_MODEM_PROP_PIN_RETRY_COUNTS:
- g_value_set_boxed (value, get_retry_counts (priv->pin_retry_counts));
- break;
- case MM_MODEM_PROP_HW_VID:
- g_value_set_uint (value, priv->vid);
- break;
- case MM_MODEM_PROP_HW_PID:
- g_value_set_uint (value, priv->pid);
- break;
- case MM_MODEM_PROP_NETWORK_TIMEZONE:
- g_value_set_boxed (value, priv->tz_data);
- break;
- case PROP_MAX_TIMEOUTS:
- g_value_set_uint (value, priv->max_timeouts);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-finalize (GObject *object)
-{
- MMModemBase *self = MM_MODEM_BASE (object);
- MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self);
-
- mm_auth_provider_cancel_for_owner (priv->authp, object);
-
- if (priv->tz_poll_id)
- g_source_remove (priv->tz_poll_id);
-
- g_hash_table_destroy (priv->ports);
- g_hash_table_destroy (priv->tz_data);
- g_free (priv->driver);
- g_free (priv->plugin);
- g_free (priv->device);
- g_free (priv->equipment_ident);
- g_free (priv->device_ident);
- g_free (priv->unlock_required);
- g_free (priv->manf);
- g_free (priv->model);
- g_free (priv->revision);
- g_free (priv->ati);
- g_free (priv->ati1);
- g_free (priv->gsn);
-
- G_OBJECT_CLASS (mm_modem_base_parent_class)->finalize (object);
-}
-
-static void
-mm_modem_base_class_init (MMModemBaseClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (object_class, sizeof (MMModemBasePrivate));
-
- /* Virtual methods */
- object_class->get_property = get_property;
- object_class->set_property = set_property;
- object_class->finalize = finalize;
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_STATE,
- MM_MODEM_STATE);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_MASTER_DEVICE,
- MM_MODEM_MASTER_DEVICE);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_DATA_DEVICE,
- MM_MODEM_DATA_DEVICE);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_DRIVER,
- MM_MODEM_DRIVER);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_PLUGIN,
- MM_MODEM_PLUGIN);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_TYPE,
- MM_MODEM_TYPE);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_IP_METHOD,
- MM_MODEM_IP_METHOD);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_IP_TIMEOUT,
- MM_MODEM_IP_TIMEOUT);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_VALID,
- MM_MODEM_VALID);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_ENABLED,
- MM_MODEM_ENABLED);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_EQUIPMENT_IDENTIFIER,
- MM_MODEM_EQUIPMENT_IDENTIFIER);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_DEVICE_IDENTIFIER,
- MM_MODEM_DEVICE_IDENTIFIER);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_UNLOCK_REQUIRED,
- MM_MODEM_UNLOCK_REQUIRED);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_UNLOCK_RETRIES,
- MM_MODEM_UNLOCK_RETRIES);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_PIN_RETRY_COUNTS,
- MM_MODEM_PIN_RETRY_COUNTS);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_HW_VID,
- MM_MODEM_HW_VID);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_HW_PID,
- MM_MODEM_HW_PID);
-
- g_object_class_override_property (object_class,
- MM_MODEM_PROP_NETWORK_TIMEZONE,
- MM_MODEM_TIME_NETWORK_TIMEZONE);
-
- g_object_class_install_property
- (object_class, PROP_MAX_TIMEOUTS,
- g_param_spec_uint (MM_MODEM_BASE_MAX_TIMEOUTS,
- "Max timeouts",
- "Maximum number of consecutive timed out commands sent to "
- "the modem before disabling it. If 0, this feature is disabled.",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE));
-
- mm_properties_changed_signal_enable (object_class);
-}
-
diff --git a/src/mm-modem-base.h b/src/mm-modem-base.h
deleted file mode 100644
index b3bd679e..00000000
--- a/src/mm-modem-base.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#ifndef MM_MODEM_BASE_H
-#define MM_MODEM_BASE_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include "mm-port.h"
-#include "mm-at-serial-port.h"
-#include "mm-qcdm-serial-port.h"
-#include "mm-modem.h"
-
-#define MM_TYPE_MODEM_BASE (mm_modem_base_get_type ())
-#define MM_MODEM_BASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_BASE, MMModemBase))
-#define MM_MODEM_BASE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_MODEM_BASE, MMModemBaseClass))
-#define MM_IS_MODEM_BASE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_BASE))
-#define MM_IS_MODEM_BASE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_MODEM_BASE))
-#define MM_MODEM_BASE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_MODEM_BASE, MMModemBaseClass))
-
-typedef struct _MMModemBase MMModemBase;
-typedef struct _MMModemBaseClass MMModemBaseClass;
-
-#define MM_MODEM_BASE_MAX_TIMEOUTS "max-timeouts"
-
-struct _MMModemBase {
- GObject parent;
-};
-
-struct _MMModemBaseClass {
- GObjectClass parent;
-
- /* Called after the base class grabs a port so that subclasses can
- * set port flags and other properties on the new port.
- */
- void (*port_grabbed) (MMModemBase *self,
- MMPort *port,
- MMAtPortFlags at_pflags,
- gpointer user_data);
-};
-
-GType mm_modem_base_get_type (void);
-
-MMPort *mm_modem_base_get_port (MMModemBase *self,
- const char *subsys,
- const char *name);
-
-GSList *mm_modem_base_get_ports (MMModemBase *self);
-
-gboolean mm_modem_base_remove_port (MMModemBase *self,
- MMPort *port);
-
-gboolean mm_modem_base_organize_ports (MMModemBase *self,
- MMAtSerialPort **out_primary,
- MMAtSerialPort **out_secondary,
- MMPort **out_data,
- MMQcdmSerialPort **out_qcdm,
- GError **error);
-
-void mm_modem_base_set_valid (MMModemBase *self,
- gboolean valid);
-
-gboolean mm_modem_base_get_valid (MMModemBase *self);
-
-const char *mm_modem_base_get_equipment_identifier (MMModemBase *self);
-
-void mm_modem_base_set_equipment_identifier (MMModemBase *self,
- const char *ident);
-
-const char *mm_modem_base_get_unlock_required (MMModemBase *self);
-
-void mm_modem_base_set_unlock_required (MMModemBase *self,
- const char *unlock_required);
-
-void mm_modem_base_set_pin_retry_counts (MMModemBase *self,
- GArray *pin_retries);
-
-void mm_modem_base_set_network_timezone (MMModemBase *self,
- gint *offset,
- gint *dst_offset,
- gint *leap_seconds);
-
-void mm_modem_base_set_network_timezone_polling (MMModemBase *self,
- gboolean should_poll);
-
-const char *mm_modem_base_get_manf (MMModemBase *self);
-void mm_modem_base_set_manf (MMModemBase *self, const char *manf);
-
-const char *mm_modem_base_get_model (MMModemBase *self);
-void mm_modem_base_set_model (MMModemBase *self, const char *model);
-
-const char *mm_modem_base_get_revision (MMModemBase *self);
-void mm_modem_base_set_revision (MMModemBase *self, const char *revision);
-
-void mm_modem_base_get_card_info (MMModemBase *self,
- MMAtSerialPort *port,
- GError *port_error,
- MMModemInfoFn callback,
- gpointer user_data);
-
-typedef struct {
- const char *name;
- guint count;
-} PinRetryCount;
-
-#endif /* MM_MODEM_BASE_H */
-
diff --git a/src/mm-modem-cdma.c b/src/mm-modem-cdma.c
deleted file mode 100644
index 7583760e..00000000
--- a/src/mm-modem-cdma.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#include <string.h>
-#include <dbus/dbus-glib.h>
-#include "mm-modem-cdma.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-marshal.h"
-#include "mm-auth-provider.h"
-
-static void impl_modem_cdma_get_signal_quality (MMModemCdma *modem, DBusGMethodInvocation *context);
-static void impl_modem_cdma_get_esn (MMModemCdma *modem, DBusGMethodInvocation *context);
-static void impl_modem_cdma_get_serving_system (MMModemCdma *modem, DBusGMethodInvocation *context);
-static void impl_modem_cdma_get_registration_state (MMModemCdma *modem, DBusGMethodInvocation *context);
-static void impl_modem_cdma_activate (MMModemCdma *modem, DBusGMethodInvocation *context);
-static void impl_modem_cdma_activate_manual (MMModemCdma *modem, DBusGMethodInvocation *context);
-
-#include "mm-modem-cdma-glue.h"
-
-enum {
- SIGNAL_QUALITY,
- REGISTRATION_STATE_CHANGED,
- ACTIVATION_STATE_CHANGED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-/*****************************************************************************/
-
-static void
-str_call_done (MMModem *modem, const char *result, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, result);
-}
-
-static void
-str_call_not_supported (MMModemCdma *self,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_string_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
-
- mm_callback_info_schedule (info);
-}
-
-static void
-uint_op_not_supported (MMModem *self,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_uint_new (self, callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-static void
-uint_call_done (MMModem *modem, guint32 result, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, result);
-}
-
-static void
-serving_system_call_done (MMModemCdma *self,
- guint32 class,
- unsigned char band,
- guint32 sid,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else {
- GValueArray *array;
- GValue value = { 0, };
- char band_str[2] = { 0, 0 };
-
- array = g_value_array_new (3);
-
- /* Band Class */
- g_value_init (&value, G_TYPE_UINT);
- g_value_set_uint (&value, class);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- /* Band */
- g_value_init (&value, G_TYPE_STRING);
- band_str[0] = band;
- g_value_set_string (&value, band_str);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- /* SID */
- g_value_init (&value, G_TYPE_UINT);
- g_value_set_uint (&value, sid);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- dbus_g_method_return (context, array);
-
- g_value_array_free (array);
- }
-}
-
-static void
-serving_system_invoke (MMCallbackInfo *info)
-{
- MMModemCdmaServingSystemFn callback = (MMModemCdmaServingSystemFn) info->callback;
-
- callback (MM_MODEM_CDMA (info->modem), 0, 0, 0, info->error, info->user_data);
-}
-
-static void
-serving_system_call_not_supported (MMModemCdma *self,
- MMModemCdmaServingSystemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self), serving_system_invoke, G_CALLBACK (callback), user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
-
- mm_callback_info_schedule (info);
-}
-
-void
-mm_modem_cdma_get_serving_system (MMModemCdma *self,
- MMModemCdmaServingSystemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_CDMA (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_CDMA_GET_INTERFACE (self)->get_serving_system)
- MM_MODEM_CDMA_GET_INTERFACE (self)->get_serving_system (self, callback, user_data);
- else
- serving_system_call_not_supported (self, callback, user_data);
-}
-
-static void
-impl_modem_cdma_get_serving_system (MMModemCdma *modem,
- DBusGMethodInvocation *context)
-{
- mm_modem_cdma_get_serving_system (modem, serving_system_call_done, context);
-}
-
-void
-mm_modem_cdma_get_esn (MMModemCdma *self,
- MMModemStringFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_CDMA (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_CDMA_GET_INTERFACE (self)->get_esn)
- MM_MODEM_CDMA_GET_INTERFACE (self)->get_esn (self, callback, user_data);
- else
- str_call_not_supported (self, callback, user_data);
-}
-
-static void
-esn_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemCdma *self = MM_MODEM_CDMA (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise get the ESN */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_cdma_get_esn (self, str_call_done, context);
-}
-
-static void
-impl_modem_cdma_get_esn (MMModemCdma *self, DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to get the ESN */
- if (!mm_modem_auth_request (MM_MODEM (self),
- MM_AUTHORIZATION_DEVICE_INFO,
- context,
- esn_auth_cb,
- NULL,
- NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-void
-mm_modem_cdma_get_signal_quality (MMModemCdma *self,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_CDMA (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_CDMA_GET_INTERFACE (self)->get_signal_quality)
- MM_MODEM_CDMA_GET_INTERFACE (self)->get_signal_quality (self, callback, user_data);
- else
- uint_op_not_supported (MM_MODEM (self), callback, user_data);
-}
-
-static void
-impl_modem_cdma_get_signal_quality (MMModemCdma *modem, DBusGMethodInvocation *context)
-{
- mm_modem_cdma_get_signal_quality (modem, uint_call_done, context);
-}
-
-void
-mm_modem_cdma_emit_signal_quality_changed (MMModemCdma *self, guint32 quality)
-{
- g_return_if_fail (MM_IS_MODEM_CDMA (self));
-
- g_signal_emit (self, signals[SIGNAL_QUALITY], 0, quality);
-}
-
-void mm_modem_cdma_activate(MMModemCdma *self, MMModemUIntFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_CDMA (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_CDMA_GET_INTERFACE (self)->activate)
- MM_MODEM_CDMA_GET_INTERFACE (self)->activate(self, callback, user_data);
- else
- uint_op_not_supported (MM_MODEM (self), callback, user_data);
-}
-
-static void impl_modem_cdma_activate(MMModemCdma *modem,
- DBusGMethodInvocation *context)
-{
- mm_modem_cdma_activate (modem, uint_call_done, context);
-}
-
-
-void mm_modem_cdma_activate_manual(MMModemCdma *self, MMModemUIntFn callback,
- gpointer user_data) {
- g_return_if_fail (MM_IS_MODEM_CDMA (self));
- g_return_if_fail (callback != NULL);
- if (MM_MODEM_CDMA_GET_INTERFACE (self)->activate_manual)
- MM_MODEM_CDMA_GET_INTERFACE (self)->activate_manual(self, callback, user_data);
- else
- uint_op_not_supported (MM_MODEM (self), callback, user_data);
-}
-static void impl_modem_cdma_activate_manual (MMModemCdma *modem,
- DBusGMethodInvocation *context) {
- mm_modem_cdma_activate_manual(modem, uint_call_done, context);
-}
-
-/*****************************************************************************/
-
-static void
-get_registration_state_call_done (MMModemCdma *self,
- MMModemCdmaRegistrationState cdma_1x_reg_state,
- MMModemCdmaRegistrationState evdo_reg_state,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, cdma_1x_reg_state, evdo_reg_state);
-}
-
-void
-mm_modem_cdma_get_registration_state (MMModemCdma *self,
- MMModemCdmaRegistrationStateFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_CDMA (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_CDMA_GET_INTERFACE (self)->get_registration_state)
- MM_MODEM_CDMA_GET_INTERFACE (self)->get_registration_state (self, callback, user_data);
- else {
- GError *error;
-
- error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
-
- callback (self,
- MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
- MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
- error,
- user_data);
-
- g_error_free (error);
- }
-}
-
-static void
-impl_modem_cdma_get_registration_state (MMModemCdma *modem, DBusGMethodInvocation *context)
-{
- mm_modem_cdma_get_registration_state (modem, get_registration_state_call_done, context);
-}
-
-void
-mm_modem_cdma_emit_registration_state_changed (MMModemCdma *self,
- MMModemCdmaRegistrationState cdma_1x_new_state,
- MMModemCdmaRegistrationState evdo_new_state)
-{
- g_return_if_fail (MM_IS_MODEM_CDMA (self));
-
- g_signal_emit (self, signals[REGISTRATION_STATE_CHANGED], 0, cdma_1x_new_state, evdo_new_state);
-}
-
-/*****************************************************************************/
-
-#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
-
-static void
-mm_modem_cdma_init (gpointer g_iface)
-{
- GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
-
- /* Properties */
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_CDMA_MEID,
- "MEID",
- "MEID",
- NULL,
- G_PARAM_READABLE));
-
- /* Signals */
- signals[SIGNAL_QUALITY] =
- g_signal_new ("signal-quality",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MMModemCdma, signal_quality),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1, G_TYPE_UINT);
-
- signals[REGISTRATION_STATE_CHANGED] =
- g_signal_new ("registration-state-changed",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MMModemCdma, registration_state_changed),
- NULL, NULL,
- mm_marshal_VOID__UINT_UINT,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-
- signals[ACTIVATION_STATE_CHANGED] =
- g_signal_new ("activation-state-changed",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MMModemCdma, registration_state_changed),
- NULL, NULL,
- mm_marshal_VOID__UINT_UINT_BOXED,
- G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, DBUS_TYPE_G_MAP_OF_VARIANT);
-
- initialized = TRUE;
-}
-
-GType
-mm_modem_cdma_get_type (void)
-{
- static GType modem_type = 0;
-
- if (!G_UNLIKELY (modem_type)) {
- const GTypeInfo modem_info = {
- sizeof (MMModemCdma), /* class_size */
- mm_modem_cdma_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- modem_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModemCdma",
- &modem_info, 0);
-
- g_type_interface_add_prerequisite (modem_type, MM_TYPE_MODEM);
-
- dbus_g_object_type_install_info (modem_type, &dbus_glib_mm_modem_cdma_object_info);
- }
-
- return modem_type;
-}
diff --git a/src/mm-modem-cdma.h b/src/mm-modem-cdma.h
deleted file mode 100644
index 8412458c..00000000
--- a/src/mm-modem-cdma.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#ifndef MM_MODEM_CDMA_H
-#define MM_MODEM_CDMA_H
-
-#include <ModemManager.h>
-#include <mm-modem.h>
-
-#define MM_TYPE_MODEM_CDMA (mm_modem_cdma_get_type ())
-#define MM_MODEM_CDMA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_CDMA, MMModemCdma))
-#define MM_IS_MODEM_CDMA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_CDMA))
-#define MM_MODEM_CDMA_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_CDMA, MMModemCdma))
-
-#define MM_MODEM_CDMA_REGISTRATION_STATE_CHANGED "registration-state-changed"
-
-#define MM_MODEM_CDMA_MEID "meid"
-
-typedef enum {
- MM_MODEM_CDMA_PROP_FIRST = 0x1200,
-
- MM_MODEM_CDMA_PROP_MEID = MM_MODEM_CDMA_PROP_FIRST,
-} MMModemCdmaProp;
-
-typedef struct _MMModemCdma MMModemCdma;
-
-typedef void (*MMModemCdmaServingSystemFn) (MMModemCdma *modem,
- guint32 class,
- unsigned char band,
- guint32 sid,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemCdmaRegistrationStateFn) (MMModemCdma *modem,
- MMModemCdmaRegistrationState cdma_1x_reg_state,
- MMModemCdmaRegistrationState evdo_reg_state,
- GError *error,
- gpointer user_data);
-
-struct _MMModemCdma {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*get_signal_quality) (MMModemCdma *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- void (*get_esn) (MMModemCdma *self,
- MMModemStringFn callback,
- gpointer user_data);
-
- void (*get_serving_system) (MMModemCdma *self,
- MMModemCdmaServingSystemFn callback,
- gpointer user_data);
-
- void (*get_registration_state) (MMModemCdma *self,
- MMModemCdmaRegistrationStateFn callback,
- gpointer user_data);
-
- void (*activate) (MMModemCdma *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- void (*activate_manual) (MMModemCdma *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- void (*activate_manual_debug) (MMModemCdma *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- /* Signals */
- void (*signal_quality) (MMModemCdma *self,
- guint32 quality);
-
- void (*registration_state_changed) (MMModemCdma *self,
- MMModemCdmaRegistrationState cdma_1x_new_state,
- MMModemCdmaRegistrationState evdo_new_state);
-};
-
-GType mm_modem_cdma_get_type (void);
-
-void mm_modem_cdma_get_signal_quality (MMModemCdma *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
-void mm_modem_cdma_get_esn (MMModemCdma *self,
- MMModemStringFn callback,
- gpointer user_data);
-
-void mm_modem_cdma_get_serving_system (MMModemCdma *self,
- MMModemCdmaServingSystemFn callback,
- gpointer user_data);
-
-void mm_modem_cdma_get_registration_state (MMModemCdma *self,
- MMModemCdmaRegistrationStateFn callback,
- gpointer user_data);
-
-void mm_modem_cdma_activate (MMModemCdma *self, MMModemUIntFn callback,
- gpointer user_data);
-
-void mm_modem_cdma_activate_manual (MMModemCdma *self, MMModemUIntFn callback,
- gpointer user_data);
-
-/* Protected */
-
-void mm_modem_cdma_emit_signal_quality_changed (MMModemCdma *self, guint32 new_quality);
-
-void mm_modem_cdma_emit_registration_state_changed (MMModemCdma *self,
- MMModemCdmaRegistrationState cdma_1x_new_state,
- MMModemCdmaRegistrationState evdo_new_state);
-
-#endif /* MM_MODEM_CDMA_H */
diff --git a/src/mm-modem-firmware.c b/src/mm-modem-firmware.c
deleted file mode 100644
index 74440fda..00000000
--- a/src/mm-modem-firmware.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2011 The Chromium OS Authors
- */
-
-#include <string.h>
-#include <dbus/dbus-glib.h>
-
-#include "mm-modem-firmware.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-marshal.h"
-
-static void impl_modem_firmware_list (MMModemFirmware *modem,
- DBusGMethodInvocation *context);
-
-static void impl_modem_firmware_select (MMModemFirmware *modem,
- const char *slot,
- DBusGMethodInvocation *context);
-
-static void impl_modem_firmware_install (MMModemFirmware *modem,
- const char *image,
- const char *slot,
- DBusGMethodInvocation *context);
-
-#include "mm-modem-firmware-glue.h"
-
-static void
-async_call_done (MMModem *modem, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context);
-}
-
-static void
-async_call_not_supported (MMModemFirmware *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-static void
-firmware_list_done (MMModemFirmware *self,
- const char *selected,
- GHashTable *installed,
- GHashTable *available,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, selected, installed, available);
-}
-
-/*****************************************************************************/
-
-static void
-firmware_list_invoke (MMCallbackInfo *info)
-{
- MMModemFirmwareListFn callback = (MMModemFirmwareListFn) info->callback;
-
- callback (MM_MODEM_FIRMWARE (info->modem), NULL, NULL, NULL, info->error, info->user_data);
-}
-
-void
-mm_modem_firmware_list (MMModemFirmware *self,
- MMModemFirmwareListFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_FIRMWARE (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_FIRMWARE_GET_INTERFACE (self)->list)
- MM_MODEM_FIRMWARE_GET_INTERFACE (self)->list (self, callback, user_data);
- else {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self),
- firmware_list_invoke,
- G_CALLBACK (callback),
- user_data);
-
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-void
-mm_modem_firmware_select (MMModemFirmware *self,
- const char *slot,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_FIRMWARE (self));
- g_return_if_fail (slot != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_FIRMWARE_GET_INTERFACE (self)->select)
- MM_MODEM_FIRMWARE_GET_INTERFACE (self)->select (self, slot, callback, user_data);
- else
- async_call_not_supported (self, async_call_done, user_data);
-}
-
-void
-mm_modem_firmware_install (MMModemFirmware *self,
- const char *image,
- const char *slot,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_FIRMWARE (self));
- g_return_if_fail (slot != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_FIRMWARE_GET_INTERFACE (self)->install)
- MM_MODEM_FIRMWARE_GET_INTERFACE (self)->install (self, image, slot, callback, user_data);
- else
- async_call_not_supported (self, async_call_done, user_data);
-}
-
-typedef struct {
- char *image;
- char *slot;
-} FirmwareAuthInfo;
-
-static void
-firmware_auth_info_destroy (gpointer data)
-{
- FirmwareAuthInfo *info = data;
-
- g_free (info->image);
- g_free (info->slot);
- memset (info, 0, sizeof (FirmwareAuthInfo));
- g_free (info);
-}
-
-static FirmwareAuthInfo *
-firmware_auth_info_new (const char *image,
- const char *slot)
-{
- FirmwareAuthInfo *info;
-
- info = g_malloc0 (sizeof (FirmwareAuthInfo));
- info->image = g_strdup(image);
- info->slot = g_strdup(slot);
-
- return info;
-}
-
-static void
-firmware_list_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemFirmware *self = MM_MODEM_FIRMWARE (owner);
- GError *error = NULL;
-
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_firmware_list (self, firmware_list_done, context);
-}
-
-static void
-impl_modem_firmware_list (MMModemFirmware *modem, DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_FIRMWARE,
- context,
- firmware_list_auth_cb,
- NULL,
- NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free(error);
- }
-}
-
-static void
-firmware_select_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemFirmware *self = MM_MODEM_FIRMWARE (owner);
- FirmwareAuthInfo *info = user_data;
- const char *slot = info->slot;
- GError *error = NULL;
-
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_firmware_select (self, slot, async_call_done, context);
-}
-
-static void
-impl_modem_firmware_select (MMModemFirmware *modem,
- const char *slot,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- FirmwareAuthInfo *info;
-
- info = firmware_auth_info_new (NULL, slot);
-
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_FIRMWARE,
- context,
- firmware_select_auth_cb,
- info,
- firmware_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-static void
-firmware_install_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemFirmware *self = MM_MODEM_FIRMWARE (owner);
- FirmwareAuthInfo *info = user_data;
- const char *image = info->image;
- const char *slot = info->slot;
- GError *error = NULL;
-
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_firmware_install (self, image, slot, async_call_done, context);
-}
-
-static void
-impl_modem_firmware_install (MMModemFirmware *modem,
- const char *image,
- const char *slot,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- FirmwareAuthInfo *info;
-
- info = firmware_auth_info_new (image, slot);
-
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_FIRMWARE,
- context,
- firmware_install_auth_cb,
- info,
- firmware_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-GType
-mm_modem_firmware_get_type (void)
-{
- static GType firmware_type = 0;
-
- if (!G_UNLIKELY (firmware_type)) {
- const GTypeInfo firmware_info = {
- sizeof (MMModemFirmware), /* class_size */
- NULL, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- firmware_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModemFirmware",
- &firmware_info, 0);
-
- g_type_interface_add_prerequisite (firmware_type, G_TYPE_OBJECT);
- dbus_g_object_type_install_info (firmware_type, &dbus_glib_mm_modem_firmware_object_info);
- }
-
- return firmware_type;
-}
diff --git a/src/mm-modem-firmware.h b/src/mm-modem-firmware.h
deleted file mode 100644
index 7e69155b..00000000
--- a/src/mm-modem-firmware.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2011 The Chromium OS Authors
- */
-
-#ifndef MM_MODEM_FIRMWARE_H
-#define MM_MODEM_FIRMWARE_H
-
-#include <mm-modem.h>
-
-#define MM_TYPE_MODEM_FIRMWARE (mm_modem_firmware_get_type ())
-#define MM_MODEM_FIRMWARE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_FIRMWARE, MMModemFirmware))
-#define MM_IS_MODEM_FIRMWARE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_FIRMWARE))
-#define MM_MODEM_FIRMWARE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_FIRMWARE, MMModemFirmware))
-
-typedef struct _MMModemFirmware MMModemFirmware;
-
-typedef void (*MMModemFirmwareListFn) (MMModemFirmware *modem,
- const char *selected,
- GHashTable *installed,
- GHashTable *available,
- GError *error,
- gpointer user_data);
-
-struct _MMModemFirmware {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*list) (MMModemFirmware *modem,
- MMModemFirmwareListFn callback,
- gpointer user_data);
-
- void (*select) (MMModemFirmware *modem,
- const char *slot,
- MMModemFn callback,
- gpointer user_data);
-
- void (*install) (MMModemFirmware *modem,
- const char *image,
- const char *slot,
- MMModemFn callback,
- gpointer user_data);
-};
-
-GType mm_modem_firmware_get_type (void);
-
-void mm_modem_firmware_list (MMModemFirmware *self,
- MMModemFirmwareListFn callback,
- gpointer user_data);
-
-void mm_modem_firmware_select (MMModemFirmware *self,
- const char *slot,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_firmware_install (MMModemFirmware *self,
- const char *image,
- const char *slot,
- MMModemFn callback,
- gpointer user_data);
-
-#endif /* MM_MODEM_FIRMWARE_H */
diff --git a/src/mm-modem-gsm-card.c b/src/mm-modem-gsm-card.c
deleted file mode 100644
index abf642af..00000000
--- a/src/mm-modem-gsm-card.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#include <dbus/dbus-glib.h>
-#include <string.h>
-
-#include <ModemManager.h>
-
-#include "mm-modem-gsm-card.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-
-static void impl_gsm_modem_get_imei (MMModemGsmCard *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_get_imsi (MMModemGsmCard *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_get_operator_id (MMModemGsmCard *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_get_spn (MMModemGsmCard *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_send_pin (MMModemGsmCard *modem,
- const char *pin,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_send_puk (MMModemGsmCard *modem,
- const char *puk,
- const char *pin,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_enable_pin (MMModemGsmCard *modem,
- const char *pin,
- gboolean enabled,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_change_pin (MMModemGsmCard *modem,
- const char *old_pin,
- const char *new_pin,
- DBusGMethodInvocation *context);
-
-#include "mm-modem-gsm-card-glue.h"
-
-/*****************************************************************************/
-
-static void
-str_call_done (MMModem *modem, const char *result, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, result);
-}
-
-static void
-str_call_not_supported (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_string_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
-
- mm_callback_info_schedule (info);
-}
-
-static void
-array_call_not_supported (MMModemGsmCard *self,
- MMModemArrayFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_array_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-static void
-async_call_done (MMModem *modem, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context);
-}
-
-static void
-async_call_not_supported (MMModemGsmCard *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-/*****************************************************************************/
-
-void
-mm_modem_gsm_card_get_imei (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_imei)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_imei (self, callback, user_data);
- else
- str_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_card_get_imsi (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_imsi)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_imsi (self, callback, user_data);
- else
- str_call_not_supported (self, callback, user_data);
-}
-
-void mm_modem_gsm_card_get_unlock_retries (MMModemGsmCard *self,
- MMModemArrayFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_unlock_retries)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_unlock_retries (self, callback, user_data);
- else
- array_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_card_get_operator_id (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_operator_id)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_operator_id (self, callback, user_data);
- else
- str_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_card_get_spn (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_spn)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->get_spn (self, callback, user_data);
- else
- str_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_card_send_puk (MMModemGsmCard *self,
- const char *puk,
- const char *pin,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (puk != NULL);
- g_return_if_fail (pin != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->send_puk)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->send_puk (self, puk, pin, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_card_send_pin (MMModemGsmCard *self,
- const char *pin,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (pin != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->send_pin)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->send_pin (self, pin, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_card_enable_pin (MMModemGsmCard *self,
- const char *pin,
- gboolean enabled,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (pin != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->enable_pin)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->enable_pin (self, pin, enabled, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_card_change_pin (MMModemGsmCard *self,
- const char *old_pin,
- const char *new_pin,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_CARD (self));
- g_return_if_fail (old_pin != NULL);
- g_return_if_fail (new_pin != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_CARD_GET_INTERFACE (self)->change_pin)
- MM_MODEM_GSM_CARD_GET_INTERFACE (self)->change_pin (self, old_pin, new_pin, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-/*****************************************************************************/
-
-static void
-imei_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise get the IMEI */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_card_get_imei (self, str_call_done, context);
-}
-
-static void
-impl_gsm_modem_get_imei (MMModemGsmCard *modem, DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to get the IMEI */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_INFO,
- context,
- imei_auth_cb,
- NULL,
- NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-imsi_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise get the IMSI */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_card_get_imsi (self, str_call_done, context);
-}
-
-static void
-impl_gsm_modem_get_imsi (MMModemGsmCard *modem, DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to get the IMSI */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_INFO,
- context,
- imsi_auth_cb,
- NULL,
- NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-spn_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise get the SPN */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_card_get_spn (self, str_call_done, context);
-}
-
-static void
-impl_gsm_modem_get_spn (MMModemGsmCard *modem, DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to get the SPN */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_INFO,
- context,
- spn_auth_cb,
- NULL,
- NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-operator_id_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise get the operator id */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_card_get_operator_id (self, str_call_done, context);
-}
-
-static void
-impl_gsm_modem_get_operator_id (MMModemGsmCard *modem, DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to get the operator id */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_INFO,
- context,
- operator_id_auth_cb,
- NULL,
- NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-typedef struct {
- char *puk;
- char *pin;
- char *pin2;
- gboolean enabled;
-} SendPinPukInfo;
-
-static void
-send_pin_puk_info_destroy (gpointer data)
-{
- SendPinPukInfo *info = data;
-
- g_free (info->puk);
- g_free (info->pin);
- g_free (info->pin2);
- memset (info, 0, sizeof (SendPinPukInfo));
- g_free (info);
-}
-
-static SendPinPukInfo *
-send_pin_puk_info_new (const char *puk,
- const char *pin,
- const char *pin2,
- gboolean enabled)
-{
- SendPinPukInfo *info;
-
- info = g_malloc0 (sizeof (SendPinPukInfo));
- info->puk = g_strdup (puk);
- info->pin = g_strdup (pin);
- info->pin2 = g_strdup (pin2);
- info->enabled = enabled;
- return info;
-}
-
-/*****************************************************************************/
-
-static void
-send_puk_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
- SendPinPukInfo *info = user_data;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise send the PUK */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_card_send_puk (self, info->puk, info->pin, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_send_puk (MMModemGsmCard *modem,
- const char *puk,
- const char *pin,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SendPinPukInfo *info;
-
- info = send_pin_puk_info_new (puk, pin, NULL, FALSE);
-
- /* Make sure the caller is authorized to send the PUK */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_CONTROL,
- context,
- send_puk_auth_cb,
- info,
- send_pin_puk_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-send_pin_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
- SendPinPukInfo *info = user_data;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise unlock the modem */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_card_send_pin (self, info->pin, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_send_pin (MMModemGsmCard *modem,
- const char *pin,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SendPinPukInfo *info;
-
- info = send_pin_puk_info_new (NULL, pin, NULL, FALSE);
-
- /* Make sure the caller is authorized to unlock the modem */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_CONTROL,
- context,
- send_pin_auth_cb,
- info,
- send_pin_puk_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-enable_pin_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
- SendPinPukInfo *info = user_data;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise enable the PIN */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_card_enable_pin (self, info->pin, info->enabled, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_enable_pin (MMModemGsmCard *modem,
- const char *pin,
- gboolean enabled,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SendPinPukInfo *info;
-
- info = send_pin_puk_info_new (NULL, pin, NULL, enabled);
-
- /* Make sure the caller is authorized to enable a PIN */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_CONTROL,
- context,
- enable_pin_auth_cb,
- info,
- send_pin_puk_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-change_pin_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmCard *self = MM_MODEM_GSM_CARD (owner);
- SendPinPukInfo *info = user_data;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise change the PIN */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_card_change_pin (self, info->pin, info->pin2, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_change_pin (MMModemGsmCard *modem,
- const char *old_pin,
- const char *new_pin,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SendPinPukInfo *info;
-
- info = send_pin_puk_info_new (NULL, old_pin, new_pin, FALSE);
-
- /* Make sure the caller is authorized to change the PIN */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_CONTROL,
- context,
- change_pin_auth_cb,
- info,
- send_pin_puk_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-mm_modem_gsm_card_init (gpointer g_iface)
-{
- static gboolean initialized = FALSE;
-
- if (G_LIKELY (initialized))
- return;
-
- initialized = TRUE;
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_GSM_CARD_SIM_IDENTIFIER,
- "SimIdentifier",
- "An obfuscated identifier of the SIM",
- NULL,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_GSM_CARD_SUPPORTED_BANDS,
- "Supported Modes",
- "Supported frequency bands of the card",
- MM_MODEM_GSM_BAND_UNKNOWN,
- G_MAXUINT32,
- MM_MODEM_GSM_BAND_UNKNOWN,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_GSM_CARD_SUPPORTED_MODES,
- "Supported Modes",
- "Supported modes of the card (ex 2G preferred, 3G preferred, 2G only, etc",
- MM_MODEM_GSM_MODE_UNKNOWN,
- G_MAXUINT32,
- MM_MODEM_GSM_MODE_UNKNOWN,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_GSM_CARD_ENABLED_FACILITY_LOCKS,
- "Enabled Facility Locks",
- "Facility locks (i.e. PINs) that are enabled",
- MM_MODEM_GSM_FACILITY_NONE,
- G_MAXUINT32,
- MM_MODEM_GSM_FACILITY_NONE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-}
-
-GType
-mm_modem_gsm_card_get_type (void)
-{
- static GType card_type = 0;
-
- if (G_UNLIKELY (!card_type)) {
- const GTypeInfo card_info = {
- sizeof (MMModemGsmCard), /* class_size */
- mm_modem_gsm_card_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- card_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModemGsmCard",
- &card_info, 0);
-
- g_type_interface_add_prerequisite (card_type, G_TYPE_OBJECT);
- g_type_interface_add_prerequisite (card_type, MM_TYPE_MODEM);
- dbus_g_object_type_install_info (card_type, &dbus_glib_mm_modem_gsm_card_object_info);
- }
-
- return card_type;
-}
diff --git a/src/mm-modem-gsm-card.h b/src/mm-modem-gsm-card.h
deleted file mode 100644
index e6e39dd1..00000000
--- a/src/mm-modem-gsm-card.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#ifndef MM_MODEM_GSM_CARD_H
-#define MM_MODEM_GSM_CARD_H
-
-#include <mm-modem.h>
-
-#define MM_MODEM_GSM_CARD_DBUS_INTERFACE "org.freedesktop.ModemManager.Modem.Gsm.Card"
-
-#define MM_TYPE_MODEM_GSM_CARD (mm_modem_gsm_card_get_type ())
-#define MM_MODEM_GSM_CARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_GSM_CARD, MMModemGsmCard))
-#define MM_IS_MODEM_GSM_CARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_GSM_CARD))
-#define MM_MODEM_GSM_CARD_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_GSM_CARD, MMModemGsmCard))
-
-#define MM_MODEM_GSM_CARD_SUPPORTED_BANDS "supported-bands"
-#define MM_MODEM_GSM_CARD_SUPPORTED_MODES "supported-modes"
-#define MM_MODEM_GSM_CARD_SIM_IDENTIFIER "sim-identifier"
-#define MM_MODEM_GSM_CARD_ENABLED_FACILITY_LOCKS "enabled-facility-locks"
-
-#define MM_MODEM_GSM_CARD_SIM_PIN "sim-pin"
-#define MM_MODEM_GSM_CARD_SIM_PIN2 "sim-pin2"
-#define MM_MODEM_GSM_CARD_SIM_PUK "sim-puk"
-#define MM_MODEM_GSM_CARD_SIM_PUK2 "sim-puk2"
-
-typedef struct _MMModemGsmCard MMModemGsmCard;
-
-struct _MMModemGsmCard {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*get_imei) (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data);
-
- void (*get_imsi) (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data);
-
- void (*get_unlock_retries) (MMModemGsmCard *self,
- MMModemArrayFn callback,
- gpointer user_data);
-
- void (*get_operator_id) (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data);
-
- void (*get_spn) (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data);
-
- void (*send_puk) (MMModemGsmCard *self,
- const char *puk,
- const char *pin,
- MMModemFn callback,
- gpointer user_data);
-
- void (*send_pin) (MMModemGsmCard *self,
- const char *pin,
- MMModemFn callback,
- gpointer user_data);
-
- void (*enable_pin) (MMModemGsmCard *self,
- const char *pin,
- gboolean enabled,
- MMModemFn callback,
- gpointer user_data);
-
- void (*change_pin) (MMModemGsmCard *self,
- const char *old_pin,
- const char *new_pin,
- MMModemFn callback,
- gpointer user_data);
-};
-
-GType mm_modem_gsm_card_get_type (void);
-
-void mm_modem_gsm_card_get_imei (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_card_get_imsi (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_card_get_unlock_retries (MMModemGsmCard *self,
- MMModemArrayFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_card_get_operator_id (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_card_get_spn (MMModemGsmCard *self,
- MMModemStringFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_card_send_puk (MMModemGsmCard *self,
- const char *puk,
- const char *pin,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_card_send_pin (MMModemGsmCard *self,
- const char *pin,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_card_enable_pin (MMModemGsmCard *self,
- const char *pin,
- gboolean enabled,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_card_change_pin (MMModemGsmCard *self,
- const char *old_pin,
- const char *new_pin,
- MMModemFn callback,
- gpointer user_data);
-
-#endif /* MM_MODEM_GSM_CARD_H */
diff --git a/src/mm-modem-gsm-network.c b/src/mm-modem-gsm-network.c
deleted file mode 100644
index 2863aafd..00000000
--- a/src/mm-modem-gsm-network.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2010 Red Hat, Inc.
- */
-
-#include <string.h>
-#include <dbus/dbus-glib.h>
-
-#include "mm-modem-gsm-network.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-marshal.h"
-#include "mm-utils.h"
-
-static void impl_gsm_modem_register (MMModemGsmNetwork *modem,
- const char *network_id,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_scan (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_set_apn (MMModemGsmNetwork *modem,
- const char *apn,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_get_signal_quality (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_set_band (MMModemGsmNetwork *modem,
- MMModemGsmBand band,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_get_band (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_set_allowed_mode (MMModemGsmNetwork *modem,
- MMModemGsmAllowedMode mode,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_set_network_mode (MMModemGsmNetwork *modem,
- MMModemGsmNetworkDeprecatedMode old_mode,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_get_network_mode (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_get_reg_info (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context);
-
-#include "mm-modem-gsm-network-glue.h"
-
-/*****************************************************************************/
-
-enum {
- SIGNAL_QUALITY,
- REGISTRATION_INFO,
- NETWORK_MODE,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-/*****************************************************************************/
-
-MMModemGsmAllowedMode
-mm_modem_gsm_network_old_mode_to_allowed (MMModemGsmNetworkDeprecatedMode old_mode)
-{
- /* Translate deprecated mode into new mode */
- switch (old_mode) {
- case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_PREFERRED:
- return MM_MODEM_GSM_ALLOWED_MODE_2G_PREFERRED;
- case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_PREFERRED:
- return MM_MODEM_GSM_ALLOWED_MODE_3G_PREFERRED;
- case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_2G_ONLY:
- return MM_MODEM_GSM_ALLOWED_MODE_2G_ONLY;
- case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_3G_ONLY:
- return MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY;
- case MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY:
- default:
- return MM_MODEM_GSM_ALLOWED_MODE_ANY;
- }
-}
-
-MMModemGsmNetworkDeprecatedMode
-mm_modem_gsm_network_act_to_old_mode (MMModemGsmAccessTech act)
-{
- /* Translate new mode into old deprecated mode */
- if (act & MM_MODEM_GSM_ACCESS_TECH_GPRS)
- return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_GPRS;
- else if (act & MM_MODEM_GSM_ACCESS_TECH_EDGE)
- return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_EDGE;
- else if (act & MM_MODEM_GSM_ACCESS_TECH_UMTS)
- return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_UMTS;
- else if (act & MM_MODEM_GSM_ACCESS_TECH_HSDPA)
- return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSDPA;
- else if (act & MM_MODEM_GSM_ACCESS_TECH_HSUPA)
- return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSUPA;
- else if (act & MM_MODEM_GSM_ACCESS_TECH_HSPA)
- return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA;
- else if (act & MM_MODEM_GSM_ACCESS_TECH_HSPA_PLUS)
- return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_HSPA;
-
- return MM_MODEM_GSM_NETWORK_DEPRECATED_MODE_ANY;
-}
-
-/*****************************************************************************/
-
-static void
-async_call_done (MMModem *modem, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context);
-}
-
-static void
-async_call_not_supported (MMModemGsmNetwork *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-static void
-uint_call_done (MMModem *modem, guint32 result, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, result);
-}
-
-static void
-uint_call_not_supported (MMModemGsmNetwork *self,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-static void
-reg_info_call_done (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegStatus status,
- const char *oper_code,
- const char *oper_name,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else {
- GValueArray *array;
- GValue value = { 0, };
-
- array = g_value_array_new (3);
-
- /* Status */
- g_value_init (&value, G_TYPE_UINT);
- g_value_set_uint (&value, (guint32) status);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- /* Operator code */
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, oper_code);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- /* Operator name */
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, oper_name);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- dbus_g_method_return (context, array);
-
- g_value_array_free (array);
- }
-}
-
-static void
-reg_info_invoke (MMCallbackInfo *info)
-{
- MMModemGsmNetworkRegInfoFn callback = (MMModemGsmNetworkRegInfoFn) info->callback;
-
- callback (MM_MODEM_GSM_NETWORK (info->modem), 0, NULL, NULL, info->error, info->user_data);
-}
-
-static void
-reg_info_call_not_supported (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegInfoFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self), reg_info_invoke, G_CALLBACK (callback), user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
-
- mm_callback_info_schedule (info);
-}
-
-static void
-scan_call_done (MMModemGsmNetwork *self,
- GPtrArray *results,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, results);
-}
-
-static void
-gsm_network_scan_invoke (MMCallbackInfo *info)
-{
- MMModemGsmNetworkScanFn callback = (MMModemGsmNetworkScanFn) info->callback;
-
- callback (MM_MODEM_GSM_NETWORK (info->modem), NULL, info->error, info->user_data);
-}
-
-static void
-scan_call_not_supported (MMModemGsmNetwork *self,
- MMModemGsmNetworkScanFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self), gsm_network_scan_invoke, G_CALLBACK (callback), user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
-
- mm_callback_info_schedule (info);
-}
-
-/*****************************************************************************/
-
-void
-mm_modem_gsm_network_register (MMModemGsmNetwork *self,
- const char *network_id,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->do_register)
- MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->do_register (self, network_id, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_network_scan (MMModemGsmNetwork *self,
- MMModemGsmNetworkScanFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->scan)
- MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->scan (self, callback, user_data);
- else
- scan_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_network_set_apn (MMModemGsmNetwork *self,
- const char *apn,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
- g_return_if_fail (apn != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_apn)
- MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_apn (self, apn, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_network_get_signal_quality (MMModemGsmNetwork *self,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->get_signal_quality)
- MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->get_signal_quality (self, callback, user_data);
- else
- uint_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_network_set_band (MMModemGsmNetwork *self,
- MMModemGsmBand band,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_band)
- MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_band (self, band, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_network_get_band (MMModemGsmNetwork *self,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->get_band)
- MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->get_band (self, callback, user_data);
- else
- uint_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_network_set_allowed_mode (MMModemGsmNetwork *self,
- MMModemGsmAllowedMode mode,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_allowed_mode)
- MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->set_allowed_mode (self, mode, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_network_get_registration_info (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegInfoFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->get_registration_info)
- MM_MODEM_GSM_NETWORK_GET_INTERFACE (self)->get_registration_info (self, callback, user_data);
- else
- reg_info_call_not_supported (self, callback, user_data);
-}
-
-void
-mm_modem_gsm_network_signal_quality (MMModemGsmNetwork *self,
- guint32 quality)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
-
- g_signal_emit (self, signals[SIGNAL_QUALITY], 0, quality);
-}
-
-void
-mm_modem_gsm_network_registration_info (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegStatus status,
- const char *oper_code,
- const char *oper_name)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_NETWORK (self));
-
- g_signal_emit (self, signals[REGISTRATION_INFO], 0, status,
- oper_code ? oper_code : "",
- oper_name ? oper_name : "");
-}
-
-/*****************************************************************************/
-
-static void
-impl_gsm_modem_register (MMModemGsmNetwork *modem,
- const char *network_id,
- DBusGMethodInvocation *context)
-{
- const char *id;
-
- /* DBus does not support NULL strings, so the caller should pass an empty string
- for manual registration. */
- if (strlen (network_id) < 1)
- id = NULL;
- else
- id = network_id;
-
- mm_modem_gsm_network_register (modem, id, async_call_done, context);
-}
-
-static void
-scan_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmNetwork *self = MM_MODEM_GSM_NETWORK (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise get the IMEI */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_network_scan (self, scan_call_done, context);
-}
-
-static void
-impl_gsm_modem_scan (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to request a scan */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_CONTROL,
- context,
- scan_auth_cb,
- NULL,
- NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-static void
-impl_gsm_modem_set_apn (MMModemGsmNetwork *modem,
- const char *apn,
- DBusGMethodInvocation *context)
-{
- mm_modem_gsm_network_set_apn (modem, apn, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_get_signal_quality (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context)
-{
- mm_modem_gsm_network_get_signal_quality (modem, uint_call_done, context);
-}
-
-static void
-impl_gsm_modem_set_band (MMModemGsmNetwork *modem,
- MMModemGsmBand band,
- DBusGMethodInvocation *context)
-{
- mm_modem_gsm_network_set_band (modem, band, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_get_band (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context)
-{
- mm_modem_gsm_network_get_band (modem, uint_call_done, context);
-}
-
-static void
-impl_gsm_modem_set_network_mode (MMModemGsmNetwork *modem,
- MMModemGsmNetworkDeprecatedMode old_mode,
- DBusGMethodInvocation *context)
-{
- if (!utils_check_for_single_value (old_mode)) {
- GError *error;
-
- error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Invalid arguments (more than one value given)");
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- mm_modem_gsm_network_set_allowed_mode (modem,
- mm_modem_gsm_network_old_mode_to_allowed (old_mode),
- async_call_done,
- context);
-}
-
-static void
-impl_gsm_modem_set_allowed_mode (MMModemGsmNetwork *modem,
- MMModemGsmAllowedMode mode,
- DBusGMethodInvocation *context)
-{
- if (mode > MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY) {
- GError *error;
-
- error = g_error_new (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Unknown allowed mode %d", mode);
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- return;
- }
-
- mm_modem_gsm_network_set_allowed_mode (modem, mode, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_get_network_mode (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context)
-{
- MMModemGsmAccessTech act = MM_MODEM_GSM_ACCESS_TECH_UNKNOWN;
-
- /* DEPRECATED; it's now a property so it's quite easy to handle */
- g_object_get (G_OBJECT (modem),
- MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY, &act,
- NULL);
- dbus_g_method_return (context, mm_modem_gsm_network_act_to_old_mode (act));
-}
-
-static void
-impl_gsm_modem_get_reg_info (MMModemGsmNetwork *modem,
- DBusGMethodInvocation *context)
-{
- mm_modem_gsm_network_get_registration_info (modem, reg_info_call_done, context);
-}
-
-/*****************************************************************************/
-
-static void
-mm_modem_gsm_network_init (gpointer g_iface)
-{
- GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
-
- /* Properties */
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_GSM_NETWORK_ALLOWED_MODE,
- "Allowed Mode",
- "Allowed network access mode",
- MM_MODEM_GSM_ALLOWED_MODE_ANY,
- MM_MODEM_GSM_ALLOWED_MODE_3G_ONLY,
- MM_MODEM_GSM_ALLOWED_MODE_ANY,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY,
- "Access Technology",
- "Current access technology in use when connected to "
- "a mobile network.",
- MM_MODEM_GSM_ACCESS_TECH_UNKNOWN,
- MM_MODEM_GSM_ACCESS_TECH_LTE,
- MM_MODEM_GSM_ACCESS_TECH_UNKNOWN,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /* Signals */
- signals[SIGNAL_QUALITY] =
- g_signal_new ("signal-quality",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MMModemGsmNetwork, signal_quality),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1,
- G_TYPE_UINT);
-
- signals[REGISTRATION_INFO] =
- g_signal_new ("registration-info",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MMModemGsmNetwork, registration_info),
- NULL, NULL,
- mm_marshal_VOID__UINT_STRING_STRING,
- G_TYPE_NONE, 3,
- G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
-
- signals[NETWORK_MODE] =
- g_signal_new ("network-mode",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1,
- G_TYPE_UINT);
-
- initialized = TRUE;
-}
-
-GType
-mm_modem_gsm_network_get_type (void)
-{
- static GType network_type = 0;
-
- if (!G_UNLIKELY (network_type)) {
- const GTypeInfo network_info = {
- sizeof (MMModemGsmNetwork), /* class_size */
- mm_modem_gsm_network_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- network_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModemGsmNetwork",
- &network_info, 0);
-
- g_type_interface_add_prerequisite (network_type, G_TYPE_OBJECT);
- g_type_interface_add_prerequisite (network_type, MM_TYPE_MODEM);
- dbus_g_object_type_install_info (network_type, &dbus_glib_mm_modem_gsm_network_object_info);
- }
-
- return network_type;
-}
diff --git a/src/mm-modem-gsm-network.h b/src/mm-modem-gsm-network.h
deleted file mode 100644
index 5b565673..00000000
--- a/src/mm-modem-gsm-network.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 Novell, Inc.
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#ifndef MM_MODEM_GSM_NETWORK_H
-#define MM_MODEM_GSM_NETWORK_H
-
-#include <ModemManager.h>
-#include <mm-modem.h>
-
-#define MM_MODEM_GSM_NETWORK_DBUS_INTERFACE "org.freedesktop.ModemManager.Modem.Gsm.Network"
-
-#define MM_TYPE_MODEM_GSM_NETWORK (mm_modem_gsm_network_get_type ())
-#define MM_MODEM_GSM_NETWORK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_GSM_NETWORK, MMModemGsmNetwork))
-#define MM_IS_MODEM_GSM_NETWORK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_GSM_NETWORK))
-#define MM_MODEM_GSM_NETWORK_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_GSM_NETWORK, MMModemGsmNetwork))
-
-#define MM_MODEM_GSM_NETWORK_ALLOWED_MODE "allowed-mode"
-#define MM_MODEM_GSM_NETWORK_ACCESS_TECHNOLOGY "access-technology"
-
-typedef enum {
- MM_MODEM_GSM_NETWORK_PROP_FIRST = 0x1200,
-
- MM_MODEM_GSM_NETWORK_PROP_ALLOWED_MODE = MM_MODEM_GSM_NETWORK_PROP_FIRST,
- MM_MODEM_GSM_NETWORK_PROP_ACCESS_TECHNOLOGY,
-} MMModemGsmNetworkProp;
-
-typedef struct _MMModemGsmNetwork MMModemGsmNetwork;
-
-typedef void (*MMModemGsmNetworkScanFn) (MMModemGsmNetwork *self,
- GPtrArray *results,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemGsmNetworkRegInfoFn) (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegStatus status,
- const char *oper_code,
- const char *oper_name,
- GError *error,
- gpointer user_data);
-
-struct _MMModemGsmNetwork {
- GTypeInterface g_iface;
-
- /* Methods */
- /* 'register' is a reserved word */
- void (*do_register) (MMModemGsmNetwork *self,
- const char *network_id,
- MMModemFn callback,
- gpointer user_data);
-
- void (*scan) (MMModemGsmNetwork *self,
- MMModemGsmNetworkScanFn callback,
- gpointer user_data);
-
- void (*set_apn) (MMModemGsmNetwork *self,
- const char *apn,
- MMModemFn callback,
- gpointer user_data);
-
- void (*get_signal_quality) (MMModemGsmNetwork *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- void (*set_band) (MMModemGsmNetwork *self,
- MMModemGsmBand band,
- MMModemFn callback,
- gpointer user_data);
-
- void (*get_band) (MMModemGsmNetwork *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- void (*set_allowed_mode) (MMModemGsmNetwork *self,
- MMModemGsmAllowedMode mode,
- MMModemFn callback,
- gpointer user_data);
-
- void (*get_registration_info) (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegInfoFn callback,
- gpointer user_data);
-
- /* Signals */
- void (*signal_quality) (MMModemGsmNetwork *self,
- guint32 quality);
-
- void (*registration_info) (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegStatus status,
- const char *open_code,
- const char *oper_name);
-};
-
-GType mm_modem_gsm_network_get_type (void);
-
-void mm_modem_gsm_network_register (MMModemGsmNetwork *self,
- const char *network_id,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_network_scan (MMModemGsmNetwork *self,
- MMModemGsmNetworkScanFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_network_set_apn (MMModemGsmNetwork *self,
- const char *apn,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_network_get_signal_quality (MMModemGsmNetwork *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_network_set_band (MMModemGsmNetwork *self,
- MMModemGsmBand band,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_network_get_band (MMModemGsmNetwork *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_network_get_registration_info (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegInfoFn callback,
- gpointer user_data);
-
-/* Protected */
-
-void mm_modem_gsm_network_signal_quality (MMModemGsmNetwork *self,
- guint32 quality);
-
-void mm_modem_gsm_network_set_allowed_mode (MMModemGsmNetwork *self,
- MMModemGsmAllowedMode mode,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_network_registration_info (MMModemGsmNetwork *self,
- MMModemGsmNetworkRegStatus status,
- const char *oper_code,
- const char *oper_name);
-
-/* Private */
-MMModemGsmNetworkDeprecatedMode mm_modem_gsm_network_act_to_old_mode (MMModemGsmAccessTech act);
-
-MMModemGsmAllowedMode mm_modem_gsm_network_old_mode_to_allowed (MMModemGsmNetworkDeprecatedMode old_mode);
-
-#endif /* MM_MODEM_GSM_NETWORK_H */
diff --git a/src/mm-modem-gsm-sms.c b/src/mm-modem-gsm-sms.c
deleted file mode 100644
index 22c42d00..00000000
--- a/src/mm-modem-gsm-sms.c
+++ /dev/null
@@ -1,836 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2009 Novell, Inc.
- */
-
-#include <string.h>
-#include <dbus/dbus-glib.h>
-
-#include "mm-modem-gsm-sms.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-marshal.h"
-
-static void impl_gsm_modem_sms_delete (MMModemGsmSms *modem,
- guint idx,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_get (MMModemGsmSms *modem,
- guint idx,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_get_format (MMModemGsmSms *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_set_format (MMModemGsmSms *modem,
- guint format,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_get_smsc (MMModemGsmSms *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_set_smsc (MMModemGsmSms *modem,
- const char *smsc,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_list (MMModemGsmSms *modem,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_save (MMModemGsmSms *modem,
- GHashTable *properties,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_send (MMModemGsmSms *modem,
- GHashTable *properties,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_send_from_storage (MMModemGsmSms *modem,
- guint idx,
- DBusGMethodInvocation *context);
-
-static void impl_gsm_modem_sms_set_indication (MMModemGsmSms *modem,
- guint mode,
- guint mt,
- guint bm,
- guint ds,
- guint bfr,
- DBusGMethodInvocation *context);
-
-#include "mm-modem-gsm-sms-glue.h"
-
-enum {
- SMS_RECEIVED,
- COMPLETED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-/*****************************************************************************/
-
-static void
-async_call_done (MMModem *modem, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context);
-}
-
-static void
-async_call_not_supported (MMModemGsmSms *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-static void
-sms_get_done (MMModemGsmSms *self,
- GHashTable *properties,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, properties);
-}
-
-static void
-sms_list_done (MMModemGsmSms *self,
- GPtrArray *results,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, results);
-}
-
-/*****************************************************************************/
-
-static void
-sms_send_invoke (MMCallbackInfo *info)
-{
- MMModemGsmSmsSendFn callback = (MMModemGsmSmsSendFn) info->callback;
-
- callback (MM_MODEM_GSM_SMS (info->modem), NULL, info->error, info->user_data);
-}
-
-void
-mm_modem_gsm_sms_send (MMModemGsmSms *self,
- const char *number,
- const char *text,
- const char *smsc,
- guint validity,
- guint class,
- MMModemGsmSmsSendFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_SMS (self));
- g_return_if_fail (number != NULL);
- g_return_if_fail (text != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_SMS_GET_INTERFACE (self)->send)
- MM_MODEM_GSM_SMS_GET_INTERFACE (self)->send (self, number, text, smsc, validity, class, callback, user_data);
- else {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self),
- sms_send_invoke,
- G_CALLBACK (callback),
- user_data);
-
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-static void
-sms_get_invoke (MMCallbackInfo *info)
-{
- MMModemGsmSmsGetFn callback = (MMModemGsmSmsGetFn) info->callback;
-
- callback (MM_MODEM_GSM_SMS (info->modem), NULL, info->error, info->user_data);
-}
-
-void
-mm_modem_gsm_sms_get (MMModemGsmSms *self,
- guint idx,
- MMModemGsmSmsGetFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_SMS (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_SMS_GET_INTERFACE (self)->get)
- MM_MODEM_GSM_SMS_GET_INTERFACE (self)->get (self, idx, callback, user_data);
- else {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self),
- sms_get_invoke,
- G_CALLBACK (callback),
- user_data);
-
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-void
-mm_modem_gsm_sms_delete (MMModemGsmSms *self,
- guint idx,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_SMS (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_SMS_GET_INTERFACE (self)->delete)
- MM_MODEM_GSM_SMS_GET_INTERFACE (self)->delete (self, idx, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-static void
-sms_list_invoke (MMCallbackInfo *info)
-{
- MMModemGsmSmsListFn callback = (MMModemGsmSmsListFn) info->callback;
-
- callback (MM_MODEM_GSM_SMS (info->modem), NULL, info->error, info->user_data);
-}
-
-void
-mm_modem_gsm_sms_list (MMModemGsmSms *self,
- MMModemGsmSmsListFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_SMS (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_SMS_GET_INTERFACE (self)->list)
- MM_MODEM_GSM_SMS_GET_INTERFACE (self)->list (self, callback, user_data);
- else {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self),
- sms_list_invoke,
- G_CALLBACK (callback),
- user_data);
-
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-void
-mm_modem_gsm_sms_received (MMModemGsmSms *self,
- guint idx,
- gboolean complete)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_SMS (self));
-
- g_signal_emit (self, signals[SMS_RECEIVED], 0,
- idx,
- complete);
-}
-
-void
-mm_modem_gsm_sms_completed (MMModemGsmSms *self,
- guint idx,
- gboolean complete)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_SMS (self));
-
- g_signal_emit (self, signals[COMPLETED], 0,
- idx,
- complete);
-}
-
-/*****************************************************************************/
-
-typedef struct {
- guint num1;
- guint num2;
- guint num3;
- guint num4;
- guint num5;
- char *str;
- GHashTable *hash;
-} SmsAuthInfo;
-
-static void
-sms_auth_info_destroy (gpointer data)
-{
- SmsAuthInfo *info = data;
-
- if (info->hash)
- g_hash_table_destroy (info->hash);
- g_free (info->str);
- memset (info, 0, sizeof (SmsAuthInfo));
- g_free (info);
-}
-
-static void
-destroy_gvalue (gpointer data)
-{
- GValue *value = (GValue *) data;
-
- g_value_unset (value);
- g_slice_free (GValue, value);
-}
-
-static SmsAuthInfo *
-sms_auth_info_new (guint num1,
- guint num2,
- guint num3,
- guint num4,
- guint num5,
- const char *str,
- GHashTable *hash)
-{
- SmsAuthInfo *info;
-
- info = g_malloc0 (sizeof (SmsAuthInfo));
- info->num1 = num1;
- info->num2 = num2;
- info->num3 = num3;
- info->num4 = num4;
- info->num5 = num5;
- info->str = g_strdup (str);
-
- /* Copy the hash table if we're given one */
- if (hash) {
- GHashTableIter iter;
- gpointer key, value;
-
- info->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, destroy_gvalue);
-
- g_hash_table_iter_init (&iter, hash);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- const char *str_key = (const char *) key;
- GValue *src = (GValue *) value;
- GValue *dst;
-
- dst = g_slice_new0 (GValue);
- g_value_init (dst, G_VALUE_TYPE (src));
- g_value_copy (src, dst);
- g_hash_table_insert (info->hash, g_strdup (str_key), dst);
- }
- }
-
- return info;
-}
-
-/*****************************************************************************/
-
-static void
-sms_delete_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
- SmsAuthInfo *info = user_data;
- GError *error = NULL;
- guint idx;
-
- /* Return any authorization error, otherwise delete the SMS */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else {
- idx = info->num1;
- mm_modem_gsm_sms_delete (self, idx, async_call_done, context);
- }
-}
-
-static void
-impl_gsm_modem_sms_delete (MMModemGsmSms *modem,
- guint idx,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SmsAuthInfo *info;
-
- info = sms_auth_info_new (idx, 0, 0, 0, 0, NULL, NULL);
-
- /* Make sure the caller is authorized to delete an SMS */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_SMS,
- context,
- sms_delete_auth_cb,
- info,
- sms_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-sms_get_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
- SmsAuthInfo *info = user_data;
- guint idx;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise get the SMS */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else {
- idx = info->num1;
- mm_modem_gsm_sms_get (self, idx, sms_get_done, context);
- }
-}
-
-static void
-impl_gsm_modem_sms_get (MMModemGsmSms *modem,
- guint idx,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SmsAuthInfo *info;
-
- info = sms_auth_info_new (idx, 0, 0, 0, 0, NULL, NULL);
-
- /* Make sure the caller is authorized to get an SMS */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_SMS,
- context,
- sms_get_auth_cb,
- info,
- sms_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-impl_gsm_modem_sms_get_format (MMModemGsmSms *modem,
- DBusGMethodInvocation *context)
-{
- async_call_not_supported (modem, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_sms_set_format (MMModemGsmSms *modem,
- guint format,
- DBusGMethodInvocation *context)
-{
- async_call_not_supported (modem, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_sms_get_smsc (MMModemGsmSms *modem,
- DBusGMethodInvocation *context)
-{
- async_call_not_supported (modem, async_call_done, context);
-}
-
-/*****************************************************************************/
-
-static void
-sms_set_smsc_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise set the SMS service center */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- async_call_not_supported (self, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_sms_set_smsc (MMModemGsmSms *modem,
- const char *smsc,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SmsAuthInfo *info;
-
- info = sms_auth_info_new (0, 0, 0, 0, 0, smsc, NULL);
-
- /* Make sure the caller is authorized to set the SMS service center */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_SMS,
- context,
- sms_set_smsc_auth_cb,
- info,
- sms_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-sms_list_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise list SMSs */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_gsm_sms_list (self, sms_list_done, context);
-}
-
-static void
-impl_gsm_modem_sms_list (MMModemGsmSms *modem,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to list SMSs */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_SMS,
- context,
- sms_list_auth_cb,
- NULL,
- NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-sms_save_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise save the SMS */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- async_call_not_supported (self, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_sms_save (MMModemGsmSms *modem,
- GHashTable *properties,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SmsAuthInfo *info;
-
- info = sms_auth_info_new (0, 0, 0, 0, 0, NULL, properties);
-
- /* Make sure the caller is authorized to save the SMS */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_SMS,
- context,
- sms_save_auth_cb,
- info,
- sms_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-send_sms_call_done (MMModemGsmSms *modem,
- GArray *indexes,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, indexes);
-}
-
-static void
-sms_send_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
- SmsAuthInfo *info = user_data;
- GError *error = NULL;
- GValue *value;
- const char *number = NULL;
- const char *text = NULL ;
- const char *smsc = NULL;
- guint validity = 0;
- guint class = 0;
-
- /* Return any authorization error, otherwise delete the SMS */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error))
- goto done;
-
- value = (GValue *) g_hash_table_lookup (info->hash, "number");
- if (value)
- number = g_value_get_string (value);
-
- value = (GValue *) g_hash_table_lookup (info->hash, "text");
- if (value)
- text = g_value_get_string (value);
-
- value = (GValue *) g_hash_table_lookup (info->hash, "smsc");
- if (value)
- smsc = g_value_get_string (value);
-
- value = (GValue *) g_hash_table_lookup (info->hash, "relative-validity");
- if (value)
- validity = g_value_get_uint (value);
-
- value = (GValue *) g_hash_table_lookup (info->hash, "class");
- if (value)
- class = g_value_get_uint (value);
-
- if (!number) {
- error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Missing number");
- } else if (!text) {
- error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Missing message text");
- }
-
-done:
- if (error) {
- send_sms_call_done (self, NULL, error, context);
- g_error_free (error);
- } else
- mm_modem_gsm_sms_send (self, number, text, smsc, validity, class, send_sms_call_done, context);
-}
-
-static void
-impl_gsm_modem_sms_send (MMModemGsmSms *modem,
- GHashTable *properties,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SmsAuthInfo *info;
-
- info = sms_auth_info_new (0, 0, 0, 0, 0, NULL, properties);
-
- /* Make sure the caller is authorized to send the PUK */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_SMS,
- context,
- sms_send_auth_cb,
- info,
- sms_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-sms_send_from_storage_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise delete the SMS */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- async_call_not_supported (self, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_sms_send_from_storage (MMModemGsmSms *modem,
- guint idx,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SmsAuthInfo *info;
-
- info = sms_auth_info_new (idx, 0, 0, 0, 0, NULL, NULL);
-
- /* Make sure the caller is authorized to send the PUK */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_SMS,
- context,
- sms_send_from_storage_auth_cb,
- info,
- sms_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-sms_set_indication_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmSms *self = MM_MODEM_GSM_SMS (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise delete the SMS */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- async_call_not_supported (self, async_call_done, context);
-}
-
-static void
-impl_gsm_modem_sms_set_indication (MMModemGsmSms *modem,
- guint mode,
- guint mt,
- guint bm,
- guint ds,
- guint bfr,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- SmsAuthInfo *info;
-
- info = sms_auth_info_new (mode, mt, bm, ds, bfr, NULL, NULL);
-
- /* Make sure the caller is authorized to send the PUK */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_SMS,
- context,
- sms_set_indication_auth_cb,
- info,
- sms_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-mm_modem_gsm_sms_init (gpointer g_iface)
-{
- GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
-
- /* Signals */
- signals[SMS_RECEIVED] =
- g_signal_new ("sms-received",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MMModemGsmSms, sms_received),
- NULL, NULL,
- mm_marshal_VOID__UINT_BOOLEAN,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_BOOLEAN);
-
- signals[COMPLETED] =
- g_signal_new ("completed",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MMModemGsmSms, completed),
- NULL, NULL,
- mm_marshal_VOID__UINT_BOOLEAN,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_BOOLEAN);
-
- initialized = TRUE;
-}
-
-GType
-mm_modem_gsm_sms_get_type (void)
-{
- static GType sms_type = 0;
-
- if (!G_UNLIKELY (sms_type)) {
- const GTypeInfo sms_info = {
- sizeof (MMModemGsmSms), /* class_size */
- mm_modem_gsm_sms_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- sms_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModemGsmSms",
- &sms_info, 0);
-
- g_type_interface_add_prerequisite (sms_type, G_TYPE_OBJECT);
- dbus_g_object_type_install_info (sms_type, &dbus_glib_mm_modem_gsm_sms_object_info);
- }
-
- return sms_type;
-}
diff --git a/src/mm-modem-gsm-sms.h b/src/mm-modem-gsm-sms.h
deleted file mode 100644
index 11a1024b..00000000
--- a/src/mm-modem-gsm-sms.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2009 Novell, Inc.
- */
-
-#ifndef MM_MODEM_GSM_SMS_H
-#define MM_MODEM_GSM_SMS_H
-
-#include <mm-modem.h>
-
-#define MM_TYPE_MODEM_GSM_SMS (mm_modem_gsm_sms_get_type ())
-#define MM_MODEM_GSM_SMS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_GSM_SMS, MMModemGsmSms))
-#define MM_IS_MODEM_GSM_SMS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_GSM_SMS))
-#define MM_MODEM_GSM_SMS_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_GSM_SMS, MMModemGsmSms))
-
-typedef struct _MMModemGsmSms MMModemGsmSms;
-
-typedef void (*MMModemGsmSmsGetFn) (MMModemGsmSms *modem,
- GHashTable *properties,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemGsmSmsListFn) (MMModemGsmSms *modem,
- GPtrArray *resultlist,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemGsmSmsSendFn) (MMModemGsmSms *modem,
- GArray *indexes,
- GError *error,
- gpointer user_data);
-
-struct _MMModemGsmSms {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*send) (MMModemGsmSms *modem,
- const char *number,
- const char *text,
- const char *smsc,
- guint validity,
- guint class,
- MMModemGsmSmsSendFn callback,
- gpointer user_data);
-
- void (*get) (MMModemGsmSms *modem,
- guint32 index,
- MMModemGsmSmsGetFn callback,
- gpointer user_data);
-
- void (*delete) (MMModemGsmSms *modem,
- guint32 index,
- MMModemFn callback,
- gpointer user_data);
-
- void (*list) (MMModemGsmSms *modem,
- MMModemGsmSmsListFn callback,
- gpointer user_data);
-
- /* Signals */
- void (*sms_received) (MMModemGsmSms *self,
- guint32 index,
- gboolean completed);
-
- void (*completed) (MMModemGsmSms *self,
- guint32 index,
- gboolean completed);
-};
-
-GType mm_modem_gsm_sms_get_type (void);
-
-void mm_modem_gsm_sms_send (MMModemGsmSms *self,
- const char *number,
- const char *text,
- const char *smsc,
- guint validity,
- guint class,
- MMModemGsmSmsSendFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_sms_get (MMModemGsmSms *self,
- guint idx,
- MMModemGsmSmsGetFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_sms_delete (MMModemGsmSms *self,
- guint idx,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_sms_list (MMModemGsmSms *self,
- MMModemGsmSmsListFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_sms_received (MMModemGsmSms *self,
- guint idx,
- gboolean complete);
-
-void mm_modem_gsm_sms_completed (MMModemGsmSms *self,
- guint idx,
- gboolean complete);
-
-
-#endif /* MM_MODEM_GSM_SMS_H */
diff --git a/src/mm-modem-gsm-ussd.c b/src/mm-modem-gsm-ussd.c
deleted file mode 100644
index 614999cb..00000000
--- a/src/mm-modem-gsm-ussd.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2010 Guido Guenther <agx@sigxcpu.org>
- */
-
-#include <string.h>
-#include <dbus/dbus-glib.h>
-
-#include "mm-modem-gsm-ussd.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-marshal.h"
-
-static void impl_modem_gsm_ussd_initiate(MMModemGsmUssd *modem,
- const char*command,
- DBusGMethodInvocation *context);
-
-static void impl_modem_gsm_ussd_respond(MMModemGsmUssd *modem,
- const char *response,
- DBusGMethodInvocation *context);
-
-static void impl_modem_gsm_ussd_cancel(MMModemGsmUssd *modem,
- DBusGMethodInvocation *context);
-
-#include "mm-modem-gsm-ussd-glue.h"
-
-
-/*****************************************************************************/
-
-static void
-str_call_done (MMModem *modem, const char *result, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, result);
-}
-
-static void
-str_call_not_supported (MMModemGsmUssd *self,
- MMModemStringFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_string_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
-
- mm_callback_info_schedule (info);
-}
-
-static void
-async_call_done (MMModem *modem, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context);
-}
-
-static void
-async_call_not_supported (MMModemGsmUssd *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-/*****************************************************************************/
-
-void
-mm_modem_gsm_ussd_initiate (MMModemGsmUssd *self,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_USSD (self));
- g_return_if_fail (command != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_USSD_GET_INTERFACE (self)->initiate)
- MM_MODEM_GSM_USSD_GET_INTERFACE (self)->initiate(self, command, callback, user_data);
- else
- str_call_not_supported (self, callback, user_data);
-
-}
-
-void
-mm_modem_gsm_ussd_respond (MMModemGsmUssd *self,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_USSD (self));
- g_return_if_fail (command != NULL);
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_USSD_GET_INTERFACE (self)->respond)
- MM_MODEM_GSM_USSD_GET_INTERFACE (self)->respond(self, command, callback, user_data);
- else
- str_call_not_supported (self, callback, user_data);
-
-}
-
-void
-mm_modem_gsm_ussd_cancel (MMModemGsmUssd *self,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_GSM_USSD (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GSM_USSD_GET_INTERFACE (self)->cancel)
- MM_MODEM_GSM_USSD_GET_INTERFACE (self)->cancel(self, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-
-}
-
-char*
-mm_modem_gsm_ussd_encode (MMModemGsmUssd *self,
- const char* command,
- guint *schema)
-{
- if (MM_MODEM_GSM_USSD_GET_INTERFACE (self)->encode)
- return MM_MODEM_GSM_USSD_GET_INTERFACE (self)->encode(self,
- command,
- schema);
- else
- return NULL;
-}
-
-char*
-mm_modem_gsm_ussd_decode (MMModemGsmUssd *self,
- const char* reply,
- guint schema)
-{
- if (MM_MODEM_GSM_USSD_GET_INTERFACE (self)->decode)
- return MM_MODEM_GSM_USSD_GET_INTERFACE (self)->decode(self,
- reply,
- schema);
- else
- return NULL;
-}
-
-/*****************************************************************************/
-
-typedef struct {
- char *command;
-} UssdAuthInfo;
-
-static void
-ussd_auth_info_destroy (gpointer data)
-{
- UssdAuthInfo *info = data;
-
- g_free (info->command);
- g_free (info);
-}
-
-static UssdAuthInfo *
-ussd_auth_info_new (const char* command)
-{
- UssdAuthInfo *info;
-
- info = g_malloc0 (sizeof (UssdAuthInfo));
- info->command = g_strdup (command);
-
- return info;
-}
-
-/*****************************************************************************/
-
-static void
-ussd_initiate_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmUssd *self = MM_MODEM_GSM_USSD (owner);
- UssdAuthInfo *info = user_data;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise initiate the USSD */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error))
- goto done;
-
- if (!info->command) {
- error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Missing USSD command");
- }
-
-done:
- if (error) {
- str_call_done (MM_MODEM (self), NULL, error, context);
- g_error_free (error);
- } else
- mm_modem_gsm_ussd_initiate (self, info->command, str_call_done, context);
-}
-
-static void
-impl_modem_gsm_ussd_initiate (MMModemGsmUssd *modem,
- const char *command,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- UssdAuthInfo *info;
-
- info = ussd_auth_info_new (command);
-
- /* Make sure the caller is authorized to initiate the USSD */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_USSD,
- context,
- ussd_initiate_auth_cb,
- info,
- ussd_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-static void
-ussd_respond_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmUssd *self = MM_MODEM_GSM_USSD (owner);
- UssdAuthInfo *info = user_data;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise respond to the USSD */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error))
- goto done;
-
- if (!info->command) {
- error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
- "Missing USSD command");
- }
-
-done:
- if (error) {
- str_call_done (MM_MODEM (self), NULL, error, context);
- g_error_free (error);
- } else
- mm_modem_gsm_ussd_respond (self, info->command, str_call_done, context);
-}
-
-static void
-impl_modem_gsm_ussd_respond (MMModemGsmUssd *modem,
- const char *command,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- UssdAuthInfo *info;
-
- info = ussd_auth_info_new (command);
-
- /* Make sure the caller is authorized to respond to the USSD */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_USSD,
- context,
- ussd_respond_auth_cb,
- info,
- ussd_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-static void
-ussd_cancel_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemGsmUssd *self = MM_MODEM_GSM_USSD (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise cancel the USSD */
- mm_modem_auth_finish (MM_MODEM (self), req, &error);
-
- if (error) {
- str_call_done (MM_MODEM (self), NULL, error, context);
- g_error_free (error);
- } else
- mm_modem_gsm_ussd_cancel (self, async_call_done, context);
-}
-
-static void
-impl_modem_gsm_ussd_cancel (MMModemGsmUssd *modem,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- UssdAuthInfo *info;
-
- info = ussd_auth_info_new (NULL);
-
- /* Make sure the caller is authorized to cancel USSD */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_USSD,
- context,
- ussd_cancel_auth_cb,
- info,
- ussd_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-mm_modem_gsm_ussd_init (gpointer g_iface)
-{
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
-
- /* Properties */
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_GSM_USSD_STATE,
- "State",
- "Current state of USSD session",
- NULL,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_GSM_USSD_NETWORK_NOTIFICATION,
- "NetworkNotification",
- "Network initiated request, no response required",
- NULL,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_GSM_USSD_NETWORK_REQUEST,
- "NetworkRequest",
- "Network initiated request, reponse required",
- NULL,
- G_PARAM_READABLE));
-
- initialized = TRUE;
-}
-
-GType
-mm_modem_gsm_ussd_get_type (void)
-{
- static GType ussd_type = 0;
-
- if (!G_UNLIKELY (ussd_type)) {
- const GTypeInfo ussd_info = {
- sizeof (MMModemGsmUssd), /* class_size */
- mm_modem_gsm_ussd_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- ussd_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModemGsmUssd",
- &ussd_info, 0);
-
- g_type_interface_add_prerequisite (ussd_type, G_TYPE_OBJECT);
- dbus_g_object_type_install_info (ussd_type, &dbus_glib_mm_modem_gsm_ussd_object_info);
-
- dbus_g_object_type_register_shadow_property (ussd_type,
- "State",
- MM_MODEM_GSM_USSD_STATE);
- }
-
- return ussd_type;
-}
diff --git a/src/mm-modem-gsm-ussd.h b/src/mm-modem-gsm-ussd.h
deleted file mode 100644
index f46be974..00000000
--- a/src/mm-modem-gsm-ussd.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2010 Guido Guenther <agx@sigxcpu.org>
- */
-
-#ifndef MM_MODEM_GSM_USSD_H
-#define MM_MODEM_GSM_USSD_H
-
-#include <mm-modem.h>
-
-typedef enum {
- MM_MODEM_GSM_USSD_STATE_IDLE = 0x00000000,
- MM_MODEM_GSM_USSD_STATE_ACTIVE = 0x00000001,
- MM_MODEM_GSM_USSD_STATE_USER_RESPONSE = 0x00000002,
-} MMModemGsmUssdState;
-
-#define MM_MODEM_GSM_USSD_STATE "ussd-state"
-#define MM_MODEM_GSM_USSD_NETWORK_NOTIFICATION "network-notification"
-#define MM_MODEM_GSM_USSD_NETWORK_REQUEST "network-request"
-
-#define MM_TYPE_MODEM_GSM_USSD (mm_modem_gsm_ussd_get_type ())
-#define MM_MODEM_GSM_USSD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_GSM_USSD, MMModemGsmUssd))
-#define MM_IS_MODEM_GSM_USSD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_GSM_USSD))
-#define MM_MODEM_GSM_USSD_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_GSM_USSD, MMModemGsmUssd))
-
-#define MM_MODEM_GSM_USSD_DBUS_INTERFACE "org.freedesktop.ModemManager.Modem.Gsm.Ussd"
-
-typedef struct _MMModemGsmUssd MMModemGsmUssd;
-
-struct _MMModemGsmUssd {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*initiate) (MMModemGsmUssd *modem,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data);
-
- void (*respond) (MMModemGsmUssd *modem,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data);
-
- void (*cancel) (MMModemGsmUssd *modem,
- MMModemFn callback,
- gpointer user_data);
-
- gchar* (*encode) (MMModemGsmUssd *modem,
- const char* command,
- guint *scheme);
-
- gchar* (*decode) (MMModemGsmUssd *modem,
- const char* command,
- guint scheme);
-};
-
-GType mm_modem_gsm_ussd_get_type (void);
-
-void mm_modem_gsm_ussd_initiate (MMModemGsmUssd *self,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_ussd_respond (MMModemGsmUssd *self,
- const char *command,
- MMModemStringFn callback,
- gpointer user_data);
-
-void mm_modem_gsm_ussd_cancel (MMModemGsmUssd *self,
- MMModemFn callback,
- gpointer user_data);
-
-/* CBS data coding scheme - 3GPP TS 23.038 */
-#define MM_MODEM_GSM_USSD_SCHEME_7BIT 0b00001111
-#define MM_MODEM_GSM_USSD_SCHEME_UCS2 0b01001000
-
-char *mm_modem_gsm_ussd_encode (MMModemGsmUssd *self,
- const char* command,
- guint *scheme);
-
-char *mm_modem_gsm_ussd_decode (MMModemGsmUssd *self,
- const char* reply,
- guint scheme);
-
-#endif /* MM_MODEM_GSM_USSD_H */
diff --git a/src/mm-modem-location.c b/src/mm-modem-location.c
deleted file mode 100644
index 2dadd4ed..00000000
--- a/src/mm-modem-location.c
+++ /dev/null
@@ -1,331 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2010 Red Hat, Inc.
- */
-
-#include <string.h>
-#include <dbus/dbus-glib.h>
-
-#include "mm-modem-location.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-marshal.h"
-
-static void impl_modem_location_enable (MMModemLocation *modem,
- gboolean enable,
- gboolean signal_location,
- DBusGMethodInvocation *context);
-
-static void impl_modem_location_get_location (MMModemLocation *modem,
- DBusGMethodInvocation *context);
-
-#include "mm-modem-location-glue.h"
-
-/*****************************************************************************/
-
-static void
-async_call_done (MMModem *modem, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context);
-}
-
-static void
-async_call_not_supported (MMModemLocation *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-/*****************************************************************************/
-
-typedef struct {
- gboolean enable;
- gboolean signals_location;
-} LocAuthInfo;
-
-static void
-loc_auth_info_destroy (gpointer data)
-{
- LocAuthInfo *info = data;
-
- memset (info, 0, sizeof (LocAuthInfo));
- g_free (info);
-}
-
-static LocAuthInfo *
-loc_auth_info_new (gboolean enable, gboolean signals_location)
-{
- LocAuthInfo *info;
-
- info = g_malloc0 (sizeof (LocAuthInfo));
- info->enable = enable;
- info->signals_location = signals_location;
- return info;
-}
-
-/*****************************************************************************/
-
-void
-mm_modem_location_enable (MMModemLocation *self,
- gboolean enable,
- gboolean signals_location,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_LOCATION (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_LOCATION_GET_INTERFACE (self)->enable)
- MM_MODEM_LOCATION_GET_INTERFACE (self)->enable (self, enable, signals_location, callback, user_data);
- else
- async_call_not_supported (self, callback, user_data);
-}
-
-/*****************************************************************************/
-
-static void
-loc_enable_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemLocation *self = MM_MODEM_LOCATION (owner);
- LocAuthInfo *info = (LocAuthInfo *) user_data;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise enable location gathering */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_location_enable (self, info->enable, info->signals_location, async_call_done, context);
-}
-
-static void
-impl_modem_location_enable (MMModemLocation *modem,
- gboolean enable,
- gboolean signals_location,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- LocAuthInfo *info;
-
- info = loc_auth_info_new (enable, signals_location);
-
- /* Make sure the caller is authorized to enable location gathering */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_LOCATION,
- context,
- loc_enable_auth_cb,
- info,
- loc_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-loc_get_invoke (MMCallbackInfo *info)
-{
- MMModemLocationGetFn callback = (MMModemLocationGetFn) info->callback;
-
- callback ((MMModemLocation *) info->modem, NULL, info->error, info->user_data);
-}
-
-static void
-async_get_call_not_supported (MMModemLocation *self,
- MMModemLocationGetFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self),
- loc_get_invoke,
- G_CALLBACK (callback),
- user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-void
-mm_modem_location_get_location (MMModemLocation *self,
- MMModemLocationGetFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_LOCATION (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_LOCATION_GET_INTERFACE (self)->get_location)
- MM_MODEM_LOCATION_GET_INTERFACE (self)->get_location (self, callback, user_data);
- else
- async_get_call_not_supported (self, callback, user_data);
-}
-
-/*****************************************************************************/
-
-static void
-async_get_call_done (MMModemLocation *self,
- GHashTable *locations,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, locations);
-}
-
-static void
-loc_get_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModemLocation *self = MM_MODEM_LOCATION (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise get the location */
- if (!mm_modem_auth_finish (MM_MODEM (self), req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_location_get_location (self, async_get_call_done, context);
-}
-
-static void
-impl_modem_location_get_location (MMModemLocation *modem,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
- LocAuthInfo *info;
-
- info = loc_auth_info_new (FALSE, FALSE);
-
- /* Make sure the caller is authorized to enable location gathering */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_LOCATION,
- context,
- loc_get_auth_cb,
- info,
- loc_auth_info_destroy,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-/*****************************************************************************/
-
-static void
-mm_modem_location_init (gpointer g_iface)
-{
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
-
- /* Properties */
- g_object_interface_install_property
- (g_iface,
- g_param_spec_boxed (MM_MODEM_LOCATION_LOCATION,
- "Location",
- "Available location information",
- MM_MODEM_LOCATION_PROP_TYPE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_LOCATION_CAPABILITIES,
- "Capabilities",
- "Supported location information methods",
- MM_MODEM_LOCATION_CAPABILITY_UNKNOWN,
- MM_MODEM_LOCATION_CAPABILITY_GPS_NMEA
- | MM_MODEM_LOCATION_CAPABILITY_GSM_LAC_CI
- | MM_MODEM_LOCATION_CAPABILITY_GPS_RAW,
- MM_MODEM_LOCATION_CAPABILITY_UNKNOWN,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_boolean (MM_MODEM_LOCATION_ENABLED,
- "Enabled",
- "Whether or not location gathering is enabled",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_boolean (MM_MODEM_LOCATION_SIGNALS_LOCATION,
- "SignalsLocation",
- "Whether or not location updates are emitted as signals",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- initialized = TRUE;
-}
-
-GType
-mm_modem_location_get_type (void)
-{
- static GType loc_type = 0;
-
- if (!G_UNLIKELY (loc_type)) {
- const GTypeInfo loc_info = {
- sizeof (MMModemLocation), /* class_size */
- mm_modem_location_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- loc_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModemLocation",
- &loc_info, 0);
-
- g_type_interface_add_prerequisite (loc_type, G_TYPE_OBJECT);
- dbus_g_object_type_install_info (loc_type, &dbus_glib_mm_modem_location_object_info);
-
- /* Register some shadow properties to handle Enabled and Capabilities
- * since these could be used by other interfaces.
- */
- dbus_g_object_type_register_shadow_property (loc_type,
- "Enabled",
- MM_MODEM_LOCATION_ENABLED);
- dbus_g_object_type_register_shadow_property (loc_type,
- "Capabilities",
- MM_MODEM_LOCATION_CAPABILITIES);
- }
-
- return loc_type;
-}
diff --git a/src/mm-modem-location.h b/src/mm-modem-location.h
deleted file mode 100644
index 87c2c4d1..00000000
--- a/src/mm-modem-location.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2010 Red Hat, Inc.
- */
-
-#ifndef MM_MODEM_LOCATION_H
-#define MM_MODEM_LOCATION_H
-
-#include <mm-modem.h>
-
-#define MM_TYPE_MODEM_LOCATION (mm_modem_location_get_type ())
-#define MM_MODEM_LOCATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_LOCATION, MMModemLocation))
-#define MM_IS_MODEM_LOCATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_LOCATION))
-#define MM_MODEM_LOCATION_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_LOCATION, MMModemLocation))
-
-#define MM_MODEM_LOCATION_DBUS_INTERFACE "org.freedesktop.ModemManager.Modem.Location"
-
-#define MM_MODEM_LOCATION_PROP_TYPE (dbus_g_type_get_map ("GHashTable", G_TYPE_UINT, G_TYPE_VALUE))
-
-#define MM_MODEM_LOCATION_CAPABILITIES "location-capabilities"
-#define MM_MODEM_LOCATION_ENABLED "location-enabled"
-#define MM_MODEM_LOCATION_SIGNALS_LOCATION "signals-location"
-#define MM_MODEM_LOCATION_LOCATION "location"
-
-typedef struct _MMModemLocation MMModemLocation;
-
-typedef void (*MMModemLocationGetFn) (MMModemLocation *modem,
- GHashTable *locations,
- GError *error,
- gpointer user_data);
-
-struct _MMModemLocation {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*enable) (MMModemLocation *modem,
- gboolean enable,
- gboolean signal_location,
- MMModemFn callback,
- gpointer user_data);
-
- void (*get_location) (MMModemLocation *modem,
- MMModemLocationGetFn callback,
- gpointer user_data);
-};
-
-GType mm_modem_location_get_type (void);
-
-void mm_modem_location_enable (MMModemLocation *self,
- gboolean enable,
- gboolean signal_location,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_location_get_location (MMModemLocation *self,
- MMModemLocationGetFn callback,
- gpointer user_data);
-
-#endif /* MM_MODEM_LOCATION_H */
diff --git a/src/mm-modem-simple.c b/src/mm-modem-simple.c
deleted file mode 100644
index 415fd44b..00000000
--- a/src/mm-modem-simple.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2009 Novell, Inc.
- * Copyright (C) 2009 Red Hat, Inc.
- */
-
-#include <dbus/dbus-glib.h>
-
-#include "mm-modem-simple.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-
-static void impl_modem_simple_connect (MMModemSimple *self, GHashTable *properties, DBusGMethodInvocation *context);
-static void impl_modem_simple_get_status (MMModemSimple *self, DBusGMethodInvocation *context);
-
-#include "mm-modem-simple-glue.h"
-
-void
-mm_modem_simple_connect (MMModemSimple *self,
- GHashTable *properties,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_SIMPLE (self));
- g_return_if_fail (properties != NULL);
-
- if (MM_MODEM_SIMPLE_GET_INTERFACE (self)->connect)
- MM_MODEM_SIMPLE_GET_INTERFACE (self)->connect (self, properties, callback, user_data);
- else {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-static void
-simple_get_status_invoke (MMCallbackInfo *info)
-{
- MMModemSimpleGetStatusFn callback = (MMModemSimpleGetStatusFn) info->callback;
-
- callback (MM_MODEM_SIMPLE (info->modem), NULL, info->error, info->user_data);
-}
-
-void
-mm_modem_simple_get_status (MMModemSimple *self,
- MMModemSimpleGetStatusFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM_SIMPLE (self));
-
- if (MM_MODEM_SIMPLE_GET_INTERFACE (self)->get_status)
- MM_MODEM_SIMPLE_GET_INTERFACE (self)->get_status (self, callback, user_data);
- else {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self),
- simple_get_status_invoke,
- G_CALLBACK (callback),
- user_data);
-
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-/*****************************************************************************/
-
-static void
-async_call_done (MMModem *modem, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context);
-}
-
-static void
-impl_modem_simple_connect (MMModemSimple *self,
- GHashTable *properties,
- DBusGMethodInvocation *context)
-{
- mm_modem_simple_connect (self, properties, async_call_done, context);
-}
-
-static void
-get_status_done (MMModemSimple *modem,
- GHashTable *properties,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context, properties);
-}
-
-static void
-impl_modem_simple_get_status (MMModemSimple *self,
- DBusGMethodInvocation *context)
-{
- mm_modem_simple_get_status (self, get_status_done, context);
-}
-
-/*****************************************************************************/
-
-static void
-mm_modem_simple_init (gpointer g_iface)
-{
-}
-
-GType
-mm_modem_simple_get_type (void)
-{
- static GType modem_type = 0;
-
- if (!G_UNLIKELY (modem_type)) {
- const GTypeInfo modem_info = {
- sizeof (MMModemSimple), /* class_size */
- mm_modem_simple_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- modem_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModemSimple",
- &modem_info, 0);
-
- g_type_interface_add_prerequisite (modem_type, G_TYPE_OBJECT);
- dbus_g_object_type_install_info (modem_type, &dbus_glib_mm_modem_simple_object_info);
- }
-
- return modem_type;
-}
diff --git a/src/mm-modem-simple.h b/src/mm-modem-simple.h
deleted file mode 100644
index 03b55618..00000000
--- a/src/mm-modem-simple.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2009 Novell, Inc.
- */
-
-#ifndef MM_MODEM_SIMPLE_H
-#define MM_MODEM_SIMPLE_H
-
-#include <glib-object.h>
-#include <mm-modem.h>
-
-#define MM_TYPE_MODEM_SIMPLE (mm_modem_simple_get_type ())
-#define MM_MODEM_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_SIMPLE, MMModemSimple))
-#define MM_IS_MODEM_SIMPLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM_SIMPLE))
-#define MM_MODEM_SIMPLE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM_SIMPLE, MMModemSimple))
-
-typedef struct _MMModemSimple MMModemSimple;
-
-typedef void (*MMModemSimpleGetStatusFn) (MMModemSimple *modem,
- GHashTable *properties,
- GError *error,
- gpointer user_data);
-
-struct _MMModemSimple {
- GTypeInterface g_iface;
-
- /* Methods */
- void (*connect) (MMModemSimple *self,
- GHashTable *properties,
- MMModemFn callback,
- gpointer user_data);
-
- void (*get_status) (MMModemSimple *self,
- MMModemSimpleGetStatusFn callback,
- gpointer user_data);
-};
-
-GType mm_modem_simple_get_type (void);
-
-void mm_modem_simple_connect (MMModemSimple *self,
- GHashTable *properties,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_simple_get_status (MMModemSimple *self,
- MMModemSimpleGetStatusFn callback,
- gpointer user_data);
-
-#endif /* MM_MODEM_SIMPLE_H */
diff --git a/src/mm-modem.c b/src/mm-modem.c
deleted file mode 100644
index 012e3203..00000000
--- a/src/mm-modem.c
+++ /dev/null
@@ -1,1008 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#include <config.h>
-#include <string.h>
-#include <dbus/dbus-glib.h>
-#include "mm-modem.h"
-#include "mm-log.h"
-#include "mm-errors.h"
-#include "mm-callback-info.h"
-#include "mm-marshal.h"
-
-static void impl_modem_enable (MMModem *modem, gboolean enable, DBusGMethodInvocation *context);
-static void impl_modem_connect (MMModem *modem, const char *number, DBusGMethodInvocation *context);
-static void impl_modem_disconnect (MMModem *modem, DBusGMethodInvocation *context);
-static void impl_modem_get_ip4_config (MMModem *modem, DBusGMethodInvocation *context);
-static void impl_modem_get_info (MMModem *modem, DBusGMethodInvocation *context);
-static void impl_modem_reset (MMModem *modem, DBusGMethodInvocation *context);
-static void impl_modem_factory_reset (MMModem *modem, const char *code, DBusGMethodInvocation *context);
-
-#include "mm-modem-glue.h"
-
-#define MM_MODEM_PIN_RETRY_COUNTS_PROP_TYPE (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_UINT))
-
-static void
-async_op_not_supported (MMModem *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (self, callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
-}
-
-static void
-async_call_done (MMModem *modem, GError *error, gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else
- dbus_g_method_return (context);
-}
-
-void
-mm_modem_enable (MMModem *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMModemState state;
-
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
-
- state = mm_modem_get_state (self);
- if (state >= MM_MODEM_STATE_ENABLED) {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (self, callback, user_data);
-
- if (state == MM_MODEM_STATE_ENABLING) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
- "The device is already being enabled.");
- } else {
- /* Already enabled */
- }
-
- mm_callback_info_schedule (info);
- return;
- }
-
- if (MM_MODEM_GET_INTERFACE (self)->enable)
- MM_MODEM_GET_INTERFACE (self)->enable (self, callback, user_data);
- else
- async_op_not_supported (self, callback, user_data);
-}
-
-static void
-finish_disable (MMModem *self,
- MMModemFn callback,
- gpointer user_data)
-{
- if (MM_MODEM_GET_INTERFACE (self)->disable)
- MM_MODEM_GET_INTERFACE (self)->disable (self, callback, user_data);
- else
- async_op_not_supported (self, callback, user_data);
-}
-
-typedef struct {
- MMModemFn callback;
- gpointer user_data;
-} DisableDisconnectInfo;
-
-static void
-disable_disconnect_done (MMModem *self,
- GError *error,
- gpointer user_data)
-{
- DisableDisconnectInfo *cb_data = user_data;
- GError *tmp_error = NULL;
-
- /* Check for modem removal */
- if (g_error_matches (error, MM_MODEM_ERROR, MM_MODEM_ERROR_REMOVED))
- tmp_error = g_error_copy (error);
- else if (!self) {
- tmp_error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_REMOVED,
- "The modem was removed.");
- }
-
- /* And send an immediate error reply if the modem was removed */
- if (tmp_error) {
- cb_data->callback (NULL, tmp_error, cb_data->user_data);
- g_free (cb_data);
- g_error_free (tmp_error);
- return;
- }
-
- if (error) {
- char *device = mm_modem_get_device (self);
-
- /* Don't really care what the error was; log it and proceed to disable */
- g_warning ("%s: (%s): error disconnecting the modem while disabling: (%d) %s",
- __func__,
- device,
- error ? error->code : -1,
- error && error->message ? error->message : "(unknown)");
- g_free (device);
- }
- finish_disable (self, cb_data->callback, cb_data->user_data);
- g_free (cb_data);
-}
-
-void
-mm_modem_disable (MMModem *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMModemState state;
-
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
-
- state = mm_modem_get_state (self);
- if (state <= MM_MODEM_STATE_DISABLING) {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new (self, callback, user_data);
-
- if (state == MM_MODEM_STATE_DISABLING) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
- "The device is already being disabled.");
- } else {
- /* Already disabled */
- }
-
- mm_callback_info_schedule (info);
- return;
- }
-
- /* If the modem is connected, disconnect it */
- if (state >= MM_MODEM_STATE_CONNECTING) {
- DisableDisconnectInfo *cb_data;
-
- cb_data = g_malloc0 (sizeof (DisableDisconnectInfo));
- cb_data->callback = callback;
- cb_data->user_data = user_data;
- mm_modem_disconnect (self, disable_disconnect_done, cb_data);
- } else
- finish_disable (self, callback, user_data);
-}
-
-static void
-impl_modem_enable (MMModem *modem,
- gboolean enable,
- DBusGMethodInvocation *context)
-{
- if (enable)
- mm_modem_enable (modem, async_call_done, context);
- else
- mm_modem_disable (modem, async_call_done, context);
-}
-
-void
-mm_modem_connect (MMModem *self,
- const char *number,
- MMModemFn callback,
- gpointer user_data)
-{
- MMModemState state;
-
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
- g_return_if_fail (number != NULL);
-
- state = mm_modem_get_state (self);
- if (state >= MM_MODEM_STATE_CONNECTING) {
- MMCallbackInfo *info;
-
- /* Already connecting */
- info = mm_callback_info_new (self, callback, user_data);
- if (state == MM_MODEM_STATE_CONNECTING) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
- "The device is already being connected.");
- } else {
- /* already connected */
- }
-
- mm_callback_info_schedule (info);
- return;
- }
-
- if (MM_MODEM_GET_INTERFACE (self)->connect)
- MM_MODEM_GET_INTERFACE (self)->connect (self, number, callback, user_data);
- else
- async_op_not_supported (self, callback, user_data);
-}
-
-static void
-impl_modem_connect (MMModem *modem,
- const char *number,
- DBusGMethodInvocation *context)
-{
- mm_modem_connect (modem, number, async_call_done, context);
-}
-
-static void
-get_ip4_invoke (MMCallbackInfo *info)
-{
- MMModemIp4Fn callback = (MMModemIp4Fn) info->callback;
-
- callback (info->modem,
- GPOINTER_TO_UINT (mm_callback_info_get_data (info, "ip4-address")),
- (GArray *) mm_callback_info_get_data (info, "ip4-dns"),
- info->error, info->user_data);
-}
-
-void
-mm_modem_get_ip4_config (MMModem *self,
- MMModemIp4Fn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GET_INTERFACE (self)->get_ip4_config)
- MM_MODEM_GET_INTERFACE (self)->get_ip4_config (self, callback, user_data);
- else {
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (self,
- get_ip4_invoke,
- G_CALLBACK (callback),
- user_data);
-
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-static void
-value_array_add_uint (GValueArray *array, guint32 i)
-{
- GValue value = { 0, };
-
- g_value_init (&value, G_TYPE_UINT);
- g_value_set_uint (&value, i);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-}
-
-static void
-get_ip4_done (MMModem *modem,
- guint32 address,
- GArray *dns,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else {
- GValueArray *array;
- guint32 dns1 = 0;
- guint32 dns2 = 0;
- guint32 dns3 = 0;
-
- array = g_value_array_new (4);
-
- if (dns) {
- if (dns->len > 0)
-
- dns1 = g_array_index (dns, guint32, 0);
- if (dns->len > 1)
- dns2 = g_array_index (dns, guint32, 1);
- if (dns->len > 2)
- dns3 = g_array_index (dns, guint32, 2);
- }
-
- value_array_add_uint (array, address);
- value_array_add_uint (array, dns1);
- value_array_add_uint (array, dns2);
- value_array_add_uint (array, dns3);
-
- dbus_g_method_return (context, array);
-
- g_value_array_free (array);
- }
-}
-
-static void
-impl_modem_get_ip4_config (MMModem *modem,
- DBusGMethodInvocation *context)
-{
- mm_modem_get_ip4_config (modem, get_ip4_done, context);
-}
-
-void
-mm_modem_disconnect (MMModem *self,
- MMModemFn callback,
- gpointer user_data)
-{
- MMModemState state;
-
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
-
- state = mm_modem_get_state (self);
- if (state <= MM_MODEM_STATE_DISCONNECTING) {
- MMCallbackInfo *info;
-
- /* Already connecting */
- info = mm_callback_info_new (self, callback, user_data);
- if (state == MM_MODEM_STATE_DISCONNECTING) {
- info->error = g_error_new_literal (MM_MODEM_ERROR,
- MM_MODEM_ERROR_OPERATION_IN_PROGRESS,
- "The device is already being disconnected.");
- } else {
- /* already disconnected */
- }
-
- mm_callback_info_schedule (info);
- return;
- }
-
- if (MM_MODEM_GET_INTERFACE (self)->disconnect)
- MM_MODEM_GET_INTERFACE (self)->disconnect (self, callback, user_data);
- else
- async_op_not_supported (self, callback, user_data);
-}
-
-static void
-impl_modem_disconnect (MMModem *modem,
- DBusGMethodInvocation *context)
-{
- mm_modem_disconnect (modem, async_call_done, context);
-}
-
-static void
-info_call_done (MMModem *self,
- const char *manufacturer,
- const char *model,
- const char *version,
- GError *error,
- gpointer user_data)
-{
- DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data;
-
- if (error)
- dbus_g_method_return_error (context, error);
- else {
- GValueArray *array;
- GValue value = { 0, };
-
- array = g_value_array_new (3);
-
- /* Manufacturer */
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, manufacturer);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- /* Model */
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, model);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- /* Version */
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, version);
- g_value_array_append (array, &value);
- g_value_unset (&value);
-
- dbus_g_method_return (context, array);
-
- g_value_array_free (array);
- }
-}
-
-static void
-info_invoke (MMCallbackInfo *info)
-{
- MMModemInfoFn callback = (MMModemInfoFn) info->callback;
-
- callback (info->modem, NULL, NULL, NULL, info->error, info->user_data);
-}
-
-static void
-info_call_not_supported (MMModem *self,
- MMModemInfoFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- info = mm_callback_info_new_full (MM_MODEM (self), info_invoke, G_CALLBACK (callback), user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
-
- mm_callback_info_schedule (info);
-}
-
-void
-mm_modem_get_info (MMModem *self,
- MMModemInfoFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GET_INTERFACE (self)->get_info)
- MM_MODEM_GET_INTERFACE (self)->get_info (self, callback, user_data);
- else
- info_call_not_supported (self, callback, user_data);
-}
-
-static void
-impl_modem_get_info (MMModem *modem,
- DBusGMethodInvocation *context)
-{
- mm_modem_get_info (modem, info_call_done, context);
-}
-
-/*****************************************************************************/
-
-static void
-reset_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModem *self = MM_MODEM (owner);
- GError *error = NULL;
-
- /* Return any authorization error, otherwise try to reset the modem */
- if (!mm_modem_auth_finish (self, req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_reset (self, async_call_done, context);
-}
-
-static void
-impl_modem_reset (MMModem *modem, DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to reset the device */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_CONTROL,
- context,
- reset_auth_cb,
- NULL, NULL,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-void
-mm_modem_reset (MMModem *self,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GET_INTERFACE (self)->reset)
- MM_MODEM_GET_INTERFACE (self)->reset (self, callback, user_data);
- else
- async_op_not_supported (self, callback, user_data);
-}
-
-/*****************************************************************************/
-
-static void
-factory_reset_auth_cb (MMAuthRequest *req,
- GObject *owner,
- DBusGMethodInvocation *context,
- gpointer user_data)
-{
- MMModem *self = MM_MODEM (owner);
- const char *code = user_data;
- GError *error = NULL;
-
- /* Return any authorization error, otherwise try to reset the modem */
- if (!mm_modem_auth_finish (self, req, &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- } else
- mm_modem_factory_reset (self, code, async_call_done, context);
-}
-
-static void
-impl_modem_factory_reset (MMModem *modem,
- const char *code,
- DBusGMethodInvocation *context)
-{
- GError *error = NULL;
-
- /* Make sure the caller is authorized to reset the device */
- if (!mm_modem_auth_request (MM_MODEM (modem),
- MM_AUTHORIZATION_DEVICE_CONTROL,
- context,
- factory_reset_auth_cb,
- g_strdup (code),
- g_free,
- &error)) {
- dbus_g_method_return_error (context, error);
- g_error_free (error);
- }
-}
-
-void
-mm_modem_factory_reset (MMModem *self,
- const char *code,
- MMModemFn callback,
- gpointer user_data)
-{
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
- g_return_if_fail (code != NULL);
-
- if (MM_MODEM_GET_INTERFACE (self)->factory_reset)
- MM_MODEM_GET_INTERFACE (self)->factory_reset (self, code, callback, user_data);
- else
- async_op_not_supported (self, callback, user_data);
-}
-
-/*****************************************************************************/
-
-void
-mm_modem_get_supported_charsets (MMModem *self,
- MMModemUIntFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GET_INTERFACE (self)->get_supported_charsets)
- MM_MODEM_GET_INTERFACE (self)->get_supported_charsets (self, callback, user_data);
- else {
- info = mm_callback_info_uint_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-void
-mm_modem_set_charset (MMModem *self,
- MMModemCharset charset,
- MMModemFn callback,
- gpointer user_data)
-{
- MMCallbackInfo *info;
-
- g_return_if_fail (charset != MM_MODEM_CHARSET_UNKNOWN);
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (callback != NULL);
-
- if (MM_MODEM_GET_INTERFACE (self)->set_charset)
- MM_MODEM_GET_INTERFACE (self)->set_charset (self, charset, callback, user_data);
- else {
- info = mm_callback_info_new (MM_MODEM (self), callback, user_data);
- info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_OPERATION_NOT_SUPPORTED,
- "Operation not supported");
- mm_callback_info_schedule (info);
- }
-}
-
-/*****************************************************************************/
-
-gboolean
-mm_modem_owns_port (MMModem *self,
- const char *subsys,
- const char *name)
-{
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
- g_return_val_if_fail (subsys, FALSE);
- g_return_val_if_fail (name, FALSE);
-
- g_assert (MM_MODEM_GET_INTERFACE (self)->owns_port);
- return MM_MODEM_GET_INTERFACE (self)->owns_port (self, subsys, name);
-}
-
-gboolean
-mm_modem_grab_port (MMModem *self,
- const char *subsys,
- const char *name,
- MMPortType ptype,
- MMAtPortFlags at_pflags,
- gpointer user_data,
- GError **error)
-{
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
- g_return_val_if_fail (subsys, FALSE);
- g_return_val_if_fail (name, FALSE);
-
- g_assert (MM_MODEM_GET_INTERFACE (self)->grab_port);
- return MM_MODEM_GET_INTERFACE (self)->grab_port (self, subsys, name, ptype, at_pflags, user_data, error);
-}
-
-gboolean
-mm_modem_organize_ports (MMModem *self, GError **error)
-{
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
-
- g_assert (MM_MODEM_GET_INTERFACE (self)->organize_ports);
- return MM_MODEM_GET_INTERFACE (self)->organize_ports (self, error);
-}
-
-void
-mm_modem_release_port (MMModem *self,
- const char *subsys,
- const char *name)
-{
- g_return_if_fail (self != NULL);
- g_return_if_fail (MM_IS_MODEM (self));
- g_return_if_fail (subsys);
- g_return_if_fail (name);
-
- g_assert (MM_MODEM_GET_INTERFACE (self)->release_port);
- MM_MODEM_GET_INTERFACE (self)->release_port (self, subsys, name);
-}
-
-gboolean
-mm_modem_get_valid (MMModem *self)
-{
- gboolean valid = FALSE;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
-
- g_object_get (G_OBJECT (self), MM_MODEM_VALID, &valid, NULL);
- return valid;
-}
-
-char *
-mm_modem_get_device (MMModem *self)
-{
- char *device;
-
- g_return_val_if_fail (self != NULL, NULL);
- g_return_val_if_fail (MM_IS_MODEM (self), NULL);
-
- g_object_get (G_OBJECT (self), MM_MODEM_MASTER_DEVICE, &device, NULL);
- return device;
-}
-
-MMModemState
-mm_modem_get_state (MMModem *self)
-{
- MMModemState state = MM_MODEM_STATE_UNKNOWN;
-
- g_object_get (G_OBJECT (self), MM_MODEM_STATE, &state, NULL);
- return state;
-}
-
-static const char *
-state_to_string (MMModemState state)
-{
- switch (state) {
- case MM_MODEM_STATE_UNKNOWN:
- return "unknown";
- case MM_MODEM_STATE_DISABLED:
- return "disabled";
- case MM_MODEM_STATE_DISABLING:
- return "disabling";
- case MM_MODEM_STATE_ENABLING:
- return "enabling";
- case MM_MODEM_STATE_ENABLED:
- return "enabled";
- case MM_MODEM_STATE_SEARCHING:
- return "searching";
- case MM_MODEM_STATE_REGISTERED:
- return "registered";
- case MM_MODEM_STATE_DISCONNECTING:
- return "disconnecting";
- case MM_MODEM_STATE_CONNECTING:
- return "connecting";
- case MM_MODEM_STATE_CONNECTED:
- return "connected";
- default:
- g_assert_not_reached ();
- break;
- }
-
- g_assert_not_reached ();
- return "(invalid)";
-}
-
-void
-mm_modem_set_state (MMModem *self,
- MMModemState new_state,
- MMModemStateReason reason)
-{
- MMModemState old_state = MM_MODEM_STATE_UNKNOWN;
- const char *dbus_path;
-
- g_object_get (G_OBJECT (self), MM_MODEM_STATE, &old_state, NULL);
-
- if (new_state != old_state) {
- g_object_set (G_OBJECT (self), MM_MODEM_STATE, new_state, NULL);
- g_signal_emit_by_name (G_OBJECT (self), "state-changed", old_state, new_state, reason);
-
- dbus_path = (const char *) g_object_get_data (G_OBJECT (self), DBUS_PATH_TAG);
- if (dbus_path) {
- mm_info ("Modem %s: state changed (%s -> %s)",
- dbus_path,
- state_to_string (old_state),
- state_to_string (new_state));
- }
- }
-}
-
-/*****************************************************************************/
-
-gboolean
-mm_modem_auth_request (MMModem *self,
- const char *authorization,
- DBusGMethodInvocation *context,
- MMAuthRequestCb callback,
- gpointer callback_data,
- GDestroyNotify notify,
- GError **error)
-{
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
- g_return_val_if_fail (authorization != NULL, FALSE);
- g_return_val_if_fail (context != NULL, FALSE);
- g_return_val_if_fail (callback != NULL, FALSE);
-
- g_return_val_if_fail (MM_MODEM_GET_INTERFACE (self)->auth_request, FALSE);
- return MM_MODEM_GET_INTERFACE (self)->auth_request (self,
- authorization,
- context,
- callback,
- callback_data,
- notify,
- error);
-}
-
-gboolean
-mm_modem_auth_finish (MMModem *self,
- MMAuthRequest *req,
- GError **error)
-{
- gboolean success;
-
- g_return_val_if_fail (self != NULL, FALSE);
- g_return_val_if_fail (MM_IS_MODEM (self), FALSE);
- g_return_val_if_fail (req != NULL, FALSE);
-
- g_return_val_if_fail (MM_MODEM_GET_INTERFACE (self)->auth_finish, FALSE);
- success = MM_MODEM_GET_INTERFACE (self)->auth_finish (self, req, error);
-
- /* If the request failed, the implementor *should* return an error */
- if (!success && error)
- g_warn_if_fail (*error != NULL);
-
- return success;
-}
-
-/*****************************************************************************/
-
-static void
-mm_modem_init (gpointer g_iface)
-{
- GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
-
- /* Properties */
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_DATA_DEVICE,
- "Device",
- "Data device",
- NULL,
- G_PARAM_READWRITE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_MASTER_DEVICE,
- "MasterDevice",
- "Master modem parent device of all the modem's ports",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_DRIVER,
- "Driver",
- "Driver",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_PLUGIN,
- "Plugin",
- "Plugin name",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_TYPE,
- "Type",
- "Type",
- 0, G_MAXUINT32, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_IP_METHOD,
- "IP method",
- "IP configuration method",
- MM_MODEM_IP_METHOD_PPP,
- MM_MODEM_IP_METHOD_DHCP,
- MM_MODEM_IP_METHOD_PPP,
- G_PARAM_READWRITE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_IP_TIMEOUT,
- "IP timeout",
- "Maximum time to wait for a successful IP establishment, "
- "when PPP is used. Modems with special needs will set this "
- "property to a value greater than 0",
- 0, G_MAXUINT32, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_boolean (MM_MODEM_VALID,
- "Valid",
- "Modem is valid",
- FALSE,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_STATE,
- "State",
- "State",
- MM_MODEM_STATE_UNKNOWN,
- MM_MODEM_STATE_CONNECTED,
- MM_MODEM_STATE_UNKNOWN,
- G_PARAM_READWRITE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_boolean (MM_MODEM_ENABLED,
- "Enabled",
- "Modem is enabled",
- FALSE,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_EQUIPMENT_IDENTIFIER,
- "EquipmentIdentifier",
- "The equipment identifier of the device",
- NULL,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_DEVICE_IDENTIFIER,
- "DeviceIdentifier",
- "A best-effort identifer of the device",
- NULL,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_string (MM_MODEM_UNLOCK_REQUIRED,
- "UnlockRequired",
- "Whether or not the modem requires an unlock "
- "code to become usable, and if so, which unlock code is required",
- NULL,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_UNLOCK_RETRIES,
- "UnlockRetries",
- "The remaining number of unlock attempts",
- 0, G_MAXUINT32, 0,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_boxed (MM_MODEM_PIN_RETRY_COUNTS,
- "PinRetryCounts",
- "The remaining number of attempts for each PIN type",
- MM_MODEM_PIN_RETRY_COUNTS_PROP_TYPE,
- G_PARAM_READABLE));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_HW_VID,
- "Hardware vendor ID",
- "Hardware vendor ID",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_interface_install_property
- (g_iface,
- g_param_spec_uint (MM_MODEM_HW_PID,
- "Hardware product ID",
- "Hardware product ID",
- 0, G_MAXUINT, 0,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /* Signals */
- g_signal_new ("state-changed",
- iface_type,
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (MMModem, state_changed),
- NULL, NULL,
- mm_marshal_VOID__UINT_UINT_UINT,
- G_TYPE_NONE, 3,
- G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT);
-
- initialized = TRUE;
-}
-
-GType
-mm_modem_get_type (void)
-{
- static GType modem_type = 0;
-
- if (!G_UNLIKELY (modem_type)) {
- const GTypeInfo modem_info = {
- sizeof (MMModem), /* class_size */
- mm_modem_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- modem_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMModem",
- &modem_info, 0);
-
- g_type_interface_add_prerequisite (modem_type, G_TYPE_OBJECT);
-
- dbus_g_object_type_install_info (modem_type, &dbus_glib_mm_modem_object_info);
- }
-
- return modem_type;
-}
diff --git a/src/mm-modem.h b/src/mm-modem.h
deleted file mode 100644
index c4200645..00000000
--- a/src/mm-modem.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2008 - 2009 Novell, Inc.
- * Copyright (C) 2009 - 2010 Red Hat, Inc.
- */
-
-#ifndef MM_MODEM_H
-#define MM_MODEM_H
-
-#include <glib-object.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
-#include <ModemManager.h>
-
-#include "mm-port.h"
-#include "mm-at-serial-port.h"
-#include "mm-auth-provider.h"
-#include "mm-charsets.h"
-
-#define DBUS_PATH_TAG "dbus-path"
-
-#define MM_TYPE_MODEM (mm_modem_get_type ())
-#define MM_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM, MMModem))
-#define MM_IS_MODEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_MODEM))
-#define MM_MODEM_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_MODEM, MMModem))
-
-#define MM_MODEM_DATA_DEVICE "device"
-#define MM_MODEM_MASTER_DEVICE "master-device"
-#define MM_MODEM_DRIVER "driver"
-#define MM_MODEM_TYPE "type"
-#define MM_MODEM_IP_METHOD "ip-method"
-#define MM_MODEM_IP_TIMEOUT "ip-timeout"
-#define MM_MODEM_ENABLED "enabled"
-#define MM_MODEM_EQUIPMENT_IDENTIFIER "equipment-identifier"
-#define MM_MODEM_DEVICE_IDENTIFIER "device-identifier"
-#define MM_MODEM_UNLOCK_REQUIRED "unlock-required"
-#define MM_MODEM_UNLOCK_RETRIES "unlock-retries"
-#define MM_MODEM_PIN_RETRY_COUNTS "pin-retry-counts"
-#define MM_MODEM_VALID "valid" /* not exported */
-#define MM_MODEM_PLUGIN "plugin" /* not exported */
-#define MM_MODEM_STATE "state" /* not exported */
-#define MM_MODEM_HW_VID "hw-vid" /* not exported */
-#define MM_MODEM_HW_PID "hw-pid" /* not exported */
-
-#define MM_MODEM_UNLOCK_RETRIES_NOT_SUPPORTED 999
-
-typedef enum {
- MM_MODEM_PROP_FIRST = 0x1000,
-
- MM_MODEM_PROP_DATA_DEVICE = MM_MODEM_PROP_FIRST,
- MM_MODEM_PROP_MASTER_DEVICE,
- MM_MODEM_PROP_DRIVER,
- MM_MODEM_PROP_TYPE,
- MM_MODEM_PROP_IP_METHOD,
- MM_MODEM_PROP_VALID, /* Not exported */
- MM_MODEM_PROP_PLUGIN, /* Not exported */
- MM_MODEM_PROP_STATE, /* Not exported */
- MM_MODEM_PROP_ENABLED,
- MM_MODEM_PROP_EQUIPMENT_IDENTIFIER,
- MM_MODEM_PROP_UNLOCK_REQUIRED,
- MM_MODEM_PROP_UNLOCK_RETRIES,
- MM_MODEM_PROP_PIN_RETRY_COUNTS,
- MM_MODEM_PROP_DEVICE_IDENTIFIER,
- MM_MODEM_PROP_HW_VID, /* Not exported */
- MM_MODEM_PROP_HW_PID, /* Not exported */
- MM_MODEM_PROP_NETWORK_TIMEZONE,
- MM_MODEM_PROP_IP_TIMEOUT
-} MMModemProp;
-
-typedef struct _MMModem MMModem;
-
-typedef void (*MMModemFn) (MMModem *modem,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemUIntFn) (MMModem *modem,
- guint32 result,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemStringFn) (MMModem *modem,
- const char *result,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemIp4Fn) (MMModem *modem,
- guint32 address,
- GArray *dns,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemInfoFn) (MMModem *modem,
- const char *manufacturer,
- const char *model,
- const char *version,
- GError *error,
- gpointer user_data);
-
-typedef void (*MMModemArrayFn) (MMModem *modem,
- GArray *items,
- GError *error,
- gpointer user_data);
-
-struct _MMModem {
- GTypeInterface g_iface;
-
- /* Methods */
- gboolean (*owns_port) (MMModem *self,
- const char *subsys,
- const char *name);
-
- /* Subclasses use this function to claim a particular port */
- gboolean (*grab_port) (MMModem *self,
- const char *subsys,
- const char *name,
- MMPortType ptype,
- MMAtPortFlags at_pflags,
- gpointer user_data,
- GError **error);
-
- /* Subclasses use this function to determine which of their
- * grabbed ports should be used for data, command and status,
- * PPP, etc. Called after all ports have been detected and
- * grabbed by the modem.
- */
- gboolean (*organize_ports) (MMModem *self,
- GError **error);
-
- void (*release_port) (MMModem *self,
- const char *subsys,
- const char *name);
-
- void (*enable) (MMModem *self,
- MMModemFn callback,
- gpointer user_data);
-
- void (*disable) (MMModem *self,
- MMModemFn callback,
- gpointer user_data);
-
- void (*connect) (MMModem *self,
- const char *number,
- MMModemFn callback,
- gpointer user_data);
-
- void (*get_ip4_config) (MMModem *self,
- MMModemIp4Fn callback,
- gpointer user_data);
-
- void (*disconnect) (MMModem *self,
- MMModemFn callback,
- gpointer user_data);
-
- void (*get_info) (MMModem *self,
- MMModemInfoFn callback,
- gpointer user_data);
-
- void (*get_supported_charsets) (MMModem *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
- void (*set_charset) (MMModem *self,
- MMModemCharset charset,
- MMModemFn callback,
- gpointer user_data);
-
-
- /* Normally implemented by the modem base class; plugins should
- * never need to implement this.
- */
- gboolean (*auth_request) (MMModem *self,
- const char *authorization,
- DBusGMethodInvocation *context,
- MMAuthRequestCb callback,
- gpointer callback_data,
- GDestroyNotify notify,
- GError **error);
-
- gboolean (*auth_finish) (MMModem *self,
- MMAuthRequest *req,
- GError **error);
-
- void (*reset) (MMModem *self,
- MMModemFn callback,
- gpointer user_data);
-
- void (*factory_reset) (MMModem *self,
- const char *code,
- MMModemFn callback,
- gpointer user_data);
-
- /* Signals */
- void (*state_changed) (MMModem *self,
- MMModemState old_state,
- MMModemState new_state,
- MMModemStateReason reason);
-};
-
-GType mm_modem_get_type (void);
-
-gboolean mm_modem_owns_port (MMModem *self,
- const char *subsys,
- const char *name);
-
-gboolean mm_modem_grab_port (MMModem *self,
- const char *subsys,
- const char *name,
- MMPortType ptype,
- MMAtPortFlags at_pflags,
- gpointer user_data,
- GError **error);
-
-gboolean mm_modem_organize_ports (MMModem *self,
- GError **error);
-
-void mm_modem_release_port (MMModem *self,
- const char *subsys,
- const char *name);
-
-void mm_modem_enable (MMModem *self,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_disable (MMModem *self,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_connect (MMModem *self,
- const char *number,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_get_ip4_config (MMModem *self,
- MMModemIp4Fn callback,
- gpointer user_data);
-
-void mm_modem_disconnect (MMModem *self,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_get_info (MMModem *self,
- MMModemInfoFn callback,
- gpointer user_data);
-
-void mm_modem_get_supported_charsets (MMModem *self,
- MMModemUIntFn callback,
- gpointer user_data);
-
-void mm_modem_set_charset (MMModem *self,
- MMModemCharset charset,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_reset (MMModem *self,
- MMModemFn callback,
- gpointer user_data);
-
-void mm_modem_factory_reset (MMModem *self,
- const char *code,
- MMModemFn callback,
- gpointer user_data);
-
-gboolean mm_modem_get_valid (MMModem *self);
-
-char *mm_modem_get_device (MMModem *self);
-
-MMModemState mm_modem_get_state (MMModem *self);
-
-void mm_modem_set_state (MMModem *self,
- MMModemState new_state,
- MMModemStateReason reason);
-
-/* Request authorization to perform an action. Used by D-Bus method
- * handlers to ensure that the incoming request is authorized to perform
- * the action it's requesting.
- */
-gboolean mm_modem_auth_request (MMModem *self,
- const char *authorization,
- DBusGMethodInvocation *context,
- MMAuthRequestCb callback,
- gpointer callback_data,
- GDestroyNotify notify,
- GError **error);
-
-gboolean mm_modem_auth_finish (MMModem *self,
- MMAuthRequest *req,
- GError **error);
-
-#endif /* MM_MODEM_H */
-
diff --git a/src/mm-properties-changed-signal.c b/src/mm-properties-changed-signal.c
deleted file mode 100644
index 4408e80a..00000000
--- a/src/mm-properties-changed-signal.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2008 - 2010 Red Hat, Inc.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <dbus/dbus-glib.h>
-#include "mm-marshal.h"
-#include "mm-properties-changed-signal.h"
-#include "mm-properties-changed-glue.h"
-#include "mm-log.h"
-
-#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
-#define DBUS_TYPE_G_ARRAY_OF_STRING (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING))
-
-#define MM_PC_SIGNAL_NAME "mm-properties-changed"
-#define DBUS_PC_SIGNAL_NAME "properties-changed"
-#define MM_DBUS_PROPERTY_CHANGED "MM_DBUS_PROPERTY_CHANGED"
-
-/*****************************************************************************/
-
-typedef struct {
- char *real_property;
- char *interface;
-} ChangeInfo;
-
-typedef struct {
- /* Whitelist of GObject property names for which changes will be emitted
- * over the bus.
- *
- * Mapping of {property-name -> ChangeInfo}
- */
- GHashTable *registered;
-
- /* Table of each D-Bus interface of the object for which one or more
- * properties have changed, and those properties and their new values.
- * Destroyed after the changed signal has been sent.
- *
- * Mapping of {dbus-interface -> {property-name -> value}}
- */
- GHashTable *hash;
-
- guint idle_id;
-} PropertiesChangedInfo;
-
-static void
-destroy_value (gpointer data)
-{
- GValue *val = (GValue *) data;
-
- g_value_unset (val);
- g_slice_free (GValue, val);
-}
-
-static void
-change_info_free (gpointer data)
-{
- ChangeInfo *info = data;
-
- g_free (info->real_property);
- g_free (info->interface);
- memset (info, 0, sizeof (ChangeInfo));
- g_free (info);
-}
-
-static PropertiesChangedInfo *
-properties_changed_info_new (void)
-{
- PropertiesChangedInfo *info;
-
- info = g_slice_new0 (PropertiesChangedInfo);
-
- info->registered = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, change_info_free);
- info->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_hash_table_destroy);
- return info;
-}
-
-static void
-properties_changed_info_destroy (gpointer data)
-{
- PropertiesChangedInfo *info = (PropertiesChangedInfo *) data;
-
- if (info->idle_id)
- g_source_remove (info->idle_id);
-
- g_hash_table_destroy (info->hash);
- g_hash_table_destroy (info->registered);
- g_slice_free (PropertiesChangedInfo, info);
-}
-
-#ifdef DEBUG
-static void
-add_to_string (gpointer key, gpointer value, gpointer user_data)
-{
- char *buf = (char *) user_data;
- GValue str_val = { 0, };
-
- g_value_init (&str_val, G_TYPE_STRING);
- if (!g_value_transform ((GValue *) value, &str_val)) {
- if (G_VALUE_HOLDS_OBJECT (value)) {
- GObject *obj = g_value_get_object (value);
-
- if (g_value_get_object (value)) {
- sprintf (buf + strlen (buf), "{%s: %p (%s)}, ",
- (const char *) key, obj, G_OBJECT_TYPE_NAME (obj));
- } else {
- sprintf (buf + strlen (buf), "{%s: %p}, ", (const char *) key, obj);
- }
- } else
- sprintf (buf + strlen (buf), "{%s: <transform error>}, ", (const char *) key);
- } else {
- sprintf (buf + strlen (buf), "{%s: %s}, ", (const char *) key, g_value_get_string (&str_val));
- }
- g_value_unset (&str_val);
-}
-#endif
-
-static gboolean
-properties_changed (gpointer data)
-{
- GObject *object = G_OBJECT (data);
- PropertiesChangedInfo *info;
- GHashTableIter iter;
- gpointer key, value;
-
- info = (PropertiesChangedInfo *) g_object_get_data (object, MM_DBUS_PROPERTY_CHANGED);
- g_assert (info);
-
- g_hash_table_iter_init (&iter, info->hash);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- const char *interface = (const char *) key;
- GHashTable *props = (GHashTable *) value;
- GPtrArray *ignore = g_ptr_array_new ();
-
-#ifdef DEBUG
- {
- char buf[2048] = { 0, };
- g_hash_table_foreach (props, add_to_string, &buf);
- mm_dbg ("%s: %s -> (%s) %s", __func__,
- G_OBJECT_TYPE_NAME (object),
- interface,
- buf);
- }
-#endif
-
- /* Send the PropertiesChanged signal */
- g_signal_emit_by_name (object, MM_PC_SIGNAL_NAME, interface, props);
- g_signal_emit_by_name (object, DBUS_PC_SIGNAL_NAME, interface, props, ignore);
- g_ptr_array_free (ignore, TRUE);
- }
- g_hash_table_remove_all (info->hash);
-
- return FALSE;
-}
-
-static void
-idle_id_reset (gpointer data)
-{
- GObject *object = G_OBJECT (data);
- PropertiesChangedInfo *info = (PropertiesChangedInfo *) g_object_get_data (object, MM_DBUS_PROPERTY_CHANGED);
-
- /* info is unset when the object is being destroyed */
- if (info)
- info->idle_id = 0;
-}
-
-static char*
-uscore_to_wincaps (const char *uscore)
-{
- const char *p;
- GString *str;
- gboolean last_was_uscore;
-
- last_was_uscore = TRUE;
-
- str = g_string_new (NULL);
- p = uscore;
- while (p && *p) {
- if (*p == '-' || *p == '_')
- last_was_uscore = TRUE;
- else {
- if (last_was_uscore) {
- g_string_append_c (str, g_ascii_toupper (*p));
- last_was_uscore = FALSE;
- } else
- g_string_append_c (str, *p);
- }
- ++p;
- }
-
- return g_string_free (str, FALSE);
-}
-
-static PropertiesChangedInfo *
-get_properties_changed_info (GObject *object)
-{
- PropertiesChangedInfo *info = NULL;
-
- info = (PropertiesChangedInfo *) g_object_get_data (object, MM_DBUS_PROPERTY_CHANGED);
- if (!info) {
- info = properties_changed_info_new ();
- g_object_set_data_full (object, MM_DBUS_PROPERTY_CHANGED, info, properties_changed_info_destroy);
- }
-
- g_assert (info);
- return info;
-}
-
-static void
-notify (GObject *object, GParamSpec *pspec)
-{
- GHashTable *interfaces;
- PropertiesChangedInfo *info;
- ChangeInfo *ch_info;
- GValue *value;
-
- info = get_properties_changed_info (object);
-
- ch_info = g_hash_table_lookup (info->registered, pspec->name);
- if (!ch_info)
- return;
-
- /* Check if there are other changed properties for this interface already,
- * otherwise create a new hash table for all changed properties for this
- * D-Bus interface.
- */
- interfaces = g_hash_table_lookup (info->hash, ch_info->interface);
- if (!interfaces) {
- interfaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, destroy_value);
- g_hash_table_insert (info->hash, g_strdup (ch_info->interface), interfaces);
- }
-
- /* Now put the changed property value into the hash table of changed values
- * for its D-Bus interface.
- */
- value = g_slice_new0 (GValue);
- g_value_init (value, pspec->value_type);
- g_object_get_property (object, pspec->name, value);
-
- /* Use real property name, which takes shadow properties into accound */
- g_hash_table_insert (interfaces, uscore_to_wincaps (ch_info->real_property), value);
-
- if (!info->idle_id)
- info->idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, properties_changed, object, idle_id_reset);
-}
-
-void
-mm_properties_changed_signal_register_property (GObject *object,
- const char *gobject_property,
- const char *real_property,
- const char *interface)
-{
- PropertiesChangedInfo *info;
- ChangeInfo *ch_info;
-
- /* All exported properties need to be registered explicitly for now since
- * dbus-glib doesn't expose any method to find out the properties registered
- * in the XML.
- */
-
- info = get_properties_changed_info (object);
- ch_info = g_hash_table_lookup (info->registered, gobject_property);
- if (ch_info) {
- g_warning ("%s: property '%s' already registerd on interface '%s'",
- __func__, gobject_property, ch_info->interface);
- } else {
- ch_info = g_malloc0 (sizeof (ChangeInfo));
- ch_info->real_property = g_strdup (real_property ? real_property : gobject_property);
- ch_info->interface = g_strdup (interface);
- g_hash_table_insert (info->registered, g_strdup (gobject_property), ch_info);
- }
-}
-
-void
-mm_properties_changed_signal_enable (GObjectClass *object_class)
-{
- object_class->notify = notify;
-}
-
-/*****************************************************************************/
-
-static void
-mm_properties_changed_init (gpointer g_iface)
-{
- static gboolean initialized = FALSE;
-
- if (initialized)
- return;
-
- g_signal_new (MM_PC_SIGNAL_NAME,
- G_TYPE_FROM_INTERFACE (g_iface),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- mm_marshal_VOID__STRING_BOXED,
- G_TYPE_NONE, 2, G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT);
-
- g_signal_new (DBUS_PC_SIGNAL_NAME,
- G_TYPE_FROM_INTERFACE (g_iface),
- G_SIGNAL_RUN_FIRST,
- 0, NULL, NULL,
- mm_marshal_VOID__STRING_BOXED_BOXED,
- G_TYPE_NONE, 3,
- G_TYPE_STRING,
- DBUS_TYPE_G_MAP_OF_VARIANT,
- DBUS_TYPE_G_ARRAY_OF_STRING);
-
- initialized = TRUE;
-}
-
-GType
-mm_properties_changed_get_type (void)
-{
- static GType pc_type = 0;
-
- if (!G_UNLIKELY (pc_type)) {
- const GTypeInfo pc_info = {
- sizeof (MMPropertiesChanged), /* class_size */
- mm_properties_changed_init, /* base_init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
-
- pc_type = g_type_register_static (G_TYPE_INTERFACE,
- "MMPropertiesChanged",
- &pc_info, 0);
-
- g_type_interface_add_prerequisite (pc_type, G_TYPE_OBJECT);
- dbus_g_object_type_install_info (pc_type, &dbus_glib_mm_properties_changed_object_info);
- }
-
- return pc_type;
-}
diff --git a/src/mm-properties-changed-signal.h b/src/mm-properties-changed-signal.h
deleted file mode 100644
index a6d0f3ee..00000000
--- a/src/mm-properties-changed-signal.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2007 - 2008 Novell, Inc.
- * Copyright (C) 2008 - 2010 Red Hat, Inc.
- */
-
-#ifndef _MM_PROPERTIES_CHANGED_SIGNAL_H_
-#define _MM_PROPERTIES_CHANGED_SIGNAL_H_
-
-#include <glib-object.h>
-
-#define MM_TYPE_PROPERTIES_CHANGED (mm_properties_changed_get_type ())
-#define MM_PROPERTIES_CHANGED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PROPERTIES_CHANGED, MMPropertiesChanged))
-#define MM_IS_PROPERTIES_CHANGED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PROPERTIES_CHANGED))
-#define MM_PROPERTIES_CHANGED_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_PROPERTIES_CHANGED, MMPropertiesChanged))
-
-typedef struct {
- GTypeInterface g_iface;
-} MMPropertiesChanged;
-
-GType mm_properties_changed_get_type (void);
-
-void mm_properties_changed_signal_enable (GObjectClass *object_class);
-
-void mm_properties_changed_signal_register_property (GObject *object,
- const char *gobject_property,
- const char *real_property,
- const char *interface);
-
-#endif /* _MM_PROPERTIES_CHANGED_SIGNAL_H_ */
diff --git a/src/mm-sms-utils.c b/src/mm-sms-utils.c
deleted file mode 100644
index 928feb08..00000000
--- a/src/mm-sms-utils.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2011 Red Hat, Inc.
- */
-
-#include <ctype.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <ModemManager.h>
-#include <mm-errors-types.h>
-
-#include "mm-charsets.h"
-#include "mm-utils.h"
-#include "mm-sms-utils.h"
-#include "mm-log.h"
-#include "dbus/dbus-glib.h"
-
-#define SMS_TP_MTI_MASK 0x03
-#define SMS_TP_MTI_SMS_DELIVER 0x00
-#define SMS_TP_MTI_SMS_SUBMIT_REPORT 0x01
-#define SMS_TP_MTI_SMS_STATUS_REPORT 0x02
-
-#define SMS_NUMBER_TYPE_MASK 0x70
-#define SMS_NUMBER_TYPE_UNKNOWN 0x00
-#define SMS_NUMBER_TYPE_INTL 0x10
-#define SMS_NUMBER_TYPE_ALPHA 0x50
-
-#define SMS_NUMBER_PLAN_MASK 0x0f
-#define SMS_NUMBER_PLAN_TELEPHONE 0x01
-
-#define SMS_TP_MMS 0x04
-#define SMS_TP_SRI 0x20
-#define SMS_TP_UDHI 0x40
-#define SMS_TP_RP 0x80
-
-#define SMS_DCS_CODING_MASK 0xec
-#define SMS_DCS_CODING_DEFAULT 0x00
-#define SMS_DCS_CODING_8BIT 0x04
-#define SMS_DCS_CODING_UCS2 0x08
-
-#define SMS_DCS_CLASS_VALID 0x10
-#define SMS_DCS_CLASS_MASK 0x03
-
-#define SMS_TIMESTAMP_LEN 7
-#define SMS_MIN_PDU_LEN (7 + SMS_TIMESTAMP_LEN)
-
-typedef enum {
- MM_SMS_ENCODING_UNKNOWN = 0x0,
- MM_SMS_ENCODING_GSM7,
- MM_SMS_ENCODING_8BIT,
- MM_SMS_ENCODING_UCS2
-} SmsEncoding;
-
-static char sms_bcd_chars[] = "0123456789*#abc\0\0";
-
-static void
-sms_semi_octets_to_bcd_string (char *dest, const guint8 *octets, int num_octets)
-{
- int i;
-
- for (i = 0 ; i < num_octets; i++) {
- *dest++ = sms_bcd_chars[octets[i] & 0xf];
- *dest++ = sms_bcd_chars[(octets[i] >> 4) & 0xf];
- }
- *dest++ = '\0';
-}
-
-static gboolean
-char_to_bcd (char in, guint8 *out)
-{
- guint32 z;
-
- if (isdigit (in)) {
- *out = in - 0x30;
- return TRUE;
- }
-
- for (z = 10; z < 16; z++) {
- if (in == sms_bcd_chars[z]) {
- *out = z;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static gsize
-sms_string_to_bcd_semi_octets (guint8 *buf, gsize buflen, const char *string)
-{
- guint i;
- guint8 bcd;
- gsize addrlen, slen;
-
- addrlen = slen = strlen (string);
- if (addrlen % 2)
- addrlen++;
- g_return_val_if_fail (buflen >= addrlen, 0);
-
- for (i = 0; i < addrlen; i += 2) {
- if (!char_to_bcd (string[i], &bcd))
- return 0;
- buf[i / 2] = bcd & 0xF;
-
- if (i >= slen - 1) {
- /* PDU address gets padded with 0xF if string is odd length */
- bcd = 0xF;
- } else if (!char_to_bcd (string[i + 1], &bcd))
- return 0;
- buf[i / 2] |= bcd << 4;
- }
- return addrlen / 2;
-}
-
-/**
- * sms_encode_address:
- *
- * @address: the phone number to encode
- * @buf: the buffer to encode @address in
- * @buflen: the size of @buf
- * @is_smsc: if %TRUE encode size as number of octets of address infromation,
- * otherwise if %FALSE encode size as number of digits of @address
- *
- * Returns: the size in bytes of the data added to @buf
- **/
-guint
-sms_encode_address (const char *address,
- guint8 *buf,
- size_t buflen,
- gboolean is_smsc)
-{
- gsize len;
-
- g_return_val_if_fail (address != NULL, 0);
- g_return_val_if_fail (buf != NULL, 0);
- g_return_val_if_fail (buflen >= 2, 0);
-
- /* Handle number type & plan */
- buf[1] = 0x80; /* Bit 7 always 1 */
- if (address[0] == '+') {
- buf[1] |= SMS_NUMBER_TYPE_INTL;
- address++;
- }
- buf[1] |= SMS_NUMBER_PLAN_TELEPHONE;
-
- len = sms_string_to_bcd_semi_octets (&buf[2], buflen, address);
-
- if (is_smsc)
- buf[0] = len + 1; /* addr length + size byte */
- else
- buf[0] = strlen (address); /* number of digits in address */
-
- return len ? len + 2 : 0; /* addr length + size byte + number type/plan */
-}
-
-/* len is in semi-octets */
-static char *
-sms_decode_address (const guint8 *address, int len)
-{
- guint8 addrtype, addrplan;
- char *utf8;
-
- addrtype = address[0] & SMS_NUMBER_TYPE_MASK;
- addrplan = address[0] & SMS_NUMBER_PLAN_MASK;
- address++;
-
- if (addrtype == SMS_NUMBER_TYPE_ALPHA) {
- guint8 *unpacked;
- guint32 unpacked_len;
- unpacked = gsm_unpack (address, (len * 4) / 7, 0, &unpacked_len);
- utf8 = (char *)mm_charset_gsm_unpacked_to_utf8 (unpacked,
- unpacked_len);
- g_free(unpacked);
- } else if (addrtype == SMS_NUMBER_TYPE_INTL &&
- addrplan == SMS_NUMBER_PLAN_TELEPHONE) {
- /* International telphone number, format as "+1234567890" */
- utf8 = g_malloc (len + 3); /* '+' + digits + possible trailing 0xf + NUL */
- utf8[0] = '+';
- sms_semi_octets_to_bcd_string (utf8 + 1, address, (len + 1) / 2);
- } else {
- /*
- * All non-alphanumeric types and plans are just digits, but
- * don't apply any special formatting if we don't know the
- * format.
- */
- utf8 = g_malloc (len + 2); /* digits + possible trailing 0xf + NUL */
- sms_semi_octets_to_bcd_string (utf8, address, (len + 1) / 2);
- }
-
- return utf8;
-}
-
-
-static char *
-sms_decode_timestamp (const guint8 *timestamp)
-{
- /* YYMMDDHHMMSS+ZZ */
- char *timestr;
- int quarters, hours;
-
- timestr = g_malloc0 (16);
- sms_semi_octets_to_bcd_string (timestr, timestamp, 6);
- quarters = ((timestamp[6] & 0x7) * 10) + ((timestamp[6] >> 4) & 0xf);
- hours = quarters / 4;
- if (timestamp[6] & 0x08)
- timestr[12] = '-';
- else
- timestr[12] = '+';
- timestr[13] = (hours / 10) + '0';
- timestr[14] = (hours % 10) + '0';
- /* TODO(njw): Change timestamp rep to something that includes quarter-hours */
- return timestr;
-}
-
-static SmsEncoding
-sms_encoding_type (int dcs)
-{
- SmsEncoding scheme = MM_SMS_ENCODING_UNKNOWN;
-
- switch ((dcs >> 4) & 0xf) {
- /* General data coding group */
- case 0: case 1:
- case 2: case 3:
- switch (dcs & 0x0c) {
- case 0x08:
- scheme = MM_SMS_ENCODING_UCS2;
- break;
- case 0x00:
- /* fallthrough */
- /* reserved - spec says to treat it as default alphabet */
- case 0x0c:
- scheme = MM_SMS_ENCODING_GSM7;
- break;
- case 0x04:
- scheme = MM_SMS_ENCODING_8BIT;
- break;
- }
- break;
-
- /* Message waiting group (default alphabet) */
- case 0xc:
- case 0xd:
- scheme = MM_SMS_ENCODING_GSM7;
- break;
-
- /* Message waiting group (UCS2 alphabet) */
- case 0xe:
- scheme = MM_SMS_ENCODING_UCS2;
- break;
-
- /* Data coding/message class group */
- case 0xf:
- switch (dcs & 0x04) {
- case 0x00:
- scheme = MM_SMS_ENCODING_GSM7;
- break;
- case 0x04:
- scheme = MM_SMS_ENCODING_8BIT;
- break;
- }
- break;
-
- /* Reserved coding group values - spec says to treat it as default alphabet */
- default:
- scheme = MM_SMS_ENCODING_GSM7;
- break;
- }
-
- return scheme;
-
-}
-
-static char *
-sms_decode_text (const guint8 *text, int len, SmsEncoding encoding, int bit_offset)
-{
- char *utf8;
- guint8 *unpacked;
- guint32 unpacked_len;
-
- if (encoding == MM_SMS_ENCODING_GSM7) {
- unpacked = gsm_unpack ((const guint8 *) text, len, bit_offset, &unpacked_len);
- utf8 = (char *) mm_charset_gsm_unpacked_to_utf8 (unpacked, unpacked_len);
- g_free (unpacked);
- } else if (encoding == MM_SMS_ENCODING_UCS2)
- utf8 = g_convert ((char *) text, len, "UTF8", "UCS-2BE", NULL, NULL, NULL);
- else {
- g_warn_if_reached ();
- utf8 = g_strdup ("");
- }
-
- return utf8;
-}
-
-static void
-simple_free_gvalue (gpointer data)
-{
- g_value_unset ((GValue *) data);
- g_slice_free (GValue, data);
-}
-
-
-
-static GValue *
-simple_uint_value (guint32 i)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_UINT);
- g_value_set_uint (val, i);
-
- return val;
-}
-
-static GValue *
-simple_string_value (const char *str)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, G_TYPE_STRING);
- g_value_set_string (val, str);
-
- return val;
-}
-
-static GValue *
-byte_array_value (const GByteArray *array)
-{
- GValue *val;
-
- val = g_slice_new0 (GValue);
- g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY);
- g_value_set_boxed (val, array);
-
- return val;
-}
-
-GHashTable *
-sms_properties_hash_new (const char *smsc,
- const char *number,
- const char *timestamp,
- const char *text,
- const GByteArray *data,
- guint data_coding_scheme,
- guint *class)
-{
- GHashTable *properties;
-
- g_return_val_if_fail (number != NULL, NULL);
- g_return_val_if_fail (text != NULL, NULL);
- g_return_val_if_fail (data != NULL, NULL);
-
- properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, simple_free_gvalue);
- g_hash_table_insert (properties, "number", simple_string_value (number));
- g_hash_table_insert (properties, "data", byte_array_value (data));
- g_hash_table_insert (properties, "data-coding-scheme", simple_uint_value (data_coding_scheme));
- g_hash_table_insert (properties, "text", simple_string_value (text));
-
- if (smsc)
- g_hash_table_insert (properties, "smsc", simple_string_value (smsc));
-
- if (timestamp)
- g_hash_table_insert (properties, "timestamp", simple_string_value (timestamp));
-
- if (class)
- g_hash_table_insert (properties, "class", simple_uint_value (*class));
-
- return properties;
-}
-
-GHashTable *
-sms_parse_pdu (const char *hexpdu, GError **error)
-{
- GHashTable *properties;
- gsize pdu_len;
- guint8 *pdu;
- guint smsc_addr_num_octets, variable_length_items, msg_start_offset,
- sender_addr_num_digits, sender_addr_num_octets,
- tp_pid_offset, tp_dcs_offset, user_data_offset, user_data_len,
- user_data_len_offset, bit_offset;
- char *smsc_addr, *sender_addr, *sc_timestamp, *msg_text;
- SmsEncoding user_data_encoding;
- GByteArray *pdu_data;
- guint concat_ref = 0, concat_max = 0, concat_seq = 0, msg_class = 0;
- gboolean multipart = FALSE, class_valid = FALSE;
-
- /* Convert PDU from hex to binary */
- pdu = (guint8 *) utils_hexstr2bin (hexpdu, &pdu_len);
- if (!pdu) {
- g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Couldn't parse PDU of SMS GET response from hex");
- return NULL;
- }
-
- /* SMSC, in address format, precedes the TPDU */
- smsc_addr_num_octets = pdu[0];
- variable_length_items = smsc_addr_num_octets;
- if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "PDU too short (1): %zd vs %d",
- pdu_len,
- variable_length_items + SMS_MIN_PDU_LEN);
- g_free (pdu);
- return NULL;
- }
-
- /* where in the PDU the actual SMS protocol message begins */
- msg_start_offset = 1 + smsc_addr_num_octets;
- sender_addr_num_digits = pdu[msg_start_offset + 1];
- /*
- * round the sender address length up to an even number of
- * semi-octets, and thus an integral number of octets
- */
- sender_addr_num_octets = (sender_addr_num_digits + 1) >> 1;
- variable_length_items += sender_addr_num_octets;
- if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "PDU too short (2): %zd vs %d",
- pdu_len,
- variable_length_items + SMS_MIN_PDU_LEN);
- g_free (pdu);
- return NULL;
- }
-
- tp_pid_offset = msg_start_offset + 3 + sender_addr_num_octets;
- tp_dcs_offset = tp_pid_offset + 1;
-
- user_data_len_offset = tp_dcs_offset + 1 + SMS_TIMESTAMP_LEN;
- user_data_offset = user_data_len_offset + 1;
- user_data_len = pdu[user_data_len_offset];
- user_data_encoding = sms_encoding_type(pdu[tp_dcs_offset]);
- if (user_data_encoding == MM_SMS_ENCODING_GSM7)
- variable_length_items += (7 * (user_data_len + 1 )) / 8;
- else
- variable_length_items += user_data_len;
- if (pdu_len < variable_length_items + SMS_MIN_PDU_LEN) {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "PDU too short (3): %zd vs %d",
- pdu_len,
- variable_length_items + SMS_MIN_PDU_LEN);
- g_free (pdu);
- return NULL;
- }
-
- /* Only handle SMS-DELIVER */
- if ((pdu[msg_start_offset] & SMS_TP_MTI_MASK) != SMS_TP_MTI_SMS_DELIVER) {
- g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
- "Unhandled message type: 0x%02x",
- pdu[msg_start_offset]);
- g_free (pdu);
- return NULL;
- }
-
- bit_offset = 0;
- if (pdu[msg_start_offset] & SMS_TP_UDHI) {
- int udhl, end, offset;
- udhl = pdu[user_data_offset] + 1;
- end = user_data_offset + udhl;
-
- for (offset = user_data_offset + 1; offset < end;) {
- guint8 ie_id, ie_len;
-
- ie_id = pdu[offset++];
- ie_len = pdu[offset++];
-
- switch (ie_id) {
- case 0x00:
- /*
- * Ignore the IE if one of the following is true:
- * - it claims to be part 0 of M
- * - it claims to be part N of M, N > M
- */
- if (pdu[offset + 2] == 0 ||
- pdu[offset + 2] > pdu[offset + 1])
- break;
-
- concat_ref = pdu[offset];
- concat_max = pdu[offset + 1];
- concat_seq = pdu[offset + 2];
- multipart = TRUE;
- break;
- case 0x08:
- /* Concatenated short message, 16-bit reference */
- if (pdu[offset + 3] == 0 ||
- pdu[offset + 3] > pdu[offset + 2])
- break;
-
- concat_ref = (pdu[offset] << 8) | pdu[offset + 1];
- concat_max = pdu[offset + 2];
- concat_seq = pdu[offset + 3];
- multipart = TRUE;
- break;
- }
-
- offset += ie_len;
- }
-
- /*
- * Move past the user data headers to prevent it from being
- * decoded into garbage text.
- */
- user_data_offset += udhl;
- if (user_data_encoding == MM_SMS_ENCODING_GSM7) {
- /*
- * Find the number of bits we need to add to the length of the
- * user data to get a multiple of 7 (the padding).
- */
- bit_offset = (7 - udhl % 7) % 7;
- user_data_len -= (udhl * 8 + bit_offset) / 7;
- } else
- user_data_len -= udhl;
- }
-
- if ( user_data_encoding == MM_SMS_ENCODING_8BIT
- || user_data_encoding == MM_SMS_ENCODING_UNKNOWN) {
- /* 8-bit encoding is usually binary data, and we have no idea what
- * actual encoding the data is in so we can't convert it.
- */
- msg_text = g_strdup ("");
- } else {
- /* Otherwise if it's 7-bit or UCS2 we can decode it */
- msg_text = sms_decode_text (&pdu[user_data_offset], user_data_len,
- user_data_encoding, bit_offset);
- g_warn_if_fail (msg_text != NULL);
- }
-
- /* Raw PDU data */
- pdu_data = g_byte_array_sized_new (user_data_len);
- g_byte_array_append (pdu_data, &pdu[user_data_offset], user_data_len);
-
- if (pdu[tp_dcs_offset] & SMS_DCS_CLASS_VALID) {
- msg_class = pdu[tp_dcs_offset] & SMS_DCS_CLASS_MASK;
- class_valid = TRUE;
- }
-
- smsc_addr = sms_decode_address (&pdu[1], 2 * (pdu[0] - 1));
- sender_addr = sms_decode_address (&pdu[msg_start_offset + 2], pdu[msg_start_offset + 1]);
- sc_timestamp = sms_decode_timestamp (&pdu[tp_dcs_offset + 1]);
-
- properties = sms_properties_hash_new (smsc_addr,
- sender_addr,
- sc_timestamp,
- msg_text,
- pdu_data,
- pdu[tp_dcs_offset] & 0xFF,
- class_valid ? &msg_class : NULL);
- g_assert (properties);
- if (multipart) {
- g_hash_table_insert (properties, "concat-reference", simple_uint_value (concat_ref));
- g_hash_table_insert (properties, "concat-max", simple_uint_value (concat_max));
- g_hash_table_insert (properties, "concat-sequence", simple_uint_value (concat_seq));
- }
-
- g_free (smsc_addr);
- g_free (sender_addr);
- g_free (sc_timestamp);
- g_free (msg_text);
- g_byte_array_free (pdu_data, TRUE);
- g_free (pdu);
-
- return properties;
-}
-
-static guint8
-validity_to_relative (guint validity)
-{
- if (validity == 0)
- return 167; /* 24 hours */
-
- if (validity <= 720) {
- /* 5 minute units up to 12 hours */
- if (validity % 5)
- validity += 5;
- return (validity / 5) - 1;
- }
-
- if (validity > 720 && validity <= 1440) {
- /* 12 hours + 30 minute units up to 1 day */
- if (validity % 30)
- validity += 30; /* round up to next 30 minutes */
- validity = MIN (validity, 1440);
- return 143 + ((validity - 720) / 30);
- }
-
- if (validity > 1440 && validity <= 43200) {
- /* 2 days up to 1 month */
- if (validity % 1440)
- validity += 1440; /* round up to next day */
- validity = MIN (validity, 43200);
- return 167 + ((validity - 1440) / 1440);
- }
-
- /* 43200 = 30 days in minutes
- * 10080 = 7 days in minutes
- * 635040 = 63 weeks in minutes
- * 40320 = 4 weeks in minutes
- */
- if (validity > 43200 && validity <= 635040) {
- /* 5 weeks up to 63 weeks */
- if (validity % 10080)
- validity += 10080; /* round up to next week */
- validity = MIN (validity, 635040);
- return 196 + ((validity - 40320) / 10080);
- }
-
- return 255; /* 63 weeks */
-}
-
-#define PDU_SIZE 200
-
-/**
- * sms_create_submit_pdu:
- *
- * @number: the subscriber number to send this message to
- * @text: the body of this SMS
- * @smsc: if given, the SMSC address
- * @validity: minutes until the SMS should expire in the SMSC, or 0 for a
- * suitable default
- * @class: unused
- * @out_pdulen: on success, the size of the returned PDU in bytes
- * @out_msgstart: on success, the byte index in the returned PDU where the
- * message starts (ie, skipping the SMSC length byte and address, if present)
- * @error: on error, filled with the error that occurred
- *
- * Constructs a single-part SMS message with the given details, preferring to
- * use the UCS2 character set when the message will fit, otherwise falling back
- * to the GSM character set.
- *
- * Returns: the constructed PDU data on success, or %NULL on error
- **/
-guint8 *
-sms_create_submit_pdu (const char *number,
- const char *text,
- const char *smsc,
- guint validity,
- guint class,
- guint *out_pdulen,
- guint *out_msgstart,
- GError **error)
-{
- guint8 *pdu;
- guint len, offset = 0;
- MMModemCharset best_cs = MM_MODEM_CHARSET_GSM;
- guint ucs2len = 0, gsm_unsupported = 0;
- guint textlen = 0;
-
- g_return_val_if_fail (number != NULL, NULL);
- g_return_val_if_fail (text != NULL, NULL);
-
- /* FIXME: support multiple fragments */
-
- textlen = mm_charset_get_encoded_len (text, MM_MODEM_CHARSET_GSM, &gsm_unsupported);
- if (textlen > 160) {
- g_set_error_literal (error,
- MM_CORE_ERROR,
- MM_CORE_ERROR_UNSUPPORTED,
- "Cannot encode message to fit into an SMS.");
- return NULL;
- }
-
- /* If there are characters that are unsupported in the GSM charset, try
- * UCS2. If the UCS2 encoded string is too long to fit in an SMS, then
- * just use GSM and suck up the unconverted chars.
- */
- if (gsm_unsupported > 0) {
- ucs2len = mm_charset_get_encoded_len (text, MM_MODEM_CHARSET_UCS2, NULL);
- if (ucs2len <= 140) {
- best_cs = MM_MODEM_CHARSET_UCS2;
- textlen = ucs2len;
- }
- }
-
- /* Build up the PDU */
- pdu = g_malloc0 (PDU_SIZE);
- g_return_val_if_fail (pdu != NULL, NULL);
-
- if (smsc) {
- len = sms_encode_address (smsc, pdu, PDU_SIZE, TRUE);
- if (len == 0) {
- g_set_error (error,
- MM_MESSAGE_ERROR,
- MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER,
- "Invalid SMSC address '%s'", smsc);
- goto error;
- }
- offset += len;
- } else {
- /* No SMSC, use default */
- pdu[offset++] = 0x00;
- }
-
- if (out_msgstart)
- *out_msgstart = offset;
-
- if (validity > 0)
- pdu[offset] = 1 << 4; /* TP-VP present; format RELATIVE */
- else
- pdu[offset] = 0; /* TP-VP not present */
- pdu[offset++] |= 0x01; /* TP-MTI = SMS-SUBMIT */
-
- pdu[offset++] = 0x00; /* TP-Message-Reference: filled by device */
-
- len = sms_encode_address (number, &pdu[offset], PDU_SIZE - offset, FALSE);
- if (len == 0) {
- g_set_error (error,
- MM_MESSAGE_ERROR,
- MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER,
- "Invalid send-to number '%s'", number);
- goto error;
- }
- offset += len;
-
- /* TP-PID */
- pdu[offset++] = 0x00;
-
- /* TP-DCS */
- if (best_cs == MM_MODEM_CHARSET_UCS2)
- pdu[offset++] = 0x08;
- else
- pdu[offset++] = 0x00; /* GSM */
-
- /* TP-Validity-Period: 4 days */
- if (validity > 0)
- pdu[offset++] = validity_to_relative (validity);
-
- /* TP-User-Data-Length */
- pdu[offset++] = textlen;
-
- if (best_cs == MM_MODEM_CHARSET_GSM) {
- guint8 *unpacked, *packed;
- guint32 unlen = 0, packlen = 0;
-
- unpacked = mm_charset_utf8_to_unpacked_gsm (text, &unlen);
- if (!unpacked || unlen == 0) {
- g_free (unpacked);
- g_set_error_literal (error,
- MM_MESSAGE_ERROR,
- MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER,
- "Failed to convert message text to GSM.");
- goto error;
- }
-
- packed = gsm_pack (unpacked, unlen, 0, &packlen);
- g_free (unpacked);
- if (!packed || packlen == 0) {
- g_free (packed);
- g_set_error_literal (error,
- MM_MESSAGE_ERROR,
- MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER,
- "Failed to pack message text to GSM.");
- goto error;
- }
-
- memcpy (&pdu[offset], packed, packlen);
- g_free (packed);
- offset += packlen;
- } else if (best_cs == MM_MODEM_CHARSET_UCS2) {
- GByteArray *array;
-
- array = g_byte_array_sized_new (textlen / 2);
- if (!mm_modem_charset_byte_array_append (array, text, FALSE, best_cs)) {
- g_byte_array_free (array, TRUE);
- g_set_error_literal (error,
- MM_MESSAGE_ERROR,
- MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER,
- "Failed to convert message text to UCS2.");
- goto error;
- }
-
- memcpy (&pdu[offset], array->data, array->len);
- offset += array->len;
- g_byte_array_free (array, TRUE);
- } else
- g_assert_not_reached ();
-
- if (out_pdulen)
- *out_pdulen = offset;
- return pdu;
-
-error:
- g_free (pdu);
- return NULL;
-}
diff --git a/src/mm-sms-utils.h b/src/mm-sms-utils.h
deleted file mode 100644
index 46f475b1..00000000
--- a/src/mm-sms-utils.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details:
- *
- * Copyright (C) 2010 Red Hat, Inc.
- */
-
-#ifndef MM_SMS_UTILS_H
-#define MM_SMS_UTILS_H
-
-#include <glib.h>
-
-#define SMS_MAX_PDU_LEN 344
-
-GHashTable *sms_parse_pdu (const char *hexpdu, GError **error);
-
-guint8 *sms_create_submit_pdu (const char *number,
- const char *text,
- const char *smsc,
- guint validity,
- guint class,
- guint *out_pdulen,
- guint *out_msgstart,
- GError **error);
-
-GHashTable *sms_properties_hash_new (const char *smsc,
- const char *number,
- const char *timestamp,
- const char *text,
- const GByteArray *data,
- guint data_coding_scheme,
- guint *class);
-
-/* For testcases only */
-guint sms_encode_address (const char *address,
- guint8 *buf,
- size_t buflen,
- gboolean is_smsc);
-
-
-#endif /* MM_SMS_UTILS_H */