aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am2
-rw-r--r--src/mm-at.c258
-rw-r--r--src/mm-at.h90
-rw-r--r--src/mm-broadband-modem.c1273
-rw-r--r--src/mm-iface-modem.c2
-rw-r--r--src/mm-sim.c537
6 files changed, 762 insertions, 1400 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index eb0dd3da..58c1504b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -101,8 +101,6 @@ modem_manager_SOURCES = \
main.c \
mm-log.c \
mm-log.h \
- mm-at.h \
- mm-at.c \
mm-callback-info.c \
mm-callback-info.h \
$(auth_sources) \
diff --git a/src/mm-at.c b/src/mm-at.c
deleted file mode 100644
index 81235377..00000000
--- a/src/mm-at.c
+++ /dev/null
@@ -1,258 +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 Aleksander Morgado <aleksander@gnu.org>
- */
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include <ModemManager.h>
-
-#include "mm-at.h"
-#include "mm-errors-types.h"
-
-typedef struct {
- GObject *owner;
- MMAtSerialPort *port;
- GCancellable *cancellable;
- MMAtCommand *current;
- MMAtCommand *sequence;
- gboolean sequence_free;
- GSimpleAsyncResult *result;
- gchar *result_signature;
- gpointer response_processor_context;
-} AtSequenceContext;
-
-static void
-at_sequence_free (MMAtCommand *sequence)
-{
- MMAtCommand *it;
-
- for (it = sequence; it->command; it++)
- g_free (it->command);
-
- g_free (sequence);
-}
-
-static void
-at_sequence_context_free (AtSequenceContext *ctx)
-{
- if (ctx->sequence_free)
- at_sequence_free (ctx->sequence);
- if (ctx->owner)
- g_object_unref (ctx->owner);
- if (ctx->cancellable)
- g_object_unref (ctx->cancellable);
- g_free (ctx->result_signature);
- g_object_unref (ctx->port);
- g_object_unref (ctx->result);
- g_free (ctx);
-}
-
-static void
-at_sequence_parse_response (MMAtSerialPort *port,
- GString *response,
- GError *error,
- AtSequenceContext *ctx)
-{
- GVariant *result = NULL;
- GError *result_error = NULL;
- gboolean continue_sequence;
-
- /* Cancelled? */
- if (g_cancellable_is_cancelled (ctx->cancellable)) {
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_CANCELLED,
- "AT sequence was cancelled");
- g_simple_async_result_complete (ctx->result);
- at_sequence_context_free (ctx);
- return;
- }
-
- /* Translate the AT response into a GVariant with the expected signature */
- if (!ctx->current->response_processor)
- /* No need to process response, go on to next command */
- continue_sequence = TRUE;
- else {
- /* Response processor will tell us if we need to keep on the sequence */
- continue_sequence = !ctx->current->response_processor (
- ctx->owner,
- ctx->response_processor_context,
- ctx->current->command,
- response->str,
- error,
- &result,
- &result_error);
- /* Were we told to abort the sequence? */
- if (result_error) {
- g_assert (result == NULL);
- g_simple_async_result_take_error (ctx->result, result_error);
- g_simple_async_result_complete (ctx->result);
- at_sequence_context_free (ctx);
- return;
- }
- }
-
- if (continue_sequence) {
- g_assert (result == NULL);
- ctx->current++;
- if (ctx->current->command) {
- /* Schedule the next command in the probing group */
- mm_at_serial_port_queue_command (
- ctx->port,
- ctx->current->command,
- ctx->current->timeout,
- (MMAtSerialResponseFn)at_sequence_parse_response,
- ctx);
- return;
- }
-
- /* On last command, end. */
- }
-
- /* Maybe we do not expect/need any result */
- if (!ctx->result_signature) {
- g_assert (result == NULL);
- g_simple_async_result_set_op_res_gpointer (ctx->result, NULL, NULL);
- }
- /* If we do expect one but got none, set error */
- else if (!result) {
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Expecting result type '%s', got none",
- ctx->result_signature);
- }
- /* Check if the result we got is of the type we expected */
- else if (!g_str_equal (g_variant_get_type_string (result),
- ctx->result_signature)) {
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Expecting result type '%s', got '%s'",
- ctx->result_signature,
- g_variant_get_type_string (result));
- }
- /* We got a valid expected reply */
- else {
- g_simple_async_result_set_op_res_gpointer (ctx->result,
- g_variant_ref (result),
- (GDestroyNotify)g_variant_unref);
- }
-
- if (result)
- g_variant_unref (result);
- g_simple_async_result_complete (ctx->result);
- at_sequence_context_free (ctx);
-}
-
-GVariant *
-mm_at_sequence_finish (GObject *owner,
- GAsyncResult *res,
- GError **error)
-{
- GVariant *result;
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res),
- error))
- return NULL;
-
- result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
-
- return (result ? g_variant_ref (result) : NULL);
-}
-
-void
-mm_at_sequence (GObject *owner,
- MMAtSerialPort *port,
- MMAtCommand *sequence,
- gpointer response_processor_context,
- gboolean sequence_free,
- const gchar *result_signature,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- AtSequenceContext *ctx;
-
- g_return_if_fail (MM_IS_AT_SERIAL_PORT (port));
- g_return_if_fail (sequence != NULL);
- g_return_if_fail (callback != NULL);
-
- ctx = g_new (AtSequenceContext, 1);
- ctx->owner = owner ? g_object_ref (owner) : NULL;
- ctx->port = g_object_ref (port);
- ctx->result_signature = g_strdup (result_signature);
- ctx->cancellable = (cancellable ?
- g_object_ref (cancellable) :
- NULL);
- ctx->result = g_simple_async_result_new (owner,
- callback,
- user_data,
- mm_at_sequence);
- ctx->current = ctx->sequence = sequence;
- ctx->sequence_free = sequence_free;
- ctx->response_processor_context = response_processor_context;
-
- mm_at_serial_port_queue_command (
- ctx->port,
- ctx->current->command,
- ctx->current->timeout,
- (MMAtSerialResponseFn)at_sequence_parse_response,
- ctx);
-}
-
-GVariant *
-mm_at_command_finish (GObject *owner,
- GAsyncResult *res,
- GError **error)
-{
- return mm_at_sequence_finish (owner, res, error);
-}
-
-void
-mm_at_command (GObject *owner,
- MMAtSerialPort *port,
- const gchar *command,
- guint timeout,
- const MMAtResponseProcessor response_processor,
- gpointer response_processor_context,
- const gchar *result_signature,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- MMAtCommand *sequence;
-
- g_return_if_fail (MM_IS_AT_SERIAL_PORT (port));
- g_return_if_fail (command != NULL);
- g_return_if_fail (response_processor != NULL ||
- result_signature == NULL);
- g_return_if_fail (callback != NULL);
-
- sequence = g_new0 (MMAtCommand, 2);
- sequence->command = g_strdup (command);
- sequence->timeout = timeout;
- sequence->response_processor = response_processor;
-
- mm_at_sequence (owner,
- port,
- sequence,
- response_processor_context,
- TRUE,
- result_signature,
- cancellable,
- callback,
- user_data);
-}
diff --git a/src/mm-at.h b/src/mm-at.h
deleted file mode 100644
index c0f24dd5..00000000
--- a/src/mm-at.h
+++ /dev/null
@@ -1,90 +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 Aleksander Morgado <aleksander@gnu.org>
- */
-
-#ifndef MM_AT_H
-#define MM_AT_H
-
-#include <gio/gio.h>
-
-#include "mm-at-serial-port.h"
-
-/*
- * The expected result depends on the specific operation, so the GVariant
- * created by the response processor needs to match the signature given
- * in this setup.
- *
- * TRUE must be returned when the operation is to be considered successful,
- * and a result (NULL allowed, if no signature specified) is given.
- *
- * FALSE must be returned when:
- * - A GError is propagated into result_error, which will be treated as a
- * critical error and therefore the operation will be aborted.
- * - When no result_error is given, to instruct the operation to go on with
- * the next scheduled command.
- *
- * This setup, therefore allows:
- * - Running a single command and processing its result.
- * - Running a set of N commands, providing a global result after all have
- * been executed.
- * - Running a set of N commands out of M (N<M), where the global result is
- * obtained without having executed all configured commands.
- */
-typedef gboolean (* MMAtResponseProcessor) (GObject *owner,
- gpointer response_processor_context,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error);
-
-/* Struct to configure AT command operations */
-typedef struct {
- /* The AT command */
- gchar *command;
- /* Timeout of the command, in seconds */
- guint timeout;
- /* The response processor */
- MMAtResponseProcessor response_processor;
-} MMAtCommand;
-
-void mm_at_sequence (GObject *owner,
- MMAtSerialPort *port,
- MMAtCommand *sequence,
- gpointer response_processor_context,
- gboolean free_sequence,
- const gchar *result_signature,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GVariant *mm_at_sequence_finish (GObject *owner,
- GAsyncResult *res,
- GError **error);
-
-void mm_at_command (GObject *owner,
- MMAtSerialPort *port,
- const gchar *command,
- guint timeout,
- const MMAtResponseProcessor response_processor,
- gpointer response_processor_context,
- const gchar *result_signature,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-GVariant *mm_at_command_finish (GObject *owner,
- GAsyncResult *res,
- GError **error);
-
-#endif /* MM_AT_H */
-
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 9c9c347a..5ff90e17 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -25,7 +25,7 @@
#include <mm-errors-types.h>
#include <mm-enums-types.h>
-#include "mm-at.h"
+#include "mm-base-modem-at.h"
#include "mm-broadband-modem.h"
#include "mm-iface-modem.h"
#include "mm-iface-modem-3gpp.h"
@@ -77,40 +77,6 @@ struct _MMBroadbandModemPrivate {
GSimpleAsyncResult *pending_reg_request;
};
-static gboolean
-common_parse_string_reply (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
-
- *result = g_variant_new_string (response);
- return TRUE;
-}
-
-static gboolean
-common_parse_no_reply (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
- return TRUE;
-}
-
/*****************************************************************************/
/* CAPABILITIES */
@@ -135,7 +101,7 @@ static const ModemCaps modem_caps[] = {
};
static gboolean
-parse_caps_gcap (MMBroadbandModem *self,
+parse_caps_gcap (MMBaseModem *self,
gpointer none,
const gchar *command,
const gchar *response,
@@ -167,7 +133,7 @@ parse_caps_gcap (MMBroadbandModem *self,
}
static gboolean
-parse_caps_cpin (MMBroadbandModem *self,
+parse_caps_cpin (MMBaseModem *self,
gpointer none,
const gchar *command,
const gchar *response,
@@ -199,7 +165,7 @@ parse_caps_cpin (MMBroadbandModem *self,
}
static gboolean
-parse_caps_cgmm (MMBroadbandModem *self,
+parse_caps_cgmm (MMBaseModem *self,
gpointer none,
const gchar *command,
const gchar *response,
@@ -258,7 +224,7 @@ load_current_capabilities_finish (MMIfaceModem *self,
MMModemCapability caps;
gchar *caps_str;
- result = mm_at_sequence_finish (G_OBJECT (self), res, error);
+ result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
if (!result)
return MM_MODEM_CAPABILITY_NONE;
@@ -266,16 +232,14 @@ load_current_capabilities_finish (MMIfaceModem *self,
caps_str = create_capabilities_string (caps);
mm_dbg ("loaded current capabilities: %s", caps_str);
g_free (caps_str);
-
- g_variant_unref (result);
return caps;
}
-static const MMAtCommand capabilities[] = {
- { "+GCAP", 2, (MMAtResponseProcessor)parse_caps_gcap },
- { "I", 1, (MMAtResponseProcessor)parse_caps_gcap },
- { "+CPIN?", 1, (MMAtResponseProcessor)parse_caps_cpin },
- { "+CGMM", 1, (MMAtResponseProcessor)parse_caps_cgmm },
+static const MMBaseModemAtCommand capabilities[] = {
+ { "+GCAP", 2, TRUE, parse_caps_gcap },
+ { "I", 1, TRUE, parse_caps_gcap }, /* yes, really parse as +GCAP */
+ { "+CPIN?", 1, FALSE, parse_caps_cpin },
+ { "+CGMM", 1, TRUE, parse_caps_cgmm },
{ NULL }
};
@@ -285,15 +249,16 @@ load_current_capabilities (MMIfaceModem *self,
gpointer user_data)
{
mm_dbg ("loading current capabilities...");
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)capabilities,
- NULL, /* response_processor_context */
- FALSE,
- "u",
- NULL, /* TODO: cancellable */
- callback,
- user_data);
+
+ /* Launch sequence, we will expect a "u" GVariant */
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ capabilities,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -307,19 +272,18 @@ load_manufacturer_finish (MMIfaceModem *self,
GVariant *result;
gchar *manufacturer;
- result = mm_at_sequence_finish (G_OBJECT (self), res, error);
+ result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
if (!result)
return NULL;
manufacturer = g_variant_dup_string (result, NULL);
mm_dbg ("loaded manufacturer: %s", manufacturer);
- g_variant_unref (result);
return manufacturer;
}
-static const MMAtCommand manufacturers[] = {
- { "+CGMI", 3, (MMAtResponseProcessor)common_parse_string_reply },
- { "+GMI", 3, (MMAtResponseProcessor)common_parse_string_reply },
+static const MMBaseModemAtCommand manufacturers[] = {
+ { "+CGMI", 3, TRUE, mm_base_modem_response_processor_string },
+ { "+GMI", 3, TRUE, mm_base_modem_response_processor_string },
{ NULL }
};
@@ -329,15 +293,14 @@ load_manufacturer (MMIfaceModem *self,
gpointer user_data)
{
mm_dbg ("loading manufacturer...");
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)manufacturers,
- NULL, /* response_processor_context */
- FALSE,
- "s",
- NULL, /* TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ manufacturers,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -351,19 +314,18 @@ load_model_finish (MMIfaceModem *self,
GVariant *result;
gchar *model;
- result = mm_at_sequence_finish (G_OBJECT (self), res, error);
+ result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
if (!result)
return NULL;
model = g_variant_dup_string (result, NULL);
mm_dbg ("loaded model: %s", model);
- g_variant_unref (result);
return model;
}
-static const MMAtCommand models[] = {
- { "+CGMM", 3, (MMAtResponseProcessor)common_parse_string_reply },
- { "+GMM", 3, (MMAtResponseProcessor)common_parse_string_reply },
+static const MMBaseModemAtCommand models[] = {
+ { "+CGMM", 3, TRUE, mm_base_modem_response_processor_string },
+ { "+GMM", 3, TRUE, mm_base_modem_response_processor_string },
{ NULL }
};
@@ -373,15 +335,14 @@ load_model (MMIfaceModem *self,
gpointer user_data)
{
mm_dbg ("loading model...");
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)models,
- NULL, /* response_processor_context */
- FALSE,
- "s",
- NULL, /* TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ models,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -395,19 +356,18 @@ load_revision_finish (MMIfaceModem *self,
GVariant *result;
gchar *revision;
- result = mm_at_sequence_finish (G_OBJECT (self), res, error);
+ result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
if (!result)
return NULL;
revision = g_variant_dup_string (result, NULL);
mm_dbg ("loaded revision: %s", revision);
- g_variant_unref (result);
return revision;
}
-static const MMAtCommand revisions[] = {
- { "+CGMR", 3, (MMAtResponseProcessor)common_parse_string_reply },
- { "+GMR", 3, (MMAtResponseProcessor)common_parse_string_reply },
+static const MMBaseModemAtCommand revisions[] = {
+ { "+CGMR", 3, TRUE, mm_base_modem_response_processor_string },
+ { "+GMR", 3, TRUE, mm_base_modem_response_processor_string },
{ NULL }
};
@@ -417,15 +377,14 @@ load_revision (MMIfaceModem *self,
gpointer user_data)
{
mm_dbg ("loading revision...");
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)revisions,
- NULL, /* response_processor_context */
- FALSE,
- "s",
- NULL, /* TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ revisions,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -439,19 +398,18 @@ load_equipment_identifier_finish (MMIfaceModem *self,
GVariant *result;
gchar *equipment_identifier;
- result = mm_at_sequence_finish (G_OBJECT (self), res, error);
+ result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
if (!result)
return NULL;
equipment_identifier = g_variant_dup_string (result, NULL);
mm_dbg ("loaded equipment identifier: %s", equipment_identifier);
- g_variant_unref (result);
return equipment_identifier;
}
-static const MMAtCommand equipment_identifiers[] = {
- { "+CGSN", 3, (MMAtResponseProcessor)common_parse_string_reply },
- { "+GSN", 3, (MMAtResponseProcessor)common_parse_string_reply },
+static const MMBaseModemAtCommand equipment_identifiers[] = {
+ { "+CGSN", 3, TRUE, mm_base_modem_response_processor_string },
+ { "+GSN", 3, TRUE, mm_base_modem_response_processor_string },
{ NULL }
};
@@ -461,45 +419,27 @@ load_equipment_identifier (MMIfaceModem *self,
gpointer user_data)
{
mm_dbg ("loading equipment identifier...");
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)equipment_identifiers,
- NULL, /* response_processor_context */
- FALSE,
- "s",
- NULL, /* TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ equipment_identifiers,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
/* DEVICE IDENTIFIER */
-static gboolean
-parse_optional_string_reply (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- *result = (error ?
- NULL :
- g_variant_new_string (response));
- return TRUE;
-}
-
typedef struct {
gchar *ati;
gchar *ati1;
- GSimpleAsyncResult *result;
} DeviceIdentifierContext;
static void
device_identifier_context_free (DeviceIdentifierContext *ctx)
{
- g_object_unref (ctx->result);
g_free (ctx->ati);
g_free (ctx->ati1);
g_free (ctx);
@@ -510,103 +450,77 @@ load_device_identifier_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
+ GError *inner_error = NULL;
+ gpointer ctx = NULL;
gchar *device_identifier;
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, &ctx, &inner_error);
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
return NULL;
-
- device_identifier = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
- mm_dbg ("loaded device identifier: %s", device_identifier);
- return device_identifier;
-}
-
-static void
-ati1_ready (MMBroadbandModem *self,
- GAsyncResult *res,
- DeviceIdentifierContext *ctx)
-{
- gchar *device_identifier;
- GVariant *result;
-
- result = mm_at_command_finish (G_OBJECT (self), res, NULL);
- if (result) {
- ctx->ati1 = g_variant_dup_string (result, NULL);
- g_variant_unref (result);
}
+ g_assert (ctx != NULL);
device_identifier = mm_create_device_identifier (
mm_base_modem_get_vendor_id (MM_BASE_MODEM (self)),
mm_base_modem_get_product_id (MM_BASE_MODEM (self)),
- ctx->ati,
- ctx->ati1,
- mm_gdbus_modem_get_equipment_identifier (MM_GDBUS_MODEM (self->priv->modem_dbus_skeleton)),
- mm_gdbus_modem_get_revision (MM_GDBUS_MODEM (self->priv->modem_dbus_skeleton)),
- mm_gdbus_modem_get_model (MM_GDBUS_MODEM (self->priv->modem_dbus_skeleton)),
- mm_gdbus_modem_get_manufacturer (MM_GDBUS_MODEM (self->priv->modem_dbus_skeleton)));
-
- g_simple_async_result_set_op_res_gpointer (ctx->result,
- device_identifier,
- NULL);
- g_simple_async_result_complete (ctx->result);
- device_identifier_context_free (ctx);
+ ((DeviceIdentifierContext *)ctx)->ati,
+ ((DeviceIdentifierContext *)ctx)->ati1,
+ mm_gdbus_modem_get_equipment_identifier (
+ MM_GDBUS_MODEM (MM_BROADBAND_MODEM (self)->priv->modem_dbus_skeleton)),
+ mm_gdbus_modem_get_revision (
+ MM_GDBUS_MODEM (MM_BROADBAND_MODEM (self)->priv->modem_dbus_skeleton)),
+ mm_gdbus_modem_get_model (
+ MM_GDBUS_MODEM (MM_BROADBAND_MODEM (self)->priv->modem_dbus_skeleton)),
+ mm_gdbus_modem_get_manufacturer (
+ MM_GDBUS_MODEM (MM_BROADBAND_MODEM (self)->priv->modem_dbus_skeleton)));
+
+ mm_dbg ("loaded device identifier: %s", device_identifier);
+ return device_identifier;
}
-static void
-ati_ready (MMBroadbandModem *self,
- GAsyncResult *res,
- DeviceIdentifierContext *ctx)
+static gboolean
+parse_ati_reply (MMBaseModem *self,
+ DeviceIdentifierContext *ctx,
+ const gchar *command,
+ const gchar *response,
+ const GError *error,
+ GVariant **result,
+ GError **result_error)
{
- GVariant *result;
-
- result = mm_at_command_finish (G_OBJECT (self), res, NULL);
- if (result) {
- ctx->ati = g_variant_dup_string (result, NULL);
- g_variant_unref (result);
+ /* Store the proper string in the proper place */
+ if (!error) {
+ if (g_str_equal (command, "ATI1"))
+ ctx->ati1 = g_strdup (response);
+ else
+ ctx->ati = g_strdup (response);
}
- /* Go on with ATI1 */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "ATI1",
- 3,
- (MMAtResponseProcessor)parse_optional_string_reply,
- NULL, /* response_processor_context */
- "s",
- NULL, /* TODO: cancellable */
- (GAsyncReadyCallback)ati1_ready,
- ctx);
+ /* Always keep on, this is a sequence where all the steps should be taken */
+ return TRUE;
}
+static const MMBaseModemAtCommand device_identifier_steps[] = {
+ { "ATI", 3, TRUE, (MMBaseModemAtResponseProcessor)parse_ati_reply },
+ { "ATI1", 3, TRUE, (MMBaseModemAtResponseProcessor)parse_ati_reply },
+ { NULL }
+};
+
static void
load_device_identifier (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- DeviceIdentifierContext *ctx;
-
mm_dbg ("loading device identifier...");
- /* To build the device identifier, we still need to get the replies for:
- * - ATI
- * - ATI1
- */
-
- ctx = g_new0 (DeviceIdentifierContext, 1);
- ctx->result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- load_device_identifier);
-
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "ATI",
- 3,
- (MMAtResponseProcessor)parse_optional_string_reply,
- NULL, /* response_processor_context */
- "s",
- NULL, /* TODO: cancellable */
- (GAsyncReadyCallback)ati_ready,
- ctx);
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ device_identifier_steps,
+ g_new0 (DeviceIdentifierContext, 1),
+ (GDestroyNotify)device_identifier_context_free,
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -638,27 +552,24 @@ static CPinResult unlock_results[] = {
{ NULL }
};
-static gboolean
-parse_unlock_required_reply (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
+static MMModemLock
+load_unlock_required_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
{
- if (error) {
- /* Let errors here be fatal */
- *result_error = g_error_copy (error);
- return FALSE;
- }
+ MMModemLock lock = MM_MODEM_LOCK_UNKNOWN;
+ const gchar *result;
+
+ result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
+ if (!result)
+ return lock;
- if (response &&
- strstr (response, "+CPIN: ")) {
+ if (result &&
+ strstr (result, "+CPIN: ")) {
CPinResult *iter = &unlock_results[0];
const gchar *str;
- str = strstr (response, "+CPIN: ") + 7;
+ str = strstr (result, "+CPIN: ") + 7;
/* Some phones (Motorola EZX models) seem to quote the response */
if (str[0] == '"')
@@ -667,51 +578,14 @@ parse_unlock_required_reply (MMBroadbandModem *self,
/* Translate the reply */
while (iter->result) {
if (g_str_has_prefix (str, iter->result)) {
- *result = g_variant_new_uint32 (iter->code);
- return TRUE;
+ lock = iter->code;
+ break;
}
iter++;
}
}
- /* Assume unlocked if we don't recognize the pin request result */
- *result = g_variant_new_uint32 (MM_MODEM_LOCK_NONE);
- return TRUE;
-}
-
-static MMModemLock
-load_unlock_required_finish (MMIfaceModem *self,
- GAsyncResult *res,
- GError **error)
-{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return MM_MODEM_LOCK_UNKNOWN;
-
- return (MMModemLock) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
-}
-
-static void
-load_unlock_required_ready (MMBroadbandModem *self,
- GAsyncResult *res,
- GSimpleAsyncResult *unlock_required_result)
-{
- GError *error = NULL;
- GVariant *command_result;
-
- command_result = mm_at_command_finish (G_OBJECT (self), res, &error);
- if (!command_result) {
- g_assert (error);
- g_simple_async_result_take_error (unlock_required_result, error);
- }
- else {
- g_simple_async_result_set_op_res_gpointer (unlock_required_result,
- GUINT_TO_POINTER (g_variant_get_uint32 (command_result)),
- NULL);
- g_variant_unref (command_result);
- }
-
- g_simple_async_result_complete (unlock_required_result);
- g_object_unref (unlock_required_result);
+ return lock;
}
static void
@@ -719,38 +593,36 @@ load_unlock_required (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
-
mm_dbg ("checking if unlock required...");
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- load_unlock_required);
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+CPIN?",
- 3,
- (MMAtResponseProcessor)parse_unlock_required_reply,
- NULL, /* response_processor_context */
- "u",
- NULL, /* TODO: cancellable */
- (GAsyncReadyCallback)load_unlock_required_ready,
- result);
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CPIN?",
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
+/* SETTING MODEM CHARSET */
typedef struct {
GSimpleAsyncResult *result;
MMModemCharset charset;
- gboolean tried_without_quotes;
+ /* Commands to try in the sequence:
+ * First one with quotes
+ * Second without.
+ * + last NUL */
+ MMBaseModemAtCommand charset_commands[3];
} ModemCharsetContext;
static void
modem_charset_context_free (ModemCharsetContext *ctx)
{
g_object_unref (ctx->result);
+ g_free (ctx->charset_commands[0].command);
+ g_free (ctx->charset_commands[1].command);
g_free (ctx);
}
@@ -765,65 +637,28 @@ modem_charset_finish (MMIfaceModem *self,
return TRUE;
}
-static gboolean
-parse_modem_charset_reply (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
- return TRUE;
-}
-
-static gboolean
-parse_current_charset_reply (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- const gchar *p;
- MMModemCharset current;
-
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
-
- p = response;
- if (g_str_has_prefix (p, "+CSCS:"))
- p += 6;
- while (*p == ' ')
- p++;
-
- current = mm_modem_charset_from_string (p);
- *result = g_variant_new_uint32 (current);
- return TRUE;
-}
-
static void
current_charset_ready (MMBroadbandModem *self,
- GAsyncResult *result,
+ GAsyncResult *res,
ModemCharsetContext *ctx)
{
GError *error = NULL;
- GVariant *reply;
- MMModemCharset current;
+ const gchar *response;
- reply = mm_at_command_finish (G_OBJECT (self), result, &error);
- if (error) {
+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
+ if (!response)
g_simple_async_result_take_error (ctx->result, error);
- } else {
- g_assert (reply != NULL);
- current = g_variant_get_uint32 (reply);
+ else {
+ MMModemCharset current;
+ const gchar *p;
+
+ p = response;
+ if (g_str_has_prefix (p, "+CSCS:"))
+ p += 6;
+ while (*p == ' ')
+ p++;
+
+ current = mm_modem_charset_from_string (p);
if (ctx->charset != current)
g_simple_async_result_set_error (ctx->result,
MM_CORE_ERROR,
@@ -831,7 +666,8 @@ current_charset_ready (MMBroadbandModem *self,
"Modem failed to change character set to %s",
mm_modem_charset_to_string (ctx->charset));
else {
- /* We'll keep track ourselves of the current charset */
+ /* We'll keep track ourselves of the current charset.
+ * TODO: Make this a property so that plugins can also store it. */
self->priv->current_charset = current;
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
}
@@ -843,38 +679,13 @@ current_charset_ready (MMBroadbandModem *self,
static void
modem_charset_ready (MMBroadbandModem *self,
- GAsyncResult *result,
+ GAsyncResult *res,
ModemCharsetContext *ctx)
{
GError *error = NULL;
- mm_at_command_finish (G_OBJECT (self), result, &error);
+ mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error);
if (error) {
- if (!ctx->tried_without_quotes) {
- gchar *command;
-
- g_error_free (error);
- ctx->tried_without_quotes = TRUE;
-
- /* Some modems puke if you include the quotes around the character
- * set name, so lets try it again without them.
- */
- command = g_strdup_printf ("+CSCS=%s",
- mm_modem_charset_to_string (ctx->charset));
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- command,
- 3,
- (MMAtResponseProcessor)parse_modem_charset_reply,
- NULL, /* response processor context */
- NULL, /* reply signature */
- NULL, /* cancellable */
- (GAsyncReadyCallback)modem_charset_ready,
- ctx);
- g_free (command);
- return;
- }
-
g_simple_async_result_take_error (ctx->result, error);
g_simple_async_result_complete (ctx->result);
modem_charset_context_free (ctx);
@@ -882,16 +693,13 @@ modem_charset_ready (MMBroadbandModem *self,
}
/* Check whether we did properly set the charset */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+CSCS?",
- 3,
- (MMAtResponseProcessor)parse_current_charset_reply,
- NULL, /* response processor context */
- "u",
- NULL, /* cancellable */
- (GAsyncReadyCallback)current_charset_ready,
- ctx);
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CSCS?",
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)current_charset_ready,
+ ctx);
}
static void
@@ -902,81 +710,79 @@ modem_charset (MMIfaceModem *self,
{
ModemCharsetContext *ctx;
const gchar *charset_str;
- gchar *command;
+ /* Build charset string to use */
+ charset_str = mm_modem_charset_to_string (charset);
+ if (!charset_str) {
+ g_simple_async_report_error_in_idle (G_OBJECT (self),
+ callback,
+ user_data,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Unhandled character set 0x%X",
+ charset);
+ return;
+ }
+
+ /* Setup context, including commands to try */
ctx = g_new0 (ModemCharsetContext, 1);
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_charset);
ctx->charset = charset;
-
- charset_str = mm_modem_charset_to_string (charset);
- if (!charset_str) {
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Unhandled character set 0x%X",
- charset);
- g_simple_async_result_complete_in_idle (ctx->result);
- modem_charset_context_free (ctx);
- return;
- }
-
- command = g_strdup_printf ("+CSCS=\"%s\"", charset_str);
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- command,
- 3,
- (MMAtResponseProcessor)parse_modem_charset_reply,
- NULL, /* response processor context */
- NULL, /* reply signature */
- NULL, /* cancellable */
- (GAsyncReadyCallback)modem_charset_ready,
- ctx);
- g_free (command);
+ /* First try, with quotes */
+ ctx->charset_commands[0].command = g_strdup_printf ("+CSCS=\"%s\"", charset_str);
+ ctx->charset_commands[0].timeout = 3;
+ ctx->charset_commands[0].allow_cached = FALSE;
+ ctx->charset_commands[0].response_processor = mm_base_modem_response_processor_no_result;
+ /* Second try.
+ * Some modems puke if you include the quotes around the character
+ * set name, so lets try it again without them.
+ */
+ ctx->charset_commands[1].command = g_strdup_printf ("+CSCS=%s", charset_str);
+ ctx->charset_commands[1].timeout = 3;
+ ctx->charset_commands[1].allow_cached = FALSE;
+ ctx->charset_commands[1].response_processor = mm_base_modem_response_processor_no_result;
+
+ /* Launch sequence */
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ ctx->charset_commands,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)modem_charset_ready,
+ ctx);
}
/*****************************************************************************/
+/* LOAD SUPPORTED CHARSETS */
static MMModemCharset
load_supported_charsets_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return MM_MODEM_CHARSET_UNKNOWN;
-
- return (MMModemCharset) g_variant_get_uint32 (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
-}
-
-static gboolean
-parse_load_supported_charsets_reply (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- MMModemCharset charsets;
+ const gchar *response;
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
+ if (!response)
+ return MM_MODEM_CHARSET_UNKNOWN;
+ else {
+ MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN;
+
+ if (!mm_gsm_parse_cscs_support_response (response, &charsets)) {
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Failed to parse the supported character "
+ "sets response");
+ return MM_MODEM_CHARSET_UNKNOWN;
+ }
- charsets = MM_MODEM_CHARSET_UNKNOWN;
- if (!mm_gsm_parse_cscs_support_response (response, &charsets)) {
- *result_error = g_error_new_literal (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Failed to parse the supported character "
- "sets response");
- return FALSE;
+ return charsets;
}
-
- *result = g_variant_new_uint32 (charsets);
- return TRUE;
}
static void
@@ -984,26 +790,25 @@ load_supported_charsets (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+CSCS=?",
- 3,
- (MMAtResponseProcessor)parse_load_supported_charsets_reply,
- NULL, /* response processor context */
- "u",
- NULL, /* cancellable */
- callback,
- user_data);
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CSCS=?",
+ 3,
+ TRUE,
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
+/* FLOW CONTROL */
static gboolean
modem_flow_control_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- return !mm_at_sequence_finish (G_OBJECT (self), res, error);
+ /* Completely ignore errors */
+ return TRUE;
}
static void
@@ -1011,27 +816,34 @@ modem_flow_control (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- /* By default, try to set XOFF/XON flow control, and ignore errors */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+IFC=1,1",
- 3,
- NULL, /* response processor */
- NULL, /* response processor context */
- NULL, /* result signature */
- NULL, /* cancellable */
- callback,
- user_data);
+ GSimpleAsyncResult *result;
+
+ /* By default, try to set XOFF/XON flow control */
+ mm_base_modem_at_command_ignore_reply (MM_BASE_MODEM (self),
+ "+IFC=1,1",
+ 3);
+
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ modem_flow_control);
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
}
/*****************************************************************************/
+/* MODEM POWER UP */
static gboolean
modem_power_up_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- return !mm_at_command_finish (G_OBJECT (self), res, error);
+ /* By default, errors in the power up command are ignored.
+ * Plugins wanting to treat power up errors should subclass the power up
+ * handling. */
+ return TRUE;
}
static void
@@ -1039,50 +851,33 @@ modem_power_up (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- /* By default, errors in the power up command are ignored.
- * Plugins wanting to treat power up errors should subclass the power up
- * handling. */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+CFUN=1",
- 5,
- NULL, /* response processor */
- NULL, /* response processor context */
- NULL, /* result signature */
- NULL, /* cancellable */
- callback,
- user_data);
+ GSimpleAsyncResult *result;
+
+ mm_base_modem_at_command_ignore_reply (MM_BASE_MODEM (self),
+ "+CFUN=1",
+ 5);
+
+ result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ modem_flow_control);
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
}
/*****************************************************************************/
+/* MODEM INITIALIZATION */
static gboolean
modem_init_finish (MMIfaceModem *self,
GAsyncResult *res,
GError **error)
{
- return !mm_at_sequence_finish (G_OBJECT (self), res, error);
+ return !mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
}
-static gboolean
-parse_init_response (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **variant,
- GError **result_error)
-{
- /* Errors in the mandatory init commands will abort the whole modem
- * initialization process */
- if (error)
- *result_error = g_error_copy (error);
-
- /* Return FALSE so that we keep on with the next steps in the sequence */
- return FALSE;
-}
-
-static const MMAtCommand modem_init_sequence[] = {
+static const MMBaseModemAtCommand modem_init_sequence[] = {
/* 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
@@ -1090,21 +885,21 @@ static const MMAtCommand modem_init_sequence[] = {
* TODO: only send init command 2nd time if 1st time failed?
*/
- { "Z E0 V1", 3, NULL },
- { "Z E0 V1", 3, (MMAtResponseProcessor)parse_init_response },
+ { "Z E0 V1", 3, FALSE, NULL },
+ { "Z E0 V1", 3, FALSE, mm_base_modem_response_processor_no_result_continue },
/* Ensure echo is off after the init command; some modems ignore the
* E0 when it's in the same line as ATZ (Option GIO322).
*/
- { "E0", 3, NULL },
+ { "E0", 3, FALSE, 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...
*/
- { "+CMEE=1", 3, NULL },
+ { "+CMEE=1", 3, FALSE, NULL },
/* Additional OPTIONAL initialization */
- { "X4 &C1", 3, NULL },
+ { "X4 &C1", 3, FALSE, NULL },
{ NULL }
};
@@ -1114,15 +909,13 @@ modem_init (MMIfaceModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)modem_init_sequence,
- NULL, /* response processor context */
- FALSE, /* free sequence */
- NULL, /* result signature */
- NULL, /* cancellable */
- callback,
- user_data);
+ mm_base_modem_at_sequence (MM_BASE_MODEM (self),
+ modem_init_sequence,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -1133,39 +926,29 @@ load_imei_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
- GVariant *result;
gchar *imei;
- result = mm_at_sequence_finish (G_OBJECT (self), res, error);
- if (!result)
+ imei = g_strdup (mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error));
+ if (!imei)
return NULL;
- imei = g_variant_dup_string (result, NULL);
mm_dbg ("loaded IMEI: %s", imei);
- g_variant_unref (result);
return imei;
}
-static const MMAtCommand imei_commands[] = {
- { "+CGSN", 3, (MMAtResponseProcessor)common_parse_string_reply },
- { NULL }
-};
-
static void
load_imei (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
mm_dbg ("loading IMEI...");
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)imei_commands,
- NULL, /* response_processor_context */
- FALSE,
- "s",
- NULL, /* TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CGSN",
+ 3,
+ TRUE,
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -1176,42 +959,34 @@ load_operator_code_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
- GVariant *result;
+ const gchar *result;
gchar *operator_code;
- result = mm_at_sequence_finish (G_OBJECT (self), res, error);
+ result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
if (!result)
return NULL;
- operator_code = mm_3gpp_parse_operator (g_variant_get_string (result, NULL),
- MM_MODEM_CHARSET_UNKNOWN);
+ operator_code = mm_3gpp_parse_operator (result, MM_MODEM_CHARSET_UNKNOWN);
if (operator_code)
mm_dbg ("loaded Operator Code: %s", operator_code);
- g_variant_unref (result);
return operator_code;
}
-static const MMAtCommand operator_code_commands[] = {
- { "+COPS=3,2;+COPS?", 3, (MMAtResponseProcessor)common_parse_string_reply },
- { NULL }
-};
-
static void
load_operator_code (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
mm_dbg ("loading Operator Code...");
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)operator_code_commands,
- NULL, /* response_processor_context */
- FALSE,
- "s",
- NULL, /* TODO: cancellable */
- callback,
- user_data);
+
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+COPS=3,2;+COPS?",
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -1222,42 +997,34 @@ load_operator_name_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
- GVariant *result;
+ const gchar *result;
gchar *operator_name;
- result = mm_at_sequence_finish (G_OBJECT (self), res, error);
+ result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
if (!result)
return NULL;
- operator_name = mm_3gpp_parse_operator (g_variant_get_string (result, NULL),
- MM_MODEM_CHARSET_UNKNOWN);
+ operator_name = mm_3gpp_parse_operator (result, MM_MODEM_CHARSET_UNKNOWN);
if (operator_name)
mm_dbg ("loaded Operator Name: %s", operator_name);
- g_variant_unref (result);
return operator_name;
}
-static const MMAtCommand operator_name_commands[] = {
- { "+COPS=3,0;+COPS?", 3, (MMAtResponseProcessor)common_parse_string_reply },
- { NULL }
-};
-
static void
load_operator_name (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
mm_dbg ("loading Operator Name...");
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)operator_name_commands,
- NULL, /* response_processor_context */
- FALSE,
- "s",
- NULL, /* TODO: cancellable */
- callback,
- user_data);
+
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+COPS=3,0;+COPS?",
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -1455,17 +1222,13 @@ scan_networks_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
- GVariant *reply;
- GList *info_list;
+ const gchar *result;
- reply = mm_at_command_finish (G_OBJECT (self), res, error);
- if (!reply)
+ result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
+ if (!result)
return NULL;
- info_list = mm_3gpp_parse_scan_response (g_variant_get_string (reply, NULL),
- error);
- g_variant_unref (reply);
- return info_list;
+ return mm_3gpp_parse_scan_response (result, error);
}
static void
@@ -1473,20 +1236,13 @@ scan_networks (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- /* It is mandatory to have a callback here right now, otherwise we may leak
- * the info list */
- g_assert (callback != NULL);
-
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+COPS=?",
- 120,
- (MMAtResponseProcessor)common_parse_string_reply,
- NULL, /* response processor context */
- "s", /* reply signature */
- NULL, /* cancellable */
- callback,
- user_data);
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+COPS=?",
+ 120,
+ FALSE,
+ NULL, /* cancellable */
+ callback,
+ user_data);
}
/*****************************************************************************/
@@ -1628,7 +1384,7 @@ register_in_network_ready (MMBroadbandModem *self,
{
GError *error = NULL;
- mm_at_command_finish (G_OBJECT (self), res, &error);
+ mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
/* 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
@@ -1699,20 +1455,20 @@ register_in_network (MMIfaceModem3gpp *self,
mm_dbg ("Not launching any new network selection request");
if (command) {
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- command,
- 120,
- (MMAtResponseProcessor)common_parse_no_reply,
- NULL, /* response processor context */
- NULL, /* reply signature */
- NULL, /* cancellable */
- (GAsyncReadyCallback)register_in_network_ready,
- result);
- } else
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ command,
+ 120,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)register_in_network_ready,
+ result);
+ } else {
/* Just rely on the unsolicited registration, periodic registration
* checks or the timeout. */
+ g_simple_async_result_set_op_res_gboolean (result, TRUE);
+ g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
+ }
}
/*****************************************************************************/
@@ -1739,14 +1495,10 @@ registration_status_check_ready (MMBroadbandModem *self,
GAsyncResult *res,
GSimpleAsyncResult *operation_result)
{
- GVariant *response_variant;
- const gchar *response = NULL;
+ const gchar *response;
GError *error = NULL;
- response_variant = mm_at_command_finish (G_OBJECT (self), res, &error);
- if (response_variant)
- response = g_variant_get_string (response_variant, NULL);
-
+ response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (!response) {
g_assert (error != NULL);
g_simple_async_result_take_error (operation_result, error);
@@ -1823,8 +1575,6 @@ registration_status_check_ready (MMBroadbandModem *self,
}
}
- if (response_variant)
- g_variant_unref (response_variant);
g_simple_async_result_complete (operation_result);
g_object_unref (operation_result);
}
@@ -1842,16 +1592,13 @@ run_cs_registration_check (MMIfaceModem3gpp *self,
run_cs_registration_check);
/* Check current CS-registration state. */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+CREG?",
- 10,
- (MMAtResponseProcessor)common_parse_string_reply,
- NULL, /* response processor context */
- "s", /* raw reply */
- NULL, /* cancellable */
- (GAsyncReadyCallback)registration_status_check_ready,
- result);
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CREG?",
+ 10,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)registration_status_check_ready,
+ result);
}
static void
@@ -1867,21 +1614,32 @@ run_ps_registration_check (MMIfaceModem3gpp *self,
run_ps_registration_check);
/* Check current PS-registration state. */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+CGREG?",
- 10,
- (MMAtResponseProcessor)common_parse_string_reply,
- NULL, /* response processor context */
- "s", /* raw reply */
- NULL, /* cancellable */
- (GAsyncReadyCallback)registration_status_check_ready,
- result);
+ mm_base_modem_at_command (MM_BASE_MODEM (self),
+ "+CGREG?",
+ 10,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)registration_status_check_ready,
+ result);
}
/*****************************************************************************/
/* CS and PS Registrations cleanup (3GPP) */
+typedef struct {
+ GSimpleAsyncResult *result;
+ gchar *command;
+ gboolean secondary_done;
+} CleanupRegistrationContext;
+
+static void
+cleanup_registration_context_free (CleanupRegistrationContext *ctx)
+{
+ g_object_unref (ctx->result);
+ g_free (ctx->command);
+ g_free (ctx);
+}
+
static gboolean
cleanup_cs_registration_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
@@ -1898,57 +1656,45 @@ cleanup_ps_registration_finish (MMIfaceModem3gpp *self,
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}
-static gboolean
-parse_reg_cleanup_reply (MMBroadbandModem *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- /* Ignore errors, just set as reply the command used */
- *result = g_variant_new_string (command);
- return TRUE;
-}
-
static void
cleanup_registration_sequence_ready (MMBroadbandModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ CleanupRegistrationContext *ctx)
{
- MMAtSerialPort *secondary;
GError *error = NULL;
- GVariant *reply;
- reply = mm_at_command_finish (G_OBJECT (self), res, &error);
+ mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (error) {
- g_simple_async_result_take_error (operation_result, error);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
+ g_simple_async_result_take_error (ctx->result, error);
+ g_simple_async_result_complete (ctx->result);
+ cleanup_registration_context_free (ctx);
return;
}
- secondary = mm_base_modem_get_port_secondary (MM_BASE_MODEM (self));
- if (secondary) {
- /* Now use the same registration setup in secondary port, if any */
- mm_at_command (G_OBJECT (self),
- secondary,
- g_variant_get_string (reply, NULL),
- 3,
- NULL, /* response processor */
- NULL, /* response processor context */
- NULL, /* result signature */
- NULL, /* cancellable */
- NULL, /* NO callback, just queue the command and forget */
- NULL); /* user data */
+ if (!ctx->secondary_done) {
+ MMAtSerialPort *secondary;
+
+ secondary = mm_base_modem_get_port_secondary (MM_BASE_MODEM (self));
+ if (secondary) {
+ /* Now use the same registration setup in secondary port, if any */
+ ctx->secondary_done = TRUE;
+ mm_base_modem_at_command_in_port (
+ MM_BASE_MODEM (self),
+ secondary,
+ ctx->command,
+ 10,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)cleanup_registration_sequence_ready,
+ ctx);
+ return;
+ }
}
/* We're done */
- g_simple_async_result_set_op_res_gboolean (operation_result, TRUE);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
- g_variant_unref (reply);
+ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ g_simple_async_result_complete (ctx->result);
+ cleanup_registration_context_free (ctx);
}
static void
@@ -1956,22 +1702,24 @@ cleanup_cs_registration (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ CleanupRegistrationContext *ctx;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- cleanup_cs_registration);
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+CREG=0",
- 3,
- (MMAtResponseProcessor)parse_reg_cleanup_reply,
- NULL, /* response processor context */
- "s", /* The cleanup command */
- NULL, /* cancellable */
- (GAsyncReadyCallback)cleanup_registration_sequence_ready,
- result);
+ ctx = g_new0 (CleanupRegistrationContext, 1);
+ ctx->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ cleanup_cs_registration);
+ ctx->command = g_strdup ("+CREG=0");
+
+ mm_base_modem_at_command_in_port (
+ MM_BASE_MODEM (self),
+ mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
+ ctx->command,
+ 10,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)cleanup_registration_sequence_ready,
+ ctx);
}
static void
@@ -1979,27 +1727,41 @@ cleanup_ps_registration (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ CleanupRegistrationContext *ctx;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- cleanup_ps_registration);
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- "+CGREG=0",
- 3,
- (MMAtResponseProcessor)parse_reg_cleanup_reply,
- NULL, /* response processor context */
- "s", /* The cleanup command */
- NULL, /* cancellable */
- (GAsyncReadyCallback)cleanup_registration_sequence_ready,
- result);
+ ctx = g_new0 (CleanupRegistrationContext, 1);
+ ctx->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ cleanup_cs_registration);
+ ctx->command = g_strdup ("+CGREG=0");
+
+ mm_base_modem_at_command_in_port (
+ MM_BASE_MODEM (self),
+ mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
+ ctx->command,
+ 10,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)cleanup_registration_sequence_ready,
+ ctx);
}
/*****************************************************************************/
/* CS and PS Registrations (3GPP) */
+typedef struct {
+ GSimpleAsyncResult *result;
+ gboolean secondary_done;
+} SetupRegistrationContext;
+
+static void
+setup_registration_context_free (SetupRegistrationContext *ctx)
+{
+ g_object_unref (ctx->result);
+ g_free (ctx);
+}
+
static gboolean
setup_cs_registration_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
@@ -2017,7 +1779,7 @@ setup_ps_registration_finish (MMIfaceModem3gpp *self,
}
static gboolean
-parse_reg_setup_reply (MMBroadbandModem *self,
+parse_reg_setup_reply (MMBaseModem *self,
gpointer none,
const gchar *command,
const gchar *response,
@@ -2029,63 +1791,78 @@ parse_reg_setup_reply (MMBroadbandModem *self,
if (error)
return FALSE;
+ /* Set COMMAND as result! */
*result = g_variant_new_string (command);
return TRUE;
}
-static const MMAtCommand cs_registration_sequence[] = {
+static const MMBaseModemAtCommand cs_registration_sequence[] = {
/* Enable unsolicited registration notifications in CS network, with location */
- { "+CREG=2", 3, (MMAtResponseProcessor)parse_reg_setup_reply },
+ { "+CREG=2", 3, FALSE, parse_reg_setup_reply },
/* Enable unsolicited registration notifications in CS network, without location */
- { "+CREG=1", 3, (MMAtResponseProcessor)parse_reg_setup_reply },
+ { "+CREG=1", 3, FALSE, parse_reg_setup_reply },
{ NULL }
};
-static const MMAtCommand ps_registration_sequence[] = {
+static const MMBaseModemAtCommand ps_registration_sequence[] = {
/* Enable unsolicited registration notifications in PS network, with location */
- { "+CGREG=2", 3, (MMAtResponseProcessor)parse_reg_setup_reply },
+ { "+CGREG=2", 3, FALSE, parse_reg_setup_reply },
/* Enable unsolicited registration notifications in PS network, without location */
- { "+CGREG=1", 3, (MMAtResponseProcessor)parse_reg_setup_reply },
+ { "+CGREG=1", 3, FALSE, parse_reg_setup_reply },
{ NULL }
};
static void
setup_registration_sequence_ready (MMBroadbandModem *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ SetupRegistrationContext *ctx)
{
- MMAtSerialPort *secondary;
GError *error = NULL;
- GVariant *reply;
- reply = mm_at_sequence_finish (G_OBJECT (self), res, &error);
- if (error) {
- g_simple_async_result_take_error (operation_result, error);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
- return;
- }
+ if (ctx->secondary_done) {
+ mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
+ if (error) {
+ g_simple_async_result_take_error (ctx->result, error);
+ g_simple_async_result_complete (ctx->result);
+ setup_registration_context_free (ctx);
+ return;
+ }
+ /* success */
+ } else {
+ GVariant *command;
+ MMAtSerialPort *secondary;
+
+ command = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error);
+ if (!command) {
+ g_assert (error != NULL);
+ g_simple_async_result_take_error (ctx->result, error);
+ g_simple_async_result_complete (ctx->result);
+ setup_registration_context_free (ctx);
+ return;
+ }
- secondary = mm_base_modem_get_port_secondary (MM_BASE_MODEM (self));
- if (secondary) {
- /* Now use the same registration setup in secondary port, if any */
- mm_at_command (G_OBJECT (self),
- secondary,
- g_variant_get_string (reply, NULL),
- 3,
- NULL, /* response processor */
- NULL, /* response processor context */
- NULL, /* result signature */
- NULL, /* cancellable */
- NULL, /* NO callback, just queue the command and forget */
- NULL); /* user data */
+ secondary = mm_base_modem_get_port_secondary (MM_BASE_MODEM (self));
+ if (secondary) {
+ /* Now use the same registration setup in secondary port, if any */
+ ctx->secondary_done = TRUE;
+ mm_base_modem_at_command_in_port (
+ MM_BASE_MODEM (self),
+ mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
+ g_variant_get_string (command, NULL),
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)setup_registration_sequence_ready,
+ ctx);
+ return;
+ }
+ /* success */
}
/* We're done */
- g_simple_async_result_set_op_res_gboolean (operation_result, TRUE);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
- g_variant_unref (reply);
+ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
+ g_simple_async_result_complete (ctx->result);
+ setup_registration_context_free (ctx);
}
static void
@@ -2093,21 +1870,22 @@ setup_cs_registration (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ SetupRegistrationContext *ctx;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- setup_cs_registration);
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)cs_registration_sequence,
- NULL, /* response processor context */
- FALSE, /* free sequence */
- "s", /* The command which worked */
- NULL, /* cancellable */
- (GAsyncReadyCallback)setup_registration_sequence_ready,
- result);
+ ctx = g_new0 (SetupRegistrationContext, 1);
+ ctx->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ setup_cs_registration);
+ mm_base_modem_at_sequence_in_port (
+ MM_BASE_MODEM (self),
+ mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
+ cs_registration_sequence,
+ NULL, /* response processor context */
+ NULL, /* response processor context free */
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)setup_registration_sequence_ready,
+ ctx);
}
static void
@@ -2115,21 +1893,22 @@ setup_ps_registration (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *result;
+ SetupRegistrationContext *ctx;
- result = g_simple_async_result_new (G_OBJECT (self),
- callback,
- user_data,
- setup_ps_registration);
- mm_at_sequence (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
- (MMAtCommand *)ps_registration_sequence,
- NULL, /* response processor context */
- FALSE, /* free sequence */
- "s", /* The command which worked */
- NULL, /* cancellable */
- (GAsyncReadyCallback)setup_registration_sequence_ready,
- result);
+ ctx = g_new0 (SetupRegistrationContext, 1);
+ ctx->result = g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ setup_ps_registration);
+ mm_base_modem_at_sequence_in_port (
+ MM_BASE_MODEM (self),
+ mm_base_modem_get_port_primary (MM_BASE_MODEM (self)),
+ ps_registration_sequence,
+ NULL, /* response processor context */
+ NULL, /* response processor context free */
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)setup_registration_sequence_ready,
+ ctx);
}
/*****************************************************************************/
@@ -2532,9 +2311,17 @@ initialize_step (InitializeContext *ctx)
}
ctx->close_port = TRUE;
/* Try to disable echo */
- mm_at_serial_port_queue_command (ctx->port, "E0", 3, NULL, NULL);
+ mm_base_modem_at_command_in_port_ignore_reply (
+ MM_BASE_MODEM (ctx->self),
+ ctx->port,
+ "E0",
+ 3);
/* Try to get extended errors */
- mm_at_serial_port_queue_command (ctx->port, "+CMEE=1", 2, NULL, NULL);
+ mm_base_modem_at_command_in_port_ignore_reply (
+ MM_BASE_MODEM (ctx->self),
+ ctx->port,
+ "+CMEE=1",
+ 3);
/* Fall down to next step */
ctx->step++;
}
diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c
index 73ac51be..f3c42f08 100644
--- a/src/mm-iface-modem.c
+++ b/src/mm-iface-modem.c
@@ -1584,7 +1584,7 @@ initialization_context_complete_and_free (InitializationContext *ctx)
gchar *val; \
\
val = MM_IFACE_MODEM_GET_INTERFACE (self)->load_##NAME##_finish (self, res, &error); \
- mm_gdbus_modem_set_##NAME (ctx->skeleton, val); \
+ mm_gdbus_modem_set_##NAME (ctx->skeleton, val); \
g_free (val); \
\
if (error) { \
diff --git a/src/mm-sim.c b/src/mm-sim.c
index 5fe83b27..8205697d 100644
--- a/src/mm-sim.c
+++ b/src/mm-sim.c
@@ -30,8 +30,8 @@
#include <mm-marshal.h>
#include "mm-iface-modem.h"
-#include "mm-at.h"
#include "mm-sim.h"
+#include "mm-base-modem-at.h"
#include "mm-base-modem.h"
#include "mm-utils.h"
#include "mm-log.h"
@@ -64,19 +64,17 @@ struct _MMSimPrivate {
gchar *path;
};
+/*****************************************************************************/
+
typedef struct {
MMSim *self;
GDBusMethodInvocation *invocation;
- MMAtSerialPort *port;
GError *save_error;
} DbusCallContext;
static void
-dbus_call_context_free (DbusCallContext *ctx,
- gboolean close_port)
+dbus_call_context_free (DbusCallContext *ctx)
{
- if (close_port)
- mm_serial_port_close (MM_SERIAL_PORT (ctx->port));
g_object_unref (ctx->invocation);
g_object_unref (ctx->self);
if (ctx->save_error)
@@ -86,77 +84,31 @@ dbus_call_context_free (DbusCallContext *ctx,
static DbusCallContext *
dbus_call_context_new (MMSim *self,
- GDBusMethodInvocation *invocation,
- GError **error)
+ GDBusMethodInvocation *invocation)
{
DbusCallContext *ctx;
ctx = g_new0 (DbusCallContext, 1);
ctx->self = g_object_ref (self);
ctx->invocation = g_object_ref (invocation);
- ctx->port = mm_base_modem_get_port_primary (self->priv->modem);
-
- if (!mm_serial_port_open (MM_SERIAL_PORT (ctx->port), error)) {
- dbus_call_context_free (ctx, FALSE);
- return NULL;
- }
-
return ctx;
}
-static gboolean
-common_parse_no_reply (MMSim *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
-
- *result = NULL;
- return TRUE;
-}
-
-static gboolean
-common_parse_string_reply (MMSim *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
-{
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
-
- *result = g_variant_new_string (response);;
- return TRUE;
-}
-
+#undef NO_REPLY_READY_FN
#define NO_REPLY_READY_FN(NAME) \
static void \
- handle_##NAME##_ready (MMSim *self, \
+ handle_##NAME##_ready (MMBaseModem *modem, \
GAsyncResult *res, \
DbusCallContext *ctx) \
{ \
GError *error = NULL; \
- GVariant *reply; \
- \
- reply = mm_at_command_finish (G_OBJECT (self), res, &error); \
- g_assert (reply == NULL); \
\
+ mm_base_modem_at_command_finish (MM_BASE_MODEM (modem), res, &error); \
if (error) \
g_dbus_method_invocation_take_error (ctx->invocation, error); \
else \
- mm_gdbus_sim_complete_##NAME (MM_GDBUS_SIM (self), ctx->invocation); \
- dbus_call_context_free (ctx, TRUE); \
+ mm_gdbus_sim_complete_##NAME (MM_GDBUS_SIM (ctx->self), ctx->invocation); \
+ dbus_call_context_free (ctx); \
}
/*****************************************************************************/
@@ -171,28 +123,18 @@ handle_change_pin (MMSim *self,
const gchar *arg_new_pin)
{
gchar *command;
- DbusCallContext *ctx;
- GError *error = NULL;
-
- ctx = dbus_call_context_new (self, invocation, &error);
- if (!ctx) {
- g_dbus_method_invocation_take_error (ctx->invocation, error);
- return TRUE;
- }
command = g_strdup_printf ("+CPWD=\"SC\",\"%s\",\"%s\"",
arg_old_pin,
arg_new_pin);
- mm_at_command (G_OBJECT (self),
- ctx->port,
- command,
- 3,
- (MMAtResponseProcessor)common_parse_no_reply,
- NULL, /* response_processor_context */
- NULL, /* result_signature */
- NULL, /* TODO: cancellable */
- (GAsyncReadyCallback)handle_change_pin_ready,
- ctx);
+ mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem),
+ command,
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)handle_change_pin_ready,
+ dbus_call_context_new (self,
+ invocation));
g_free (command);
return TRUE;
}
@@ -209,28 +151,18 @@ handle_enable_pin (MMSim *self,
gboolean arg_enabled)
{
gchar *command;
- DbusCallContext *ctx;
- GError *error = NULL;
-
- ctx = dbus_call_context_new (self, invocation, &error);
- if (!ctx) {
- g_dbus_method_invocation_take_error (ctx->invocation, error);
- return TRUE;
- }
command = g_strdup_printf ("+CLCK=\"SC\",%d,\"%s\"",
arg_enabled ? 1 : 0,
arg_pin);
- mm_at_command (G_OBJECT (self),
- ctx->port,
- command,
- 3,
- (MMAtResponseProcessor)common_parse_no_reply,
- NULL, /* response_processor_context */
- NULL, /* result_signature */
- NULL, /* TODO: cancellable */
- (GAsyncReadyCallback)handle_enable_pin_ready,
- ctx);
+ mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem),
+ command,
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)handle_enable_pin_ready,
+ dbus_call_context_new (self,
+ invocation));
g_free (command);
return TRUE;
}
@@ -313,21 +245,20 @@ unlock_check_ready (MMIfaceModem *modem,
g_warn_if_reached ();
}
- dbus_call_context_free (ctx, TRUE);
+ dbus_call_context_free (ctx);
}
static void
-handle_send_pin_puk_ready (MMSim *self,
+handle_send_pin_puk_ready (MMBaseModem *modem,
GAsyncResult *res,
DbusCallContext *ctx)
{
- GVariant *reply;
-
- reply = mm_at_command_finish (G_OBJECT (self), res, &ctx->save_error);
- g_assert (reply == NULL);
+ mm_base_modem_at_command_finish (modem,
+ res,
+ &ctx->save_error);
/* Once pin/puk has been sent, recheck lock */
- mm_iface_modem_unlock_check (MM_IFACE_MODEM (self->priv->modem),
+ mm_iface_modem_unlock_check (MM_IFACE_MODEM (modem),
(GAsyncReadyCallback)unlock_check_ready,
ctx);
}
@@ -338,26 +269,16 @@ handle_send_pin (MMSim *self,
const gchar *arg_pin)
{
gchar *command;
- DbusCallContext *ctx;
- GError *error = NULL;
-
- ctx = dbus_call_context_new (self, invocation, &error);
- if (!ctx) {
- g_dbus_method_invocation_take_error (ctx->invocation, error);
- return TRUE;
- }
command = g_strdup_printf ("+CPIN=\"%s\"", arg_pin);
- mm_at_command (G_OBJECT (self),
- ctx->port,
- command,
- 3,
- (MMAtResponseProcessor)common_parse_no_reply,
- NULL, /* response_processor_context */
- NULL, /* result_signature */
- NULL, /* TODO: cancellable */
- (GAsyncReadyCallback)handle_send_pin_puk_ready,
- ctx);
+ mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem),
+ command,
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)handle_send_pin_puk_ready,
+ dbus_call_context_new (self,
+ invocation));
g_free (command);
return TRUE;
}
@@ -369,28 +290,18 @@ handle_send_puk (MMSim *self,
const gchar *arg_pin)
{
gchar *command;
- DbusCallContext *ctx;
- GError *error = NULL;
-
- ctx = dbus_call_context_new (self, invocation, &error);
- if (!ctx) {
- g_dbus_method_invocation_take_error (ctx->invocation, error);
- return TRUE;
- }
command = g_strdup_printf ("+CPIN=\"%s\",\"%s\"",
arg_puk,
arg_pin);
- mm_at_command (G_OBJECT (self),
- ctx->port,
- command,
- 3,
- (MMAtResponseProcessor)common_parse_no_reply,
- NULL, /* response_processor_context */
- NULL, /* result_signature */
- NULL, /* TODO: cancellable */
- (GAsyncReadyCallback)handle_send_pin_puk_ready,
- ctx);
+ mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem),
+ command,
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)handle_send_pin_puk_ready,
+ dbus_call_context_new (self,
+ invocation));
g_free (command);
return TRUE;
}
@@ -438,16 +349,35 @@ mm_sim_unexport (MMSim *self)
}
/*****************************************************************************/
+
+#undef STR_REPLY_READY_FN
+#define STR_REPLY_READY_FN(NAME) \
+ static void \
+ NAME##_command_ready (MMBaseModem *modem, \
+ GAsyncResult *res, \
+ GSimpleAsyncResult *operation_result) \
+ { \
+ GError *error = NULL; \
+ const gchar *response; \
+ \
+ response = mm_base_modem_at_command_finish (modem, res, &error); \
+ if (error) \
+ g_simple_async_result_take_error (operation_result, error); \
+ else \
+ g_simple_async_result_set_op_res_gpointer (operation_result, \
+ (gpointer)response, \
+ NULL); \
+ \
+ g_simple_async_result_complete (operation_result); \
+ g_object_unref (operation_result); \
+ }
+
+/*****************************************************************************/
/* SIM IDENTIFIER */
-static gboolean
-parse_iccid (MMSim *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
+static gchar *
+parse_iccid (const gchar *response,
+ GError **error)
{
gchar buf[21];
gchar swapped[21];
@@ -456,11 +386,6 @@ parse_iccid (MMSim *self,
gint sw2;
gboolean success = FALSE;
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
-
memset (buf, 0, sizeof (buf));
str = mm_strip_tag (response, "+CRSM:");
if (sscanf (str, "%d,%d,\"%20c\"", &sw1, &sw2, (char *) &buf) == 3)
@@ -472,10 +397,11 @@ parse_iccid (MMSim *self,
}
if (!success) {
- *result_error = g_error_new_literal (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Could not parse the CRSM response");
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Could not parse the CRSM response");
+ return NULL;
}
if ((sw1 == 0x90 && sw2 == 0x00) ||
@@ -501,28 +427,31 @@ parse_iccid (MMSim *self,
}
/* Invalid character */
- *result_error = g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "CRSM ICCID response contained invalid character '%c'",
- buf[len]);
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "CRSM ICCID response contained invalid character '%c'",
+ buf[len]);
+ return NULL;
}
/* BCD encoded ICCIDs are 20 digits long */
if (len != 20) {
- *result_error = g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Invalid +CRSM ICCID response size (was %zd, expected 20)",
- len);
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Invalid +CRSM ICCID response size (was %zd, expected 20)",
+ len);
+ return NULL;
}
/* Ensure if there's an 'F' that it's second-to-last */
if ((f_pos >= 0) && (f_pos != len - 2)) {
- *result_error = g_error_new_literal (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Invalid +CRSM ICCID length (unexpected F)");
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Invalid +CRSM ICCID length (unexpected F)");
+ return NULL;
}
/* Swap digits in the EFiccid response to get the actual ICCID, each
@@ -540,14 +469,15 @@ parse_iccid (MMSim *self,
if (swapped[len - 1] == 'F')
swapped[len - 1] = 0;
- *result = g_variant_new_string (swapped);
- return TRUE;
+
+ return g_strdup (swapped);
} else {
- *result_error = g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
- sw1, sw2);
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
+ sw1, sw2);
+ return NULL;
}
}
@@ -556,19 +486,23 @@ load_sim_identifier_finish (MMSim *self,
GAsyncResult *res,
GError **error)
{
- GVariant *result;
+ const gchar *result;
gchar *sim_identifier;
- result = mm_at_command_finish (G_OBJECT (self), res, error);
- if (!result)
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ return NULL;
+ result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
+
+ sim_identifier = parse_iccid (result, error);
+ if (!sim_identifier)
return NULL;
- sim_identifier = g_variant_dup_string (result, NULL);
mm_dbg ("loaded SIM identifier: %s", sim_identifier);
- g_variant_unref (result);
return sim_identifier;
}
+STR_REPLY_READY_FN (load_sim_identifier)
+
static void
load_sim_identifier (MMSim *self,
GAsyncReadyCallback callback,
@@ -577,16 +511,17 @@ load_sim_identifier (MMSim *self,
mm_dbg ("loading SIM identifier...");
/* READ BINARY of EFiccid (ICC Identification) ETSI TS 102.221 section 13.2 */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self->priv->modem)),
- "+CRSM=176,12258,0,0,10",
- 20,
- (MMAtResponseProcessor)parse_iccid,
- NULL, /* response_processor_context */
- "s",
- NULL, /*TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_command (
+ MM_BASE_MODEM (self->priv->modem),
+ "+CRSM=176,12258,0,0,10",
+ 20,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)load_sim_identifier_command_ready,
+ g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ load_sim_identifier));
}
/*****************************************************************************/
@@ -597,19 +532,18 @@ load_imsi_finish (MMSim *self,
GAsyncResult *res,
GError **error)
{
- GVariant *result;
gchar *imsi;
- result = mm_at_command_finish (G_OBJECT (self), res, error);
- if (!result)
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
+ imsi = g_strdup (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
- imsi = g_variant_dup_string (result, NULL);
mm_dbg ("loaded IMSI: %s", imsi);
- g_variant_unref (result);
return imsi;
}
+STR_REPLY_READY_FN (load_imsi)
+
static void
load_imsi (MMSim *self,
GAsyncReadyCallback callback,
@@ -617,40 +551,31 @@ load_imsi (MMSim *self,
{
mm_dbg ("loading IMSI...");
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self->priv->modem)),
- "+CIMI",
- 3,
- (MMAtResponseProcessor)common_parse_string_reply,
- NULL, /* response_processor_context */
- "s",
- NULL, /*TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_command (
+ MM_BASE_MODEM (self->priv->modem),
+ "+CIMI",
+ 3,
+ TRUE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)load_imsi_command_ready,
+ g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ load_imsi));
}
/*****************************************************************************/
/* Operator ID */
-static gboolean
-parse_mnc_length (MMSim *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
+static guint
+parse_mnc_length (const gchar *response,
+ GError **error)
{
gint sw1;
gint sw2;
gboolean success = FALSE;
gchar hex[51];
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
-
memset (hex, 0, sizeof (hex));
if (sscanf (response, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3)
success = TRUE;
@@ -661,10 +586,11 @@ parse_mnc_length (MMSim *self,
}
if (!success) {
- *result_error = g_error_new_literal (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Could not parse the CRSM response");
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Could not parse the CRSM response");
+ return 0;
}
if ((sw1 == 0x90 && sw2 == 0x00) ||
@@ -687,35 +613,37 @@ parse_mnc_length (MMSim *self,
/* Convert hex string to binary */
bin = utils_hexstr2bin (hex, &buflen);
if (!bin || buflen < 4) {
- *result_error = g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "SIM returned malformed response '%s'",
- hex);
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "SIM returned malformed response '%s'",
+ hex);
g_free (bin);
- return FALSE;
+ return 0;
}
/* MNC length is byte 4 of this SIM file */
mnc_len = bin[3] & 0xFF;
if (mnc_len == 2 || mnc_len == 3) {
- *result = g_variant_new_uint32 (mnc_len);
g_free (bin);
- return TRUE;
+ return mnc_len;
}
- *result_error = g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "SIM returned invalid MNC length %d (should be either 2 or 3)",
- mnc_len);
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "SIM returned invalid MNC length %d (should be either 2 or 3)",
+ mnc_len);
g_free (bin);
- return FALSE;
+ return 0;
}
- *result_error = g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
- sw1, sw2);
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
+ sw1, sw2);
+ return 0;
}
static gchar *
@@ -723,17 +651,17 @@ load_operator_identifier_finish (MMSim *self,
GAsyncResult *res,
GError **error)
{
- GVariant *result;
- gchar *operator_id;
+ GError *inner_error = NULL;
const gchar *imsi;
+ const gchar *result;
+ guint mnc_length;
- result = mm_at_command_finish (G_OBJECT (self), res, error);
- if (!result)
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
+ result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
imsi = mm_gdbus_sim_get_imsi (MM_GDBUS_SIM (self));
if (!imsi) {
- g_variant_unref (result);
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
@@ -741,13 +669,18 @@ load_operator_identifier_finish (MMSim *self,
return NULL;
}
+ mnc_length = parse_mnc_length (result, &inner_error);
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return NULL;
+ }
+
/* Build Operator ID */
- operator_id = g_strndup (imsi,
- 3 + g_variant_get_uint32 (result));
- g_variant_unref (result);
- return operator_id;
+ return g_strndup (imsi, 3 + mnc_length);
}
+STR_REPLY_READY_FN (load_operator_identifier)
+
static void
load_operator_identifier (MMSim *self,
GAsyncReadyCallback callback,
@@ -756,40 +689,31 @@ load_operator_identifier (MMSim *self,
mm_dbg ("loading Operator ID...");
/* READ BINARY of EFad (Administrative Data) ETSI 51.011 section 10.3.18 */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self->priv->modem)),
- "+CRSM=176,28589,0,0,4",
- 3,
- (MMAtResponseProcessor)parse_mnc_length,
- NULL, /* response_processor_context */
- "u", /* mnc length */
- NULL, /*TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_command (
+ MM_BASE_MODEM (self->priv->modem),
+ "+CRSM=176,28589,0,0,4",
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)load_operator_identifier_command_ready,
+ g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ load_operator_identifier));
}
/*****************************************************************************/
/* Operator Name (Service Provider Name) */
-static gboolean
-parse_spn (MMSim *self,
- gpointer none,
- const gchar *command,
- const gchar *response,
- const GError *error,
- GVariant **result,
- GError **result_error)
+static gchar *
+parse_spn (const gchar *response,
+ GError **error)
{
gint sw1;
gint sw2;
gboolean success = FALSE;
gchar hex[51];
- if (error) {
- *result_error = g_error_copy (error);
- return FALSE;
- }
-
memset (hex, 0, sizeof (hex));
if (sscanf (response, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3)
success = TRUE;
@@ -800,10 +724,11 @@ parse_spn (MMSim *self,
}
if (!success) {
- *result_error = g_error_new_literal (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Could not parse the CRSM response");
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "Could not parse the CRSM response");
+ return NULL;
}
if ((sw1 == 0x90 && sw2 == 0x00) ||
@@ -826,11 +751,12 @@ parse_spn (MMSim *self,
/* Convert hex string to binary */
bin = utils_hexstr2bin (hex, &buflen);
if (!bin) {
- *result_error = g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "SIM returned malformed response '%s'",
- hex);
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "SIM returned malformed response '%s'",
+ hex);
+ return NULL;
}
/* Remove the FF filler at the end */
@@ -839,17 +765,16 @@ parse_spn (MMSim *self,
/* First byte is metadata; remainder is GSM-7 unpacked into octets; convert to UTF8 */
utf8 = (gchar *)mm_charset_gsm_unpacked_to_utf8 ((guint8 *)bin + 1, buflen - 1);
- *result = g_variant_new_string (utf8);
- g_free (utf8);
g_free (bin);
- return TRUE;
+ return utf8;
}
- *result_error = g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
- sw1, sw2);
- return FALSE;
+ g_set_error (error,
+ MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "SIM failed to handle CRSM request (sw1 %d sw2 %d)",
+ sw1, sw2);
+ return NULL;
}
static gchar *
@@ -857,18 +782,17 @@ load_operator_name_finish (MMSim *self,
GAsyncResult *res,
GError **error)
{
- GVariant *result;
- gchar *operator_name;
+ const gchar *result;
- result = mm_at_command_finish (G_OBJECT (self), res, error);
- if (!result)
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
return NULL;
+ result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
- operator_name = g_variant_dup_string (result, NULL);
- g_variant_unref (result);
- return operator_name;
+ return parse_spn (result, error);
}
+STR_REPLY_READY_FN (load_operator_name)
+
static void
load_operator_name (MMSim *self,
GAsyncReadyCallback callback,
@@ -877,16 +801,17 @@ load_operator_name (MMSim *self,
mm_dbg ("loading Operator Name...");
/* READ BINARY of EFspn (Service Provider Name) ETSI 51.011 section 10.3.11 */
- mm_at_command (G_OBJECT (self),
- mm_base_modem_get_port_primary (MM_BASE_MODEM (self->priv->modem)),
- "+CRSM=176,28486,0,0,17",
- 3,
- (MMAtResponseProcessor)parse_spn,
- NULL, /* response_processor_context */
- "s", /* spn */
- NULL, /*TODO: cancellable */
- callback,
- user_data);
+ mm_base_modem_at_command (
+ MM_BASE_MODEM (self->priv->modem),
+ "+CRSM=176,28486,0,0,17",
+ 3,
+ FALSE,
+ NULL, /* cancellable */
+ (GAsyncReadyCallback)load_operator_name_command_ready,
+ g_simple_async_result_new (G_OBJECT (self),
+ callback,
+ user_data,
+ load_operator_name));
}
/*****************************************************************************/
@@ -976,6 +901,7 @@ load_sim_identifier_ready (MMSim *self,
interface_initialization_step (ctx);
}
+#undef STR_REPLY_READY_FN
#define STR_REPLY_READY_FN(NAME,DISPLAY) \
static void \
load_##NAME##_ready (MMSim *self, \
@@ -1301,4 +1227,3 @@ mm_sim_class_init (MMSimClass *klass)
G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_MODEM, properties[PROP_MODEM]);
}
-