diff options
-rw-r--r-- | src/mm-broadband-modem.c | 59 | ||||
-rw-r--r-- | src/mm-call-list.c | 59 | ||||
-rw-r--r-- | src/mm-call-list.h | 3 | ||||
-rw-r--r-- | src/mm-iface-modem-voice.c | 104 | ||||
-rw-r--r-- | src/mm-iface-modem-voice.h | 8 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 26 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 8 |
7 files changed, 258 insertions, 9 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 720ef62c..a3e69c08 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -6285,7 +6285,7 @@ ring_received (MMPortSerialAt *port, //Do not match anything from regex (void)info; - mm_iface_modem_voice_create_call(MM_IFACE_MODEM_VOICE(self)); + mm_iface_modem_voice_create_incoming_call(MM_IFACE_MODEM_VOICE(self)); } static void @@ -6293,14 +6293,47 @@ cring_received (MMPortSerialAt *port, GMatchInfo *info, MMBroadbandModem *self) { - gchar *str; - /* The match info gives us in which storage the index applies */ - str = mm_get_string_unquoted_from_match_info (info, 1); + gchar *str = mm_get_string_unquoted_from_match_info (info, 1); //TODO: In str you could have "VOICE" or "DATA". Now consider only "VOICE" g_free (str); - mm_iface_modem_voice_create_call(MM_IFACE_MODEM_VOICE(self)); + mm_iface_modem_voice_create_incoming_call(MM_IFACE_MODEM_VOICE(self)); +} + +static void +clip_received (MMPortSerialAt *port, + GMatchInfo *info, + MMBroadbandModem *self) +{ + /* The match info gives us in which storage the index applies */ + gchar *str = mm_get_string_unquoted_from_match_info (info, 1); + + if( !str ) { + guint validity = 0; + guint type = 0; + + mm_get_uint_from_match_info (info, 2, &type); + mm_get_uint_from_match_info (info, 3, &validity); + + mm_dbg ("[%s:%d] CLIP regex => number:'%s', type:'%d', validity:'%d'", __func__, __LINE__, str, type, validity); + + mm_iface_modem_voice_update_incoming_call_number(MM_IFACE_MODEM_VOICE(self), str, type, validity); + + g_free(str); + } +} + +static void +nocarrier_received (MMPortSerialAt *port, + GMatchInfo *info, + MMBroadbandModem *self) +{ + //Do not match anything from regex + (void)info; + + mm_dbg ("[%s:%d]", __func__, __LINE__); + mm_iface_modem_voice_network_hangup(MM_IFACE_MODEM_VOICE(self)); } static void @@ -6344,8 +6377,10 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, { GSimpleAsyncResult *result; MMPortSerialAt *ports[2]; + GRegex *nocarrier_regex; GRegex *cring_regex; GRegex *ring_regex; + GRegex *clip_regex; GRegex *dtmf_regex; guint i; @@ -6354,8 +6389,10 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, user_data, set_voice_unsolicited_events_handlers); + nocarrier_regex = mm_voice_nocarrier_regex_get (); cring_regex = mm_voice_cring_regex_get (); ring_regex = mm_voice_ring_regex_get (); + clip_regex = mm_voice_clip_regex_get (); dtmf_regex = mm_voice_dtmf_regex_get (); ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); @@ -6383,6 +6420,18 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, NULL); mm_port_serial_at_add_unsolicited_msg_handler ( ports[i], + clip_regex, + enable ? (MMPortSerialAtUnsolicitedMsgFn) clip_received : NULL, + enable ? self : NULL, + NULL); + mm_port_serial_at_add_unsolicited_msg_handler ( + ports[i], + nocarrier_regex, + enable ? (MMPortSerialAtUnsolicitedMsgFn) nocarrier_received : NULL, + enable ? self : NULL, + NULL); + mm_port_serial_at_add_unsolicited_msg_handler ( + ports[i], dtmf_regex, enable ? (MMPortSerialAtUnsolicitedMsgFn) dtmf_received : NULL, enable ? self : NULL, diff --git a/src/mm-call-list.c b/src/mm-call-list.c index 76af785b..aa650058 100644 --- a/src/mm-call-list.c +++ b/src/mm-call-list.c @@ -84,6 +84,65 @@ mm_call_list_get_paths (MMCallList *self) /*****************************************************************************/ +MMBaseCall* mm_call_list_get_new_incoming(MMCallList *self) +{ + MMBaseCall *call = NULL; + GList *l; + guint i; + + for (i = 0, l = self->priv->list; l && !call; l = g_list_next (l)) { + + MMCallState state; + MMCallStateReason reason; + MMCallDirection direct; + + g_object_get (MM_BASE_CALL (l->data), + "state" , &state, + "state-reason", &reason, + "direction" , &direct, + 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; + } + } + + return call; +} + +MMBaseCall* mm_call_list_get_first_non_terminated_call(MMCallList *self) +{ + MMBaseCall *call = NULL; + GList *l; + guint i; + + for (i = 0, l = self->priv->list; l && !call; l = g_list_next (l)) { + + MMCallState state; + MMCallStateReason reason; + MMCallDirection direct; + + g_object_get (MM_BASE_CALL (l->data), + "state" , &state, + "state-reason", &reason, + "direction" , &direct, + NULL); + + if( state != MM_CALL_STATE_TERMINATED ) { + call = MM_BASE_CALL (l->data); + break; + } + } + + return call; +} + +/*****************************************************************************/ + typedef struct { MMCallList *self; GSimpleAsyncResult *result; diff --git a/src/mm-call-list.h b/src/mm-call-list.h index e3c2a65f..7d47e49c 100644 --- a/src/mm-call-list.h +++ b/src/mm-call-list.h @@ -72,4 +72,7 @@ gboolean mm_call_list_delete_call_finish (MMCallList *self, GAsyncResult *res, GError **error); +MMBaseCall* mm_call_list_get_new_incoming (MMCallList *self); +MMBaseCall* mm_call_list_get_first_non_terminated_call (MMCallList *self); + #endif /* MM_CALL_LIST_H */ diff --git a/src/mm-iface-modem-voice.c b/src/mm-iface-modem-voice.c index 990ebee4..6b896dbd 100644 --- a/src/mm-iface-modem-voice.c +++ b/src/mm-iface-modem-voice.c @@ -46,6 +46,110 @@ mm_iface_modem_voice_create_call (MMIfaceModemVoice *self) return MM_IFACE_MODEM_VOICE_GET_INTERFACE (self)->create_call (self); } +//BASCETTA:TODO: bisogna aggiungere la gestione degli errori. +MMBaseCall * +mm_iface_modem_voice_create_incoming_call (MMIfaceModemVoice *self) +{ + MMBaseCall *call = NULL; + MMCallList *list = NULL; + + g_object_get (MM_BASE_MODEM (self), + MM_IFACE_MODEM_VOICE_CALL_LIST, &list, + NULL); + + if( list ) { + + call = mm_call_list_get_new_incoming(list); + if( !call ) { + + mm_dbg("[%s:%d] Incoming call does not exist; create it", __func__, __LINE__); + + 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_dbg ("[%s:%d] New call exported to DBUS", __func__, __LINE__); + + mm_call_list_add_call(list, call); + mm_dbg ("[%s:%d] Call added to list", __func__, __LINE__); + + } else { +// mm_dbg("[%s:%d] Incoming call already exist. Do nothing", __func__, __LINE__); + } + + g_object_unref (list); + } + + return call; +} + +gboolean mm_iface_modem_voice_update_incoming_call_number (MMIfaceModemVoice *self, gchar *number, guint type, guint validity) +{ + gboolean updated = FALSE; + MMBaseCall *call = NULL; + MMCallList *list = NULL; + + g_object_get (MM_BASE_MODEM (self), + MM_IFACE_MODEM_VOICE_CALL_LIST, &list, + NULL); + + if( list ) { + + call = mm_call_list_get_new_incoming(list); + if( call ) { + g_object_set (call, "number", number, NULL); + mm_gdbus_call_set_number(MM_GDBUS_CALL (call), number); + + //TODO: Maybe also this parameters should be used + (void)type; + (void)validity; + + updated = TRUE; + } else { + mm_dbg("[%s:%d] Incoming call does not exist yet", __func__, __LINE__); + } + } + + return updated; +} + +gboolean mm_iface_modem_voice_network_hangup (MMIfaceModemVoice *self) +{ + gboolean updated = FALSE; + MMBaseCall *call = NULL; + MMCallList *list = NULL; + + g_object_get (MM_BASE_MODEM (self), + MM_IFACE_MODEM_VOICE_CALL_LIST, &list, + NULL); + + if( list ) { + + call = mm_call_list_get_first_non_terminated_call(list); + if( call ) { + //BASCETTA:TODO: Hang this call! + g_object_set (call, + "state", MM_CALL_STATE_TERMINATED, + "state-reason", MM_CALL_STATE_REASON_TERMINATED, + NULL); + mm_gdbus_call_set_state(MM_GDBUS_CALL (call), MM_CALL_STATE_TERMINATED); + mm_gdbus_call_set_state_reason(MM_GDBUS_CALL (call), MM_CALL_STATE_REASON_TERMINATED); + updated = TRUE; + + //BASCETTA:TODO: I have to signal state change... + + } else { + mm_dbg("[%s:%d] Incoming call does not exist yet", __func__, __LINE__); + } + } + + return updated; +} /*****************************************************************************/ typedef struct { diff --git a/src/mm-iface-modem-voice.h b/src/mm-iface-modem-voice.h index 35415190..65e5a1e4 100644 --- a/src/mm-iface-modem-voice.h +++ b/src/mm-iface-modem-voice.h @@ -117,7 +117,13 @@ void mm_iface_modem_voice_bind_simple_status (MMIfaceModemVoice *self, MMSimpleStatus *status); /* CALL creation */ -MMBaseCall *mm_iface_modem_voice_create_call (MMIfaceModemVoice *self); +MMBaseCall *mm_iface_modem_voice_create_call (MMIfaceModemVoice *self); +MMBaseCall *mm_iface_modem_voice_create_incoming_call (MMIfaceModemVoice *self); +gboolean mm_iface_modem_voice_update_incoming_call_number (MMIfaceModemVoice *self, + gchar *number, + guint type, + guint validity); +gboolean mm_iface_modem_voice_network_hangup (MMIfaceModemVoice *self); /* Look for a new valid multipart reference */ guint8 mm_iface_modem_voice_get_local_multipart_reference (MMIfaceModemVoice *self, diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index 36eb0390..7ba00f9e 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -349,6 +349,32 @@ mm_voice_cring_regex_get (void) } GRegex * +mm_voice_clip_regex_get (void) +{ + /* Example: + * <CR><LF>+CLIP: "+393351391306",145,,,,0<CR><LF> + * \_ Number \_ Type \_ Validity + */ + + return g_regex_new ("\\r\\n\\+CLIP:\\s*\"(\\S+)\",\\s*(\\d+),\\s*,\\s*,\\s*,\\s*(\\d+)\\r\\n", + G_REGEX_RAW | G_REGEX_OPTIMIZE, + 0, + NULL); +} + +GRegex * +mm_voice_nocarrier_regex_get (void) +{ + /* Example: + * <CR><LF>NO CARRIER<CR><LF> + */ + return g_regex_new ("\\r\\n\\NO CARRIER\\r\\n", + G_REGEX_RAW | G_REGEX_OPTIMIZE, + 0, + NULL); +} + +GRegex * mm_voice_dtmf_regex_get (void) { /* Example: diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 1a3324a6..844368f8 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -85,9 +85,11 @@ GArray *mm_filter_supported_capabilities (MMModemCapability all, /*****************************************************************************/ /* VOICE specific helpers and utilities */ /*****************************************************************************/ -GRegex *mm_voice_ring_regex_get (void); -GRegex *mm_voice_cring_regex_get (void); -GRegex *mm_voice_dtmf_regex_get (void); +GRegex *mm_voice_ring_regex_get (void); +GRegex *mm_voice_cring_regex_get(void); +GRegex *mm_voice_clip_regex_get (void); +GRegex *mm_voice_nocarrier_regex_get (void); +GRegex *mm_voice_dtmf_regex_get (void); /*****************************************************************************/ /* 3GPP specific helpers and utilities */ |