broadband-modem-qmi: implement UE mode get/set
Instead of relying on getting/setting the UE mode via AT +CEMODE command which on Quectel RM520N (And I assume other QMI based modems) only allows getting the value and not setting one it has special AT commands for CS/PS and voice/data centric values. So lets instead use the QMI Get/Set System Selection Preference TLV which offers service domain and usage domain preference info so we can use those to get/set the 3GPP TS 24.301 UE mode values. Signed-off-by: Robert Marko <robert.marko@sartura.hr>
This commit is contained in:
@@ -11845,6 +11845,230 @@ modem_3gpp_load_initial_eps_bearer_settings (MMIfaceModem3gpp *_self,
|
||||
load_initial_eps_bearer_get_profile_settings (task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* UE mode of operation for EPS loading (3GPP interface) */
|
||||
|
||||
static MMModem3gppEpsUeModeOperation
|
||||
modem_3gpp_load_eps_ue_mode_operation_finish (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
GError *inner_error = NULL;
|
||||
gssize uemode;
|
||||
|
||||
uemode = g_task_propagate_int (G_TASK (res), &inner_error);
|
||||
if (inner_error) {
|
||||
g_propagate_error (error, inner_error);
|
||||
return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN;
|
||||
}
|
||||
|
||||
return (MMModem3gppEpsUeModeOperation)uemode;
|
||||
}
|
||||
|
||||
static MMModem3gppEpsUeModeOperation
|
||||
qmi_uemode_find (QmiNasServiceDomainPreference service_domain_preference,
|
||||
QmiNasUsagePreference usage_preference)
|
||||
{
|
||||
switch (service_domain_preference) {
|
||||
case QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_ONLY:
|
||||
if (usage_preference == QMI_NAS_USAGE_PREFERENCE_VOICE_CENTRIC)
|
||||
return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_1;
|
||||
else
|
||||
return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_2;
|
||||
case QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_PS:
|
||||
if (usage_preference == QMI_NAS_USAGE_PREFERENCE_VOICE_CENTRIC)
|
||||
return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_1;
|
||||
else
|
||||
return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_2;
|
||||
case QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_ONLY:
|
||||
case QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_ATTACH:
|
||||
case QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_DETACH:
|
||||
default:
|
||||
return MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_uemode_ready (QmiClientNas *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
g_autoptr(QmiMessageNasGetSystemSelectionPreferenceOutput) output = NULL;
|
||||
QmiNasServiceDomainPreference service_domain_preference = QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_ONLY;
|
||||
QmiNasUsagePreference usage_preference = QMI_NAS_USAGE_PREFERENCE_UNKNOWN;
|
||||
MMBroadbandModemQmi *self;
|
||||
GError *error = NULL;
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
|
||||
output = qmi_client_nas_get_system_selection_preference_finish (client, res, &error);
|
||||
if (!output) {
|
||||
mm_obj_warn (self, "couldn't get system selection preference: '%s'", error->message);
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qmi_message_nas_get_system_selection_preference_output_get_result (output, &error)) {
|
||||
mm_obj_warn (self, "couldn't get system selection preference: '%s'", error->message);
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qmi_message_nas_get_system_selection_preference_output_get_service_domain_preference (
|
||||
output,
|
||||
&service_domain_preference,
|
||||
&error)) {
|
||||
mm_obj_warn (self, "couldn't get service domain preference: '%s'", error->message);
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qmi_message_nas_get_system_selection_preference_output_get_usage_preference (
|
||||
output,
|
||||
&usage_preference,
|
||||
&error)) {
|
||||
mm_obj_warn (self, "couldn't get usage domain preference: '%s'", error->message);
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
g_task_return_int (task, qmi_uemode_find (service_domain_preference, usage_preference));
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
modem_3gpp_load_eps_ue_mode_operation (MMIfaceModem3gpp *_self,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
|
||||
QmiClient *client = NULL;
|
||||
GTask *task;
|
||||
|
||||
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_obj_dbg (self, "loading UE mode of operation for EPS via QMI...");
|
||||
qmi_client_nas_get_system_selection_preference (QMI_CLIENT_NAS (client),
|
||||
NULL,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)get_uemode_ready,
|
||||
task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* UE mode of operation for EPS setting (3GPP interface) */
|
||||
|
||||
static gboolean
|
||||
modem_3gpp_set_eps_ue_mode_operation_finish (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return g_task_propagate_boolean (G_TASK (res), error);
|
||||
}
|
||||
|
||||
static void
|
||||
set_uemode_ready (QmiClientNas *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
g_autoptr(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_task_return_error (task, error);
|
||||
else
|
||||
g_task_return_boolean (task, TRUE);
|
||||
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
qmi_uemode_build (MMModem3gppEpsUeModeOperation mode,
|
||||
QmiMessageNasSetSystemSelectionPreferenceInput *input)
|
||||
{
|
||||
QmiNasServiceDomainPreference service_domain_preference;
|
||||
QmiNasUsagePreference usage_preference;
|
||||
|
||||
g_return_if_fail (mode != MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN);
|
||||
|
||||
switch (mode) {
|
||||
case MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_1:
|
||||
service_domain_preference = QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_ONLY;
|
||||
usage_preference = QMI_NAS_USAGE_PREFERENCE_VOICE_CENTRIC;
|
||||
break;
|
||||
case MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_PS_2:
|
||||
service_domain_preference = QMI_NAS_SERVICE_DOMAIN_PREFERENCE_PS_ONLY;
|
||||
usage_preference = QMI_NAS_USAGE_PREFERENCE_DATA_CENTRIC;
|
||||
break;
|
||||
case MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_1:
|
||||
service_domain_preference = QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_PS;
|
||||
usage_preference = QMI_NAS_USAGE_PREFERENCE_VOICE_CENTRIC;
|
||||
break;
|
||||
case MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_CSPS_2:
|
||||
service_domain_preference = QMI_NAS_SERVICE_DOMAIN_PREFERENCE_CS_PS;
|
||||
usage_preference = QMI_NAS_USAGE_PREFERENCE_DATA_CENTRIC;
|
||||
break;
|
||||
case MM_MODEM_3GPP_EPS_UE_MODE_OPERATION_UNKNOWN:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
qmi_message_nas_set_system_selection_preference_input_set_usage_preference (
|
||||
input,
|
||||
usage_preference,
|
||||
NULL);
|
||||
qmi_message_nas_set_system_selection_preference_input_set_service_domain_preference (
|
||||
input,
|
||||
service_domain_preference,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
modem_3gpp_set_eps_ue_mode_operation (MMIfaceModem3gpp *_self,
|
||||
MMModem3gppEpsUeModeOperation mode,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self);
|
||||
QmiMessageNasSetSystemSelectionPreferenceInput *input;
|
||||
QmiClient *client = NULL;
|
||||
GTask *task;
|
||||
|
||||
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_obj_dbg (self, "updating UE mode of operation for EPS via QMI...");
|
||||
|
||||
input = qmi_message_nas_set_system_selection_preference_input_new ();
|
||||
|
||||
qmi_uemode_build (mode, input);
|
||||
|
||||
qmi_client_nas_set_system_selection_preference (
|
||||
QMI_CLIENT_NAS (client),
|
||||
input,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback)set_uemode_ready,
|
||||
task);
|
||||
|
||||
qmi_message_nas_set_system_selection_preference_input_unref (input);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Check firmware support (Firmware interface) */
|
||||
|
||||
@@ -13935,6 +14159,10 @@ iface_modem_3gpp_init (MMIfaceModem3gppInterface *iface)
|
||||
iface->disable_facility_lock_finish = modem_3gpp_disable_facility_lock_finish;
|
||||
iface->set_packet_service_state = mm_shared_qmi_set_packet_service_state;
|
||||
iface->set_packet_service_state_finish = mm_shared_qmi_set_packet_service_state_finish;
|
||||
iface->load_eps_ue_mode_operation = modem_3gpp_load_eps_ue_mode_operation;
|
||||
iface->load_eps_ue_mode_operation_finish = modem_3gpp_load_eps_ue_mode_operation_finish;
|
||||
iface->set_eps_ue_mode_operation = modem_3gpp_set_eps_ue_mode_operation;
|
||||
iface->set_eps_ue_mode_operation_finish = modem_3gpp_set_eps_ue_mode_operation_finish;
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user