aboutsummaryrefslogtreecommitdiff
path: root/src/mm-call-at.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-call-at.c')
-rw-r--r--src/mm-call-at.c73
1 files changed, 62 insertions, 11 deletions
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,