From d61cb4a21cc1f3509c54f841e2eafafc3ea9a4a9 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Tue, 15 Oct 2019 11:07:41 +0200 Subject: [PATCH] simtech: handle '+RXDTMF' URCs reporting DTMF tones --- plugins/simtech/mm-modem-helpers-simtech.c | 16 ++++++ plugins/simtech/mm-modem-helpers-simtech.h | 5 ++ plugins/simtech/mm-shared-simtech.c | 23 +++++++++ .../tests/test-modem-helpers-simtech.c | 50 +++++++++++++++++++ 4 files changed, 94 insertions(+) diff --git a/plugins/simtech/mm-modem-helpers-simtech.c b/plugins/simtech/mm-modem-helpers-simtech.c index 331853d8..4da3c988 100644 --- a/plugins/simtech/mm-modem-helpers-simtech.c +++ b/plugins/simtech/mm-modem-helpers-simtech.c @@ -161,3 +161,19 @@ mm_simtech_get_cring_urc_regex (void) return g_regex_new ("(?:\\r)+\\n\\+CRING:\\s*(\\S+)(?:\\r)+\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); } + +/*****************************************************************************/ + +/* + * +RXDTMF: 8 + * +RXDTMF: * + * +RXDTMF: 7 + * + * Note! using TWO instead of one... + */ +GRegex * +mm_simtech_get_rxdtmf_urc_regex (void) +{ + return g_regex_new ("(?:\\r)+\\n\\+RXDTMF:\\s*([0-9A-D\\*\\#])(?:\\r)+\\n", + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); +} diff --git a/plugins/simtech/mm-modem-helpers-simtech.h b/plugins/simtech/mm-modem-helpers-simtech.h index b003b029..958d9cfb 100644 --- a/plugins/simtech/mm-modem-helpers-simtech.h +++ b/plugins/simtech/mm-modem-helpers-simtech.h @@ -50,4 +50,9 @@ gboolean mm_simtech_parse_voice_call_urc (GMatchInfo *match_info, GRegex *mm_simtech_get_cring_urc_regex (void); +/*****************************************************************************/ +/* +RXDTMF URC helpers */ + +GRegex *mm_simtech_get_rxdtmf_urc_regex (void); + #endif /* MM_MODEM_HELPERS_SIMTECH_H */ diff --git a/plugins/simtech/mm-shared-simtech.c b/plugins/simtech/mm-shared-simtech.c index 45869c31..ea24466e 100644 --- a/plugins/simtech/mm-shared-simtech.c +++ b/plugins/simtech/mm-shared-simtech.c @@ -54,11 +54,13 @@ typedef struct { GRegex *clcc_urc_regex; GRegex *voice_call_regex; GRegex *cring_regex; + GRegex *rxdtmf_regex; } Private; static void private_free (Private *ctx) { + g_regex_unref (ctx->rxdtmf_regex); g_regex_unref (ctx->cring_regex); g_regex_unref (ctx->voice_call_regex); g_regex_unref (ctx->clcc_urc_regex); @@ -83,6 +85,7 @@ get_private (MMSharedSimtech *self) priv->clcc_urc_regex = mm_simtech_get_clcc_urc_regex (); priv->voice_call_regex = mm_simtech_get_voice_call_urc_regex (); priv->cring_regex = mm_simtech_get_cring_urc_regex (); + priv->rxdtmf_regex = mm_simtech_get_rxdtmf_urc_regex (); /* Setup parent class' MMIfaceModemLocation and MMIfaceModemVoice */ @@ -853,6 +856,20 @@ cring_urc_received (MMPortSerialAt *port, mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info); } +static void +rxdtmf_urc_received (MMPortSerialAt *port, + GMatchInfo *match_info, + MMSharedSimtech *self) +{ + gchar *dtmf; + + dtmf = g_match_info_fetch (match_info, 1); + mm_dbg ("Received DTMF: %s", dtmf); + /* call index unknown */ + mm_iface_modem_voice_received_dtmf (MM_IFACE_MODEM_VOICE (self), 0, dtmf); + g_free (dtmf); +} + static void common_voice_setup_cleanup_unsolicited_events (MMSharedSimtech *self, gboolean enable) @@ -888,6 +905,12 @@ common_voice_setup_cleanup_unsolicited_events (MMSharedSimtech *self, enable ? (MMPortSerialAtUnsolicitedMsgFn)cring_urc_received : NULL, enable ? self : NULL, NULL); + + mm_port_serial_at_add_unsolicited_msg_handler (ports[i], + priv->rxdtmf_regex, + enable ? (MMPortSerialAtUnsolicitedMsgFn)rxdtmf_urc_received : NULL, + enable ? self : NULL, + NULL); } } diff --git a/plugins/simtech/tests/test-modem-helpers-simtech.c b/plugins/simtech/tests/test-modem-helpers-simtech.c index 0274ae92..5a90f374 100644 --- a/plugins/simtech/tests/test-modem-helpers-simtech.c +++ b/plugins/simtech/tests/test-modem-helpers-simtech.c @@ -234,6 +234,53 @@ test_cring_urc_one_cr (void) /*****************************************************************************/ +static void +common_test_rxdtmf_urc (const gchar *urc, + const gchar *expected_str) +{ + GError *error = NULL; + GRegex *rxdtmf_regex = NULL; + GMatchInfo *match_info = NULL; + gchar *type; + gboolean result; + + rxdtmf_regex = mm_simtech_get_rxdtmf_urc_regex (); + + /* Same matching logic as done in MMSerialPortAt when processing URCs! */ + result = g_regex_match_full (rxdtmf_regex, urc, -1, 0, 0, &match_info, &error); + g_assert_no_error (error); + g_assert (result); + + type = g_match_info_fetch (match_info, 1); + g_assert (type); + + g_assert_cmpstr (type, ==, expected_str); + + g_match_info_free (match_info); + g_regex_unref (rxdtmf_regex); + g_free (type); +} + +static void +test_rxdtmf_urc_two_crs (void) +{ + common_test_rxdtmf_urc ("\r\r\n+RXDTMF: 8\r\r\n", "8"); + common_test_rxdtmf_urc ("\r\r\n+RXDTMF: *\r\r\n", "*"); + common_test_rxdtmf_urc ("\r\r\n+RXDTMF: #\r\r\n", "#"); + common_test_rxdtmf_urc ("\r\r\n+RXDTMF: A\r\r\n", "A"); +} + +static void +test_rxdtmf_urc_one_cr (void) +{ + common_test_rxdtmf_urc ("\r\n+RXDTMF: 8\r\n", "8"); + common_test_rxdtmf_urc ("\r\n+RXDTMF: *\r\n", "*"); + common_test_rxdtmf_urc ("\r\n+RXDTMF: #\r\n", "#"); + common_test_rxdtmf_urc ("\r\n+RXDTMF: A\r\n", "A"); +} + +/*****************************************************************************/ + void _mm_log (const char *loc, const char *func, @@ -271,5 +318,8 @@ int main (int argc, char **argv) g_test_add_func ("/MM/simtech/cring/urc/two-crs", test_cring_urc_two_crs); g_test_add_func ("/MM/simtech/cring/urc/one-cr", test_cring_urc_one_cr); + g_test_add_func ("/MM/simtech/rxdtmf/urc/two-crs", test_rxdtmf_urc_two_crs); + g_test_add_func ("/MM/simtech/rxdtmf/urc/one-cr", test_rxdtmf_urc_one_cr); + return g_test_run (); }