diff options
-rw-r--r-- | plugins/huawei/mm-broadband-modem-huawei.c | 189 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 42 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 12 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 1 |
4 files changed, 189 insertions, 55 deletions
diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c index 471150c1..55904826 100644 --- a/plugins/huawei/mm-broadband-modem-huawei.c +++ b/plugins/huawei/mm-broadband-modem-huawei.c @@ -98,6 +98,7 @@ struct _MMBroadbandModemHuaweiPrivate { GRegex *conf_regex; GRegex *conn_regex; GRegex *cend_regex; + GRegex *ddtmf_regex; /* Regex to ignore */ GRegex *boot_regex; @@ -2939,6 +2940,19 @@ huawei_voice_call_end (MMPortSerialAt *port, mm_iface_modem_voice_network_hangup(MM_IFACE_MODEM_VOICE(self)); } +static void +huawei_voice_received_dtmf (MMPortSerialAt *port, + GMatchInfo *match_info, + MMBroadbandModemHuawei *self) +{ + gchar *key; + + key = g_match_info_fetch (match_info, 1); + + if( key && key[0] ) { + mm_dbg ("[%s:%d][^DDTMF] Received DTMF '%c'", __func__, __LINE__, key[0]); + } +} static void set_voice_unsolicited_events_handlers (MMBroadbandModemHuawei *self, @@ -2976,6 +2990,12 @@ set_voice_unsolicited_events_handlers (MMBroadbandModemHuawei *self, enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_call_end : NULL, enable ? self : NULL, NULL); + mm_port_serial_at_add_unsolicited_msg_handler ( + port, + self->priv->ddtmf_regex, + enable ? (MMPortSerialAtUnsolicitedMsgFn)huawei_voice_received_dtmf: NULL, + enable ? self : NULL, + NULL); } g_list_free_full (ports, (GDestroyNotify)g_object_unref); @@ -3065,6 +3085,162 @@ modem_voice_cleanup_unsolicited_events (MMIfaceModemVoice *self, } /*****************************************************************************/ +/* Enabling unsolicited events (Voice interface) */ + +static gboolean +modem_voice_enable_unsolicited_events_finish (MMIfaceModemVoice *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void +own_voice_enable_unsolicited_events_ready (MMBaseModem *self, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + mm_base_modem_at_sequence_full_finish (self, res, NULL, &error); + if (error) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static const MMBaseModemAtCommand unsolicited_voice_enable_sequence[] = { + /* With ^DDTMFCFG we active the DTMF Decoder */ + { "^DDTMFCFG=0,1", 3, FALSE, NULL }, + { NULL } +}; + +static void +parent_voice_enable_unsolicited_events_ready (MMIfaceModemVoice *self, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + if (!iface_modem_voice_parent->enable_unsolicited_events_finish (self, res, &error)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); + } + + /* Our own enable now */ + mm_base_modem_at_sequence_full ( + MM_BASE_MODEM (self), + mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), + unsolicited_voice_enable_sequence, + NULL, /* response_processor_context */ + NULL, /* response_processor_context_free */ + NULL, /* cancellable */ + (GAsyncReadyCallback)own_voice_enable_unsolicited_events_ready, + simple); +} + +static void +modem_voice_enable_unsolicited_events (MMIfaceModemVoice *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + + result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + modem_voice_enable_unsolicited_events); + + /* Chain up parent's enable */ + iface_modem_voice_parent->enable_unsolicited_events ( + self, + (GAsyncReadyCallback)parent_voice_enable_unsolicited_events_ready, + result); +} + +/*****************************************************************************/ +/* Disabling unsolicited events (Voice interface) */ + +static gboolean +modem_voice_disable_unsolicited_events_finish (MMIfaceModemVoice *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void +own_voice_disable_unsolicited_events_ready (MMBaseModem *self, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + mm_base_modem_at_sequence_full_finish (self, res, NULL, &error); + if (error) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static const MMBaseModemAtCommand unsolicited_voice_disable_sequence[] = { + /* With ^DDTMFCFG we deactivate the DTMF Decoder */ + { "^DDTMFCFG=1,0", 3, FALSE, NULL }, + { NULL } +}; + +static void +parent_voice_disable_unsolicited_events_ready (MMIfaceModemVoice *self, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + if (!iface_modem_voice_parent->disable_unsolicited_events_finish (self, res, &error)) { + g_simple_async_result_take_error (simple, error); + g_simple_async_result_complete (simple); + g_object_unref (simple); + } + + /* Our own enable now */ + mm_base_modem_at_sequence_full ( + MM_BASE_MODEM (self), + mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), + unsolicited_voice_disable_sequence, + NULL, /* response_processor_context */ + NULL, /* response_processor_context_free */ + NULL, /* cancellable */ + (GAsyncReadyCallback)own_voice_disable_unsolicited_events_ready, + simple); +} + + + +static void +modem_voice_disable_unsolicited_events (MMIfaceModemVoice *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + + result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + modem_voice_disable_unsolicited_events); + + /* Chain up parent's enable */ + iface_modem_voice_parent->disable_unsolicited_events ( + self, + (GAsyncReadyCallback)parent_voice_disable_unsolicited_events_ready, + result); +} + +/*****************************************************************************/ /* Load network time (Time interface) */ static MMNetworkTimezone * @@ -3997,6 +4173,13 @@ mm_broadband_modem_huawei_init (MMBroadbandModemHuawei *self) self->priv->cend_regex = g_regex_new ("\\r\\n\\^CEND:\\s*(\\d+),\\s*(\\d+),\\s*(\\d+),?\\s*(\\d*)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + /* Voice: receive DTMF regex + * <CR><LF>^DDTMF: <key><CR><LF> + * Key should be 0-9, A-D, *, # + */ + self->priv->ddtmf_regex = g_regex_new ("\\r\\n\\^DDTMF:\\s*([0-9A-D\\*\\#])\\r\\n", + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + self->priv->ndisdup_support = FEATURE_SUPPORT_UNKNOWN; self->priv->rfswitch_support = FEATURE_SUPPORT_UNKNOWN; @@ -4038,6 +4221,7 @@ finalize (GObject *object) g_regex_unref (self->priv->conf_regex); g_regex_unref (self->priv->conn_regex); g_regex_unref (self->priv->cend_regex); + g_regex_unref (self->priv->ddtmf_regex); if (self->priv->syscfg_supported_modes) g_array_unref (self->priv->syscfg_supported_modes); @@ -4176,5 +4360,10 @@ iface_modem_voice_init (MMIfaceModemVoice *iface) iface->setup_unsolicited_events_finish = modem_voice_setup_cleanup_unsolicited_events_finish; iface->cleanup_unsolicited_events = modem_voice_cleanup_unsolicited_events; iface->cleanup_unsolicited_events_finish = modem_voice_setup_cleanup_unsolicited_events_finish; + iface->enable_unsolicited_events = modem_voice_enable_unsolicited_events; + iface->enable_unsolicited_events_finish = modem_voice_enable_unsolicited_events_finish; + iface->disable_unsolicited_events = modem_voice_disable_unsolicited_events; + iface->disable_unsolicited_events_finish = modem_voice_disable_unsolicited_events_finish; + iface->create_call = create_call; } diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index e917b036..7ae83973 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -6337,39 +6337,6 @@ nocarrier_received (MMPortSerialAt *port, } static void -dtmf_received (MMPortSerialAt *port, - GMatchInfo *info, - MMBroadbandModem *self) -{ -// GError *error = NULL; -// MMCallPart *part; -// guint length; -// gchar *pdu; -// -// mm_dbg ("Got new non-stored message indication"); -// -// if (!mm_get_uint_from_match_info (info, 1, &length)) -// return; -// -// pdu = g_match_info_fetch (info, 2); -// if (!pdu) -// return; -// -// part = mm_call_part_3gpp_new_from_pdu (CALL_PART_INVALID_INDEX, pdu, &error); -// if (part) { -// mm_dbg ("Correctly parsed non-stored PDU"); -// mm_iface_modem_voice_take_part (MM_IFACE_MODEM_VOICE (self), -// part, -// MM_CALL_STATE_RECEIVED, -// MM_CALL_STORAGE_UNKNOWN); -// } else { -// /* Don't treat the error as critical */ -// mm_dbg ("Error parsing non-stored PDU: %s", error->message); -// g_error_free (error); -// } -} - -static void set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, gboolean enable, GAsyncReadyCallback callback, @@ -6381,7 +6348,6 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, GRegex *cring_regex; GRegex *ring_regex; GRegex *clip_regex; - GRegex *dtmf_regex; guint i; result = g_simple_async_result_new (G_OBJECT (self), @@ -6393,7 +6359,6 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, 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)); @@ -6430,17 +6395,10 @@ set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self, 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, - NULL); } g_regex_unref (cring_regex); g_regex_unref (ring_regex); - g_regex_unref (dtmf_regex); g_simple_async_result_set_op_res_gboolean (result, TRUE); g_simple_async_result_complete_in_idle (result); g_object_unref (result); diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index 48685bcf..4ac1564e 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -373,18 +373,6 @@ mm_voice_nocarrier_regex_get (void) NULL); } -GRegex * -mm_voice_dtmf_regex_get (void) -{ - /* Example: - * <CR><LF>^DDTMF: 1<CR><LF> - */ - return g_regex_new ("\\r\\n\\^DDTMF:\\s*([0-9A-D\\*\\#])\\r\\n", - G_REGEX_RAW | G_REGEX_OPTIMIZE, - 0, - NULL); -} - /*************************************************************************/ /* +CREG: <stat> (GSM 07.07 CREG=1 unsolicited) */ diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 844368f8..1aee2a2a 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -89,7 +89,6 @@ 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 */ |