1
0
Fork 0
mirror of https://gitlab.gnome.org/GNOME/calls.git synced 2024-12-04 20:07:36 +00:00

ofono-{call,origin}: Send DTMF tones for active calls

The oFono DTMF support doesn't match our model; you can only send
tones to the network and not to a particular call.  The telephony
standards dictate that only a single call can be active at a time so
we just get the call to emit a "tone" signal if the call is in the
active state and get the origin to listen for the signal.
This commit is contained in:
Bob Ham 2018-05-31 10:43:10 +00:00
parent dd815fa86f
commit 443613991c
2 changed files with 103 additions and 10 deletions

View file

@ -57,6 +57,12 @@ enum {
};
static GParamSpec *props[PROP_LAST_PROP];
enum {
SIGNAL_TONE,
SIGNAL_LAST_SIGNAL,
};
static guint signals [SIGNAL_LAST_SIGNAL];
#define DEFINE_GET_BODY(member) \
get_##member (CallsCall *iface) \
@ -154,14 +160,15 @@ hang_up (CallsCall *call)
static void
tone_start (CallsCall *call, gchar key)
{
g_info ("Beep! (%c)", (int)key);
}
CallsOfonoCall *self = CALLS_OFONO_CALL (call);
if (self->state != CALLS_CALL_STATE_ACTIVE)
{
g_warning ("Tone start requested for non-active call to `%s'",
self->number);
return;
}
static void
tone_stop (CallsCall *call, gchar key)
{
g_info ("Beep end (%c)", (int)key);
g_signal_emit_by_name (self, "tone", key);
}
@ -308,6 +315,7 @@ static void
calls_ofono_call_class_init (CallsOfonoCallClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GType tone_arg_types = G_TYPE_CHAR;
object_class->set_property = set_property;
object_class->constructed = constructed;
@ -330,6 +338,15 @@ calls_ofono_call_class_init (CallsOfonoCallClass *klass)
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_properties (object_class, PROP_LAST_PROP, props);
signals[SIGNAL_TONE] =
g_signal_newv ("tone",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
NULL, NULL, NULL, NULL,
G_TYPE_NONE,
1, &tone_arg_types);
}
@ -348,7 +365,6 @@ calls_ofono_call_call_interface_init (CallsCallInterface *iface)
iface->answer = answer;
iface->hang_up = hang_up;
iface->tone_start = tone_start;
iface->tone_stop = tone_stop;
}

View file

@ -37,6 +37,8 @@ struct _CallsOfonoOrigin
GDBOModem *modem;
gchar *name;
GDBOVoiceCallManager *voice;
gboolean sending_tones;
GString *tone_queue;
GHashTable *calls;
};
@ -210,6 +212,78 @@ struct CallsVoiceCallProxyNewData
};
static void
send_tones_cb (GDBOVoiceCallManager *voice,
GAsyncResult *res,
CallsOfonoOrigin *self)
{
gboolean ok;
GError *error = NULL;
/* Deal with old tones */
ok = gdbo_voice_call_manager_call_send_tones_finish
(voice, res, &error);
if (!ok)
{
g_warning ("Error sending DTMF tones to network on modem `%s': %s",
self->name, error->message);
CALLS_EMIT_MESSAGE (self, error->message, GTK_MESSAGE_WARNING);
}
/* Possibly send new tones */
if (self->tone_queue)
{
g_debug ("Sending queued DTMF tones `%s'", self->tone_queue->str);
gdbo_voice_call_manager_call_send_tones
(voice,
self->tone_queue->str,
NULL,
(GAsyncReadyCallback) send_tones_cb,
self);
g_string_free (self->tone_queue, TRUE);
self->tone_queue = NULL;
}
else
{
self->sending_tones = FALSE;
}
}
static void
tone_cb (CallsOfonoOrigin *self,
gchar key)
{
const gchar key_str[2] = { key, '\0' };
if (self->sending_tones)
{
if (self->tone_queue)
{
g_string_append_c (self->tone_queue, key);
}
else
{
self->tone_queue = g_string_new (key_str);
}
}
else
{
g_debug ("Sending immediate DTMF tone `%c'", key);
gdbo_voice_call_manager_call_send_tones
(self->voice,
key_str,
NULL,
(GAsyncReadyCallback) send_tones_cb,
self);
self->sending_tones = TRUE;
}
}
static void
voice_call_proxy_new_cb (GDBusConnection *connection,
GAsyncResult *res,
@ -233,6 +307,8 @@ voice_call_proxy_new_cb (GDBusConnection *connection,
}
call = calls_ofono_call_new (voice_call, data->properties);
g_signal_connect_swapped (call, "tone",
G_CALLBACK (tone_cb), self);
path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (voice_call));
g_hash_table_insert (self->calls, g_strdup(path), call);
@ -447,10 +523,11 @@ finalize (GObject *object)
GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
CallsOfonoOrigin *self = CALLS_OFONO_ORIGIN (object);
if (self->name)
if (self->tone_queue)
{
g_free (self->name);
g_string_free (self->tone_queue, TRUE);
}
CALLS_FREE_PTR_PROPERTY (self->name);
parent_class->finalize (object);
}