diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-base-call.c | 14 | ||||
-rw-r--r-- | src/mm-base-call.h | 9 | ||||
-rw-r--r-- | src/mm-broadband-modem-qmi.c | 6 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 4 | ||||
-rw-r--r-- | src/mm-call-at.c | 73 | ||||
-rw-r--r-- | src/mm-call-at.h | 1 | ||||
-rw-r--r-- | src/mm-call-qmi.c | 21 | ||||
-rw-r--r-- | src/mm-call-qmi.h | 3 | ||||
-rw-r--r-- | src/mm-iface-modem-voice.c | 10 | ||||
-rw-r--r-- | src/mm-iface-modem-voice.h | 3 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 16 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 5 | ||||
-rw-r--r-- | src/plugins/cinterion/mm-shared-cinterion.c | 6 | ||||
-rw-r--r-- | src/plugins/cinterion/mm-shared-cinterion.h | 3 | ||||
-rw-r--r-- | src/plugins/huawei/mm-broadband-modem-huawei.c | 4 | ||||
-rw-r--r-- | src/plugins/ublox/mm-broadband-modem-ublox.c | 4 |
16 files changed, 152 insertions, 30 deletions
diff --git a/src/mm-base-call.c b/src/mm-base-call.c index a59aca85..72982b1d 100644 --- a/src/mm-base-call.c +++ b/src/mm-base-call.c @@ -922,6 +922,20 @@ mm_base_call_set_multiparty (MMBaseCall *self, return mm_gdbus_call_set_multiparty (MM_GDBUS_CALL (self), multiparty); } +guint +mm_base_call_get_dtmf_tone_duration (MMBaseCall *self) +{ + return mm_dtmf_duration_normalize (mm_gdbus_call_get_dtmf_tone_duration (MM_GDBUS_CALL (self))); +} + +void +mm_base_call_set_dtmf_tone_duration (MMBaseCall *self, + guint duration_ms) +{ + return mm_gdbus_call_set_dtmf_tone_duration (MM_GDBUS_CALL (self), + mm_dtmf_duration_normalize (duration_ms)); +} + /*****************************************************************************/ /* Current call index, only applicable while the call is ongoing * See 3GPP TS 22.030 [27], subclause 6.5.5.1. diff --git a/src/mm-base-call.h b/src/mm-base-call.h index a7666145..fb738630 100644 --- a/src/mm-base-call.h +++ b/src/mm-base-call.h @@ -37,6 +37,10 @@ typedef struct _MMBaseCall MMBaseCall; typedef struct _MMBaseCallClass MMBaseCallClass; typedef struct _MMBaseCallPrivate MMBaseCallPrivate; +#define MM_CALL_DIRECTION "direction" +#define MM_CALL_NUMBER "number" +#define MM_CALL_DTMF_TONE_DURATION "dtmf-tone-duration" + #define MM_BASE_CALL_PATH "call-path" #define MM_BASE_CALL_CONNECTION "call-connection" #define MM_BASE_CALL_IFACE_MODEM_VOICE "call-iface-modem-voice" @@ -129,4 +133,9 @@ void mm_base_call_received_dtmf (MMBaseCall *self, void mm_base_call_incoming_refresh (MMBaseCall *self); +guint mm_base_call_get_dtmf_tone_duration (MMBaseCall *self); + +void mm_base_call_set_dtmf_tone_duration (MMBaseCall *self, + guint duration_ms); + #endif /* MM_BASE_CALL_H */ diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index 1b9cf04f..80cf157d 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -12190,11 +12190,13 @@ modem_voice_load_call_list (MMIfaceModemVoice *self, static MMBaseCall * modem_voice_create_call (MMIfaceModemVoice *self, MMCallDirection direction, - const gchar *number) + const gchar *number, + const guint dtmf_tone_duration) { return mm_call_qmi_new (MM_BASE_MODEM (self), direction, - number); + number, + dtmf_tone_duration); } /*****************************************************************************/ diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 3d9cec56..27ac8f56 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -8899,7 +8899,8 @@ modem_voice_disable_unsolicited_events (MMIfaceModemVoice *self, static MMBaseCall * modem_voice_create_call (MMIfaceModemVoice *_self, MMCallDirection direction, - const gchar *number) + const gchar *number, + const guint dtmf_tone_duration) { MMBroadbandModem *self = MM_BROADBAND_MODEM (_self); @@ -8907,6 +8908,7 @@ modem_voice_create_call (MMIfaceModemVoice *_self, G_OBJECT (self), direction, number, + dtmf_tone_duration, /* If +CLCC is supported, we want no incoming timeout. * Also, we're able to support detailed call state updates without * additional vendor-specific commands. */ diff --git a/src/mm-call-at.c b/src/mm-call-at.c index 88bcb349..0a81b929 100644 --- a/src/mm-call-at.c +++ b/src/mm-call-at.c @@ -36,9 +36,18 @@ G_DEFINE_TYPE (MMCallAt, mm_call_at, MM_TYPE_BASE_CALL) +typedef enum { + FEATURE_SUPPORT_UNKNOWN, + FEATURE_NOT_SUPPORTED, + FEATURE_SUPPORTED, +} FeatureSupport; + struct _MMCallAtPrivate { /* The modem which owns this call */ MMBaseModem *modem; + + /* DTMF support */ + FeatureSupport vtd_supported; }; /*****************************************************************************/ @@ -334,26 +343,66 @@ call_send_dtmf_ready (MMBaseModem *modem, } static void +send_dtmf_digit (MMCallAt *self, + GTask *task, + const gchar dtmf_digit) +{ + g_autofree gchar *cmd = NULL; + + cmd = g_strdup_printf ("AT+VTS=%c", dtmf_digit); + mm_base_modem_at_command (self->priv->modem, + cmd, + 3, + FALSE, + (GAsyncReadyCallback)call_send_dtmf_ready, + task); +} + +static void +call_dtmf_vtd_ready (MMBaseModem *modem, + GAsyncResult *res, + GTask *task) +{ + MMCallAt *self; + g_autoptr(GError) error = NULL; + gchar dtmf_digit; + + self = g_task_get_source_object (task); + + mm_base_modem_at_command_finish (modem, res, &error); + self->priv->vtd_supported = error ? FEATURE_NOT_SUPPORTED : FEATURE_SUPPORTED; + + dtmf_digit = (gchar) GPOINTER_TO_UINT (g_task_get_task_data (task)); + send_dtmf_digit (self, task, dtmf_digit); +} + +static void call_send_dtmf (MMBaseCall *_self, const gchar *dtmf, GAsyncReadyCallback callback, gpointer user_data) { - MMCallAt *self = MM_CALL_AT (_self); - GTask *task; - gchar *cmd; + MMCallAt *self = MM_CALL_AT (_self); + GTask *task; + g_autofree gchar *cmd = NULL; task = g_task_new (self, NULL, callback, user_data); - cmd = g_strdup_printf ("AT+VTS=%c", dtmf[0]); + if (self->priv->vtd_supported == FEATURE_NOT_SUPPORTED) { + send_dtmf_digit (self, task, dtmf[0]); + return; + } + + g_task_set_task_data (task, GUINT_TO_POINTER (dtmf[0]), NULL); + + /* Otherwise try to set duration */ + cmd = g_strdup_printf ("AT+VTD=%u", mm_base_call_get_dtmf_tone_duration (_self)); mm_base_modem_at_command (self->priv->modem, cmd, 3, FALSE, - (GAsyncReadyCallback)call_send_dtmf_ready, + (GAsyncReadyCallback)call_dtmf_vtd_ready, task); - - g_free (cmd); } /*****************************************************************************/ @@ -363,6 +412,7 @@ mm_call_at_new (MMBaseModem *modem, GObject *bind_to, MMCallDirection direction, const gchar *number, + const guint dtmf_tone_duration, gboolean skip_incoming_timeout, gboolean supports_dialing_to_ringing, gboolean supports_ringing_to_active) @@ -370,10 +420,11 @@ mm_call_at_new (MMBaseModem *modem, MMBaseCall *call; call = MM_BASE_CALL (g_object_new (MM_TYPE_CALL_AT, - MM_BASE_CALL_IFACE_MODEM_VOICE, modem, - MM_BIND_TO, bind_to, - "direction", direction, - "number", number, + MM_BASE_CALL_IFACE_MODEM_VOICE, modem, + MM_BIND_TO, bind_to, + MM_CALL_DIRECTION, direction, + MM_CALL_NUMBER, number, + MM_CALL_DTMF_TONE_DURATION, dtmf_tone_duration, MM_BASE_CALL_SKIP_INCOMING_TIMEOUT, skip_incoming_timeout, MM_BASE_CALL_SUPPORTS_DIALING_TO_RINGING, supports_dialing_to_ringing, MM_BASE_CALL_SUPPORTS_RINGING_TO_ACTIVE, supports_ringing_to_active, diff --git a/src/mm-call-at.h b/src/mm-call-at.h index e1ae336e..64aed048 100644 --- a/src/mm-call-at.h +++ b/src/mm-call-at.h @@ -53,6 +53,7 @@ MMBaseCall *mm_call_at_new (MMBaseModem *modem, GObject *bind_to, MMCallDirection direction, const gchar *number, + const guint dtmf_tone_duration, gboolean skip_incoming_timeout, gboolean supports_dialing_to_ringing, gboolean supports_ringing_to_active); diff --git a/src/mm-call-qmi.c b/src/mm-call-qmi.c index 55bfa89a..1a9b2dd7 100644 --- a/src/mm-call-qmi.c +++ b/src/mm-call-qmi.c @@ -402,9 +402,12 @@ voice_start_continuous_dtmf_ready (QmiClientVoice *client, GAsyncResult *res, GTask *task) { + MMCallQmi *self; g_autoptr(QmiMessageVoiceStartContinuousDtmfOutput) output = NULL; GError *error = NULL; + self = g_task_get_source_object (task); + output = qmi_client_voice_start_continuous_dtmf_finish (client, res, &error); if (!output) { g_prefix_error (&error, "QMI operation failed: "); @@ -420,8 +423,10 @@ voice_start_continuous_dtmf_ready (QmiClientVoice *client, return; } - /* Disable DTMF press after 500 ms */ - g_timeout_add (500, (GSourceFunc) voice_stop_continuous_dtmf, task); + /* Disable DTMF press after DTMF tone duration elapses */ + g_timeout_add (mm_base_call_get_dtmf_tone_duration (MM_BASE_CALL (self)), + (GSourceFunc) voice_stop_continuous_dtmf, + task); } static void @@ -489,15 +494,17 @@ call_send_dtmf (MMBaseCall *self, MMBaseCall * mm_call_qmi_new (MMBaseModem *modem, MMCallDirection direction, - const gchar *number) + const gchar *number, + const guint dtmf_tone_duration) { MMBaseCall *call; call = MM_BASE_CALL (g_object_new (MM_TYPE_CALL_QMI, - MM_BASE_CALL_IFACE_MODEM_VOICE, modem, - MM_BIND_TO, modem, - "direction", direction, - "number", number, + MM_BASE_CALL_IFACE_MODEM_VOICE, modem, + MM_BIND_TO, modem, + MM_CALL_DIRECTION, direction, + MM_CALL_NUMBER, number, + MM_CALL_DTMF_TONE_DURATION, dtmf_tone_duration, MM_BASE_CALL_SKIP_INCOMING_TIMEOUT, TRUE, MM_BASE_CALL_SUPPORTS_DIALING_TO_RINGING, TRUE, MM_BASE_CALL_SUPPORTS_RINGING_TO_ACTIVE, TRUE, diff --git a/src/mm-call-qmi.h b/src/mm-call-qmi.h index 34231bcc..f99e7e10 100644 --- a/src/mm-call-qmi.h +++ b/src/mm-call-qmi.h @@ -49,6 +49,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMCallQmi, g_object_unref) MMBaseCall *mm_call_qmi_new (MMBaseModem *modem, MMCallDirection direction, - const gchar *number); + const gchar *number, + const guint dtmf_tone_duration); #endif /* MM_CALL_QMI_H */ diff --git a/src/mm-iface-modem-voice.c b/src/mm-iface-modem-voice.c index 2ce0ec6b..0bba2a34 100644 --- a/src/mm-iface-modem-voice.c +++ b/src/mm-iface-modem-voice.c @@ -161,7 +161,7 @@ create_incoming_call (MMIfaceModemVoice *self, g_assert (MM_IFACE_MODEM_VOICE_GET_IFACE (self)->create_call != NULL); - call = MM_IFACE_MODEM_VOICE_GET_IFACE (self)->create_call (self, MM_CALL_DIRECTION_INCOMING, number); + call = MM_IFACE_MODEM_VOICE_GET_IFACE (self)->create_call (self, MM_CALL_DIRECTION_INCOMING, number, 0); update_audio_settings_in_call (self, call); return call; } @@ -173,6 +173,7 @@ create_outgoing_call_from_properties (MMIfaceModemVoice *self, { MMBaseCall *call; const gchar *number; + guint dtmf_tone_duration; /* Don't create CALL from properties if either number is missing */ number = mm_call_properties_get_number (properties) ; @@ -184,9 +185,14 @@ create_outgoing_call_from_properties (MMIfaceModemVoice *self, return NULL; } + dtmf_tone_duration = mm_call_properties_get_dtmf_tone_duration (properties) ; + /* Create a call object as defined by the interface */ g_assert (MM_IFACE_MODEM_VOICE_GET_IFACE (self)->create_call != NULL); - call = MM_IFACE_MODEM_VOICE_GET_IFACE (self)->create_call (self, MM_CALL_DIRECTION_OUTGOING, number); + call = MM_IFACE_MODEM_VOICE_GET_IFACE (self)->create_call (self, + MM_CALL_DIRECTION_OUTGOING, + number, + dtmf_tone_duration); update_audio_settings_in_call (self, call); return call; } diff --git a/src/mm-iface-modem-voice.h b/src/mm-iface-modem-voice.h index 2d8b5160..716988d5 100644 --- a/src/mm-iface-modem-voice.h +++ b/src/mm-iface-modem-voice.h @@ -123,7 +123,8 @@ struct _MMIfaceModemVoiceInterface { /* Create call objects */ MMBaseCall * (* create_call) (MMIfaceModemVoice *self, MMCallDirection direction, - const gchar *number); + const gchar *number, + const guint dtmf_tone_duration); /* Hold and accept */ void (* hold_and_accept) (MMIfaceModemVoice *self, diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index a79ca956..0e258e61 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -5871,3 +5871,19 @@ mm_parse_cpin_response (const gchar *response, return MM_MODEM_LOCK_UNKNOWN; } + +/*****************************************************************************/ + +guint +mm_dtmf_duration_normalize (guint duration_ms) +{ + /* Default to 500ms */ + if (duration_ms == 0) + return 500; + + /* round to next highest 100ms */ + if (duration_ms % 100) + duration_ms = ((duration_ms + 100) / 100) * 100; + + return CLAMP (duration_ms, 100, 1000); +} diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index eb62a551..74626c90 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -643,4 +643,9 @@ guint mm_string_uint_map_lookup (const MMStringUintMap *map, MMModemLock mm_parse_cpin_response (const gchar *response, gboolean expect_cpin_prefix); +/*****************************************************************************/ + +/* Helper to clamp duration and round to next 100ms */ +guint mm_dtmf_duration_normalize (guint duration_ms); + #endif /* MM_MODEM_HELPERS_H */ diff --git a/src/plugins/cinterion/mm-shared-cinterion.c b/src/plugins/cinterion/mm-shared-cinterion.c index 60bbe6db..aa9b6208 100644 --- a/src/plugins/cinterion/mm-shared-cinterion.c +++ b/src/plugins/cinterion/mm-shared-cinterion.c @@ -998,7 +998,8 @@ mm_shared_cinterion_enable_location_gathering (MMIfaceModemLocation *self, MMBaseCall * mm_shared_cinterion_create_call (MMIfaceModemVoice *self, MMCallDirection direction, - const gchar *number) + const gchar *number, + const guint dtmf_tone_duration) { Private *priv; @@ -1010,6 +1011,7 @@ mm_shared_cinterion_create_call (MMIfaceModemVoice *self, G_OBJECT (self), direction, number, + dtmf_tone_duration, /* When SLCC is supported we have support for detailed * call list events via call list report URCs */ TRUE, /* incoming timeout not required */ @@ -1020,7 +1022,7 @@ mm_shared_cinterion_create_call (MMIfaceModemVoice *self, /* otherwise, run parent's generic base call logic */ g_assert (priv->iface_modem_voice_parent); g_assert (priv->iface_modem_voice_parent->create_call); - return priv->iface_modem_voice_parent->create_call (self, direction, number); + return priv->iface_modem_voice_parent->create_call (self, direction, number, dtmf_tone_duration); } /*****************************************************************************/ diff --git a/src/plugins/cinterion/mm-shared-cinterion.h b/src/plugins/cinterion/mm-shared-cinterion.h index f330e328..146ae96a 100644 --- a/src/plugins/cinterion/mm-shared-cinterion.h +++ b/src/plugins/cinterion/mm-shared-cinterion.h @@ -105,7 +105,8 @@ gboolean mm_shared_cinterion_disable_location_gathering_finish (MMI MMBaseCall *mm_shared_cinterion_create_call (MMIfaceModemVoice *self, MMCallDirection direction, - const gchar *number); + const gchar *number, + const guint dtmf_tone_duration); void mm_shared_cinterion_voice_check_support (MMIfaceModemVoice *self, GAsyncReadyCallback callback, diff --git a/src/plugins/huawei/mm-broadband-modem-huawei.c b/src/plugins/huawei/mm-broadband-modem-huawei.c index 76180a76..5de6c4d5 100644 --- a/src/plugins/huawei/mm-broadband-modem-huawei.c +++ b/src/plugins/huawei/mm-broadband-modem-huawei.c @@ -3879,12 +3879,14 @@ modem_voice_disable_unsolicited_events (MMIfaceModemVoice *self, static MMBaseCall * create_call (MMIfaceModemVoice *self, MMCallDirection direction, - const gchar *number) + const gchar *number, + const guint dtmf_tone_duration) { return mm_call_at_new (MM_BASE_MODEM (self), G_OBJECT (self), direction, number, + dtmf_tone_duration, TRUE, /* skip_incoming_timeout */ TRUE, /* supports_dialing_to_ringing */ TRUE); /* supports_ringing_to_active) */ diff --git a/src/plugins/ublox/mm-broadband-modem-ublox.c b/src/plugins/ublox/mm-broadband-modem-ublox.c index 4213480e..ab049024 100644 --- a/src/plugins/ublox/mm-broadband-modem-ublox.c +++ b/src/plugins/ublox/mm-broadband-modem-ublox.c @@ -1504,12 +1504,14 @@ modem_voice_setup_unsolicited_events (MMIfaceModemVoice *self, static MMBaseCall * create_call (MMIfaceModemVoice *self, MMCallDirection direction, - const gchar *number) + const gchar *number, + const guint dtmf_tone_duration) { return mm_call_at_new (MM_BASE_MODEM (self), G_OBJECT (self), direction, number, + dtmf_tone_duration, TRUE, /* skip_incoming_timeout */ TRUE, /* supports_dialing_to_ringing */ TRUE); /* supports_ringing_to_active */ |