aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-modem-helpers-qmi.c108
-rw-r--r--src/mm-modem-helpers-qmi.h9
-rw-r--r--src/mm-shared-qmi.c64
3 files changed, 100 insertions, 81 deletions
diff --git a/src/mm-modem-helpers-qmi.c b/src/mm-modem-helpers-qmi.c
index ef951bac..7d98084a 100644
--- a/src/mm-modem-helpers-qmi.c
+++ b/src/mm-modem-helpers-qmi.c
@@ -1106,67 +1106,75 @@ mm_modem_capability_to_qmi_acquisition_order_preference (MMModemCapability caps)
return array;
}
-GArray *
-mm_modem_mode_to_qmi_acquisition_order_preference (MMModemMode allowed,
- MMModemMode preferred,
- gboolean is_cdma,
- gboolean is_3gpp)
+static gboolean
+radio_interface_array_contains (GArray *array,
+ QmiNasRadioInterface act)
{
- GArray *array;
- QmiNasRadioInterface value;
+ guint i;
- array = g_array_new (FALSE, FALSE, sizeof (QmiNasRadioInterface));
+ for (i = 0; i < array->len; i++) {
+ QmiNasRadioInterface value;
- if (allowed & MM_MODEM_MODE_5G) {
- value = QMI_NAS_RADIO_INTERFACE_5GNR;
- if (preferred == MM_MODEM_MODE_5G)
- g_array_prepend_val (array, value);
- else
- g_array_append_val (array, value);
+ value = g_array_index (array, QmiNasRadioInterface, i);
+ if (value == act)
+ return TRUE;
}
+ return FALSE;
+}
- if (allowed & MM_MODEM_MODE_4G) {
- value = QMI_NAS_RADIO_INTERFACE_LTE;
- if (preferred == MM_MODEM_MODE_4G)
- g_array_prepend_val (array, value);
- else
+static void
+radio_interface_array_add_missing (GArray *array,
+ GArray *all)
+{
+ guint i;
+
+ for (i = 0; i < all->len; i++) {
+ QmiNasRadioInterface value;
+
+ value = g_array_index (all, QmiNasRadioInterface, i);
+ if (!radio_interface_array_contains (array, value))
g_array_append_val (array, value);
}
+}
- if (allowed & MM_MODEM_MODE_3G) {
- if (is_cdma) {
- value = QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO;
- if (preferred == MM_MODEM_MODE_3G)
- g_array_prepend_val (array, value);
- else
- g_array_append_val (array, value);
- }
- if (is_3gpp) {
- value = QMI_NAS_RADIO_INTERFACE_UMTS;
- if (preferred == MM_MODEM_MODE_3G)
- g_array_prepend_val (array, value);
- else
- g_array_append_val (array, value);
- }
- }
+GArray *
+mm_modem_mode_to_qmi_acquisition_order_preference (MMModemMode allowed,
+ MMModemMode preferred,
+ GArray *all)
+{
+ GArray *array;
+ QmiNasRadioInterface preferred_radio = QMI_NAS_RADIO_INTERFACE_UNKNOWN;
+ QmiNasRadioInterface value;
- if (allowed & MM_MODEM_MODE_2G) {
- if (is_cdma) {
- value = QMI_NAS_RADIO_INTERFACE_CDMA_1X;
- if (preferred == MM_MODEM_MODE_2G)
- g_array_prepend_val (array, value);
- else
- g_array_append_val (array, value);
- }
- if (is_3gpp) {
- value = QMI_NAS_RADIO_INTERFACE_GSM;
- if (preferred == MM_MODEM_MODE_2G)
- g_array_prepend_val (array, value);
- else
- g_array_append_val (array, value);
- }
+ array = g_array_sized_new (FALSE, FALSE, sizeof (QmiNasRadioInterface), all->len);
+
+#define PROCESS_ALLOWED_PREFERRED_MODE(MODE,RADIO) \
+ if ((allowed & MODE) && (radio_interface_array_contains (all, RADIO))) { \
+ if ((preferred == MODE) && (preferred_radio == QMI_NAS_RADIO_INTERFACE_UNKNOWN)) \
+ preferred_radio = RADIO; \
+ else { \
+ value = RADIO; \
+ g_array_append_val (array, value); \
+ } \
}
+ PROCESS_ALLOWED_PREFERRED_MODE (MM_MODEM_MODE_5G, QMI_NAS_RADIO_INTERFACE_5GNR);
+ PROCESS_ALLOWED_PREFERRED_MODE (MM_MODEM_MODE_4G, QMI_NAS_RADIO_INTERFACE_LTE);
+ PROCESS_ALLOWED_PREFERRED_MODE (MM_MODEM_MODE_3G, QMI_NAS_RADIO_INTERFACE_UMTS);
+ PROCESS_ALLOWED_PREFERRED_MODE (MM_MODEM_MODE_3G, QMI_NAS_RADIO_INTERFACE_CDMA_1XEVDO);
+ PROCESS_ALLOWED_PREFERRED_MODE (MM_MODEM_MODE_2G, QMI_NAS_RADIO_INTERFACE_GSM);
+ PROCESS_ALLOWED_PREFERRED_MODE (MM_MODEM_MODE_2G, QMI_NAS_RADIO_INTERFACE_CDMA_1X);
+
+#undef PROCESS_ALLOWED_PREFERRED_MODE
+
+ if (preferred_radio != QMI_NAS_RADIO_INTERFACE_UNKNOWN)
+ g_array_prepend_val (array, preferred_radio);
+
+ /* the acquisition order preference is a TLV that must ALWAYS contain the
+ * same list of QmiNasRadioInterface values, just with a different order. */
+ radio_interface_array_add_missing (array, all);
+ g_assert_cmpuint (array->len, ==, all->len);
+
return array;
}
diff --git a/src/mm-modem-helpers-qmi.h b/src/mm-modem-helpers-qmi.h
index d64f94cb..831418a3 100644
--- a/src/mm-modem-helpers-qmi.h
+++ b/src/mm-modem-helpers-qmi.h
@@ -66,11 +66,10 @@ QmiNasRatModePreference mm_modem_mode_to_qmi_rat_mode_preference (MMModemMode mo
MMModemCapability mm_modem_capability_from_qmi_rat_mode_preference (QmiNasRatModePreference qmi);
QmiNasRatModePreference mm_modem_capability_to_qmi_rat_mode_preference (MMModemCapability caps);
-GArray *mm_modem_capability_to_qmi_acquisition_order_preference (MMModemCapability caps);
-GArray *mm_modem_mode_to_qmi_acquisition_order_preference (MMModemMode allowed,
- MMModemMode preferred,
- gboolean is_cdma,
- gboolean is_3gpp);
+GArray *mm_modem_capability_to_qmi_acquisition_order_preference (MMModemCapability caps);
+GArray *mm_modem_mode_to_qmi_acquisition_order_preference (MMModemMode allowed,
+ MMModemMode preferred,
+ GArray *all);
MMModemCapability mm_modem_capability_from_qmi_radio_technology_preference (QmiNasRadioTechnologyPreference qmi);
QmiNasRadioTechnologyPreference mm_modem_capability_to_qmi_radio_technology_preference (MMModemCapability caps);
diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c
index 84baa64c..f7e9eb0d 100644
--- a/src/mm-shared-qmi.c
+++ b/src/mm-shared-qmi.c
@@ -74,6 +74,8 @@ typedef struct {
Feature feature_nas_tp;
Feature feature_nas_ssp;
Feature feature_nas_ssp_extended_lte_band_preference;
+ Feature feature_nas_ssp_acquisition_order_preference;
+ GArray *feature_nas_ssp_acquisition_order_preference_array;
gboolean disable_4g_only_mode;
GArray *supported_bands;
@@ -125,6 +127,8 @@ private_free (Private *priv)
g_object_unref (priv->uim_client);
if (priv->uim_refresh_start_timeout_id)
g_source_remove (priv->uim_refresh_start_timeout_id);
+ if (priv->feature_nas_ssp_acquisition_order_preference_array)
+ g_array_unref (priv->feature_nas_ssp_acquisition_order_preference_array);
g_strfreev (priv->loc_assistance_data_servers);
g_slice_free (Private, priv);
}
@@ -144,6 +148,7 @@ get_private (MMSharedQmi *self)
priv->feature_nas_tp = FEATURE_UNKNOWN;
priv->feature_nas_ssp = FEATURE_UNKNOWN;
priv->feature_nas_ssp_extended_lte_band_preference = FEATURE_UNKNOWN;
+ priv->feature_nas_ssp_acquisition_order_preference = FEATURE_UNKNOWN;
priv->config_active_i = -1;
/* Setup parent class' MMIfaceModemLocation */
@@ -923,6 +928,7 @@ load_current_capabilities_get_system_selection_preference_ready (QmiClientNas *c
priv->feature_nas_ssp = FEATURE_UNSUPPORTED;
priv->feature_nas_ssp_extended_lte_band_preference = FEATURE_UNSUPPORTED;
+ priv->feature_nas_ssp_acquisition_order_preference = FEATURE_UNSUPPORTED;
output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error);
if (!output) {
@@ -938,6 +944,12 @@ load_current_capabilities_get_system_selection_preference_ready (QmiClientNas *c
priv->feature_nas_ssp = FEATURE_SUPPORTED;
if (qmi_message_nas_get_system_selection_preference_output_get_extended_lte_band_preference (output, NULL, NULL, NULL, NULL, NULL))
priv->feature_nas_ssp_extended_lte_band_preference = FEATURE_SUPPORTED;
+ if (qmi_message_nas_get_system_selection_preference_output_get_acquisition_order_preference (output, &acquisition_order_preference_array, NULL) &&
+ acquisition_order_preference_array &&
+ acquisition_order_preference_array->len) {
+ priv->feature_nas_ssp_acquisition_order_preference = FEATURE_SUPPORTED;
+ priv->feature_nas_ssp_acquisition_order_preference_array = g_array_ref (acquisition_order_preference_array);
+ }
qmi_message_nas_get_system_selection_preference_output_get_mode_preference (
output,
@@ -1259,11 +1271,13 @@ static void
set_current_modes_system_selection_preference (GTask *task)
{
MMIfaceModem *self;
+ Private *priv;
SetCurrentModesContext *ctx;
QmiMessageNasSetSystemSelectionPreferenceInput *input;
QmiNasRatModePreference pref;
self = g_task_get_source_object (task);
+ priv = get_private (MM_SHARED_QMI (self));
ctx = g_task_get_task_data (task);
input = qmi_message_nas_set_system_selection_preference_input_new ();
@@ -1272,16 +1286,17 @@ set_current_modes_system_selection_preference (GTask *task)
/* Preferred modes */
if (ctx->preferred != MM_MODEM_MODE_NONE) {
- GArray *array;
-
- /* Acquisition order array */
- array = mm_modem_mode_to_qmi_acquisition_order_preference (ctx->allowed,
- ctx->preferred,
- mm_iface_modem_is_cdma (self),
- mm_iface_modem_is_3gpp (self));
- g_assert (array);
- qmi_message_nas_set_system_selection_preference_input_set_acquisition_order_preference (input, array, NULL);
- g_array_unref (array);
+ if (priv->feature_nas_ssp_acquisition_order_preference == FEATURE_SUPPORTED) {
+ GArray *array;
+
+ /* Acquisition order array */
+ array = mm_modem_mode_to_qmi_acquisition_order_preference (ctx->allowed,
+ ctx->preferred,
+ priv->feature_nas_ssp_acquisition_order_preference_array);
+ g_assert (array);
+ qmi_message_nas_set_system_selection_preference_input_set_acquisition_order_preference (input, array, NULL);
+ g_array_unref (array);
+ }
/* Only set GSM/WCDMA acquisition order preference if both 2G and 3G given as allowed */
if (mm_iface_modem_is_3gpp (self) && ((ctx->allowed & (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G))) {
@@ -1508,24 +1523,11 @@ load_current_modes_system_selection_preference_ready (QmiClientNas *client,
result->allowed = allowed;
result->preferred = MM_MODEM_MODE_NONE;
- /* For 2G+3G only rely on the GSM/WCDMA acquisition order preference TLV */
- if (mode_preference_mask == (QMI_NAS_RAT_MODE_PREFERENCE_GSM | QMI_NAS_RAT_MODE_PREFERENCE_UMTS)) {
- QmiNasGsmWcdmaAcquisitionOrderPreference gsm_or_wcdma;
-
- if (qmi_message_nas_get_system_selection_preference_output_get_gsm_wcdma_acquisition_order_preference (
- output,
- &gsm_or_wcdma,
- NULL))
- result->preferred = mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (gsm_or_wcdma, self);
- }
- /* Otherwise, rely on the acquisition order array TLV */
- else {
+ /* If acquisition order preference is available, always use that first */
+ if (priv->feature_nas_ssp_acquisition_order_preference == FEATURE_SUPPORTED) {
GArray *array;
- if (qmi_message_nas_get_system_selection_preference_output_get_acquisition_order_preference (
- output,
- &array,
- NULL) &&
+ if (qmi_message_nas_get_system_selection_preference_output_get_acquisition_order_preference (output, &array, NULL) &&
array->len > 0) {
guint i;
@@ -1546,6 +1548,16 @@ load_current_modes_system_selection_preference_ready (QmiClientNas *client,
}
}
}
+ /* For 2G+3G only rely on the GSM/WCDMA acquisition order preference TLV */
+ else if (mode_preference_mask == (QMI_NAS_RAT_MODE_PREFERENCE_GSM | QMI_NAS_RAT_MODE_PREFERENCE_UMTS)) {
+ QmiNasGsmWcdmaAcquisitionOrderPreference gsm_or_wcdma;
+
+ if (qmi_message_nas_get_system_selection_preference_output_get_gsm_wcdma_acquisition_order_preference (
+ output,
+ &gsm_or_wcdma,
+ NULL))
+ result->preferred = mm_modem_mode_from_qmi_gsm_wcdma_acquisition_order_preference (gsm_or_wcdma, self);
+ }
g_task_return_pointer (task, result, g_free);