diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2019-10-15 10:40:11 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2019-10-15 11:14:40 +0200 |
commit | 345922caa10fc86dad181ccd83239af1f43fd30e (patch) | |
tree | 1900b7bc68b9c0c72044fb17cb5766d1c000cca6 /plugins/simtech | |
parent | 395b22178c4f6dd24d552e82d2d46dfb24c65297 (diff) |
simtech: handle non-standard '+CRING' URCs
The SIM7600E ends up emitting these URCs with too many <CR>s, and the
generic +CRING handler doesn't catch them, interfering with other
actions, e.g.:
$ sudo mmcli --call 1 --accept
error: couldn't accept the call: 'GDBus.Error:org.freedesktop.ModemManager1.Error.Core.Failed: Couldn't accept the call: Unhandled response '+CRING: VOICE
+CRING: VOICE''
Diffstat (limited to 'plugins/simtech')
-rw-r--r-- | plugins/simtech/mm-modem-helpers-simtech.c | 13 | ||||
-rw-r--r-- | plugins/simtech/mm-modem-helpers-simtech.h | 5 | ||||
-rw-r--r-- | plugins/simtech/mm-shared-simtech.c | 30 | ||||
-rw-r--r-- | plugins/simtech/tests/test-modem-helpers-simtech.c | 44 |
4 files changed, 92 insertions, 0 deletions
diff --git a/plugins/simtech/mm-modem-helpers-simtech.c b/plugins/simtech/mm-modem-helpers-simtech.c index 5926c44f..331853d8 100644 --- a/plugins/simtech/mm-modem-helpers-simtech.c +++ b/plugins/simtech/mm-modem-helpers-simtech.c @@ -148,3 +148,16 @@ out: return TRUE; } + +/*****************************************************************************/ + +/* + * Using TWO <CR> instead of one... + * <CR><CR><LF>+CRING: VOICE<CR><CR><LF> + */ +GRegex * +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); +} diff --git a/plugins/simtech/mm-modem-helpers-simtech.h b/plugins/simtech/mm-modem-helpers-simtech.h index 1a046f58..b003b029 100644 --- a/plugins/simtech/mm-modem-helpers-simtech.h +++ b/plugins/simtech/mm-modem-helpers-simtech.h @@ -45,4 +45,9 @@ gboolean mm_simtech_parse_voice_call_urc (GMatchInfo *match_info, guint *duration, GError **error); +/*****************************************************************************/ +/* Non-standard CRING URC helpers */ + +GRegex *mm_simtech_get_cring_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 5a54ba44..45869c31 100644 --- a/plugins/simtech/mm-shared-simtech.c +++ b/plugins/simtech/mm-shared-simtech.c @@ -53,11 +53,13 @@ typedef struct { FeatureSupport clcc_urc_support; GRegex *clcc_urc_regex; GRegex *voice_call_regex; + GRegex *cring_regex; } Private; static void private_free (Private *ctx) { + g_regex_unref (ctx->cring_regex); g_regex_unref (ctx->voice_call_regex); g_regex_unref (ctx->clcc_urc_regex); g_slice_free (Private, ctx); @@ -80,6 +82,7 @@ get_private (MMSharedSimtech *self) priv->clcc_urc_support = FEATURE_SUPPORT_UNKNOWN; 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 (); /* Setup parent class' MMIfaceModemLocation and MMIfaceModemVoice */ @@ -830,6 +833,27 @@ voice_call_urc_received (MMPortSerialAt *port, } static void +cring_urc_received (MMPortSerialAt *port, + GMatchInfo *info, + MMSharedSimtech *self) +{ + MMCallInfo call_info; + gchar *str; + + /* We could have "VOICE" or "DATA". Now consider only "VOICE" */ + str = mm_get_string_unquoted_from_match_info (info, 1); + mm_dbg ("Ringing (%s)", str); + g_free (str); + + call_info.index = 0; + call_info.direction = MM_CALL_DIRECTION_INCOMING; + call_info.state = MM_CALL_STATE_RINGING_IN; + call_info.number = NULL; + + mm_iface_modem_voice_report_call (MM_IFACE_MODEM_VOICE (self), &call_info); +} + +static void common_voice_setup_cleanup_unsolicited_events (MMSharedSimtech *self, gboolean enable) { @@ -858,6 +882,12 @@ common_voice_setup_cleanup_unsolicited_events (MMSharedSimtech *self, enable ? (MMPortSerialAtUnsolicitedMsgFn)voice_call_urc_received : NULL, enable ? self : NULL, NULL); + + mm_port_serial_at_add_unsolicited_msg_handler (ports[i], + priv->cring_regex, + enable ? (MMPortSerialAtUnsolicitedMsgFn)cring_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 3092e936..0274ae92 100644 --- a/plugins/simtech/tests/test-modem-helpers-simtech.c +++ b/plugins/simtech/tests/test-modem-helpers-simtech.c @@ -193,6 +193,47 @@ test_voice_call_end_duration_urc (void) /*****************************************************************************/ +static void +common_test_cring_urc (const gchar *urc, + const gchar *expected_type) +{ + GError *error = NULL; + GRegex *cring_regex = NULL; + GMatchInfo *match_info = NULL; + gchar *type; + gboolean result; + + cring_regex = mm_simtech_get_cring_urc_regex (); + + /* Same matching logic as done in MMSerialPortAt when processing URCs! */ + result = g_regex_match_full (cring_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_type); + + g_match_info_free (match_info); + g_regex_unref (cring_regex); + g_free (type); +} + +static void +test_cring_urc_two_crs (void) +{ + common_test_cring_urc ("\r\r\n+CRING: VOICE\r\r\n", "VOICE"); +} + +static void +test_cring_urc_one_cr (void) +{ + common_test_cring_urc ("\r\n+CRING: VOICE\r\n", "VOICE"); +} + +/*****************************************************************************/ + void _mm_log (const char *loc, const char *func, @@ -227,5 +268,8 @@ int main (int argc, char **argv) g_test_add_func ("/MM/simtech/voicecall/urc/end", test_voice_call_end_urc); g_test_add_func ("/MM/simtech/voicecall/urc/end-duration", test_voice_call_end_duration_urc); + 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); + return g_test_run (); } |