bearer-mbim: check if IP session is activated before deactivating it

It may be undesirable to issue a MBIM_CID_CONNECT
(MBIMActivationCommandDeactivate) command to deactivate an IP session
when the session isn't activated. For instance, it's been observed on
Huawei ME936 that it takes more than 30s for the modem to deactivate a
not-yet-activated session. This patch modifies MMBearerMbim to query if
a session is activated before trying to deactivate the session during a
connection attempt.
This commit is contained in:
Ben Chan
2018-02-02 09:32:53 -06:00
committed by Dan Williams
parent 785dfd3edd
commit 636c245cd3
+75
View File
@@ -211,6 +211,7 @@ typedef enum {
CONNECT_STEP_FIRST,
CONNECT_STEP_PACKET_SERVICE,
CONNECT_STEP_PROVISIONED_CONTEXTS,
CONNECT_STEP_CHECK_DISCONNECTED,
CONNECT_STEP_ENSURE_DISCONNECTED,
CONNECT_STEP_CONNECT,
CONNECT_STEP_IP_CONFIGURATION,
@@ -644,6 +645,53 @@ ensure_disconnected_ready (MbimDevice *device,
connect_context_step (task);
}
static void
check_disconnected_ready (MbimDevice *device,
GAsyncResult *res,
GTask *task)
{
ConnectContext *ctx;
GError *error = NULL;
MbimMessage *response;
guint32 session_id;
MbimActivationState activation_state;
ctx = g_task_get_task_data (task);
response = mbim_device_command_finish (device, res, &error);
if (response &&
mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) &&
mbim_message_connect_response_parse (
response,
&session_id,
&activation_state,
NULL, /* voice_call_state */
NULL, /* ip_type */
NULL, /* context_type */
NULL, /* nw_error */
&error)) {
mm_dbg ("Session ID '%u': %s", session_id, mbim_activation_state_get_string (activation_state));
} else
activation_state = MBIM_ACTIVATION_STATE_UNKNOWN;
if (response)
mbim_message_unref (response);
/* Some modem (e.g. Huawei ME936) reports MBIM_ACTIVATION_STATE_UNKNOWN
* when being queried for the activation state before an IP session has
* been activated once. Here we expect a modem would at least tell the
* truth when the session has been activated, so we proceed to deactivate
* the session only the modem indicates the session has been activated or
* is being activated.
*/
if (activation_state == MBIM_ACTIVATION_STATE_ACTIVATED || activation_state == MBIM_ACTIVATION_STATE_ACTIVATING)
ctx->step = CONNECT_STEP_ENSURE_DISCONNECTED;
else
ctx->step = CONNECT_STEP_CONNECT;
connect_context_step (task);
}
static void
provisioned_contexts_query_ready (MbimDevice *device,
GAsyncResult *res,
@@ -829,6 +877,33 @@ connect_context_step (GTask *task)
mbim_message_unref (message);
return;
case CONNECT_STEP_CHECK_DISCONNECTED: {
GError *error = NULL;
message = (mbim_message_connect_query_new (
self->priv->session_id,
MBIM_ACTIVATION_STATE_UNKNOWN,
MBIM_VOICE_CALL_STATE_NONE,
MBIM_CONTEXT_IP_TYPE_DEFAULT,
mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
0,
&error));
if (!message) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
mbim_device_command (ctx->device,
message,
10,
NULL,
(GAsyncReadyCallback)check_disconnected_ready,
task);
mbim_message_unref (message);
return;
}
case CONNECT_STEP_ENSURE_DISCONNECTED: {
GError *error = NULL;