Merge remote-tracking branch 'cros/upstream' into 'cros/master'

Change-Id: Idf086e4237138dccbf30e74f489a56b91c24fd3c
diff --git a/data/mbim-service-ms-basic-connect-extensions.json b/data/mbim-service-ms-basic-connect-extensions.json
index a079088..cce9cac 100644
--- a/data/mbim-service-ms-basic-connect-extensions.json
+++ b/data/mbim-service-ms-basic-connect-extensions.json
@@ -28,6 +28,91 @@
                          "struct-type" : "MbimPcoValue" } ],
     "notification" : [ { "name"        : "PcoValue",
                          "format"      : "struct",
-                         "struct-type" : "MbimPcoValue" } ] }
+                         "struct-type" : "MbimPcoValue" } ] },
 
+  // *********************************************************************************
+
+  { "name"     : "MbimLteAttachConfiguration",
+    "type"     : "Struct",
+    "contents" : [ { "name"          : "IpType",
+                     "format"        : "guint32",
+                     "public-format" : "MbimContextIpType" },
+                   { "name"          : "Roaming",
+                     "format"        : "guint32",
+                     "public-format" : "MbimLteAttachContextRoamingControl" },
+                   { "name"          : "Source",
+                     "format"        : "guint32",
+                     "public-format" : "MbimContextSource" },
+                   { "name"   : "AccessString",
+                     "format" : "string" },
+                   { "name"   : "UserName",
+                     "format" : "string" },
+                   { "name"   : "Password",
+                     "format" : "string" },
+                   { "name"          : "Compression",
+                     "format"        : "guint32",
+                     "public-format" : "MbimCompression" },
+                   { "name"          : "AuthProtocol",
+                     "format"        : "guint32",
+                     "public-format" : "MbimAuthProtocol" } ] },
+
+  { "name"         : "Lte Attach Configuration",
+    "service"      : "Ms Basic Connect Extensions",
+    "type"         : "Command",
+    "set"          : [ { "name"          : "Operation",
+                         "format"        : "guint32",
+                         "public-format" : "MbimLteAttachContextOperation" },
+                       { "name"   : "ConfigurationCount",
+                         "format" : "guint32" },
+                       { "name"             : "Configurations",
+                         "format"           : "ref-struct-array" ,
+                         "struct-type"      : "MbimLteAttachConfiguration",
+                         "array-size-field" : "ConfigurationCount" } ],
+    "query"        : [],
+    "response"     : [ { "name"   : "ConfigurationCount",
+                         "format" : "guint32" },
+                       { "name"             : "Configurations",
+                         "format"           : "ref-struct-array" ,
+                         "struct-type"      : "MbimLteAttachConfiguration",
+                         "array-size-field" : "ConfigurationCount" } ],
+    "notification" : [ { "name"   : "ConfigurationCount",
+                         "format" : "guint32" },
+                       { "name"             : "Configurations",
+                         "format"           : "ref-struct-array" ,
+                         "struct-type"      : "MbimLteAttachConfiguration",
+                         "array-size-field" : "ConfigurationCount" } ] },
+
+  // *********************************************************************************
+
+  { "name"     : "MbimLteAttachStatus",
+    "type"     : "Struct",
+    "contents" : [ { "name"          : "LteAttachState",
+                     "format"        : "guint32",
+                     "public-format" : "MbimLteAttachState" },
+		   { "name"          : "IpType",
+                     "format"        : "guint32",
+                     "public-format" : "MbimContextIpType" },
+                   { "name"   : "AccessString",
+                     "format" : "string" },
+                   { "name"   : "UserName",
+                     "format" : "string" },
+                   { "name"   : "Password",
+                     "format" : "string" },
+                   { "name"          : "Compression",
+                     "format"        : "guint32",
+                     "public-format" : "MbimCompression" },
+                   { "name"          : "AuthProtocol",
+                     "format"        : "guint32",
+                     "public-format" : "MbimAuthProtocol" } ] },
+
+  { "name"         : "Lte Attach Status",
+    "service"      : "Ms Basic Connect Extensions",
+    "type"         : "Command",
+    "query"        : [],
+    "response"     : [ { "name"        : "LteAttachStatus",
+                         "format"      : "struct",
+			 "struct-type" : "MbimLteAttachStatus" } ],
+    "notification" : [ { "name"        : "LteAttachStatus",
+                         "format"      : "struct",
+			 "struct-type" : "MbimLteAttachStatus" } ] }
 ]
