summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Chan <benchan@chromium.org>2012-11-04 01:00:03 (GMT)
committerAleksander Morgado <aleksander@lanedo.com>2012-11-05 15:10:19 (GMT)
commit5a16f2aff10660bdf279a5ebbd0138f6aea6480a (patch)
tree9ca62f3fadcc0a50163c17de5b6b31b59d2726d3
parentaf48e1c8b7b4cdc4212540d0f893a09f68630959 (diff)
novatel-lte: use $NWMDN to read own number when +CNUM fails
+CNUM may return ERROR when the modem fails to read the own numbers from the SIM card or when the SIM card hasn't been activated. Use $NWMDN to read the MDN as a fallback, which distinguishes these two cases.
-rw-r--r--plugins/novatel/mm-broadband-modem-novatel-lte.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/plugins/novatel/mm-broadband-modem-novatel-lte.c b/plugins/novatel/mm-broadband-modem-novatel-lte.c
index 6f2e7e2..249a4a1 100644
--- a/plugins/novatel/mm-broadband-modem-novatel-lte.c
+++ b/plugins/novatel/mm-broadband-modem-novatel-lte.c
@@ -158,6 +158,107 @@ modem_after_sim_unlock (MMIfaceModem *self,
}
/*****************************************************************************/
+/* Load own numbers (Modem interface) */
+
+static GStrv
+load_own_numbers_finish (MMIfaceModem *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ GVariant *result;
+ GStrv own_numbers;
+
+ result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
+ if (!result)
+ return NULL;
+
+ own_numbers = (GStrv) g_variant_dup_strv (result, NULL);
+ return own_numbers;
+}
+
+static gboolean
+response_processor_cnum_ignore_at_errors (MMBaseModem *self,
+ gpointer none,
+ const gchar *command,
+ const gchar *response,
+ gboolean last_command,
+ const GError *error,
+ GVariant **result,
+ GError **result_error)
+{
+ GStrv own_numbers;
+
+ if (error) {
+ /* Ignore AT errors (ie, ERROR or CMx ERROR) */
+ if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command)
+ *result_error = g_error_copy (error);
+
+ return FALSE;
+ }
+
+ own_numbers = mm_3gpp_parse_cnum_exec_response (response, result_error);
+ if (!own_numbers)
+ return FALSE;
+
+ *result = g_variant_new_strv ((const gchar *const *) own_numbers, -1);
+ g_strfreev (own_numbers);
+ return TRUE;
+}
+
+static gboolean
+response_processor_nwmdn_ignore_at_errors (MMBaseModem *self,
+ gpointer none,
+ const gchar *command,
+ const gchar *response,
+ gboolean last_command,
+ const GError *error,
+ GVariant **result,
+ GError **result_error)
+{
+ GArray *array;
+ GStrv own_numbers;
+ gchar *mdn;
+
+ if (error) {
+ /* Ignore AT errors (ie, ERROR or CMx ERROR) */
+ if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command)
+ *result_error = g_error_copy (error);
+
+ return FALSE;
+ }
+
+ mdn = g_strdup (mm_strip_tag (response, "$NWMDN:"));
+ array = g_array_new (TRUE, TRUE, sizeof (gchar *));
+ g_array_append_val (array, mdn);
+ own_numbers = (GStrv) g_array_free (array, FALSE);
+
+ *result = g_variant_new_strv ((const gchar *const *) own_numbers, -1);
+ g_strfreev (own_numbers);
+ return TRUE;
+}
+
+static const MMBaseModemAtCommand own_numbers_commands[] = {
+ { "+CNUM", 3, TRUE, response_processor_cnum_ignore_at_errors },
+ { "$NWMDN", 3, TRUE, response_processor_nwmdn_ignore_at_errors },
+ { NULL }
+};
+
+static void
+load_own_numbers (MMIfaceModem *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ mm_dbg ("loading (Novatel LTE) own numbers...");
+ mm_base_modem_at_sequence (
+ MM_BASE_MODEM (self),
+ own_numbers_commands,
+ NULL, /* response_processor_context */
+ NULL, /* response_processor_context_free */
+ callback,
+ user_data);
+}
+
+/*****************************************************************************/
/* Load supported bands (Modem interface) */
/*
@@ -449,6 +550,8 @@ iface_modem_init (MMIfaceModem *iface)
iface->create_sim_finish = modem_create_sim_finish;
iface->modem_after_sim_unlock = modem_after_sim_unlock;
iface->modem_after_sim_unlock_finish = modem_after_sim_unlock_finish;
+ iface->load_own_numbers = load_own_numbers;
+ iface->load_own_numbers_finish = load_own_numbers_finish;
iface->load_supported_bands = load_supported_bands;
iface->load_supported_bands_finish = load_supported_bands_finish;
iface->load_current_bands = load_current_bands;