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:
parent
dd815fa86f
commit
443613991c
2 changed files with 103 additions and 10 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue