summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Chan <benchan@chromium.org>2018-01-31 21:57:09 -0800
committerDan Williams <dcbw@redhat.com>2018-02-02 09:43:49 -0600
commit30b7ca152af2b978ae98228b449b5cc327105614 (patch)
treea918dcfebe384d075a1c9ed210c20964aac10c3b
parentaaad15f86ca7b5c51b5208c5d931cebe69c1221b (diff)
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. (cherry picked from commit 636c245cd37bcddf6f354cbd53eb88ccf8104387)
-rw-r--r--src/mm-bearer-mbim.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/mm-bearer-mbim.c b/src/mm-bearer-mbim.c
index 8b090aba..31e40696 100644
--- a/src/mm-bearer-mbim.c
+++ b/src/mm-bearer-mbim.c
@@ -221,6 +221,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,
@@ -656,6 +657,50 @@ ensure_disconnected_ready (MbimDevice *device,
}
static void
+check_disconnected_ready (MbimDevice *device,
+ GAsyncResult *res,
+ ConnectContext *ctx)
+{
+ GError *error = NULL;
+ MbimMessage *response;
+ guint32 session_id;
+ MbimActivationState activation_state;
+
+ 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 (ctx);
+}
+
+static void
provisioned_contexts_query_ready (MbimDevice *device,
GAsyncResult *res,
ConnectContext *ctx)
@@ -833,6 +878,33 @@ connect_context_step (ConnectContext *ctx)
mbim_message_unref (message);
return;
+ case CONNECT_STEP_CHECK_DISCONNECTED: {
+ GError *error = NULL;
+
+ message = (mbim_message_connect_query_new (
+ ctx->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_simple_async_result_take_error (ctx->result, error);
+ connect_context_complete_and_free (ctx);
+ return;
+ }
+
+ mbim_device_command (ctx->device,
+ message,
+ 10,
+ NULL,
+ (GAsyncReadyCallback)check_disconnected_ready,
+ ctx);
+ mbim_message_unref (message);
+ return;
+ }
+
case CONNECT_STEP_ENSURE_DISCONNECTED: {
GError *error = NULL;