cinterion: add retry mechanism to the ^SWWAN? command

Since it is possible that the delayed status request for the connection
(^SWWAN?) also does not return the updated status a retry is needed.
This retry is only done for the activation path. So the connection
status monitoring and the deactivation path is not affected.

Signed-off-by: Heiko Thiery <heiko.thiery@gmail.com>
This commit is contained in:
Heiko Thiery
2022-11-21 08:30:43 +01:00
committed by Aleksander Morgado
parent 41bbe42182
commit b5c9bae104

View File

@@ -101,6 +101,21 @@ load_connection_status_finish (MMBaseBearer *bearer,
return (MMBearerConnectionStatus) aux;
}
typedef struct {
guint cid;
guint retries;
gboolean delay;
gboolean retry;
} LoadConnectionContext;
static void
load_connection_context_free (LoadConnectionContext *ctx)
{
g_slice_free (LoadConnectionContext, ctx);
}
static gboolean swwan_check_status (GTask *task);
static void
swwan_check_status_ready (MMBaseModem *modem,
GAsyncResult *res,
@@ -110,10 +125,10 @@ swwan_check_status_ready (MMBaseModem *modem,
const gchar *response;
GError *error = NULL;
MMBearerConnectionStatus status;
guint cid;
LoadConnectionContext *ctx;
self = g_task_get_source_object (task);
cid = GPOINTER_TO_UINT (g_task_get_task_data (task));
ctx = g_task_get_task_data (task);
response = mm_base_modem_at_command_finish (modem, res, &error);
if (!response) {
@@ -121,10 +136,25 @@ swwan_check_status_ready (MMBaseModem *modem,
goto out;
}
status = mm_cinterion_parse_swwan_response (response, cid, self, &error);
status = mm_cinterion_parse_swwan_response (response, ctx->cid, self, &error);
if (status == MM_BEARER_CONNECTION_STATUS_UNKNOWN) {
g_task_return_error (task, error);
goto out;
} else if (ctx->retry && status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED) {
mm_obj_dbg (self, "check status retry");
if (ctx->retries == 0) {
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"CID %u status check retry exceeded", ctx->cid);
goto out;
} else {
if (ctx->delay) {
g_timeout_add_seconds (1, (GSourceFunc)swwan_check_status, task);
} else {
g_idle_add ((GSourceFunc)swwan_check_status, task);
}
ctx->retries--;
return;
}
}
g_assert (status == MM_BEARER_CONNECTION_STATUS_DISCONNECTED ||
@@ -159,10 +189,12 @@ static void
load_connection_status_by_cid (MMBroadbandBearerCinterion *bearer,
gint cid,
gboolean delay,
gboolean retry,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
LoadConnectionContext *ctx;
task = g_task_new (bearer, NULL, callback, user_data);
if (cid == MM_3GPP_PROFILE_ID_UNKNOWN) {
@@ -172,7 +204,14 @@ load_connection_status_by_cid (MMBroadbandBearerCinterion *bearer,
return;
}
g_task_set_task_data (task, GUINT_TO_POINTER (cid), NULL);
ctx = g_slice_new0 (LoadConnectionContext);
g_task_set_task_data (task, ctx, (GDestroyNotify) load_connection_context_free);
/* Setup context */
ctx->cid = cid;
ctx->retries = 5;
ctx->delay = delay;
ctx->retry = retry;
/* Some modems require a delay before querying the SWWAN status
* This is only needed for step DIAL_3GPP_CONTEXT_STEP_VALIDATE_CONNECTION
@@ -192,6 +231,7 @@ load_connection_status (MMBaseBearer *bearer,
load_connection_status_by_cid (MM_BROADBAND_BEARER_CINTERION (bearer),
mm_base_bearer_get_profile_id (bearer),
FALSE,
FALSE,
callback,
user_data);
}
@@ -431,6 +471,7 @@ dial_3gpp_context_step (GTask *task)
load_connection_status_by_cid (ctx->self,
(gint) ctx->cid,
TRUE,
TRUE,
(GAsyncReadyCallback) dial_connection_status_ready,
task);
return;
@@ -630,6 +671,7 @@ disconnect_3gpp_context_step (GTask *task)
load_connection_status_by_cid (MM_BROADBAND_BEARER_CINTERION (ctx->self),
(gint) ctx->cid,
TRUE,
FALSE,
(GAsyncReadyCallback) disconnect_connection_status_ready,
task);
return;