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 @@ --> + + +