From 8b01958cb4f1060c9cda114228168be32090c639 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Thu, 27 Jun 2019 14:50:00 +0200 Subject: [PATCH] api,voice: new Transfer() method This method will join all active and held calls into a single multiparty call, and then request the network to terminate the call on the subscriber's end and transfer the control of the call to the parties that are still in the call. --- cli/mmcli-modem-voice.c | 51 ++++++- .../libmm-glib/libmm-glib-sections.txt | 7 + include/ModemManager-enums.h | 4 +- ....freedesktop.ModemManager1.Modem.Voice.xml | 11 ++ libmm-glib/mm-modem-voice.c | 79 ++++++++++ libmm-glib/mm-modem-voice.h | 11 ++ src/mm-iface-modem-voice.c | 135 ++++++++++++++++++ src/mm-iface-modem-voice.h | 8 ++ 8 files changed, 304 insertions(+), 2 deletions(-) diff --git a/cli/mmcli-modem-voice.c b/cli/mmcli-modem-voice.c index dac650dd..0eff1f00 100644 --- a/cli/mmcli-modem-voice.c +++ b/cli/mmcli-modem-voice.c @@ -53,6 +53,7 @@ static gchar *delete_str; static gboolean hold_and_accept_flag; static gboolean hangup_and_accept_flag; static gboolean hangup_all_flag; +static gboolean transfer_flag; static GOptionEntry entries[] = { { "voice-list-calls", 0, 0, G_OPTION_ARG_NONE, &list_flag, @@ -79,6 +80,10 @@ static GOptionEntry entries[] = { "Hangs up all ongoing (active, waiting, held) calls", NULL }, + { "voice-transfer", 0, 0, G_OPTION_ARG_NONE, &transfer_flag, + "Joins active and held calls and disconnects from them", + NULL + }, { NULL } }; @@ -111,7 +116,8 @@ mmcli_modem_voice_options_enabled (void) !!delete_str + hold_and_accept_flag + hangup_and_accept_flag + - hangup_all_flag); + hangup_all_flag + + transfer_flag); if (n_actions > 1) { g_printerr ("error: too many Voice actions requested\n"); @@ -193,6 +199,31 @@ output_call_info (MMCall *call) g_free (extra); } +static void +transfer_process_reply (const GError *error) +{ + if (error) { + g_printerr ("error: couldn't hangup all: '%s'\n", + error->message); + exit (EXIT_FAILURE); + } + + g_print ("operation successful\n"); +} + +static void +transfer_ready (MMModemVoice *modem, + GAsyncResult *result, + gpointer nothing) +{ + GError *error = NULL; + + mm_modem_voice_transfer_finish (modem, result, &error); + transfer_process_reply (error); + + mmcli_async_operation_done (); +} + static void hangup_all_process_reply (const GError *error) { @@ -457,6 +488,16 @@ get_modem_ready (GObject *source, return; } + /* Request to transfer? */ + if (transfer_flag) { + g_debug ("Asynchronously transferring calls..."); + mm_modem_voice_transfer (ctx->modem_voice, + ctx->cancellable, + (GAsyncReadyCallback)transfer_ready, + NULL); + return; + } + g_warn_if_reached (); } @@ -577,5 +618,13 @@ mmcli_modem_voice_run_synchronous (GDBusConnection *connection) return; } + /* Request to transfer? */ + if (transfer_flag) { + g_debug ("Synchronously transferring calls..."); + mm_modem_voice_transfer_sync (ctx->modem_voice, NULL, &error); + transfer_process_reply (error); + return; + } + g_warn_if_reached (); } diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt index be0bdcfe..b1727913 100644 --- a/docs/reference/libmm-glib/libmm-glib-sections.txt +++ b/docs/reference/libmm-glib/libmm-glib-sections.txt @@ -1021,6 +1021,9 @@ mm_modem_voice_hold_and_accept_sync mm_modem_voice_hangup_all mm_modem_voice_hangup_all_finish mm_modem_voice_hangup_all_sync +mm_modem_voice_transfer +mm_modem_voice_transfer_finish +mm_modem_voice_transfer_sync MMModemVoiceClass MMModemVoicePrivate @@ -2853,6 +2856,9 @@ mm_gdbus_modem_voice_call_hold_and_accept_sync mm_gdbus_modem_voice_call_hangup_all mm_gdbus_modem_voice_call_hangup_all_finish mm_gdbus_modem_voice_call_hangup_all_sync +mm_gdbus_modem_voice_call_transfer +mm_gdbus_modem_voice_call_transfer_finish +mm_gdbus_modem_voice_call_transfer_sync mm_gdbus_modem_voice_set_calls mm_gdbus_modem_voice_emit_call_added @@ -2863,6 +2869,7 @@ mm_gdbus_modem_voice_complete_list_calls mm_gdbus_modem_voice_complete_hangup_and_accept mm_gdbus_modem_voice_complete_hold_and_accept mm_gdbus_modem_voice_complete_hangup_all +mm_gdbus_modem_voice_complete_transfer mm_gdbus_modem_voice_interface_info mm_gdbus_modem_voice_override_properties diff --git a/include/ModemManager-enums.h b/include/ModemManager-enums.h index 037aa0c9..15d701e2 100644 --- a/include/ModemManager-enums.h +++ b/include/ModemManager-enums.h @@ -1386,6 +1386,7 @@ typedef enum { /*< underscore_name=mm_call_state >*/ * @MM_CALL_STATE_REASON_REFUSED_OR_BUSY: Remote peer is busy or refused call. * @MM_CALL_STATE_REASON_ERROR: Wrong number or generic network error. * @MM_CALL_STATE_REASON_AUDIO_SETUP_FAILED: Error setting up audio channel. + * @MM_CALL_STATE_REASON_TRANSFERRED: Call has been transferred. Since 1.12. * * Reason for the state change in the call. */ @@ -1397,7 +1398,8 @@ typedef enum { /*< underscore_name=mm_call_state_reason >*/ MM_CALL_STATE_REASON_TERMINATED = 4, MM_CALL_STATE_REASON_REFUSED_OR_BUSY = 5, MM_CALL_STATE_REASON_ERROR = 6, - MM_CALL_STATE_REASON_AUDIO_SETUP_FAILED = 7 + MM_CALL_STATE_REASON_AUDIO_SETUP_FAILED = 7, + MM_CALL_STATE_REASON_TRANSFERRED = 8, } MMCallStateReason; /** diff --git a/introspection/org.freedesktop.ModemManager1.Modem.Voice.xml b/introspection/org.freedesktop.ModemManager1.Modem.Voice.xml index 72674e61..edaba5bc 100644 --- a/introspection/org.freedesktop.ModemManager1.Modem.Voice.xml +++ b/introspection/org.freedesktop.ModemManager1.Modem.Voice.xml @@ -111,6 +111,17 @@ --> + + +