diff options
-rw-r--r-- | src/mm-broadband-modem-mbim.c | 6 | ||||
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 347 | ||||
-rw-r--r-- | src/mm-shared-qmi.c | 258 | ||||
-rw-r--r-- | src/mm-shared-qmi.h | 19 |
4 files changed, 289 insertions, 341 deletions
diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index 14290cf85..e05a152c4 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -4766,6 +4766,12 @@ iface_modem_init (MMIfaceModem *iface) iface->modem_power_down_finish = power_down_finish; iface->load_supported_ip_families = modem_load_supported_ip_families; iface->load_supported_ip_families_finish = modem_load_supported_ip_families_finish; + iface->load_supported_bands = mm_shared_qmi_load_supported_bands; + iface->load_supported_bands_finish = mm_shared_qmi_load_supported_bands_finish; + iface->load_current_bands = mm_shared_qmi_load_current_bands; + iface->load_current_bands_finish = mm_shared_qmi_load_current_bands_finish; + iface->set_current_bands = mm_shared_qmi_set_current_bands; + iface->set_current_bands_finish = mm_shared_qmi_set_current_bands_finish; /* Additional actions */ iface->load_signal_quality = modem_load_signal_quality; diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index 54a6b368c..102d20142 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -1305,341 +1305,6 @@ modem_load_unlock_retries (MMIfaceModem *_self, } /*****************************************************************************/ -/* Load supported bands (Modem interface) */ - -static GArray * -modem_load_supported_bands_finish (MMIfaceModem *_self, - GAsyncResult *res, - GError **error) -{ - MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self); - GArray *supported_bands; - - supported_bands = g_task_propagate_pointer (G_TASK (res), error); - if (supported_bands) { - if (self->priv->supported_bands) - g_array_unref (self->priv->supported_bands); - - /* Cache the supported bands value */ - self->priv->supported_bands = g_array_ref (supported_bands); - } - return supported_bands; -} - -static void -dms_get_band_capabilities_ready (QmiClientDms *client, - GAsyncResult *res, - GTask *task) -{ - QmiMessageDmsGetBandCapabilitiesOutput *output; - GError *error = NULL; - - output = qmi_client_dms_get_band_capabilities_finish (client, res, &error); - if (!output) { - g_prefix_error (&error, "QMI operation failed: "); - g_task_return_error (task, error); - } else if (!qmi_message_dms_get_band_capabilities_output_get_result (output, &error)) { - g_prefix_error (&error, "Couldn't get band capabilities: "); - g_task_return_error (task, error); - } else { - GArray *mm_bands; - QmiDmsBandCapability qmi_bands = 0; - QmiDmsLteBandCapability qmi_lte_bands = 0; - - qmi_message_dms_get_band_capabilities_output_get_band_capability ( - output, - &qmi_bands, - NULL); - qmi_message_dms_get_band_capabilities_output_get_lte_band_capability ( - output, - &qmi_lte_bands, - NULL); - - mm_bands = mm_modem_bands_from_qmi_band_capabilities (qmi_bands, qmi_lte_bands); - - if (mm_bands->len == 0) { - g_array_unref (mm_bands); - g_task_return_new_error (task, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't parse the list of supported bands"); - } else { - g_task_return_pointer (task, mm_bands, (GDestroyNotify)g_array_unref); - } - } - - if (output) - qmi_message_dms_get_band_capabilities_output_unref (output); - - g_object_unref (task); -} - -static void -modem_load_supported_bands (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - QmiClient *client = NULL; - - if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self), - QMI_SERVICE_DMS, &client, - callback, user_data)) - return; - - mm_dbg ("loading band capabilities..."); - qmi_client_dms_get_band_capabilities (QMI_CLIENT_DMS (client), - NULL, - 5, - NULL, - (GAsyncReadyCallback)dms_get_band_capabilities_ready, - g_task_new (self, NULL, callback, user_data)); -} - -/*****************************************************************************/ -/* Load current bands (Modem interface) */ - -static GArray * -modem_load_current_bands_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_pointer (G_TASK (res), error); -} - -#if defined WITH_NEWEST_QMI_COMMANDS - -static void -nas_get_rf_band_information_ready (QmiClientNas *client, - GAsyncResult *res, - GTask *task) -{ - QmiMessageNasGetRfBandInformationOutput *output; - GError *error = NULL; - - output = qmi_client_nas_get_rf_band_information_finish (client, res, &error); - if (!output) { - g_prefix_error (&error, "QMI operation failed: "); - g_task_return_error (task, error); - } else if (!qmi_message_nas_get_rf_band_information_output_get_result (output, &error)) { - g_prefix_error (&error, "Couldn't get current band information: "); - g_task_return_error (task, error); - } else { - GArray *mm_bands; - GArray *info_array = NULL; - - qmi_message_nas_get_rf_band_information_output_get_list (output, &info_array, NULL); - - mm_bands = mm_modem_bands_from_qmi_rf_band_information_array (info_array); - - if (mm_bands->len == 0) { - g_array_unref (mm_bands); - g_task_return_new_error (task, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't parse the list of current bands"); - } else { - g_task_return_pointer (task, mm_bands, (GDestroyNotify)g_array_unref); - } - } - - if (output) - qmi_message_nas_get_rf_band_information_output_unref (output); - - g_object_unref (task); -} - -#endif /* WITH_NEWEST_QMI_COMMANDS */ - -static void -load_bands_get_system_selection_preference_ready (QmiClientNas *client, - GAsyncResult *res, - GTask *task) -{ - QmiMessageNasGetSystemSelectionPreferenceOutput *output = NULL; - GError *error = NULL; - - output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error); - if (!output) { - g_prefix_error (&error, "QMI operation failed: "); - g_task_return_error (task, error); - } else if (!qmi_message_nas_get_system_selection_preference_output_get_result (output, &error)) { - g_prefix_error (&error, "Couldn't get system selection preference: "); - g_task_return_error (task, error); - } else { - GArray *mm_bands; - QmiNasBandPreference band_preference_mask = 0; - QmiNasLteBandPreference lte_band_preference_mask = 0; - - qmi_message_nas_get_system_selection_preference_output_get_band_preference ( - output, - &band_preference_mask, - NULL); - - qmi_message_nas_get_system_selection_preference_output_get_lte_band_preference ( - output, - <e_band_preference_mask, - NULL); - - mm_bands = mm_modem_bands_from_qmi_band_preference (band_preference_mask, - lte_band_preference_mask); - - if (mm_bands->len == 0) { - g_array_unref (mm_bands); - g_task_return_new_error (task, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't parse the list of current bands"); - } else { - gchar *str; - - str = qmi_nas_band_preference_build_string_from_mask (band_preference_mask); - mm_dbg ("Bands reported in system selection preference: '%s'", str); - g_free (str); - - g_task_return_pointer (task, mm_bands, (GDestroyNotify)g_array_unref); - } - } - - if (output) - qmi_message_nas_get_system_selection_preference_output_unref (output); - - g_object_unref (task); -} - -static void -modem_load_current_bands (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - QmiClient *client = NULL; - - if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self), - QMI_SERVICE_NAS, &client, - callback, user_data)) - return; - - task = g_task_new (self, NULL, callback, user_data); - - mm_dbg ("loading current bands..."); - -#if defined WITH_NEWEST_QMI_COMMANDS - /* Introduced in NAS 1.19 */ - if (qmi_client_check_version (client, 1, 19)) { - qmi_client_nas_get_rf_band_information (QMI_CLIENT_NAS (client), - NULL, - 5, - NULL, - (GAsyncReadyCallback)nas_get_rf_band_information_ready, - task); - return; - } -#endif - - qmi_client_nas_get_system_selection_preference ( - QMI_CLIENT_NAS (client), - NULL, /* no input */ - 5, - NULL, /* cancellable */ - (GAsyncReadyCallback)load_bands_get_system_selection_preference_ready, - task); -} - -/*****************************************************************************/ -/* Set current bands (Modem interface) */ - -static gboolean -set_current_bands_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -bands_set_system_selection_preference_ready (QmiClientNas *client, - GAsyncResult *res, - GTask *task) -{ - QmiMessageNasSetSystemSelectionPreferenceOutput *output = NULL; - GError *error = NULL; - - output = qmi_client_nas_set_system_selection_preference_finish (client, res, &error); - if (!output) { - g_prefix_error (&error, "QMI operation failed: "); - g_task_return_error (task, error); - } else if (!qmi_message_nas_set_system_selection_preference_output_get_result (output, &error)) { - g_prefix_error (&error, "Couldn't set system selection preference: "); - g_task_return_error (task, error); - - } else - /* Good! TODO: do we really need to wait for the indication? */ - g_task_return_boolean (task, TRUE); - - if (output) - qmi_message_nas_set_system_selection_preference_output_unref (output); - - g_object_unref (task); -} - -static void -set_current_bands (MMIfaceModem *_self, - GArray *bands_array, - GAsyncReadyCallback callback, - gpointer user_data) -{ - MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self); - QmiMessageNasSetSystemSelectionPreferenceInput *input; - GTask *task; - QmiClient *client = NULL; - QmiNasBandPreference qmi_bands = 0; - QmiNasLteBandPreference qmi_lte_bands = 0; - - if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self), - QMI_SERVICE_NAS, &client, - callback, user_data)) - return; - - task = g_task_new (self, NULL, callback, user_data); - - /* Handle ANY separately */ - if (bands_array->len == 1 && - g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) { - if (!self->priv->supported_bands) { - g_task_return_new_error (task, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Cannot handle 'ANY' if supported bands are unknown"); - g_object_unref (task); - return; - } - - mm_modem_bands_to_qmi_band_preference (self->priv->supported_bands, - &qmi_bands, - &qmi_lte_bands); - } else - mm_modem_bands_to_qmi_band_preference (bands_array, - &qmi_bands, - &qmi_lte_bands); - - input = qmi_message_nas_set_system_selection_preference_input_new (); - qmi_message_nas_set_system_selection_preference_input_set_band_preference (input, qmi_bands, NULL); - if (mm_iface_modem_is_3gpp_lte (_self)) - qmi_message_nas_set_system_selection_preference_input_set_lte_band_preference (input, qmi_lte_bands, NULL); - - qmi_message_nas_set_system_selection_preference_input_set_change_duration (input, QMI_NAS_CHANGE_DURATION_PERMANENT, NULL); - - qmi_client_nas_set_system_selection_preference ( - QMI_CLIENT_NAS (client), - input, - 5, - NULL, /* cancellable */ - (GAsyncReadyCallback)bands_set_system_selection_preference_ready, - task); - qmi_message_nas_set_system_selection_preference_input_unref (input); -} - -/*****************************************************************************/ /* Load supported IP families (Modem interface) */ static MMBearerIpFamily @@ -8874,8 +8539,8 @@ iface_modem_init (MMIfaceModem *iface) iface->load_unlock_required_finish = modem_load_unlock_required_finish; iface->load_unlock_retries = modem_load_unlock_retries; iface->load_unlock_retries_finish = modem_load_unlock_retries_finish; - iface->load_supported_bands = modem_load_supported_bands; - iface->load_supported_bands_finish = modem_load_supported_bands_finish; + iface->load_supported_bands = mm_shared_qmi_load_supported_bands; + iface->load_supported_bands_finish = mm_shared_qmi_load_supported_bands_finish; iface->load_supported_modes = mm_shared_qmi_load_supported_modes; iface->load_supported_modes_finish = mm_shared_qmi_load_supported_modes_finish; iface->load_power_state = load_power_state; @@ -8904,10 +8569,10 @@ iface_modem_init (MMIfaceModem *iface) iface->set_current_modes_finish = mm_shared_qmi_set_current_modes_finish; iface->load_signal_quality = load_signal_quality; iface->load_signal_quality_finish = load_signal_quality_finish; - iface->load_current_bands = modem_load_current_bands; - iface->load_current_bands_finish = modem_load_current_bands_finish; - iface->set_current_bands = set_current_bands; - iface->set_current_bands_finish = set_current_bands_finish; + iface->load_current_bands = mm_shared_qmi_load_current_bands; + iface->load_current_bands_finish = mm_shared_qmi_load_current_bands_finish; + iface->set_current_bands = mm_shared_qmi_set_current_bands; + iface->set_current_bands_finish = mm_shared_qmi_set_current_bands_finish; /* Don't try to load access technologies, as we would be using parent's * generic method (QCDM based). Access technologies are already reported via diff --git a/src/mm-shared-qmi.c b/src/mm-shared-qmi.c index 1cc19d368..5c36f1662 100644 --- a/src/mm-shared-qmi.c +++ b/src/mm-shared-qmi.c @@ -55,6 +55,7 @@ typedef struct { Feature feature_nas_technology_preference; Feature feature_nas_system_selection_preference; gboolean disable_4g_only_mode; + GArray *supported_bands; /* Location helpers */ MMModemLocationSource enabled_sources; @@ -70,6 +71,8 @@ typedef struct { static void private_free (Private *priv) { + if (priv->supported_bands) + g_array_unref (priv->supported_bands); if (priv->supported_radio_interfaces) g_array_unref (priv->supported_radio_interfaces); if (priv->pds_location_event_report_indication_id) @@ -1454,6 +1457,261 @@ mm_shared_qmi_load_supported_modes (MMIfaceModem *self, } /*****************************************************************************/ +/* Load supported bands (Modem interface) */ + +GArray * +mm_shared_qmi_load_supported_bands_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) +{ + return (GArray *) g_task_propagate_pointer (G_TASK (res), error); +} + +static void +dms_get_band_capabilities_ready (QmiClientDms *client, + GAsyncResult *res, + GTask *task) +{ + MMSharedQmi *self; + Private *priv; + QmiMessageDmsGetBandCapabilitiesOutput *output; + GError *error = NULL; + GArray *mm_bands = NULL; + QmiDmsBandCapability qmi_bands = 0; + QmiDmsLteBandCapability qmi_lte_bands = 0; + + self = g_task_get_source_object (task); + priv = get_private (self); + + output = qmi_client_dms_get_band_capabilities_finish (client, res, &error); + if (!output || !qmi_message_dms_get_band_capabilities_output_get_result (output, &error)) { + g_prefix_error (&error, "Couldn't get band capabilities: "); + goto out; + } + + qmi_message_dms_get_band_capabilities_output_get_band_capability ( + output, + &qmi_bands, + NULL); + qmi_message_dms_get_band_capabilities_output_get_lte_band_capability ( + output, + &qmi_lte_bands, + NULL); + + mm_bands = mm_modem_bands_from_qmi_band_capabilities (qmi_bands, qmi_lte_bands); + if (mm_bands->len == 0) { + g_clear_pointer (&mm_bands, g_array_unref); + error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't parse the list of supported bands"); + goto out; + } + + /* Cache the result */ + g_clear_pointer (&priv->supported_bands, g_array_unref); + priv->supported_bands = g_array_ref (mm_bands); + + out: + if (output) + qmi_message_dms_get_band_capabilities_output_unref (output); + + if (error) + g_task_return_error (task, error); + else if (mm_bands) + g_task_return_pointer (task, mm_bands, (GDestroyNotify)g_array_unref); + else + g_assert_not_reached (); + g_object_unref (task); +} + +void +mm_shared_qmi_load_supported_bands (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + QmiClient *client = NULL; + + if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self), + QMI_SERVICE_DMS, &client, + callback, user_data)) + return; + + task = g_task_new (self, NULL, callback, user_data); + + qmi_client_dms_get_band_capabilities (QMI_CLIENT_DMS (client), + NULL, + 5, + NULL, + (GAsyncReadyCallback)dms_get_band_capabilities_ready, + task); +} + +/*****************************************************************************/ +/* Load current bands (Modem interface) */ + +GArray * +mm_shared_qmi_load_current_bands_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) +{ + return (GArray *) g_task_propagate_pointer (G_TASK (res), error); +} + +static void +load_bands_get_system_selection_preference_ready (QmiClientNas *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageNasGetSystemSelectionPreferenceOutput *output = NULL; + GError *error = NULL; + GArray *mm_bands = NULL; + QmiNasBandPreference band_preference_mask = 0; + QmiNasLteBandPreference lte_band_preference_mask = 0; + + output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error); + if (!output || !qmi_message_nas_get_system_selection_preference_output_get_result (output, &error)) { + g_prefix_error (&error, "Couldn't get system selection preference: "); + goto out; + } + + qmi_message_nas_get_system_selection_preference_output_get_band_preference ( + output, + &band_preference_mask, + NULL); + + qmi_message_nas_get_system_selection_preference_output_get_lte_band_preference ( + output, + <e_band_preference_mask, + NULL); + + mm_bands = mm_modem_bands_from_qmi_band_preference (band_preference_mask, lte_band_preference_mask); + + if (mm_bands->len == 0) { + g_clear_pointer (&mm_bands, g_array_unref); + error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Couldn't parse the list of current bands"); + } + + out: + + if (output) + qmi_message_nas_get_system_selection_preference_output_unref (output); + + if (error) + g_task_return_error (task, error); + else if (mm_bands) + g_task_return_pointer (task, mm_bands, (GDestroyNotify)g_array_unref); + else + g_assert_not_reached (); + g_object_unref (task); +} + +void +mm_shared_qmi_load_current_bands (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + QmiClient *client = NULL; + + if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self), + QMI_SERVICE_NAS, &client, + callback, user_data)) + return; + + task = g_task_new (self, NULL, callback, user_data); + + qmi_client_nas_get_system_selection_preference ( + QMI_CLIENT_NAS (client), + NULL, /* no input */ + 5, + NULL, /* cancellable */ + (GAsyncReadyCallback)load_bands_get_system_selection_preference_ready, + task); +} + +/*****************************************************************************/ +/* Set current bands (Modem interface) */ + +gboolean +mm_shared_qmi_set_current_bands_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +bands_set_system_selection_preference_ready (QmiClientNas *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageNasSetSystemSelectionPreferenceOutput *output = NULL; + GError *error = NULL; + + output = qmi_client_nas_set_system_selection_preference_finish (client, res, &error); + if (!output || !qmi_message_nas_set_system_selection_preference_output_get_result (output, &error)) { + g_prefix_error (&error, "Couldn't set system selection preference: "); + g_task_return_error (task, error); + } else + g_task_return_boolean (task, TRUE); + + if (output) + qmi_message_nas_set_system_selection_preference_output_unref (output); + + g_object_unref (task); +} + +void +mm_shared_qmi_set_current_bands (MMIfaceModem *self, + GArray *bands_array, + GAsyncReadyCallback callback, + gpointer user_data) +{ + QmiMessageNasSetSystemSelectionPreferenceInput *input; + Private *priv; + GTask *task; + QmiClient *client = NULL; + QmiNasBandPreference qmi_bands = 0; + QmiNasLteBandPreference qmi_lte_bands = 0; + + if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self), + QMI_SERVICE_NAS, &client, + callback, user_data)) + return; + + task = g_task_new (self, NULL, callback, user_data); + priv = get_private (MM_SHARED_QMI (self)); + + /* Handle ANY separately */ + if (bands_array->len == 1 && g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) { + if (!priv->supported_bands) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Cannot handle 'ANY' if supported bands are unknown"); + g_object_unref (task); + return; + } + mm_modem_bands_to_qmi_band_preference (priv->supported_bands, &qmi_bands, &qmi_lte_bands); + } else + mm_modem_bands_to_qmi_band_preference (bands_array, &qmi_bands, &qmi_lte_bands); + + input = qmi_message_nas_set_system_selection_preference_input_new (); + qmi_message_nas_set_system_selection_preference_input_set_band_preference (input, qmi_bands, NULL); + if (mm_iface_modem_is_3gpp_lte (self)) + qmi_message_nas_set_system_selection_preference_input_set_lte_band_preference (input, qmi_lte_bands, NULL); + qmi_message_nas_set_system_selection_preference_input_set_change_duration (input, QMI_NAS_CHANGE_DURATION_PERMANENT, NULL); + + qmi_client_nas_set_system_selection_preference ( + QMI_CLIENT_NAS (client), + input, + 5, + NULL, /* cancellable */ + (GAsyncReadyCallback)bands_set_system_selection_preference_ready, + task); + qmi_message_nas_set_system_selection_preference_input_unref (input); +} + +/*****************************************************************************/ /* Reset (Modem interface) */ gboolean diff --git a/src/mm-shared-qmi.h b/src/mm-shared-qmi.h index 014104196..71ffa9da3 100644 --- a/src/mm-shared-qmi.h +++ b/src/mm-shared-qmi.h @@ -112,6 +112,25 @@ void mm_shared_qmi_set_current_modes (MMIfaceMode gboolean mm_shared_qmi_set_current_modes_finish (MMIfaceModem *self, GAsyncResult *res, GError **error); +void mm_shared_qmi_load_supported_bands (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data); +GArray *mm_shared_qmi_load_supported_bands_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error); +void mm_shared_qmi_load_current_bands (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data); +GArray *mm_shared_qmi_load_current_bands_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error); +void mm_shared_qmi_set_current_bands (MMIfaceModem *self, + GArray *bands_array, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_shared_qmi_set_current_bands_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error); void mm_shared_qmi_reset (MMIfaceModem *self, GAsyncReadyCallback callback, gpointer user_data); |