aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoel Selvaraj <jo@jsfamily.in>2021-07-18 03:12:12 +0530
committerAleksander Morgado <aleksander@aleksander.es>2021-08-02 13:11:29 +0000
commit1894dd77679b2a24abce08c72f3da54d1332ba2d (patch)
tree0c721254b32456d36114fc2b3785bb1ba77b18f9 /src
parent82054410e2f1668e9418616c24f35a5b3c6826fe (diff)
modem-qmi: implement setup in call unsolicited events
Handle supplementary service notification indication. Useful to know when existing call is on hold, unheld and waiting.
Diffstat (limited to 'src')
-rw-r--r--src/mm-broadband-modem-qmi.c124
1 files changed, 123 insertions, 1 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
index f8c81be2..997b87f2 100644
--- a/src/mm-broadband-modem-qmi.c
+++ b/src/mm-broadband-modem-qmi.c
@@ -48,6 +48,7 @@
#include "mm-sms-part-3gpp.h"
#include "mm-sms-part-cdma.h"
#include "mm-call-qmi.h"
+#include "mm-call-list.h"
static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
@@ -152,6 +153,8 @@ struct _MMBroadbandModemQmiPrivate {
guint all_call_status_indication_id;
gboolean all_call_status_unsolicited_events_enabled;
gboolean all_call_status_unsolicited_events_setup;
+ guint supplementary_service_indication_id;
+ gboolean supplementary_service_unsolicited_events_setup;
/* Firmware helpers */
gboolean firmware_list_preloaded;
@@ -8868,6 +8871,49 @@ all_call_status_indication_cb (QmiClientVoice *client,
}
/*****************************************************************************/
+/* Supplementary service indication */
+
+static void
+supplementary_service_indication_cb (QmiClientVoice *client,
+ QmiIndicationVoiceSupplementaryServiceOutput *output,
+ MMBroadbandModemQmi *self)
+{
+ QmiVoiceSupplementaryServiceNotificationType notification_type;
+ guint8 call_id = 0;
+ g_autoptr(MMCallList) call_list = NULL;
+ MMBaseCall *call = NULL;
+
+ if (!qmi_indication_voice_supplementary_service_output_get_info (output, &call_id, &notification_type, NULL)) {
+ mm_obj_dbg (self, "Ignoring supplementary service indication: no call id or notification type given");
+ return;
+ }
+
+ /* Retrieve list of known calls */
+ g_object_get (MM_BASE_MODEM (self),
+ MM_IFACE_MODEM_VOICE_CALL_LIST, &call_list,
+ NULL);
+ if (!call_list) {
+ mm_obj_dbg (self, "Ignoring supplementary service indication: no call list exists");
+ return;
+ }
+
+ call = mm_call_list_get_call_by_index (call_list, call_id);
+ if (!call) {
+ mm_obj_dbg (self, "Ignoring supplementary service indication: no matching call exists");
+ return;
+ }
+
+ if (notification_type == QMI_VOICE_SUPPLEMENTARY_SERVICE_NOTIFICATION_TYPE_CALL_IS_ON_HOLD)
+ mm_base_call_change_state (call, MM_CALL_STATE_HELD, MM_CALL_STATE_REASON_UNKNOWN);
+ else if (notification_type == QMI_VOICE_SUPPLEMENTARY_SERVICE_NOTIFICATION_TYPE_CALL_IS_RETRIEVED)
+ mm_base_call_change_state (call, MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_UNKNOWN);
+ else if (notification_type == QMI_VOICE_SUPPLEMENTARY_SERVICE_NOTIFICATION_TYPE_OUTGOING_CALL_IS_WAITING)
+ mm_base_call_change_state (call, MM_CALL_STATE_WAITING, MM_CALL_STATE_REASON_REFUSED_OR_BUSY);
+ else
+ mm_obj_dbg (self, "Ignoring supplementary service indication: unhandled notification type");
+}
+
+/*****************************************************************************/
/* Setup/cleanup unsolicited events */
static gboolean
@@ -8985,7 +9031,7 @@ common_voice_enable_disable_unsolicited_events (MMBroadbandModemQmi *self,
task = g_task_new (self, NULL, callback, user_data);
if (enable == self->priv->all_call_status_unsolicited_events_enabled) {
- mm_obj_dbg (self, "All Call Status unsolicited events already %s; skipping",
+ mm_obj_dbg (self, "voice unsolicited events already %s; skipping",
enable ? "enabled" : "disabled");
g_task_return_boolean (task, TRUE);
g_object_unref (task);
@@ -8995,6 +9041,7 @@ common_voice_enable_disable_unsolicited_events (MMBroadbandModemQmi *self,
input = qmi_message_voice_indication_register_input_new ();
qmi_message_voice_indication_register_input_set_call_notification_events (input, enable, NULL);
+ qmi_message_voice_indication_register_input_set_supplementary_service_notification_events (input, enable, NULL);
qmi_client_voice_indication_register (QMI_CLIENT_VOICE (client),
input,
10,
@@ -9020,6 +9067,75 @@ modem_voice_disable_unsolicited_events (MMIfaceModemVoice *self,
}
/*****************************************************************************/
+/* Setup/cleanup in-call unsolicited events */
+
+static gboolean
+common_voice_setup_cleanup_in_call_unsolicited_events_finish (MMIfaceModemVoice *self,
+ GAsyncResult *res,
+ GError **error)
+{
+ return g_task_propagate_boolean (G_TASK (res), error);
+}
+
+static void
+common_voice_setup_in_call_cleanup_unsolicited_events (MMBroadbandModemQmi *self,
+ gboolean setup,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ QmiClient *client = NULL;
+
+ if (!mm_shared_qmi_ensure_client (MM_SHARED_QMI (self),
+ QMI_SERVICE_VOICE, &client,
+ callback, user_data))
+ return;
+
+ task = g_task_new (self, NULL, callback, user_data);
+
+ if (setup == self->priv->supplementary_service_unsolicited_events_setup) {
+ mm_obj_dbg (self, "Supplementary service unsolicited events already %s; skipping",
+ setup ? "setup" : "cleanup");
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+ return;
+ }
+ self->priv->supplementary_service_unsolicited_events_setup = setup;
+
+ if (setup) {
+ g_assert (self->priv->supplementary_service_indication_id == 0);
+ self->priv->supplementary_service_indication_id =
+ g_signal_connect (client,
+ "supplementary-service",
+ G_CALLBACK (supplementary_service_indication_cb),
+ self);
+ } else {
+ g_assert (self->priv->supplementary_service_indication_id != 0);
+ g_signal_handler_disconnect (client, self->priv->supplementary_service_indication_id);
+ self->priv->supplementary_service_indication_id = 0;
+ }
+
+ g_task_return_boolean (task, TRUE);
+ g_object_unref (task);
+}
+
+static void
+modem_voice_setup_in_call_unsolicited_events (MMIfaceModemVoice *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ common_voice_setup_in_call_cleanup_unsolicited_events (MM_BROADBAND_MODEM_QMI (self), TRUE, callback, user_data);
+}
+
+static void
+modem_voice_cleanup_in_call_unsolicited_events (MMIfaceModemVoice *self,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ common_voice_setup_in_call_cleanup_unsolicited_events (MM_BROADBAND_MODEM_QMI (self), FALSE, callback, user_data);
+}
+
+/*****************************************************************************/
/* Create CALL (Voice interface) */
static MMBaseCall *
@@ -11583,6 +11699,12 @@ iface_modem_voice_init (MMIfaceModemVoice *iface)
iface->disable_unsolicited_events_finish = common_voice_enable_disable_unsolicited_events_finish;
iface->cleanup_unsolicited_events = modem_voice_cleanup_unsolicited_events;
iface->cleanup_unsolicited_events_finish = common_voice_setup_cleanup_unsolicited_events_finish;
+
+ iface->setup_in_call_unsolicited_events = modem_voice_setup_in_call_unsolicited_events;
+ iface->setup_in_call_unsolicited_events_finish = common_voice_setup_cleanup_in_call_unsolicited_events_finish;
+ iface->cleanup_in_call_unsolicited_events = modem_voice_cleanup_in_call_unsolicited_events;
+ iface->cleanup_in_call_unsolicited_events_finish = common_voice_setup_cleanup_in_call_unsolicited_events_finish;
+
iface->create_call = modem_voice_create_call;
}