diff --git a/docs/reference/libmbim-glib/libmbim-glib-common.sections b/docs/reference/libmbim-glib/libmbim-glib-common.sections
index fbe44aa..7634a7b 100644
--- a/docs/reference/libmbim-glib/libmbim-glib-common.sections
+++ b/docs/reference/libmbim-glib/libmbim-glib-common.sections
@@ -315,6 +315,10 @@
 MbimEmergencyModeState
 MbimDssLinkState
 MbimPcoType
+MbimContextSource
+MbimLteAttachContextOperation
+MbimLteAttachContextRoamingControl
+MbimLteAttachState
 <SUBSECTION Methods>
 mbim_device_type_get_string
 mbim_cellular_class_build_string_from_mask
@@ -367,6 +371,10 @@
 mbim_atds_provider_plmn_mode_get_string
 mbim_atds_rat_mode_get_string
 mbim_pco_type_get_string
+mbim_context_source_get_string
+mbim_lte_attach_context_operation_get_string
+mbim_lte_attach_context_roaming_control_get_string
+mbim_lte_attach_state_get_string
 <SUBSECTION Private>
 mbim_device_type_build_string_from_mask
 mbim_cellular_class_get_string
@@ -421,6 +429,10 @@
 mbim_atds_provider_plmn_mode_build_string_from_mask
 mbim_atds_rat_mode_build_string_from_mask
 mbim_pco_type_build_string_from_mask
+mbim_context_source_build_string_from_mask
+mbim_lte_attach_context_operation_build_string_from_mask
+mbim_lte_attach_context_roaming_control_build_string_from_mask
+mbim_lte_attach_state_build_string_from_mask
 <SUBSECTION Standard>
 MBIM_TYPE_ACTIVATION_COMMAND
 MBIM_TYPE_ACTIVATION_STATE
@@ -478,6 +490,10 @@
 MBIM_TYPE_EMERGENCY_MODE_STATE
 MBIM_TYPE_DSS_LINK_STATE
 MBIM_TYPE_PCO_TYPE
+MBIM_TYPE_CONTEXT_SOURCE
+MBIM_TYPE_LTE_ATTACH_CONTEXT_OPERATION
+MBIM_TYPE_LTE_ATTACH_CONTEXT_ROAMING_CONTROL
+MBIM_TYPE_LTE_ATTACH_STATE
 mbim_activation_command_get_type
 mbim_activation_state_get_type
 mbim_auth_protocol_get_type
@@ -534,6 +550,10 @@
 mbim_atds_provider_plmn_mode_get_type
 mbim_atds_rat_mode_get_type
 mbim_pco_type_get_type
+mbim_context_source_get_type
+mbim_lte_attach_context_operation_get_type
+mbim_lte_attach_context_roaming_control_get_type
+mbim_lte_attach_state_get_type
 </SECTION>
 
 <SECTION>
diff --git a/src/libmbim-glib/mbim-enums.h b/src/libmbim-glib/mbim-enums.h
index 4681d33..c85243a 100644
--- a/src/libmbim-glib/mbim-enums.h
+++ b/src/libmbim-glib/mbim-enums.h
@@ -1037,6 +1037,63 @@
     MBIM_PCO_TYPE_PARTIAL  = 1
 } MbimPcoType;
 
