shared-qmi: unlock location engine at modem start
On SDM845 (OP6T) modem always starts with engine lock 'all'. It doesn't allow to read assistance server settings at the beginning. QMI call 'Get Predicted Orbits Data Source' (0x0036) fails with general failure. As a result it's not possible to inject assistance data using 'mmcli -m any --location-inject-assistance-data=<file>'. Commit90843b7a0d("shared-qmi: Lock and unlock GPS engine when starting and stopping") unlocks engine on GNSS start, that allows geolocation to work on SDM845, but it locks engine back on GNSS stop. As a result after GNSS stop it's not possible to inject XTRA data again. On EG25-G engine lock settings is stored in NV storage and is preserved after modem restart. By default engine lock is 'none'. But currently on GNSS stop this value is changed to 'all', that blocks location engine. If previous ModemManager version is installed after stopping geolocation and locking the engine, geolocation will not work, since the engine is still locked and modem restart will not help. This commit unlocks engine on modem start so all following operations with an engine succeed. Engine isn't locked back. Tested on SDM845 (OP6T) and Quectel EG25-G. Fixes:90843b7a0d("shared-qmi: Lock and unlock GPS engine when starting and stopping") Signed-off-by: Andrey Skvortsov <andrej.skvortzov@gmail.com>
This commit is contained in:
committed by
Dan Williams
parent
f2318ecc7b
commit
9c4aeeb33a
+98
-103
@@ -5107,16 +5107,16 @@ pds_gps_service_state_stop_ready (QmiClientPds *client,
|
||||
}
|
||||
|
||||
static void
|
||||
loc_lock_engine_ready (QmiClientLoc *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
loc_stop_ready (QmiClientLoc *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
MMSharedQmi *self;
|
||||
Private *priv;
|
||||
QmiMessageLocSetEngineLockOutput *output;
|
||||
QmiMessageLocStopOutput *output;
|
||||
GError *error = NULL;
|
||||
|
||||
output = qmi_client_loc_set_engine_lock_finish (client, res, &error);
|
||||
output = qmi_client_loc_stop_finish (client, res, &error);
|
||||
if (!output) {
|
||||
g_prefix_error (&error, "QMI operation failed: ");
|
||||
g_task_return_error (task, error);
|
||||
@@ -5124,17 +5124,17 @@ loc_lock_engine_ready (QmiClientLoc *client,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qmi_message_loc_set_engine_lock_output_get_result (output, &error)
|
||||
if (!qmi_message_loc_stop_output_get_result (output, &error)
|
||||
&& !g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_PERMISSION)) {
|
||||
g_prefix_error (&error, "Couldn't lock GPS engine: ");
|
||||
g_prefix_error (&error, "Couldn't stop GPS engine: ");
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
qmi_message_loc_set_engine_lock_output_unref (output);
|
||||
qmi_message_loc_stop_output_unref (output);
|
||||
return;
|
||||
}
|
||||
|
||||
g_clear_error (&error);
|
||||
qmi_message_loc_set_engine_lock_output_unref (output);
|
||||
qmi_message_loc_stop_output_unref (output);
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
priv = get_private (self);
|
||||
@@ -5151,45 +5151,6 @@ loc_lock_engine_ready (QmiClientLoc *client,
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
loc_stop_ready (QmiClientLoc *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
QmiMessageLocStopOutput *output;
|
||||
QmiMessageLocSetEngineLockInput *input;
|
||||
GError *error = NULL;
|
||||
|
||||
output = qmi_client_loc_stop_finish (client, res, &error);
|
||||
if (!output) {
|
||||
g_prefix_error (&error, "QMI operation failed: ");
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qmi_message_loc_stop_output_get_result (output, &error)) {
|
||||
g_prefix_error (&error, "Couldn't stop GPS engine: ");
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
qmi_message_loc_stop_output_unref (output);
|
||||
return;
|
||||
}
|
||||
|
||||
qmi_message_loc_stop_output_unref (output);
|
||||
|
||||
input = qmi_message_loc_set_engine_lock_input_new ();
|
||||
qmi_message_loc_set_engine_lock_input_set_lock_type (input, QMI_LOC_LOCK_TYPE_ALL, NULL);
|
||||
qmi_client_loc_set_engine_lock (QMI_CLIENT_LOC (client),
|
||||
input,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) loc_lock_engine_ready,
|
||||
task);
|
||||
qmi_message_loc_set_engine_lock_input_unref (input);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
stop_gps_engine (MMSharedQmi *self,
|
||||
GAsyncReadyCallback callback,
|
||||
@@ -5741,48 +5702,6 @@ loc_start_ready (QmiClientLoc *client,
|
||||
qmi_message_loc_register_events_input_unref (input);
|
||||
}
|
||||
|
||||
static void
|
||||
loc_unlock_engine_ready (QmiClientLoc *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
QmiMessageLocStartInput *input;
|
||||
QmiMessageLocSetEngineLockOutput *output;
|
||||
GError *error = NULL;
|
||||
|
||||
output = qmi_client_loc_set_engine_lock_finish (client, res, &error);
|
||||
if (!output) {
|
||||
g_prefix_error (&error, "QMI operation failed: ");
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!qmi_message_loc_set_engine_lock_output_get_result (output, &error)
|
||||
&& !g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_PERMISSION)) {
|
||||
g_prefix_error (&error, "Couldn't unlock GPS engine: ");
|
||||
g_task_return_error (task, error);
|
||||
g_object_unref (task);
|
||||
qmi_message_loc_set_engine_lock_output_unref (output);
|
||||
return;
|
||||
}
|
||||
|
||||
g_clear_error (&error);
|
||||
qmi_message_loc_set_engine_lock_output_unref (output);
|
||||
|
||||
input = qmi_message_loc_start_input_new ();
|
||||
qmi_message_loc_start_input_set_session_id (input, DEFAULT_LOC_SESSION_ID, NULL);
|
||||
qmi_message_loc_start_input_set_intermediate_report_state (input, QMI_LOC_INTERMEDIATE_REPORT_STATE_DISABLE, NULL);
|
||||
qmi_message_loc_start_input_set_minimum_interval_between_position_reports (input, 1000, NULL);
|
||||
qmi_message_loc_start_input_set_fix_recurrence_type (input, QMI_LOC_FIX_RECURRENCE_TYPE_REQUEST_PERIODIC_FIXES, NULL);
|
||||
qmi_client_loc_start (QMI_CLIENT_LOC (client),
|
||||
input,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) loc_start_ready,
|
||||
task);
|
||||
qmi_message_loc_start_input_unref (input);
|
||||
}
|
||||
|
||||
static void
|
||||
start_gps_engine (MMSharedQmi *self,
|
||||
@@ -5821,17 +5740,20 @@ start_gps_engine (MMSharedQmi *self,
|
||||
MM_PORT_QMI_FLAG_DEFAULT,
|
||||
NULL);
|
||||
if (client) {
|
||||
QmiMessageLocSetEngineLockInput *input;
|
||||
QmiMessageLocStartInput *input;
|
||||
|
||||
input = qmi_message_loc_set_engine_lock_input_new ();
|
||||
qmi_message_loc_set_engine_lock_input_set_lock_type (input, QMI_LOC_LOCK_TYPE_MT, NULL);
|
||||
qmi_client_loc_set_engine_lock (QMI_CLIENT_LOC (client),
|
||||
input,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) loc_unlock_engine_ready,
|
||||
task);
|
||||
qmi_message_loc_set_engine_lock_input_unref (input);
|
||||
input = qmi_message_loc_start_input_new ();
|
||||
qmi_message_loc_start_input_set_session_id (input, DEFAULT_LOC_SESSION_ID, NULL);
|
||||
qmi_message_loc_start_input_set_intermediate_report_state (input, QMI_LOC_INTERMEDIATE_REPORT_STATE_DISABLE, NULL);
|
||||
qmi_message_loc_start_input_set_minimum_interval_between_position_reports (input, 1000, NULL);
|
||||
qmi_message_loc_start_input_set_fix_recurrence_type (input, QMI_LOC_FIX_RECURRENCE_TYPE_REQUEST_PERIODIC_FIXES, NULL);
|
||||
qmi_client_loc_start (QMI_CLIENT_LOC (client),
|
||||
input,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) loc_start_ready,
|
||||
task);
|
||||
qmi_message_loc_start_input_unref (input);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6621,6 +6543,81 @@ parent_load_capabilities_ready (MMIfaceModemLocation *self,
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void
|
||||
location_load_capabilities (MMIfaceModemLocation *self,
|
||||
GTask *task)
|
||||
{
|
||||
Private *priv;
|
||||
|
||||
priv = get_private (MM_SHARED_QMI (self));
|
||||
priv->iface_modem_location_parent->load_capabilities (self,
|
||||
(GAsyncReadyCallback)parent_load_capabilities_ready,
|
||||
task);
|
||||
}
|
||||
|
||||
static void
|
||||
loc_unlock_location_engine_ready (QmiClientLoc *client,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
MMIfaceModemLocation *self;
|
||||
QmiMessageLocSetEngineLockOutput *output;
|
||||
GError *error = NULL;
|
||||
|
||||
output = qmi_client_loc_set_engine_lock_finish (client, res, &error);
|
||||
if (!output) {
|
||||
mm_obj_warn (client, "QMI operation failed: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
if (!qmi_message_loc_set_engine_lock_output_get_result (output, &error)
|
||||
&& !g_error_matches (error, QMI_PROTOCOL_ERROR, QMI_PROTOCOL_ERROR_NO_PERMISSION)) {
|
||||
mm_obj_warn (client, "Couldn't unlock GPS engine: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
qmi_message_loc_set_engine_lock_output_unref (output);
|
||||
|
||||
self = g_task_get_source_object (task);
|
||||
location_load_capabilities (self, task);
|
||||
}
|
||||
|
||||
static void
|
||||
unlock_location_engine (MMIfaceModemLocation *self,
|
||||
GTask *task)
|
||||
{
|
||||
QmiClient *client;
|
||||
QmiMessageLocSetEngineLockInput *input;
|
||||
|
||||
/* Prefer PDS, no need to unlock engine */
|
||||
if (mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
|
||||
QMI_SERVICE_PDS,
|
||||
MM_PORT_QMI_FLAG_DEFAULT,
|
||||
NULL))
|
||||
goto out;
|
||||
|
||||
/* Otherwise LOC */
|
||||
client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self),
|
||||
QMI_SERVICE_LOC,
|
||||
MM_PORT_QMI_FLAG_DEFAULT,
|
||||
NULL);
|
||||
if (!client)
|
||||
goto out;
|
||||
|
||||
input = qmi_message_loc_set_engine_lock_input_new ();
|
||||
qmi_message_loc_set_engine_lock_input_set_lock_type (input, QMI_LOC_LOCK_TYPE_MT, NULL);
|
||||
qmi_client_loc_set_engine_lock (QMI_CLIENT_LOC (client),
|
||||
input,
|
||||
10,
|
||||
NULL,
|
||||
(GAsyncReadyCallback) loc_unlock_location_engine_ready,
|
||||
task);
|
||||
qmi_message_loc_set_engine_lock_input_unref (input);
|
||||
return;
|
||||
out:
|
||||
location_load_capabilities (self, task);
|
||||
}
|
||||
|
||||
void
|
||||
mm_shared_qmi_location_load_capabilities (MMIfaceModemLocation *self,
|
||||
GAsyncReadyCallback callback,
|
||||
@@ -6636,9 +6633,7 @@ mm_shared_qmi_location_load_capabilities (MMIfaceModemLocation *self,
|
||||
g_assert (priv->iface_modem_location_parent->load_capabilities);
|
||||
g_assert (priv->iface_modem_location_parent->load_capabilities_finish);
|
||||
|
||||
priv->iface_modem_location_parent->load_capabilities (self,
|
||||
(GAsyncReadyCallback)parent_load_capabilities_ready,
|
||||
task);
|
||||
unlock_location_engine (self, task);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user