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

Change-Id: Idb254aef33715d56a2440f04b285d5caf723ac7e
diff --git a/configure.ac b/configure.ac
index eeb9754..d26ca3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,7 +4,7 @@
 dnl The QMI version number
 m4_define([qmi_major_version], [1])
 m4_define([qmi_minor_version], [21])
-m4_define([qmi_micro_version], [2])
+m4_define([qmi_micro_version], [3])
 m4_define([qmi_version],
           [qmi_major_version.qmi_minor_version.qmi_micro_version])
 
diff --git a/data/qmi-service-nas.json b/data/qmi-service-nas.json
index 5769429..725275a 100644
--- a/data/qmi-service-nas.json
+++ b/data/qmi-service-nas.json
@@ -1284,6 +1284,14 @@
                       "since"         : "1.0",
                       "format"        : "guint64",
                       "public-format" : "QmiNasTdScdmaBandPreference" },
+                    { "name"               : "Acquisition Order Preference",
+                      "id"                 : "0x1E",
+                      "type"               : "TLV",
+                      "since"              : "1.22",
+                      "format"             : "array",
+                      "size-prefix-format" : "guint8",
+                      "array-element"      : { "format"        : "gint8",
+                                               "public-format" : "QmiNasRadioInterface" } },
                     { "name"          : "Extended LTE Band Preference",
                       "id"            : "0x24",
                       "type"          : "TLV",
@@ -1367,6 +1375,14 @@
                       "since"         : "1.0",
                       "format"        : "guint64",
                       "public-format" : "QmiNasTdScdmaBandPreference" },
+                    { "name"               : "Acquisition Order Preference",
+                      "id"                 : "0x1C",
+                      "type"               : "TLV",
+                      "since"              : "1.22",
+                      "format"             : "array",
+                      "size-prefix-format" : "guint8",
+                      "array-element"      : { "format"        : "gint8",
+                                               "public-format" : "QmiNasRadioInterface" } },
                     { "name"      : "Manual Network Selection",
                       "id"        : "0x1B",
                       "type"      : "TLV",
diff --git a/src/qmicli/qmicli-helpers.c b/src/qmicli/qmicli-helpers.c
index 00f7122..7d996d2 100644
--- a/src/qmicli/qmicli-helpers.c
+++ b/src/qmicli/qmicli-helpers.c
@@ -225,42 +225,69 @@
 }
 
 gboolean
