simtech: handle '+RXDTMF' URCs reporting DTMF tones
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* <CR><CR><LF>+RXDTMF: 8<CR><CR><LF>
|
||||
* <CR><CR><LF>+RXDTMF: *<CR><CR><LF>
|
||||
* <CR><CR><LF>+RXDTMF: 7<CR><CR><LF>
|
||||
*
|
||||
* Note! using TWO <CR> 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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user