+/*****************************************************************************/
+/* 'LTE Attach Configuration' enums */
+
+/**
+ * MbimLteAttachContextOperation:
+ * @MBIM_LTE_ATTACH_CONTEXT_OPERATION_DEFAULT: Overwrite existing contexts.
+ * @MBIM_LTE_ATTACH_CONTEXT_OPERATION_RESTORE_FACTORY: Restore factory preconfigured contexts.
+ *
+ * Command to run when updating LTE attach configuration.
+ */
+typedef enum {
+    MBIM_LTE_ATTACH_CONTEXT_OPERATION_DEFAULT         = 0,
+    MBIM_LTE_ATTACH_CONTEXT_OPERATION_RESTORE_FACTORY = 1
+} MbimLteAttachContextOperation;
+
+/**
+ * MbimLteAttachContextRoamingControl:
+ * @MBIM_LTE_ATTACH_CONTEXT_ROAMING_CONTROL_HOME: Context allowed to be used on home network.
+ * @MBIM_LTE_ATTACH_CONTEXT_ROAMING_CONTROL_PARTNER: Context allowed to be used on partner network.
+ * @MBIM_LTE_ATTACH_CONTEXT_ROAMING_CONTROL_NON_PARTNER: Context allowed to be used on non-partner network.
+*/
+typedef enum {
+    MBIM_LTE_ATTACH_CONTEXT_ROAMING_CONTROL_HOME        = 0,
+    MBIM_LTE_ATTACH_CONTEXT_ROAMING_CONTROL_PARTNER     = 1,
+    MBIM_LTE_ATTACH_CONTEXT_ROAMING_CONTROL_NON_PARTNER = 2
+} MbimLteAttachContextRoamingControl;
+
+/**
+ * MbimContextSource:
+ * @MBIM_CONTEXT_SOURCE_ADMIN: Context created by enterprise IT.
+ * @MBIM_CONTEXT_SOURCE_USER: Context created by user.
+ * @MBIM_CONTEXT_SOURCE_OPERATOR: Context created by operator.
+ * @MBIM_CONTEXT_SOURCE_MODEM: Context created by modem manufacturer.
+ * @MBIM_CONTEXT_SOURCE_DEVICE: Context created by OS APN database.
+ *
+ * Source of context creation.
+ */
+typedef enum {
+    MBIM_CONTEXT_SOURCE_ADMIN    = 0,
+    MBIM_CONTEXT_SOURCE_USER     = 1,
+    MBIM_CONTEXT_SOURCE_OPERATOR = 2,
+    MBIM_CONTEXT_SOURCE_MODEM    = 3,
+    MBIM_CONTEXT_SOURCE_DEVICE   = 4
+} MbimContextSource;
+
+/**
+ * MbimLteAttachState:
+ * @MBIM_LTE_ATTACH_STATE_DETACHED: Detached.
+ * @MBIM_LTE_ATTACH_STATE_ATTACHED: Attached.
+ *
+ * LTE attach state.
+ */
+typedef enum {
+    MBIM_LTE_ATTACH_STATE_DETACHED = 0,
+    MBIM_LTE_ATTACH_STATE_ATTACHED = 1
+} MbimLteAttachState;
+
 G_END_DECLS
 
 #endif /* _LIBMBIM_GLIB_MBIM_ENUMS_H_ */
diff --git a/src/mbimcli/mbimcli-ms-basic-connect-extensions.c b/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
index db44ec3..092afbb 100644
--- a/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
+++ b/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
@@ -15,7 +15,8 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright 2018 Google LLC
+ * Copyright (C) 2018 Google LLC
+ * Copyright (C) 2018 Aleksander Morgado <aleksander@aleksander.es>
  */
 
 #include "config.h"
@@ -42,7 +43,9 @@
 static Context *ctx;
 
 /* Options */
-static gchar *query_pco_str;
+static gchar    *query_pco_str;
+static gboolean  query_lte_attach_configuration_flag;
+static gboolean  query_lte_attach_status_flag;
 
 static gboolean query_pco_arg_parse (const char *option_name,
                                      const char *value,
@@ -54,6 +57,14 @@
       "Query PCO value (SessionID is optional, defaults to 0)",
       "[SessionID]"
     },
+    { "ms-query-lte-attach-configuration", 0, 0, G_OPTION_ARG_NONE, &query_lte_attach_configuration_flag,
+      "Query LTE attach configuration",
+      NULL
+    },
+    { "ms-query-lte-attach-status", 0, 0, G_OPTION_ARG_NONE, &query_lte_attach_status_flag,
+      "Query LTE attach status",
+      NULL
+    },
     { NULL }
 };
 
@@ -122,7 +133,9 @@
     if (checked)
         return !!n_actions;
 
-    n_actions = !!query_pco_str;
+    n_actions = (!!query_pco_str +
+                 query_lte_attach_configuration_flag +
+                 query_lte_attach_status_flag);
 
     if (n_actions > 1) {
         g_printerr ("error: too many Microsoft Basic Connect Extensions Service actions requested\n");
@@ -204,6 +217,107 @@
     shutdown (TRUE);
 }
 
