aboutsummaryrefslogtreecommitdiff
path: root/src/mm-base-call.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2018-06-14 15:36:06 +0200
committerDan Williams <dcbw@redhat.com>2018-10-16 17:09:21 +0000
commitbd3b5aca01a3d3102c607b7ca6fab310963ec77c (patch)
tree12f0701ab5575a6aa198f54ba97bbd65298e6763 /src/mm-base-call.c
parent0090124ec0d0d28fa78f5a0dd153e36584a0f171 (diff)
base-call: automatically terminate unanswered incoming calls
Try to automatically detect when the caller finishes the attempt to establish the call.
Diffstat (limited to 'src/mm-base-call.c')
-rw-r--r--src/mm-base-call.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/mm-base-call.c b/src/mm-base-call.c
index ab63a1d7..dfbdb702 100644
--- a/src/mm-base-call.c
+++ b/src/mm-base-call.c
@@ -57,9 +57,38 @@ struct _MMBaseCallPrivate {
/* Features */
gboolean supports_dialing_to_ringing;
gboolean supports_ringing_to_active;
+
+ guint incoming_timeout;
};
/*****************************************************************************/
+/* Incoming calls are reported via RING URCs. If the caller stops the call
+ * attempt before it has been answered, the only thing we would see is that the
+ * URCs are no longer received. So, we will start a timeout whenever a new RING
+ * URC is received, and we refresh the timeout any time a new URC arrives. If
+ * the timeout is expired (meaning no URCs were received in the last N seconds)
+ * then we assume the call attempt is finished and we transition to TERMINATED.
+ */
+
+#define INCOMING_TIMEOUT_SECS 5
+
+static gboolean
+incoming_timeout_cb (MMBaseCall *self)
+{
+ self->priv->incoming_timeout = 0;
+ mm_base_call_change_state (self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_TERMINATED);
+ return G_SOURCE_REMOVE;
+}
+
+void
+mm_base_call_incoming_refresh (MMBaseCall *self)
+{
+ if (self->priv->incoming_timeout)
+ g_source_remove (self->priv->incoming_timeout);
+ self->priv->incoming_timeout = g_timeout_add_seconds (INCOMING_TIMEOUT_SECS, (GSourceFunc)incoming_timeout_cb, self);
+}
+
+/*****************************************************************************/
/* Start call (DBus call handling) */
typedef struct {
@@ -205,6 +234,10 @@ handle_accept_ready (MMBaseCall *self,
mm_base_call_change_state (self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_ERROR);
g_dbus_method_invocation_take_error (ctx->invocation, error);
} else {
+ if (ctx->self->priv->incoming_timeout) {
+ g_source_remove (ctx->self->priv->incoming_timeout);
+ ctx->self->priv->incoming_timeout = 0;
+ }
mm_base_call_change_state (self, MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_ACCEPTED);
mm_gdbus_call_complete_accept (MM_GDBUS_CALL (ctx->self), ctx->invocation);
}
@@ -305,8 +338,13 @@ handle_hangup_ready (MMBaseCall *self,
if (!MM_BASE_CALL_GET_CLASS (self)->hangup_finish (self, res, &error))
g_dbus_method_invocation_take_error (ctx->invocation, error);
- else
+ else {
+ if (ctx->self->priv->incoming_timeout) {
+ g_source_remove (ctx->self->priv->incoming_timeout);
+ ctx->self->priv->incoming_timeout = 0;
+ }
mm_gdbus_call_complete_hangup (MM_GDBUS_CALL (ctx->self), ctx->invocation);
+ }
handle_hangup_context_free (ctx);
}
@@ -963,6 +1001,11 @@ dispose (GObject *object)
{
MMBaseCall *self = MM_BASE_CALL (object);
+ if (self->priv->incoming_timeout) {
+ g_source_remove (self->priv->incoming_timeout);
+ self->priv->incoming_timeout = 0;
+ }
+
if (self->priv->connection) {
/* If we arrived here with a valid connection, make sure we unexport
* the object */