Merge remote-tracking branch 'cros/upstream' into 'cros/master'
diff --git a/src/libmbim-glib/mbim-compat.c b/src/libmbim-glib/mbim-compat.c
index ee30a48..edf513d 100644
--- a/src/libmbim-glib/mbim-compat.c
+++ b/src/libmbim-glib/mbim-compat.c
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -45,14 +45,14 @@
  */
 MbimMessage *
 mbim_message_device_service_subscriber_list_set_new (
-	guint32 events_count,
-	const MbimEventEntry *const *events,
-	GError **error)
+    guint32 events_count,
+    const MbimEventEntry *const *events,
+    GError **error)
 {
     return (mbim_message_device_service_subscribe_list_set_new (
-				events_count,
-				events,
-				error));
+                events_count,
+                events,
+                error));
 }
 
 /**
@@ -70,14 +70,14 @@
  */
 gboolean
 mbim_message_device_service_subscriber_list_response_parse (
-	const MbimMessage *message,
+    const MbimMessage *message,
     guint32 *events_count,
     MbimEventEntry ***events,
     GError **error)
 {
-	return (mbim_message_device_service_subscribe_list_response_parse (
-				message,
-				events_count,
-				events,
-				error));
+    return (mbim_message_device_service_subscribe_list_response_parse (
+                message,
+                events_count,
+                events,
+                error));
 }
diff --git a/src/libmbim-glib/mbim-compat.h b/src/libmbim-glib/mbim-compat.h
index 8fbf8b8..0edd527 100644
--- a/src/libmbim-glib/mbim-compat.h
+++ b/src/libmbim-glib/mbim-compat.h
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -59,13 +59,13 @@
 
 G_DEPRECATED_FOR (mbim_message_device_service_subscribe_list_set_new)
 MbimMessage *mbim_message_device_service_subscriber_list_set_new (
-	guint32 events_count,
-	const MbimEventEntry *const *events,
-	GError **error);
+    guint32 events_count,
+    const MbimEventEntry *const *events,
+    GError **error);
 
 G_DEPRECATED_FOR (mbim_message_device_service_subscribe_list_response_parse)
 gboolean mbim_message_device_service_subscriber_list_response_parse (
-	const MbimMessage *message,
+    const MbimMessage *message,
     guint32 *events_count,
     MbimEventEntry ***events,
     GError **error);