+static void
+query_lte_attach_configuration_ready (MbimDevice   *device,
+                                      GAsyncResult *res)
+{
+    MbimMessage                 *response;
+    GError                      *error = NULL;
+    guint32                      configuration_count = 0;
+    MbimLteAttachConfiguration **configurations = NULL;
+    guint                        i;
+
+    response = mbim_device_command_finish (device, res, &error);
+    if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        if (response)
+            mbim_message_unref (response);
+        shutdown (FALSE);
+        return;
+    }
+
+    g_print ("[%s] Successfully queried LTE attach configuration\n",
+             mbim_device_get_path_display (device));
+
+    if (!mbim_message_ms_basic_connect_extensions_lte_attach_configuration_response_parse (
+               response,
+               &configuration_count,
+               &configurations,
+               &error)) {
+        g_printerr ("error: couldn't parse response message: %s\n", error->message);
+        g_error_free (error);
+        mbim_message_unref (response);
+        shutdown (FALSE);
+        return;
+    }
+
+#define VALIDATE_NA(str) (str ? str : "n/a")
+    for (i = 0; i < configuration_count; i++) {
+        g_print ("Configuration %u:\n", i);
+        g_print ("  IP type:       %s\n", mbim_context_ip_type_get_string (configurations[i]->ip_type));
+        g_print ("  Roaming:       %s\n", mbim_lte_attach_context_roaming_control_get_string (configurations[i]->roaming));
+        g_print ("  Source:        %s\n", mbim_context_source_get_string (configurations[i]->source));
+        g_print ("  Access string: %s\n", VALIDATE_NA (configurations[i]->access_string));
+        g_print ("  Username:      %s\n", VALIDATE_NA (configurations[i]->user_name));
+        g_print ("  Password:      %s\n", VALIDATE_NA (configurations[i]->password));
+        g_print ("  Compression:   %s\n", mbim_compression_get_string (configurations[i]->compression));
+        g_print ("  Auth protocol: %s\n", mbim_auth_protocol_get_string (configurations[i]->auth_protocol));
+    }
+#undef VALIDATE_NA
+
+    mbim_lte_attach_configuration_array_free (configurations);
+    mbim_message_unref (response);
+    shutdown (TRUE);
+}
+
+static void
+query_lte_attach_status_ready (MbimDevice   *device,
+                               GAsyncResult *res)
+{
+    MbimMessage         *response;
+    GError              *error = NULL;
+    MbimLteAttachStatus *lte_attach_status = NULL;
+
+    response = mbim_device_command_finish (device, res, &error);
+    if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+        g_printerr ("error: operation failed: %s\n", error->message);
+        g_error_free (error);
+        if (response)
+            mbim_message_unref (response);
+        shutdown (FALSE);
+        return;
+    }
+
+    g_print ("[%s] Successfully queried LTE attach status\n",
+             mbim_device_get_path_display (device));
+
+    if (!mbim_message_ms_basic_connect_extensions_lte_attach_status_response_parse (
+            response,
+            &lte_attach_status,
+            &error)) {
+        g_printerr ("error: couldn't parse response message: %s\n", error->message);
+        g_error_free (error);
+        mbim_message_unref (response);
+        shutdown (FALSE);
+        return;
+    }
+
+#define VALIDATE_NA(str) (str ? str : "n/a")
+    g_print ("  Attach state:  %s\n", mbim_lte_attach_state_get_string (lte_attach_status->lte_attach_state));
+    g_print ("  IP type:       %s\n", mbim_context_ip_type_get_string (lte_attach_status->ip_type));
+    g_print ("  Access string: %s\n", VALIDATE_NA (lte_attach_status->access_string));
+    g_print ("  Username:      %s\n", VALIDATE_NA (lte_attach_status->user_name));
+    g_print ("  Password:      %s\n", VALIDATE_NA (lte_attach_status->password));
+    g_print ("  Compression:   %s\n", mbim_compression_get_string (lte_attach_status->compression));
+    g_print ("  Auth protocol: %s\n", mbim_auth_protocol_get_string (lte_attach_status->auth_protocol));
+#undef VALIDATE_NA
+
+    mbim_lte_attach_status_free (lte_attach_status);
+    mbim_message_unref (response);
+    shutdown (TRUE);
+}
+
 void
 mbimcli_ms_basic_connect_extensions_run (MbimDevice   *device,
                                          GCancellable *cancellable)
@@ -242,5 +356,37 @@
         return;
     }
 
+    /* Request to query LTE attach configuration? */
+    if (query_lte_attach_configuration_flag) {
+        MbimMessage *request;
+
+        g_debug ("Asynchronously querying LTE attach configuration...");
+        request = mbim_message_ms_basic_connect_extensions_lte_attach_configuration_query_new (NULL);
+        mbim_device_command (ctx->device,
+                             request,
+                             10,
+                             ctx->cancellable,
+                             (GAsyncReadyCallback)query_lte_attach_configuration_ready,
+                             NULL);
+        mbim_message_unref (request);
+        return;
+    }
+
+    /* Request to query LTE attach status? */
+    if (query_lte_attach_status_flag) {
+        MbimMessage *request;
+
+        g_debug ("Asynchronously querying LTE attach status...");
+        request = mbim_message_ms_basic_connect_extensions_lte_attach_status_query_new (NULL);
+        mbim_device_command (ctx->device,
+                             request,
+                             10,
+                             ctx->cancellable,
+                             (GAsyncReadyCallback)query_lte_attach_status_ready,
+                             NULL);
+        mbim_message_unref (request);
+        return;
+    }
+
     g_warn_if_reached ();
 }