-qmicli_read_rat_mode_pref_from_string (const gchar *str,
-                                       QmiNasRatModePreference *out)
+qmicli_read_ssp_options_from_string (const gchar              *str,
+                                     QmiNasRatModePreference  *out_mode_preference,
+                                     GArray                  **out_acquisition_order)
 {
-    GType type;
-    GFlagsClass *flags_class;
-    GFlagsValue *flags_value;
-    gboolean success = TRUE, set = FALSE;
-    char **items, **iter;
+    GType        rat_mode_preference_type;
+    GFlagsClass *rat_mode_preference_flags_class;
+    GFlagsValue *rat_mode_preference_flags_value;
+    gboolean     mode_preference_set = FALSE;
+    GType        radio_interface_type;
+    GEnumClass  *radio_interface_enum_class;
+    GEnumValue  *radio_interface_enum_value;
+    gboolean     acquisition_order_set = FALSE;
+    gboolean     success = TRUE;
+    char       **items, **iter;
 
-    type = qmi_nas_rat_mode_preference_get_type ();
-    flags_class = G_FLAGS_CLASS (g_type_class_ref (type));
+    rat_mode_preference_type = qmi_nas_rat_mode_preference_get_type ();
+    rat_mode_preference_flags_class = G_FLAGS_CLASS (g_type_class_ref (rat_mode_preference_type));
+    radio_interface_type = qmi_nas_radio_interface_get_type ();
+    radio_interface_enum_class = G_ENUM_CLASS (g_type_class_ref (radio_interface_type));
 
-    *out = 0;
+    *out_mode_preference   = 0;
+    *out_acquisition_order = g_array_new (FALSE, FALSE, sizeof (QmiNasRadioInterface));
 
     items = g_strsplit_set (str, "|", 0);
     for (iter = items; iter && *iter && success; iter++) {
         if (!*iter[0])
             continue;
 
-        flags_value = g_flags_get_value_by_nick (flags_class, *iter);
-        if (flags_value) {
-            *out |= (QmiNasRatModePreference)flags_value->value;
-            set = TRUE;
+        /* Note: we can use the same nick names both for mode preference flags
+         * and acquistion order enums, which is very fortunate */
+
+        rat_mode_preference_flags_value = g_flags_get_value_by_nick (rat_mode_preference_flags_class, *iter);
+        if (rat_mode_preference_flags_value) {
+            *out_mode_preference |= (QmiNasRatModePreference)rat_mode_preference_flags_value->value;
+            mode_preference_set = TRUE;
         } else {
             g_printerr ("error: invalid rat mode pref value given: '%s'\n", *iter);
             success = FALSE;
         }
+
+        radio_interface_enum_value = g_enum_get_value_by_nick (radio_interface_enum_class, *iter);
+        if (radio_interface_enum_value) {
+            QmiNasRadioInterface value;
+
+            value = (QmiNasRadioInterface)(radio_interface_enum_value->value);
+            g_array_append_val (*out_acquisition_order, value);
+            acquisition_order_set = TRUE;
+        } else {
+            g_printerr ("error: invalid radio interface value given: '%s'\n", *iter);
+            success = FALSE;
+        }
     }
 
-    if (!set)
+    if (!mode_preference_set)
+        g_printerr ("error: invalid rat mode pref input given: '%s'\n", str);
+    if (!acquisition_order_set)
         g_printerr ("error: invalid rat mode pref input given: '%s'\n", str);
 
     if (items)
         g_strfreev (items);
-    g_type_class_unref (flags_class);
-    return success && set;
+    g_type_class_unref (rat_mode_preference_flags_class);
+    g_type_class_unref (radio_interface_enum_class);
+    return success && (mode_preference_set || acquisition_order_set);;
 }
 
 gboolean
diff --git a/src/qmicli/qmicli-helpers.h b/src/qmicli/qmicli-helpers.h
index e8fac1d..144151e 100644
--- a/src/qmicli/qmicli-helpers.h
+++ b/src/qmicli/qmicli-helpers.h
@@ -38,8 +38,9 @@
                                                               QmiUimPinId *out);
 gboolean qmicli_read_operating_mode_from_string              (const gchar *str,
                                                               QmiDmsOperatingMode *out);
-gboolean qmicli_read_rat_mode_pref_from_string               (const gchar *str,
-                                                              QmiNasRatModePreference *out);
+gboolean qmicli_read_ssp_options_from_string                 (const gchar              *str,
+                                                              QmiNasRatModePreference  *out_mode_preference,
+                                                              GArray                  **out_acquisition_order);
 gboolean qmicli_read_facility_from_string                    (const gchar *str,
                                                               QmiDmsUimFacility *out);
 gboolean qmicli_read_enable_disable_from_string              (const gchar *str,
diff --git a/src/qmicli/qmicli-nas.c b/src/qmicli/qmicli-nas.c
index 8581828..01b4ab0 100644
--- a/src/qmicli/qmicli-nas.c
+++ b/src/qmicli/qmicli-nas.c
@@ -1971,6 +1971,7 @@
     guint16 mnc;
     guint64 extended_lte_band_preference[4];
     gboolean has_pcs_digit;
+    GArray *acquisition_order_preference;
 
     output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error);
     if (!output) {
@@ -2110,7 +2111,7 @@
             output,
             &gsm_wcdma_acquisition_order_preference,
             NULL)) {
-        g_print ("\tService selection preference: '%s'\n",
+        g_print ("\tGSM/WCDMA acquisition order preference: '%s'\n",
                  qmi_nas_gsm_wcdma_acquisition_order_preference_get_string (gsm_wcdma_acquisition_order_preference));
     }
 
@@ -2129,6 +2130,24 @@
                  has_pcs_digit ? "yes" : "no");
     }
 