diff --git a/src/libmbim-glib/mbim-device.c b/src/libmbim-glib/mbim-device.c
index 6f965e9..da2d507 100644
--- a/src/libmbim-glib/mbim-device.c
+++ b/src/libmbim-glib/mbim-device.c
@@ -123,6 +123,7 @@
 
 typedef struct {
     MbimMessage *fragments;
+    MbimMessageType type;
     guint32 transaction_id;
     GSimpleAsyncResult *result;
     guint timeout_id;
@@ -133,6 +134,7 @@
 
 static Transaction *
 transaction_new (MbimDevice          *self,
+                 MbimMessageType      type,
                  guint32              transaction_id,
                  GCancellable        *cancellable,
                  GAsyncReadyCallback  callback,
@@ -141,6 +143,7 @@
     Transaction *tr;
 
     tr = g_slice_new0 (Transaction);
+    tr->type = type;
     tr->transaction_id = transaction_id;
     tr->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
@@ -187,13 +190,14 @@
 static Transaction *
 device_release_transaction (MbimDevice      *self,
                             TransactionType  type,
+                            MbimMessageType  expected_type,
                             guint32          transaction_id)
 {
     Transaction *tr = NULL;
 
     if (self->priv->transactions[type]) {
         tr = g_hash_table_lookup (self->priv->transactions[type], GUINT_TO_POINTER (transaction_id));
-        if (tr)
+        if (tr && ((tr->type == expected_type) || (expected_type == MBIM_MESSAGE_TYPE_INVALID)))
             /* If found, remove it from the HT */
             g_hash_table_remove (self->priv->transactions[type], GUINT_TO_POINTER (transaction_id));
     }
@@ -207,7 +211,10 @@
     Transaction *tr;
     GError *error = NULL;
 
-    tr = device_release_transaction (ctx->self, ctx->type, ctx->transaction_id);
+    tr = device_release_transaction (ctx->self,
+                                     ctx->type,
+                                     MBIM_MESSAGE_TYPE_INVALID,
+                                     ctx->transaction_id);
     tr->timeout_id = 0;
 
     /* If no fragment was received, complete transaction with a timeout error */
@@ -240,7 +247,10 @@
     Transaction *tr;
     GError *error = NULL;
 
-    tr = device_release_transaction (ctx->self, ctx->type, ctx->transaction_id);
+    tr = device_release_transaction (ctx->self,
+                                     ctx->type,
+                                     MBIM_MESSAGE_TYPE_INVALID,
+                                     ctx->transaction_id);
     tr->cancellable_id = 0;
 
     /* Complete transaction with an abort error */
@@ -294,15 +304,6 @@
     return TRUE;
 }
 
-static Transaction *
-device_match_transaction (MbimDevice        *self,
-                          TransactionType    type,
-                          const MbimMessage *message)
-{
-    /* msg can be either the original message or the response */
-    return device_release_transaction (self, type, mbim_message_get_transaction_id (message));
-}
-
 /*****************************************************************************/
 
 /**
@@ -417,12 +418,13 @@
 process_message (MbimDevice  *self,
                  const MbimMessage *message)
 {
+    gboolean is_partial_fragment;
+
+    is_partial_fragment = (_mbim_message_is_fragment (message) &&
+                           _mbim_message_fragment_get_total (message) > 1);
+
     if (mbim_utils_get_traces_enabled ()) {
         gchar *printable;
-        gboolean is_partial_fragment;
-
-        is_partial_fragment = (_mbim_message_is_fragment (message) &&
-                               _mbim_message_fragment_get_total (message) > 1);
 
         printable = __mbim_utils_str_hex (((GByteArray *)message)->data,
                                           ((GByteArray *)message)->len,
@@ -456,20 +458,39 @@
 
         if (MBIM_MESSAGE_GET_MESSAGE_TYPE (message) == MBIM_MESSAGE_TYPE_INDICATE_STATUS) {
             /* Grab transaction */
-            tr = device_match_transaction (self, TRANSACTION_TYPE_MODEM, message);
+            tr = device_release_transaction (self,
+                                             TRANSACTION_TYPE_MODEM,
+                                             MBIM_MESSAGE_TYPE_INDICATE_STATUS,
+                                             mbim_message_get_transaction_id (message));
+
             if (!tr)
                 /* Create new transaction for the indication */
                 tr = transaction_new (self,
+                                      MBIM_MESSAGE_TYPE_INDICATE_STATUS,
                                       mbim_message_get_transaction_id (message),
                                       NULL, /* no cancellable */
                                       (GAsyncReadyCallback)indication_ready,
                                       NULL);
         } else {
-            /* Grab transaction */
-            tr = device_match_transaction (self, TRANSACTION_TYPE_HOST, message);
+            /* Grab transaction. This is a _DONE message, so look for the request
+             * that generated the _DONE */
+            tr = device_release_transaction (self,
+                                             TRANSACTION_TYPE_HOST,
+                                             (MBIM_MESSAGE_GET_MESSAGE_TYPE (message) - 0x80000000),
+                                             mbim_message_get_transaction_id (message));
             if (!tr) {
+                gchar *printable;
+
                 g_debug ("[%s] No transaction matched in received message",
                          self->priv->path_display);
+                /* Attempt to print a user friendly dump of the packet anyway */
+                printable = mbim_message_get_printable (message, ">>>>>> ", is_partial_fragment);
+                if (printable) {
+                    g_debug ("[%s] Received unexpected message (translated)...\n%s",
+                             self->priv->path_display,
+                             printable);
+                    g_free (printable);
+                }
                 return;
             }
 
@@ -1466,6 +1487,7 @@
     }
 
     tr = transaction_new (self,
+                          MBIM_MESSAGE_GET_MESSAGE_TYPE (message),
                           transaction_id,
                           cancellable,
                           callback,
@@ -1491,7 +1513,10 @@
 
     if (!device_send (self, message, &error)) {
         /* Match transaction so that we remove it from our tracking table */
-        tr = device_match_transaction (self, TRANSACTION_TYPE_HOST, message);
+        tr = device_release_transaction (self,
+                                         TRANSACTION_TYPE_HOST,
+                                         MBIM_MESSAGE_GET_MESSAGE_TYPE (message),
+                                         mbim_message_get_transaction_id (message));
         transaction_complete_and_free (tr, error);
         g_error_free (error);
         return;
diff --git a/src/libmbim-glib/mbim-enums.h b/src/libmbim-glib/mbim-enums.h
index d851934..02f94aa 100644
--- a/src/libmbim-glib/mbim-enums.h
+++ b/src/libmbim-glib/mbim-enums.h
@@ -388,6 +388,7 @@
  * @MBIM_NW_ERROR_CONGESTION: Congestion.
  * @MBIM_NW_ERROR_GSM_AUTHENTICATION_UNACCEPTABLE: GSM authentication unacceptable.
  * @MBIM_NW_ERROR_NOT_AUTHORIZED_FOR_CSG: Not authorized for this CSG.
+ * @MBIM_NW_ERROR_MISSING_OR_UNKNOWN_APN: Missing or unknown access point name.
  * @MBIM_NW_ERROR_SERVICE_OPTION_NOT_SUPPORTED: Service option not supported.
  * @MBIM_NW_ERROR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED: Requested service option not subscribed.
  * @MBIM_NW_ERROR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER: Service option temporarily out of order.
@@ -426,6 +427,7 @@
     MBIM_NW_ERROR_CONGESTION                                          = 22,
     MBIM_NW_ERROR_GSM_AUTHENTICATION_UNACCEPTABLE                     = 23,
     MBIM_NW_ERROR_NOT_AUTHORIZED_FOR_CSG                              = 25,
+    MBIM_NW_ERROR_MISSING_OR_UNKNOWN_APN                              = 27,
     MBIM_NW_ERROR_SERVICE_OPTION_NOT_SUPPORTED                        = 32,
     MBIM_NW_ERROR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED             = 33,
     MBIM_NW_ERROR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER             = 34,
diff --git a/src/libmbim-glib/mbim-version.h.in b/src/libmbim-glib/mbim-version.h.in
index 23debda..3a7397b 100644
--- a/src/libmbim-glib/mbim-version.h.in
+++ b/src/libmbim-glib/mbim-version.h.in
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public