diff options
author | Sven Schwermer <sven.schwermer@disruptive-technologies.com> | 2022-08-05 11:20:08 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2022-10-17 09:35:30 +0000 |
commit | e5bb33a46369f12ef97b766079fa61b7d4a2f9f8 (patch) | |
tree | d5c6bc2582e0fdf215771a87370cf27530679794 /plugins | |
parent | 04ed52a74cf9d24c5deacbb118ec985375ac4a9b (diff) |
fibocom: Monitor connection status using +GTRNDIS?
In situations where the configured APN for the initial EPS bearer
(cid=1) does not match the APN for the actual connection, ModemManager
sets up a context (cid!=1) with the proper APN when connecting. If the
APN for the initial EPS bearer was not valid, the SIM may fall back to a
default one. If that default matches the APN for the proper connection,
the initial EPS bearer is re-used for the actual connection. In that
scenario, +CGACT? will report deactivated for the actual connection
context (cid!=1). ModemManager subsequently reports the connection as
disconnected.
+GTRNDIS? will always reflect the correct state for the context ID we
used to set up the ECM connection. Hence, it makes sense to use this
command to assess the connection status.
This has been tested with the MA510-GL modem module.
Signed-off-by: Sven Schwermer <sven.schwermer@disruptive-technologies.com>
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/fibocom/mm-broadband-bearer-fibocom-ecm.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/plugins/fibocom/mm-broadband-bearer-fibocom-ecm.c b/plugins/fibocom/mm-broadband-bearer-fibocom-ecm.c index 6d045e1f..bc4ee1ec 100644 --- a/plugins/fibocom/mm-broadband-bearer-fibocom-ecm.c +++ b/plugins/fibocom/mm-broadband-bearer-fibocom-ecm.c @@ -64,6 +64,73 @@ parse_gtrndis_read_response (const gchar *response, } /*****************************************************************************/ +/* Connection status monitoring */ + +static MMBearerConnectionStatus +load_connection_status_finish (MMBaseBearer *bearer, + GAsyncResult *res, + GError **error) +{ + GError *inner_error = NULL; + gssize value; + + value = g_task_propagate_int (G_TASK (res), &inner_error); + if (inner_error) { + g_propagate_error (error, inner_error); + return MM_BEARER_CONNECTION_STATUS_UNKNOWN; + } + return (MMBearerConnectionStatus) value; +} + +static void +gtrndis_query_ready (MMBaseModem *modem, + GAsyncResult *res, + GTask *task) +{ + MMBaseBearer *bearer; + GError *error = NULL; + const gchar *result; + guint state; + guint cid; + + bearer = g_task_get_source_object (task); + result = mm_base_modem_at_command_finish (modem, res, &error); + if (!result) + g_task_return_error (task, error); + else if (!parse_gtrndis_read_response (result, &state, &cid, &error)) + g_task_return_error (task, error); + else if (!state || (gint) cid != mm_base_bearer_get_profile_id (bearer)) + g_task_return_int (task, MM_BEARER_CONNECTION_STATUS_DISCONNECTED); + else + g_task_return_int (task, MM_BEARER_CONNECTION_STATUS_CONNECTED); + + g_object_unref (task); +} + +static void +load_connection_status (MMBaseBearer *bearer, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + MMBaseModem *modem = NULL; + + task = g_task_new (bearer, NULL, callback, user_data); + + g_object_get (MM_BASE_BEARER (bearer), + MM_BASE_BEARER_MODEM, &modem, + NULL); + + mm_base_modem_at_command (modem, + "+GTRNDIS?", + 3, + FALSE, + (GAsyncReadyCallback) gtrndis_query_ready, + task); + g_object_unref (modem); +} + +/*****************************************************************************/ /* 3GPP Connect */ typedef struct { @@ -458,8 +525,12 @@ mm_broadband_bearer_fibocom_ecm_init (MMBroadbandBearerFibocomEcm *self) static void mm_broadband_bearer_fibocom_ecm_class_init (MMBroadbandBearerFibocomEcmClass *klass) { + MMBaseBearerClass *base_bearer_class = MM_BASE_BEARER_CLASS (klass); MMBroadbandBearerClass *broadband_bearer_class = MM_BROADBAND_BEARER_CLASS (klass); + base_bearer_class->load_connection_status = load_connection_status; + base_bearer_class->load_connection_status_finish = load_connection_status_finish; + broadband_bearer_class->connect_3gpp = connect_3gpp; broadband_bearer_class->connect_3gpp_finish = connect_3gpp_finish; broadband_bearer_class->dial_3gpp = dial_3gpp; |