+    if (qmi_message_nas_get_system_selection_preference_output_get_acquisition_order_preference (
+            output,
+            &acquisition_order_preference,
+            NULL)) {
+        guint i;
+
+        g_print ("\tAcquisition order preference: ");
+        for (i = 0; i < acquisition_order_preference->len; i++) {
+            QmiNasRadioInterface radio_interface;
+
+            radio_interface = g_array_index (acquisition_order_preference, QmiNasRadioInterface, i);
+            g_print ("%s%s",
+                     i > 0 ? ", " : "",
+                     qmi_nas_radio_interface_get_string (radio_interface));
+        }
+        g_print ("\n");
+    }
+
     qmi_message_nas_get_system_selection_preference_output_unref (output);
     operation_shutdown (TRUE);
 }
@@ -2137,52 +2156,45 @@
 set_system_selection_preference_input_create (const gchar *str)
 {
     QmiMessageNasSetSystemSelectionPreferenceInput *input = NULL;
-    QmiNasRatModePreference pref;
-    GError *error = NULL;
+    QmiNasRatModePreference                         rat_mode_preference;
+    GArray                                         *acquisition_order;
+    GError                                         *error = NULL;
 
-    if (!qmicli_read_rat_mode_pref_from_string (str, &pref)) {
-        g_printerr ("error: failed to parse mode pref\n");
+    if (!qmicli_read_ssp_options_from_string (str, &rat_mode_preference, &acquisition_order)) {
+        g_printerr ("error: failed to parse system selection preference options\n");
         return NULL;
     }
 
     input = qmi_message_nas_set_system_selection_preference_input_new ();
-    if (!qmi_message_nas_set_system_selection_preference_input_set_mode_preference (
+
+    if (!qmi_message_nas_set_system_selection_preference_input_set_change_duration (input, QMI_NAS_CHANGE_DURATION_PERMANENT, &error))
+        goto out;
+
+    if (rat_mode_preference && !qmi_message_nas_set_system_selection_preference_input_set_mode_preference (input, rat_mode_preference, &error))
+        goto out;
+
+    if ((rat_mode_preference & (QMI_NAS_RAT_MODE_PREFERENCE_GSM | QMI_NAS_RAT_MODE_PREFERENCE_UMTS | QMI_NAS_RAT_MODE_PREFERENCE_LTE)) &&
+        (!qmi_message_nas_set_system_selection_preference_input_set_gsm_wcdma_acquisition_order_preference (
             input,
-            pref,
-            &error)) {
-        g_printerr ("error: couldn't create input data bundle: '%s'\n",
-                    error->message);
+            QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC,
+            &error)))
+        goto out;
+
+    if (acquisition_order && !qmi_message_nas_set_system_selection_preference_input_set_acquisition_order_preference (input, acquisition_order, &error))
+        goto out;
+
+out:
+
+    if (acquisition_order)
+        g_array_unref (acquisition_order);
+
+    if (error) {
+        g_printerr ("error: couldn't create input data bundle: '%s'\n", error->message);
         g_error_free (error);
         qmi_message_nas_set_system_selection_preference_input_unref (input);
         return NULL;
     }
 
-    if (!qmi_message_nas_set_system_selection_preference_input_set_change_duration (
-            input,
-            QMI_NAS_CHANGE_DURATION_PERMANENT,
-            &error)) {
-        g_printerr ("error: couldn't create input data bundle: '%s'\n",
-                    error->message);
-        g_error_free (error);
-        qmi_message_nas_set_system_selection_preference_input_unref (input);
-        return NULL;
-    }
-
-    if (pref & (QMI_NAS_RAT_MODE_PREFERENCE_GSM |
-                QMI_NAS_RAT_MODE_PREFERENCE_UMTS |
-                QMI_NAS_RAT_MODE_PREFERENCE_LTE)) {
-        if (!qmi_message_nas_set_system_selection_preference_input_set_gsm_wcdma_acquisition_order_preference (
-                input,
-                QMI_NAS_GSM_WCDMA_ACQUISITION_ORDER_PREFERENCE_AUTOMATIC,
-                &error)) {
-            g_printerr ("error: couldn't create input data bundle: '%s'\n",
-                        error->message);
-            g_error_free (error);
-            qmi_message_nas_set_system_selection_preference_input_unref (input);
-            return NULL;
-        }
-    }
-
     return input;
 }