aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-base-call.c45
-rw-r--r--src/mm-base-call.h20
-rw-r--r--src/mm-broadband-modem.c4
-rw-r--r--src/mm-call-list.c29
-rw-r--r--src/mm-call-list.h12
-rw-r--r--src/mm-iface-modem-voice.c53
-rw-r--r--src/mm-iface-modem-voice.h2
7 files changed, 108 insertions, 57 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 */
diff --git a/src/mm-base-call.h b/src/mm-base-call.h
index da31a9b9..5b8c06c6 100644
--- a/src/mm-base-call.h
+++ b/src/mm-base-call.h
@@ -97,13 +97,17 @@ MMBaseCall *mm_base_call_new_from_properties (MMBaseModem *modem,
MMCallProperties *properties,
GError **error);
-void mm_base_call_export (MMBaseCall *self);
-void mm_base_call_unexport (MMBaseCall *self);
-const gchar *mm_base_call_get_path (MMBaseCall *self);
-void mm_base_call_change_state (MMBaseCall *self,
- MMCallState new_state,
- MMCallStateReason reason);
-void mm_base_call_received_dtmf (MMBaseCall *self,
- const gchar *dtmf);
+void mm_base_call_export (MMBaseCall *self);
+void mm_base_call_unexport (MMBaseCall *self);
+const gchar *mm_base_call_get_path (MMBaseCall *self);
+
+void mm_base_call_change_state (MMBaseCall *self,
+ MMCallState new_state,
+ MMCallStateReason reason);
+
+void mm_base_call_received_dtmf (MMBaseCall *self,
+ const gchar *dtmf);
+
+void mm_base_call_incoming_refresh (MMBaseCall *self);
#endif /* MM_BASE_CALL_H */
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c
index 7b11cd43..93a3a3e0 100644
--- a/src/mm-broadband-modem.c
+++ b/src/mm-broadband-modem.c
@@ -6928,7 +6928,7 @@ ring_received (MMPortSerialAt *port,
MMBroadbandModem *self)
{
mm_dbg ("Ringing");
- mm_iface_modem_voice_create_incoming_call (MM_IFACE_MODEM_VOICE (self));
+ mm_iface_modem_voice_incoming_call (MM_IFACE_MODEM_VOICE (self));
}
static void
@@ -6945,7 +6945,7 @@ cring_received (MMPortSerialAt *port,
mm_dbg ("Ringing (%s)", str);
g_free (str);
- mm_iface_modem_voice_create_incoming_call (MM_IFACE_MODEM_VOICE (self));
+ mm_iface_modem_voice_incoming_call (MM_IFACE_MODEM_VOICE (self));
}
static void
diff --git a/src/mm-call-list.c b/src/mm-call-list.c
index b1950e3a..91ccc8d0 100644
--- a/src/mm-call-list.c
+++ b/src/mm-call-list.c
@@ -84,36 +84,33 @@ mm_call_list_get_paths (MMCallList *self)
/*****************************************************************************/
MMBaseCall *
-mm_call_list_get_new_incoming (MMCallList *self)
+mm_call_list_get_first_ringing_in_call (MMCallList *self)
{
- MMBaseCall *call = NULL;
GList *l;
for (l = self->priv->list; l; l = g_list_next (l)) {
-
+ MMBaseCall *call;
MMCallState state;
- MMCallStateReason reason;
- MMCallDirection direct;
+ MMCallDirection direction;
- g_object_get (MM_BASE_CALL (l->data),
- "state", &state,
- "state-reason", &reason,
- "direction", &direct,
+ call = MM_BASE_CALL (l->data);
+
+ g_object_get (call,
+ "state", &state,
+ "direction", &direction,
NULL);
- if (direct == MM_CALL_DIRECTION_INCOMING &&
- state == MM_CALL_STATE_RINGING_IN &&
- reason == MM_CALL_STATE_REASON_INCOMING_NEW ) {
- call = MM_BASE_CALL (l->data);
- break;
+ if (direction == MM_CALL_DIRECTION_INCOMING &&
+ state == MM_CALL_STATE_RINGING_IN) {
+ return call;
}
}
- return call;
+ return NULL;
}
MMBaseCall *
-mm_call_list_get_first_ringing_call (MMCallList *self)
+mm_call_list_get_first_ringing_out_call (MMCallList *self)
{
MMBaseCall *call = NULL;
GList *l;
diff --git a/src/mm-call-list.h b/src/mm-call-list.h
index 1c668500..53102d06 100644
--- a/src/mm-call-list.h
+++ b/src/mm-call-list.h
@@ -68,11 +68,11 @@ gboolean mm_call_list_delete_call (MMCallList *self,
const gchar *call_path,
GError **error);
-MMBaseCall *mm_call_list_get_new_incoming (MMCallList *self);
-MMBaseCall *mm_call_list_get_first_ringing_call (MMCallList *self);
-MMBaseCall *mm_call_list_get_first_outgoing_dialing_call(MMCallList *self);
-MMBaseCall *mm_call_list_get_first_non_terminated_call (MMCallList *self);
-gboolean mm_call_list_send_dtmf_to_active_calls (MMCallList *self,
- const gchar *dtmf);
+MMBaseCall *mm_call_list_get_first_ringing_in_call (MMCallList *self);
+MMBaseCall *mm_call_list_get_first_ringing_out_call (MMCallList *self);
+MMBaseCall *mm_call_list_get_first_outgoing_dialing_call (MMCallList *self);
+MMBaseCall *mm_call_list_get_first_non_terminated_call (MMCallList *self);
+gboolean mm_call_list_send_dtmf_to_active_calls (MMCallList *self,
+ const gchar *dtmf);
#endif /* MM_CALL_LIST_H */
diff --git a/src/mm-iface-modem-voice.c b/src/mm-iface-modem-voice.c
index 844b8310..9cab1cdd 100644
--- a/src/mm-iface-modem-voice.c
+++ b/src/mm-iface-modem-voice.c
@@ -46,8 +46,8 @@ mm_iface_modem_voice_create_call (MMIfaceModemVoice *self)
return MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->create_call (self);
}
-MMBaseCall *
-mm_iface_modem_voice_create_incoming_call (MMIfaceModemVoice *self)
+void
+mm_iface_modem_voice_incoming_call (MMIfaceModemVoice *self)
{
MMBaseCall *call = NULL;
MMCallList *list = NULL;
@@ -56,29 +56,36 @@ mm_iface_modem_voice_create_incoming_call (MMIfaceModemVoice *self)
MM_IFACE_MODEM_VOICE_CALL_LIST, &list,
NULL);
- if (list) {
- call = mm_call_list_get_new_incoming (list);
-
- if (!call) {
- mm_dbg ("Creating new incoming call...");
-
- call = mm_base_call_new (MM_BASE_MODEM (self));
- g_object_set (call,
- "state", MM_CALL_STATE_RINGING_IN,
- "state-reason", MM_CALL_STATE_REASON_INCOMING_NEW,
- "direction", MM_CALL_DIRECTION_INCOMING,
- NULL);
-
- /* Only export once properly created */
- mm_base_call_export (call);
- mm_call_list_add_call (list, call);
- g_object_unref (call);
- }
+ if (!list) {
+ mm_warn ("Cannot create incoming call: missing call list");
+ return;
+ }
+
+ call = mm_call_list_get_first_ringing_in_call (list);
+ /* If call exists already, refresh its validity */
+ if (call) {
+ mm_base_call_incoming_refresh (call);
g_object_unref (list);
+ return;
}
- return call;
+ mm_dbg ("Creating new incoming call...");
+ call = mm_base_call_new (MM_BASE_MODEM (self));
+ g_object_set (call,
+ "state", MM_CALL_STATE_RINGING_IN,
+ "state-reason", MM_CALL_STATE_REASON_INCOMING_NEW,
+ "direction", MM_CALL_DIRECTION_INCOMING,
+ NULL);
+
+ /* Start its validity timeout */
+ mm_base_call_incoming_refresh (call);
+
+ /* Only export once properly created */
+ mm_base_call_export (call);
+ mm_call_list_add_call (list, call);
+ g_object_unref (call);
+ g_object_unref (list);
}
gboolean
@@ -96,7 +103,7 @@ mm_iface_modem_voice_update_incoming_call_number (MMIfaceModemVoice *self,
NULL);
if (list) {
- call = mm_call_list_get_new_incoming (list);
+ call = mm_call_list_get_first_ringing_in_call (list);
if (call) {
mm_gdbus_call_set_number (MM_GDBUS_CALL (call), number);
@@ -153,7 +160,7 @@ mm_iface_modem_voice_call_ringing_to_active (MMIfaceModemVoice *self)
NULL);
if (list) {
- call = mm_call_list_get_first_ringing_call (list);
+ call = mm_call_list_get_first_ringing_out_call (list);
if (call) {
mm_base_call_change_state (call, MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_ACCEPTED);
diff --git a/src/mm-iface-modem-voice.h b/src/mm-iface-modem-voice.h
index e182060a..229ebb5d 100644
--- a/src/mm-iface-modem-voice.h
+++ b/src/mm-iface-modem-voice.h
@@ -118,7 +118,7 @@ void mm_iface_modem_voice_bind_simple_status (MMIfaceModemVoice *self,
/* CALL creation */
MMBaseCall *mm_iface_modem_voice_create_call (MMIfaceModemVoice *self);
-MMBaseCall *mm_iface_modem_voice_create_incoming_call (MMIfaceModemVoice *self);
+void mm_iface_modem_voice_incoming_call (MMIfaceModemVoice *self);
gboolean mm_iface_modem_voice_update_incoming_call_number (MMIfaceModemVoice *self,
gchar *number,
guint type,