diff options
author | Guido Günther <agx@sigxcpu.org> | 2025-04-03 11:17:44 +0200 |
---|---|---|
committer | Dan Williams <dan@ioncontrol.co> | 2025-04-13 05:01:32 +0000 |
commit | 1ea564f5e84aa160f23b68d4e6a5d532d2044c6a (patch) | |
tree | abf4aae213f961fb77ad0ecc86d107cca0b20bd0 /src | |
parent | 9c5f5833e514b2ed93518f30da1aacccceba477a (diff) |
broadband-modem-qmi: Add support for setting channels
This allows to receive Cell Broadcast messages in the specified channel
range on SDM670 based devices (X12 modem) and SDM845 (X20 modem) without
any AT ports (like the OnePlus 6/6T and Google Pixel 3a).
Helps: https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/1325
Signed-off-by: Guido Günther <agx@sigxcpu.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index 371e910b..58887c29 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -10952,6 +10952,90 @@ cell_broadcast_setup_unsolicited_events (MMIfaceModemCellBroadcast *_self, } } +/***********************************************************************************/ +/* Get channels (CellBroadcast interface) */ + +static gboolean +cell_broadcast_set_channels_finish (MMIfaceModemCellBroadcast *_self, + GAsyncResult *res, + GError **error) +{ + MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self); + + /* Handle AT URC only fallback */ + if (self->priv->cell_broadcast_fallback_at_only) { + return iface_modem_cell_broadcast_parent->set_channels_finish (_self, res, error); + } + + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +cell_broadcast_set_broadcast_config_ready (QmiClientWms *client, + GAsyncResult *res, + gpointer *user_data) +{ + g_autoptr(QmiMessageWmsSetBroadcastConfigOutput) output = NULL; + g_autoptr(GTask) task = G_TASK (user_data); + GError *error = NULL; + + output = qmi_client_wms_set_broadcast_config_finish (client, res, &error); + if (!output) { + g_prefix_error (&error, "QMI operation failed: "); + g_task_return_error (task, error); + } else if (!qmi_message_wms_set_broadcast_config_output_get_result (output, &error)) { + g_prefix_error (&error, "Couldn't set cbs channels: "); + g_task_return_error (task, error); + } else + g_task_return_boolean (task, TRUE); +} + +static void +cell_broadcast_set_channels (MMIfaceModemCellBroadcast *_self, + GArray *channels, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MMBroadbandModemQmi *self = MM_BROADBAND_MODEM_QMI (_self); + QmiClient *client = NULL; + g_autoptr(GArray) channels_array = NULL; + g_autoptr(QmiMessageWmsSetBroadcastConfigInput) input = NULL; + guint i; + + /* Handle AT URC only fallback */ + if (self->priv->cell_broadcast_fallback_at_only) { + iface_modem_cell_broadcast_parent->set_channels (_self, channels, callback, user_data); + return; + } + + if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self), + QMI_SERVICE_WMS, &client, + callback, user_data)) + return; + + channels_array = g_array_new (FALSE, FALSE, sizeof (QmiMessageWmsSetBroadcastConfigInputChannelsElement)); + for (i = 0; i < channels->len; i++) { + QmiMessageWmsSetBroadcastConfigInputChannelsElement elem; + MMCellBroadcastChannels ch = g_array_index (channels, MMCellBroadcastChannels, i); + + elem.start = ch.start; + elem.end = ch.end; + elem.selected = TRUE; + g_array_append_val (channels_array, elem); + } + + mm_obj_dbg (self, "Setting channels..."); + input = qmi_message_wms_set_broadcast_config_input_new (); + qmi_message_wms_set_broadcast_config_input_set_message_mode (input, QMI_WMS_MESSAGE_MODE_GSM_WCDMA, NULL); + qmi_message_wms_set_broadcast_config_input_set_channels (input, channels_array, NULL); + qmi_client_wms_set_broadcast_config (QMI_CLIENT_WMS (client), + input, + 5, + NULL, + (GAsyncReadyCallback)cell_broadcast_set_broadcast_config_ready, + g_task_new (self, NULL, callback, user_data)); +} + /*****************************************************************************/ /* Create CBM (CellBroadcast interface) */ @@ -14736,6 +14820,8 @@ iface_modem_cell_broadcast_init (MMIfaceModemCellBroadcastInterface *iface) iface->setup_unsolicited_events_finish = cell_broadcast_setup_unsolicited_events_finish; iface->cleanup_unsolicited_events = cell_broadcast_cleanup_unsolicited_events; iface->cleanup_unsolicited_events_finish = cell_broadcast_cleanup_unsolicited_events_finish; + iface->set_channels = cell_broadcast_set_channels; + iface->set_channels_finish = cell_broadcast_set_channels_finish; iface->create_cbm = cell_broadcast_create_cbm; } |