diff options
author | Aleksander Morgado <aleksandermj@chromium.org> | 2024-04-04 11:05:58 +0000 |
---|---|---|
committer | Dan Williams <dan@bigw.org> | 2024-04-12 01:17:14 +0000 |
commit | b158c2e92ad8f363c86523ff3bfcd8c9098915b7 (patch) | |
tree | 5b3958b3da7ed8ac432a46aaa536af871614e4e3 | |
parent | ec8bbeeafcdce7c39ff0693ba5f474644d5b0ac7 (diff) |
broadband-modem: don't assume an AT port always exists in explicit registration
-rw-r--r-- | src/mm-broadband-modem.c | 120 |
1 files changed, 74 insertions, 46 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 8fb15644..48b3c823 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -5003,6 +5003,19 @@ modem_3gpp_scan_networks (MMIfaceModem3gpp *self, /*****************************************************************************/ /* Register in network (3GPP interface) */ +typedef struct { + gchar *operator_id; + MMPortSerialAt *port; +} RegisterInNetworkContext; + +static void +register_in_network_context_free (RegisterInNetworkContext *ctx) +{ + g_free (ctx->operator_id); + g_object_unref (ctx->port); + g_slice_free (RegisterInNetworkContext, ctx); +} + static gboolean modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self, GAsyncResult *res, @@ -5034,42 +5047,48 @@ cops_ascii_set_ready (MMBaseModem *_self, g_autoptr(GError) error = NULL; if (!mm_base_modem_at_command_full_finish (_self, res, &error)) { + RegisterInNetworkContext *ctx; + g_autoptr(GError) enc_error = NULL; + g_autofree gchar *operator_id_enc = NULL; + g_autofree gchar *command = NULL; + + if (!g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED)) { + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + return; + } + /* If it failed with an unsupported error, retry with current modem charset */ - if (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED)) { - g_autoptr(GError) enc_error = NULL; - g_autofree gchar *operator_id_enc = NULL; - gchar *operator_id; - - /* try to encode to current charset */ - operator_id = g_task_get_task_data (task); - operator_id_enc = mm_modem_charset_str_from_utf8 (operator_id, self->priv->modem_current_charset, FALSE, &enc_error); - if (!operator_id_enc) { - mm_obj_dbg (self, "couldn't convert operator id to current charset: %s", enc_error->message); - g_task_return_error (task, g_steal_pointer (&error)); - g_object_unref (task); - return; - } + ctx = g_task_get_task_data (task); + operator_id_enc = mm_modem_charset_str_from_utf8 (ctx->operator_id, self->priv->modem_current_charset, FALSE, &enc_error); + if (!operator_id_enc) { + mm_obj_dbg (self, "couldn't convert operator id to current charset: %s", enc_error->message); + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + return; + } - /* retry only if encoded string is different to the non-encoded one */ - if (g_strcmp0 (operator_id, operator_id_enc) != 0) { - g_autofree gchar *command = NULL; - - command = g_strdup_printf ("+COPS=1,2,\"%s\"", operator_id_enc); - mm_base_modem_at_command_full (_self, - mm_base_modem_peek_best_at_port (_self, NULL), - command, - 120, - FALSE, - FALSE, /* raw */ - g_task_get_cancellable (task), - (GAsyncReadyCallback)cops_set_ready, - task); - return; - } + /* retry only if encoded string is different to the non-encoded one */ + if (g_strcmp0 (ctx->operator_id, operator_id_enc) == 0) { + g_task_return_error (task, g_steal_pointer (&error)); + g_object_unref (task); + return; } - g_task_return_error (task, g_steal_pointer (&error)); - } else - g_task_return_boolean (task, TRUE); + + command = g_strdup_printf ("+COPS=1,2,\"%s\"", operator_id_enc); + mm_base_modem_at_command_full (_self, + ctx->port, + command, + 120, + FALSE, + FALSE, /* raw */ + g_task_get_cancellable (task), + (GAsyncReadyCallback)cops_set_ready, + task); + return; + } + + g_task_return_boolean (task, TRUE); g_object_unref (task); } @@ -5080,17 +5099,31 @@ modem_3gpp_register_in_network (MMIfaceModem3gpp *self, GAsyncReadyCallback callback, gpointer user_data) { - GTask *task; - gchar *command; + RegisterInNetworkContext *ctx; + GTask *task; + MMPortSerialAt *port; + GError *error = NULL; + g_autofree gchar *command = NULL; task = g_task_new (self, cancellable, callback, user_data); + port = mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), &error); + if (!port) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + ctx = g_slice_new0 (RegisterInNetworkContext); + ctx->port = g_object_ref (port); + ctx->operator_id = g_strdup (operator_id); + g_task_set_task_data (task, ctx, (GDestroyNotify)register_in_network_context_free); + /* Trigger automatic network registration if no explicit operator id given */ - if (!operator_id) { - /* Note that '+COPS=0,,' (same but with commas) won't work in some Nokia - * phones */ + if (!ctx->operator_id) { + /* Note that '+COPS=0,,' (same but with commas) won't work in some Nokia phones */ mm_base_modem_at_command_full (MM_BASE_MODEM (self), - mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL), + port, "+COPS=0", 120, FALSE, @@ -5101,14 +5134,10 @@ modem_3gpp_register_in_network (MMIfaceModem3gpp *self, return; } - /* Store operator id in context, in case we need to retry with the current - * modem charset */ - g_task_set_task_data (task, g_strdup (operator_id), g_free); - /* Use the operator id given in ASCII initially */ - command = g_strdup_printf ("+COPS=1,2,\"%s\"", operator_id); + command = g_strdup_printf ("+COPS=1,2,\"%s\"", ctx->operator_id); mm_base_modem_at_command_full (MM_BASE_MODEM (self), - mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL), + port, command, 120, FALSE, @@ -5116,7 +5145,6 @@ modem_3gpp_register_in_network (MMIfaceModem3gpp *self, cancellable, (GAsyncReadyCallback)cops_ascii_set_ready, task); - g_free (command); } /*****************************************************************************/ |