diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2019-07-02 14:30:27 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2019-07-11 23:21:00 +0200 |
commit | 8bc38110c98566955de89b3af57910cedaedbf68 (patch) | |
tree | a8adeafa3a6571e0120407a7942b71b16a17115f /src | |
parent | 73096c0596b6b56dd95081ac0d78b2cc59d53267 (diff) |
base-call: remove in-call event and audio settings logic
The in-call unsolicited events and the in-call audio settings are
managed exclusively at modem level, and no longer at call object
level. This is because these two things are applicable to all calls
that may be active at the same time.
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-base-call.c | 250 | ||||
-rw-r--r-- | src/mm-base-call.h | 22 |
2 files changed, 25 insertions, 247 deletions
diff --git a/src/mm-base-call.c b/src/mm-base-call.c index 9dd30aef..6ff7153d 100644 --- a/src/mm-base-call.c +++ b/src/mm-base-call.c @@ -11,6 +11,7 @@ * GNU General Public License for more details: * * Copyright (C) 2015 Riccardo Vangelisti <riccardo.vangelisti@sadel.it> + * Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es> */ #include <config.h> @@ -61,7 +62,6 @@ struct _MMBaseCallPrivate { gboolean supports_ringing_to_active; guint incoming_timeout; - GRegex *in_call_events; /* The port used for audio while call is ongoing, if known */ MMPort *audio_port; @@ -71,79 +71,6 @@ struct _MMBaseCallPrivate { }; /*****************************************************************************/ -/* In-call unsolicited events - * Once a call is started, we may need to detect special URCs to trigger call - * state changes, e.g. "NO CARRIER" when the remote party hangs up. */ - -static void -in_call_event_received (MMPortSerialAt *port, - GMatchInfo *info, - MMBaseCall *self) -{ - gchar *str; - - str = g_match_info_fetch (info, 1); - if (!str) - return; - - if (!strcmp (str, "NO DIALTONE")) - mm_base_call_change_state (self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_ERROR); - else if (!strcmp (str, "NO CARRIER") || !strcmp (str, "BUSY") || !strcmp (str, "NO ANSWER")) - mm_base_call_change_state (self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_REFUSED_OR_BUSY); - - g_free (str); -} - -static gboolean -common_setup_cleanup_unsolicited_events (MMBaseCall *self, - gboolean enable, - GError **error) -{ - MMBaseModem *modem = NULL; - MMPortSerialAt *ports[2]; - gint i; - - if (G_UNLIKELY (!self->priv->in_call_events)) - self->priv->in_call_events = g_regex_new ("\\r\\n(NO CARRIER|BUSY|NO ANSWER|NO DIALTONE)\\r\\n$", - G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - - g_object_get (self, - MM_BASE_CALL_MODEM, &modem, - NULL); - - ports[0] = mm_base_modem_peek_port_primary (modem); - ports[1] = mm_base_modem_peek_port_secondary (modem); - - for (i = 0; i < G_N_ELEMENTS (ports); i++) { - if (!ports[i]) - continue; - - mm_port_serial_at_add_unsolicited_msg_handler (ports[i], - self->priv->in_call_events, - enable ? (MMPortSerialAtUnsolicitedMsgFn) in_call_event_received : NULL, - enable ? self : NULL, - NULL); - } - - g_object_unref (modem); - return TRUE; -} - -static gboolean -setup_unsolicited_events (MMBaseCall *self, - GError **error) -{ - return common_setup_cleanup_unsolicited_events (self, TRUE, error); -} - -static gboolean -cleanup_unsolicited_events (MMBaseCall *self, - GError **error) -{ - return common_setup_cleanup_unsolicited_events (self, FALSE, error); -} - -/*****************************************************************************/ /* 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 @@ -214,50 +141,6 @@ handle_start_context_free (HandleStartContext *ctx) } static void -call_started (HandleStartContext *ctx) -{ - mm_info ("call is started"); - - /* If dialing to ringing supported, leave it dialing */ - if (!ctx->self->priv->supports_dialing_to_ringing) { - /* If ringing to active supported, set it ringing */ - if (ctx->self->priv->supports_ringing_to_active) - mm_base_call_change_state (ctx->self, MM_CALL_STATE_RINGING_OUT, MM_CALL_STATE_REASON_OUTGOING_STARTED); - else - /* Otherwise, active right away */ - mm_base_call_change_state (ctx->self, MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_OUTGOING_STARTED); - } - mm_gdbus_call_complete_start (MM_GDBUS_CALL (ctx->self), ctx->invocation); - handle_start_context_free (ctx); -} - -static void -start_setup_audio_channel_ready (MMBaseCall *self, - GAsyncResult *res, - HandleStartContext *ctx) -{ - MMPort *audio_port = NULL; - MMCallAudioFormat *audio_format = NULL; - GError *error = NULL; - - if (!MM_BASE_CALL_GET_CLASS (self)->setup_audio_channel_finish (self, res, &audio_port, &audio_format, &error)) { - mm_warn ("Couldn't setup audio channel: '%s'", error->message); - mm_base_call_change_state (self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_AUDIO_SETUP_FAILED); - g_dbus_method_invocation_take_error (ctx->invocation, error); - handle_start_context_free (ctx); - return; - } - - if (audio_port || audio_format) { - mm_base_call_change_audio_settings (self, audio_port, audio_format); - g_clear_object (&audio_port); - g_clear_object (&audio_format); - } - - call_started (ctx); -} - -static void handle_start_ready (MMBaseCall *self, GAsyncResult *res, HandleStartContext *ctx) @@ -280,17 +163,19 @@ handle_start_ready (MMBaseCall *self, return; } - /* If there is an audio setup method, run it now */ - if (MM_BASE_CALL_GET_CLASS (self)->setup_audio_channel) { - mm_info ("setting up audio channel..."); - MM_BASE_CALL_GET_CLASS (self)->setup_audio_channel (self, - (GAsyncReadyCallback) start_setup_audio_channel_ready, - ctx); - return; - } + mm_info ("call is started"); - /* Otherwise, we're done */ - call_started (ctx); + /* If dialing to ringing supported, leave it dialing */ + if (!ctx->self->priv->supports_dialing_to_ringing) { + /* If ringing to active supported, set it ringing */ + if (ctx->self->priv->supports_ringing_to_active) + mm_base_call_change_state (ctx->self, MM_CALL_STATE_RINGING_OUT, MM_CALL_STATE_REASON_OUTGOING_STARTED); + else + /* Otherwise, active right away */ + mm_base_call_change_state (ctx->self, MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_OUTGOING_STARTED); + } + mm_gdbus_call_complete_start (MM_GDBUS_CALL (ctx->self), ctx->invocation); + handle_start_context_free (ctx); } static void @@ -379,46 +264,6 @@ handle_accept_context_free (HandleAcceptContext *ctx) } static void -call_accepted (HandleAcceptContext *ctx) -{ - mm_info ("call is accepted"); - - 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 (ctx->self, MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_ACCEPTED); - mm_gdbus_call_complete_accept (MM_GDBUS_CALL (ctx->self), ctx->invocation); - handle_accept_context_free (ctx); -} - -static void -accept_setup_audio_channel_ready (MMBaseCall *self, - GAsyncResult *res, - HandleAcceptContext *ctx) -{ - MMPort *audio_port = NULL; - MMCallAudioFormat *audio_format = NULL; - GError *error = NULL; - - if (!MM_BASE_CALL_GET_CLASS (self)->setup_audio_channel_finish (self, res, &audio_port, &audio_format, &error)) { - mm_warn ("Couldn't setup audio channel: '%s'", error->message); - mm_base_call_change_state (self, MM_CALL_STATE_TERMINATED, MM_CALL_STATE_REASON_AUDIO_SETUP_FAILED); - g_dbus_method_invocation_take_error (ctx->invocation, error); - handle_accept_context_free (ctx); - return; - } - - if (audio_port || audio_format) { - mm_base_call_change_audio_settings (self, audio_port, audio_format); - g_clear_object (&audio_port); - g_clear_object (&audio_format); - } - - call_accepted (ctx); -} - -static void handle_accept_ready (MMBaseCall *self, GAsyncResult *res, HandleAcceptContext *ctx) @@ -432,17 +277,15 @@ handle_accept_ready (MMBaseCall *self, return; } - /* If there is an audio setup method, run it now */ - if (MM_BASE_CALL_GET_CLASS (self)->setup_audio_channel) { - mm_info ("setting up audio channel..."); - MM_BASE_CALL_GET_CLASS (self)->setup_audio_channel (self, - (GAsyncReadyCallback) accept_setup_audio_channel_ready, - ctx); - return; - } + mm_info ("call is accepted"); - /* Otherwise, we're done */ - call_accepted (ctx); + 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 (ctx->self, MM_CALL_STATE_ACTIVE, MM_CALL_STATE_REASON_ACCEPTED); + mm_gdbus_call_complete_accept (MM_GDBUS_CALL (ctx->self), ctx->invocation); + handle_accept_context_free (ctx); } static void @@ -947,32 +790,12 @@ mm_base_call_set_index (MMBaseCall *self, /*****************************************************************************/ -/* Define the states in which we want to handle in-call events */ -#define MM_CALL_STATE_IS_IN_CALL(state) \ - (state == MM_CALL_STATE_DIALING || \ - state == MM_CALL_STATE_RINGING_IN || \ - state == MM_CALL_STATE_RINGING_OUT || \ - state == MM_CALL_STATE_ACTIVE) - -static void -cleanup_audio_channel_ready (MMBaseCall *self, - GAsyncResult *res) -{ - GError *error = NULL; - - if (!MM_BASE_CALL_GET_CLASS (self)->cleanup_audio_channel_finish (self, res, &error)) { - mm_warn ("audio channel cleanup failed: %s", error->message); - g_error_free (error); - } -} - void mm_base_call_change_state (MMBaseCall *self, MMCallState new_state, MMCallStateReason reason) { - MMCallState old_state; - GError *error = NULL; + MMCallState old_state; old_state = mm_gdbus_call_get_state (MM_GDBUS_CALL (self)); @@ -985,27 +808,7 @@ mm_base_call_change_state (MMBaseCall *self, mm_call_state_reason_get_string (reason)); /* Setup/cleanup unsolicited events based on state transitions to/from ACTIVE */ - if (!MM_CALL_STATE_IS_IN_CALL (old_state) && MM_CALL_STATE_IS_IN_CALL (new_state)) { - mm_dbg ("Setting up in-call unsolicited events..."); - if (MM_BASE_CALL_GET_CLASS (self)->setup_unsolicited_events && - !MM_BASE_CALL_GET_CLASS (self)->setup_unsolicited_events (self, &error)) { - mm_warn ("Couldn't setup in-call unsolicited events: %s", error->message); - g_error_free (error); - } - } else if (MM_CALL_STATE_IS_IN_CALL (old_state) && !MM_CALL_STATE_IS_IN_CALL (new_state)) { - mm_dbg ("Cleaning up in-call unsolicited events..."); - if (MM_BASE_CALL_GET_CLASS (self)->cleanup_unsolicited_events && - !MM_BASE_CALL_GET_CLASS (self)->cleanup_unsolicited_events (self, &error)) { - mm_warn ("Couldn't cleanup in-call unsolicited events: %s", error->message); - g_error_free (error); - } - if (MM_BASE_CALL_GET_CLASS (self)->cleanup_audio_channel) { - mm_info ("cleaning up audio channel..."); - mm_base_call_change_audio_settings (self, NULL, NULL); - MM_BASE_CALL_GET_CLASS (self)->cleanup_audio_channel (self, - (GAsyncReadyCallback) cleanup_audio_channel_ready, - NULL); - } + if (new_state == MM_CALL_STATE_TERMINATED) { /* reset index */ self->priv->index = 0; /* cleanup incoming timeout, if any */ @@ -1020,6 +823,8 @@ mm_base_call_change_state (MMBaseCall *self, mm_gdbus_call_emit_state_changed (MM_GDBUS_CALL (self), old_state, new_state, reason); } +/*****************************************************************************/ + void mm_base_call_received_dtmf (MMBaseCall *self, const gchar *dtmf) @@ -1441,8 +1246,6 @@ finalize (GObject *object) { MMBaseCall *self = MM_BASE_CALL (object); - if (self->priv->in_call_events) - g_regex_unref (self->priv->in_call_events); g_free (self->priv->path); G_OBJECT_CLASS (mm_base_call_parent_class)->finalize (object); @@ -1495,9 +1298,6 @@ mm_base_call_class_init (MMBaseCallClass *klass) klass->hangup_finish = call_hangup_finish; klass->send_dtmf = call_send_dtmf; klass->send_dtmf_finish = call_send_dtmf_finish; - klass->setup_unsolicited_events = setup_unsolicited_events; - klass->cleanup_unsolicited_events = cleanup_unsolicited_events; - properties[PROP_CONNECTION] = g_param_spec_object (MM_BASE_CALL_CONNECTION, diff --git a/src/mm-base-call.h b/src/mm-base-call.h index 888c7871..e858e08f 100644 --- a/src/mm-base-call.h +++ b/src/mm-base-call.h @@ -92,28 +92,6 @@ struct _MMBaseCallClass { gboolean (* send_dtmf_finish) (MMBaseCall *self, GAsyncResult *res, GError **error); - - /* Setup/cleanup in-call unsolicited events */ - gboolean (* setup_unsolicited_events) (MMBaseCall *self, - GError **error); - gboolean (* cleanup_unsolicited_events) (MMBaseCall *self, - GError **error); - - /* Setup/cleanup audio channel */ - void (* setup_audio_channel) (MMBaseCall *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (* setup_audio_channel_finish) (MMBaseCall *self, - GAsyncResult *res, - MMPort **audio_port, - MMCallAudioFormat **audio_format, - GError **error); - void (* cleanup_audio_channel) (MMBaseCall *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (* cleanup_audio_channel_finish) (MMBaseCall *self, - GAsyncResult *res, - GError **error); }; GType mm_base_call_get_type (void); |