serial-parsers,port-serial-at: move echo removal into serial parser

Mainly because we need somewhere to stash the call end regex, and
it's silly to have a 3rd instance of that in MMPortSerialAt when
we already have one in the serial parsers that MMPortSerialAt
relies on pretty heavily.

Signed-off-by: Dan Williams <dan@ioncontrol.co>
This commit is contained in:
Dan Williams
2025-05-22 08:05:58 -05:00
parent 7f014add61
commit 24f9309d6e
9 changed files with 41 additions and 25 deletions
+1
View File
@@ -468,6 +468,7 @@ base_modem_internal_grab_port (MMBaseModem *self,
if (MM_IS_PORT_SERIAL_AT (port)) { if (MM_IS_PORT_SERIAL_AT (port)) {
mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (port), mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (port),
mm_serial_parser_v1_parse, mm_serial_parser_v1_parse,
mm_serial_parser_v1_remove_echo,
mm_serial_parser_v1_new (), mm_serial_parser_v1_new (),
mm_serial_parser_v1_destroy); mm_serial_parser_v1_destroy);
/* Prefer plugin-provided flags to the generic ones */ /* Prefer plugin-provided flags to the generic ones */
+1
View File
@@ -1434,6 +1434,7 @@ serial_open_at (MMPortProbe *self)
NULL); NULL);
mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (ctx->serial), mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (ctx->serial),
mm_serial_parser_v1_parse, mm_serial_parser_v1_parse,
mm_serial_parser_v1_remove_echo,
parser, parser,
mm_serial_parser_v1_destroy); mm_serial_parser_v1_destroy);
} }
+5 -22
View File
@@ -42,6 +42,7 @@ enum {
struct _MMPortSerialAtPrivate { struct _MMPortSerialAtPrivate {
/* Response parser data */ /* Response parser data */
MMPortSerialAtResponseParserFn response_parser_fn; MMPortSerialAtResponseParserFn response_parser_fn;
MMPortSerialAtRemoveEchoFn remove_echo_fn;
gpointer response_parser_user_data; gpointer response_parser_user_data;
GDestroyNotify response_parser_notify; GDestroyNotify response_parser_notify;
@@ -61,6 +62,7 @@ struct _MMPortSerialAtPrivate {
void void
mm_port_serial_at_set_response_parser (MMPortSerialAt *self, mm_port_serial_at_set_response_parser (MMPortSerialAt *self,
MMPortSerialAtResponseParserFn fn, MMPortSerialAtResponseParserFn fn,
MMPortSerialAtRemoveEchoFn echo_fn,
gpointer user_data, gpointer user_data,
GDestroyNotify notify) GDestroyNotify notify)
{ {
@@ -70,30 +72,11 @@ mm_port_serial_at_set_response_parser (MMPortSerialAt *self,
self->priv->response_parser_notify (self->priv->response_parser_user_data); self->priv->response_parser_notify (self->priv->response_parser_user_data);
self->priv->response_parser_fn = fn; self->priv->response_parser_fn = fn;
self->priv->remove_echo_fn = echo_fn;
self->priv->response_parser_user_data = user_data; self->priv->response_parser_user_data = user_data;
self->priv->response_parser_notify = notify; self->priv->response_parser_notify = notify;
} }
void
mm_port_serial_at_remove_echo (GByteArray *response)
{
guint i;
if (response->len <= 2)
return;
for (i = 0; i < (response->len - 1); i++) {
/* If there is any content before the first
* <CR><LF>, assume it's echo or garbage, and skip it */
if (response->data[i] == '\r' && response->data[i + 1] == '\n') {
if (i > 0)
g_byte_array_remove_range (response, 0, i);
/* else, good, we're already started with <CR><LF> */
break;
}
}
}
static MMPortSerialResponseType static MMPortSerialResponseType
parse_response (MMPortSerial *port, parse_response (MMPortSerial *port,
GByteArray *response, GByteArray *response,
@@ -109,7 +92,7 @@ parse_response (MMPortSerial *port,
/* Remove echo */ /* Remove echo */
if (self->priv->remove_echo) if (self->priv->remove_echo)
mm_port_serial_at_remove_echo (response); self->priv->remove_echo_fn (self->priv->response_parser_user_data, response);
/* If there's no response to receive, we're done; e.g. if we only got /* If there's no response to receive, we're done; e.g. if we only got
* unsolicited messages */ * unsolicited messages */
@@ -243,7 +226,7 @@ parse_unsolicited (MMPortSerial *port, GByteArray *response)
/* Remove echo */ /* Remove echo */
if (self->priv->remove_echo) if (self->priv->remove_echo)
mm_port_serial_at_remove_echo (response); self->priv->remove_echo_fn (self->priv->response_parser_user_data, response);
for (iter = self->priv->unsolicited_msg_handlers; iter; iter = iter->next) { for (iter = self->priv->unsolicited_msg_handlers; iter; iter = iter->next) {
MMAtUnsolicitedMsgHandler *handler = (MMAtUnsolicitedMsgHandler *) iter->data; MMAtUnsolicitedMsgHandler *handler = (MMAtUnsolicitedMsgHandler *) iter->data;
+4 -2
View File
@@ -65,6 +65,9 @@ typedef void (*MMPortSerialAtUnsolicitedMsgFn) (MMPortSerialAt *port,
GMatchInfo *match_info, GMatchInfo *match_info,
gpointer user_data); gpointer user_data);
typedef void (*MMPortSerialAtRemoveEchoFn) (gpointer user_data,
GByteArray *response);
#define MM_PORT_SERIAL_AT_REMOVE_ECHO "remove-echo" #define MM_PORT_SERIAL_AT_REMOVE_ECHO "remove-echo"
#define MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED "init-sequence-enabled" #define MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED "init-sequence-enabled"
#define MM_PORT_SERIAL_AT_INIT_SEQUENCE "init-sequence" #define MM_PORT_SERIAL_AT_INIT_SEQUENCE "init-sequence"
@@ -97,6 +100,7 @@ void mm_port_serial_at_enable_unsolicited_msg_handler (MMPortSerialAt *self,
void mm_port_serial_at_set_response_parser (MMPortSerialAt *self, void mm_port_serial_at_set_response_parser (MMPortSerialAt *self,
MMPortSerialAtResponseParserFn fn, MMPortSerialAtResponseParserFn fn,
MMPortSerialAtRemoveEchoFn echo_fn,
gpointer user_data, gpointer user_data,
GDestroyNotify notify); GDestroyNotify notify);
@@ -113,8 +117,6 @@ gchar *mm_port_serial_at_command_finish (MMPortSerialAt *self,
GError **error); GError **error);
/* Just for unit tests */ /* Just for unit tests */
void mm_port_serial_at_remove_echo (GByteArray *response);
void mm_port_serial_at_set_flags (MMPortSerialAt *self, void mm_port_serial_at_set_flags (MMPortSerialAt *self,
MMPortSerialAtFlag flags); MMPortSerialAtFlag flags);
+21
View File
@@ -160,6 +160,27 @@ mm_serial_parser_v1_add_filter (gpointer data,
parser->filter_user_data = user_data; parser->filter_user_data = user_data;
} }
void
mm_serial_parser_v1_remove_echo (gpointer data,
GByteArray *response)
{
guint i;
if (response->len <= 2)
return;
for (i = 0; i < (response->len - 1); i++) {
/* If there is any content before the first
* <CR><LF>, assume it's echo or garbage, and skip it */
if (response->data[i] == '\r' && response->data[i + 1] == '\n') {
if (i > 0)
g_byte_array_remove_range (response, 0, i);
/* else, good, we're already started with <CR><LF> */
break;
}
}
}
gboolean gboolean
mm_serial_parser_v1_parse (gpointer data, mm_serial_parser_v1_parse (gpointer data,
GString *response, GString *response,
+2
View File
@@ -26,6 +26,8 @@ gboolean mm_serial_parser_v1_parse (gpointer parser,
GString *response, GString *response,
gpointer log_object, gpointer log_object,
GError **error); GError **error);
void mm_serial_parser_v1_remove_echo (gpointer parser,
GByteArray *response);
void mm_serial_parser_v1_destroy (gpointer parser); void mm_serial_parser_v1_destroy (gpointer parser);
gboolean mm_serial_parser_v1_is_known_error (const GError *error); gboolean mm_serial_parser_v1_is_known_error (const GError *error);
@@ -1245,6 +1245,7 @@ setup_ports (MMBroadbandModem *self)
mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (primary), mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (primary),
mm_serial_parser_v1_parse, mm_serial_parser_v1_parse,
mm_serial_parser_v1_remove_echo,
parser, parser,
mm_serial_parser_v1_destroy); mm_serial_parser_v1_destroy);
} }
+5 -1
View File
@@ -89,6 +89,7 @@ at_serial_echo_removal (void)
guint i; guint i;
for (i = 0; i < G_N_ELEMENTS (echo_removal_tests); i++) { for (i = 0; i < G_N_ELEMENTS (echo_removal_tests); i++) {
gpointer parser;
GByteArray *ba; GByteArray *ba;
/* Note that we add last NUL also to the byte array, so that we can compare /* Note that we add last NUL also to the byte array, so that we can compare
@@ -98,7 +99,9 @@ at_serial_echo_removal (void)
(guint8 *)echo_removal_tests[i].original, (guint8 *)echo_removal_tests[i].original,
strlen (echo_removal_tests[i].original) + 1); strlen (echo_removal_tests[i].original) + 1);
mm_port_serial_at_remove_echo (ba); parser = mm_serial_parser_v1_new ();
mm_serial_parser_v1_remove_echo (parser, ba);
mm_serial_parser_v1_destroy (parser);
g_assert_cmpstr ((gchar *)ba->data, ==, echo_removal_tests[i].without_echo); g_assert_cmpstr ((gchar *)ba->data, ==, echo_removal_tests[i].without_echo);
@@ -119,6 +122,7 @@ _run_parse_test (const ParseResponseTest tests[], guint number_of_tests)
parser = mm_serial_parser_v1_new (); parser = mm_serial_parser_v1_new ();
response = g_string_new (tests[i].response); response = g_string_new (tests[i].response);
found = mm_serial_parser_v1_parse (parser, response, NULL, &error); found = mm_serial_parser_v1_parse (parser, response, NULL, &error);
mm_serial_parser_v1_destroy (parser);
/* Verify if we expect a match or not */ /* Verify if we expect a match or not */
g_assert_cmpint (found, ==, tests[i].found); g_assert_cmpint (found, ==, tests[i].found);
+1
View File
@@ -237,6 +237,7 @@ start_cb (void)
/* Set common response parser */ /* Set common response parser */
mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (port), mm_port_serial_at_set_response_parser (MM_PORT_SERIAL_AT (port),
mm_serial_parser_v1_parse, mm_serial_parser_v1_parse,
mm_serial_parser_v1_remove_echo,
mm_serial_parser_v1_new (), mm_serial_parser_v1_new (),
mm_serial_parser_v1_destroy); mm_serial_parser_v1_destroy);