aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Schwermer <sven.schwermer@disruptive-technologies.com>2022-08-05 11:20:08 +0200
committerAleksander Morgado <aleksandermj@chromium.org>2022-10-17 09:35:30 +0000
commite5bb33a46369f12ef97b766079fa61b7d4a2f9f8 (patch)
treed5c6bc2582e0fdf215771a87370cf27530679794
parent04ed52a74cf9d24c5deacbb118ec985375ac4a9b (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>
-rw-r--r--plugins/fibocom/mm-broadband-bearer-fibocom-ecm.c71
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;