diff options
author | Daniele Palmas <dnlplm@gmail.com> | 2025-05-09 11:31:21 +0200 |
---|---|---|
committer | Dan Williams <dan@ioncontrol.co> | 2025-05-19 08:59:00 -0500 |
commit | b0589932d790a4b5e4af16199c95333158aa469e (patch) | |
tree | 7c80eb2fe1dba9b4869b11c61a9f3fd820c59c3a | |
parent | ec218e7052b7fd85302d1f5c9b01086ef3e562d9 (diff) |
broadband-modem: support +CGEREP values different than 2
Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
-rw-r--r-- | src/mm-broadband-modem.c | 29 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 83 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 13 | ||||
-rw-r--r-- | src/tests/test-modem-helpers.c | 44 |
4 files changed, 163 insertions, 6 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index f164be01..41159a6c 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -202,6 +202,8 @@ struct _MMBroadbandModemPrivate { MM3gppCmerMode modem_cmer_disable_mode; MM3gppCmerInd modem_cmer_ind; gboolean modem_cgerep_support_checked; + MM3gppCgerepMode modem_cgerep_enable_mode; + MM3gppCgerepMode modem_cgerep_disable_mode; gboolean modem_cgerep_supported; MMFlowControl flow_control; @@ -3727,20 +3729,33 @@ cgerep_format_check_ready (MMBroadbandModem *self, GAsyncResult *res, GTask *task) { - GError *error = NULL; - const gchar *result; + MM3gppCgerepMode supported_modes = MM_3GPP_CGEREP_MODE_NONE; + GError *error = NULL; + const gchar *result; + gchar *aux; result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); - if (!result) { + if (error || !mm_3gpp_parse_cgerep_test_response (result, self, &supported_modes, &error)) { mm_obj_dbg (self, "+CGEREP check failed: %s", error->message); mm_obj_dbg (self, "packet domain event reporting is unsupported"); g_error_free (error); goto out; } - mm_obj_dbg (self, "packet domain event reporting is supported"); + aux = mm_3gpp_cgerep_mode_build_string_from_mask (supported_modes); + mm_obj_dbg (self, "supported +CGEREP modes: %s", aux); + g_free (aux); + self->priv->modem_cgerep_supported = TRUE; + if (supported_modes & MM_3GPP_CGEREP_MODE_BUFFER_URCS_IF_LINK_RESERVED) + self->priv->modem_cgerep_enable_mode = MM_3GPP_CGEREP_MODE_BUFFER_URCS_IF_LINK_RESERVED; + else if (supported_modes & MM_3GPP_CGEREP_MODE_DISCARD_URCS_IF_LINK_RESERVED) + self->priv->modem_cgerep_enable_mode = MM_3GPP_CGEREP_MODE_DISCARD_URCS_IF_LINK_RESERVED; + + if (supported_modes & MM_3GPP_CGEREP_MODE_DISCARD_URCS) + self->priv->modem_cgerep_disable_mode = MM_3GPP_CGEREP_MODE_DISCARD_URCS; + out: /* go on with remaining checks */ check_and_setup_3gpp_urc_support (task); @@ -4081,7 +4096,7 @@ modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *_self, ctx->cmer_command = mm_3gpp_build_cmer_set_request (self->priv->modem_cmer_enable_mode, self->priv->modem_cmer_ind); if (self->priv->modem_cgerep_support_checked && self->priv->modem_cgerep_supported) - ctx->cgerep_command = g_strdup ("+CGEREP=2"); + ctx->cgerep_command = mm_3gpp_build_cgerep_set_request (self->priv->modem_cgerep_enable_mode); run_unsolicited_events_setup (task); } @@ -4106,7 +4121,7 @@ modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *_self, ctx->cmer_command = mm_3gpp_build_cmer_set_request (self->priv->modem_cmer_disable_mode, MM_3GPP_CMER_IND_NONE); if (self->priv->modem_cgerep_support_checked && self->priv->modem_cgerep_supported) - ctx->cgerep_command = g_strdup ("+CGEREP=0"); + ctx->cgerep_command = mm_3gpp_build_cgerep_set_request (self->priv->modem_cgerep_disable_mode); run_unsolicited_events_setup (task); } @@ -14215,6 +14230,8 @@ mm_broadband_modem_init (MMBroadbandModem *self) self->priv->modem_cmer_enable_mode = MM_3GPP_CMER_MODE_NONE; self->priv->modem_cmer_disable_mode = MM_3GPP_CMER_MODE_NONE; self->priv->modem_cmer_ind = MM_3GPP_CMER_IND_NONE; + self->priv->modem_cgerep_enable_mode = MM_3GPP_CGEREP_MODE_NONE; + self->priv->modem_cgerep_disable_mode = MM_3GPP_CGEREP_MODE_NONE; self->priv->flow_control = MM_FLOW_CONTROL_NONE; self->priv->initial_eps_bearer_cid = -1; } diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index e1450a05..cbdd0d61 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -3865,6 +3865,89 @@ mm_3gpp_parse_cind_read_response (const gchar *reply, } /*************************************************************************/ + +gchar * +mm_3gpp_build_cgerep_set_request (MM3gppCgerepMode mode) +{ + guint mode_val; + + if (mode == MM_3GPP_CGEREP_MODE_DISCARD_URCS) + return g_strdup ("+CGEREP=0"); + if (mode < MM_3GPP_CGEREP_MODE_DISCARD_URCS || mode > MM_3GPP_CGEREP_MODE_BUFFER_URCS_IF_LINK_RESERVED) + return NULL; + mode_val = mm_find_bit_set (mode); + + return g_strdup_printf ("+CGEREP=%u", mode_val); +} + +gboolean +mm_3gpp_parse_cgerep_test_response (const gchar *response, + gpointer log_object, + MM3gppCgerepMode *out_supported_modes, + GError **error) +{ + gchar **split; + GError *inner_error = NULL; + GArray *array_supported_modes = NULL; + gboolean ret = FALSE; + MM3gppCgerepMode supported_modes = 0; + guint i; + + /* + * AT+CGEREP=? + * +CGEREP: (0,1),(0) + * + * AT+CGEREP=? + * +CGEREP: (0,2),(0-1) + * + * AT+CGEREP=? + * +CGEREP: (0,2),(0,1) + */ + + split = mm_split_string_groups (mm_strip_tag (response, "+CGEREP:")); + if (!split) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Couldn't split +CGEREP test response in groups"); + goto out; + } + + /* We want the 1st group */ + if (g_strv_length (split) < 1) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing groups in +CGEREP test response (%u < 1)", g_strv_length (split)); + goto out; + } + + /* Modes in 1st group */ + if (!(array_supported_modes = mm_parse_uint_list (split[0], &inner_error))) + goto out; + + for (i = 0; i < array_supported_modes->len; i++) { + guint mode_val; + + mode_val = g_array_index (array_supported_modes, guint, i); + if (mode_val <= 2) + supported_modes |= (MM3gppCgerepMode) (1 << mode_val); + else + mm_obj_dbg (log_object, "unknown +CGEREP mode reported: %u", mode_val); + } + + if (out_supported_modes) + *out_supported_modes = supported_modes; + ret = TRUE; + +out: + + if (array_supported_modes) + g_array_unref (array_supported_modes); + + g_strfreev (split); + + if (inner_error) + g_propagate_error (error, inner_error); + + return ret; +} + +/*************************************************************************/ /* +CGEV indication parser * * We provide full parsing support, including parameters, for these messages: diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 133c7006..469492b2 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -301,6 +301,19 @@ gint mm_3gpp_cind_response_get_max (MM3gppCindResponse *r); GByteArray *mm_3gpp_parse_cind_read_response (const gchar *reply, GError **error); +/* AT+CGEREP=? (Packet Domain Event Reporting) response parser */ +typedef enum { /*< underscore_name=mm_3gpp_cgerep_mode >*/ + MM_3GPP_CGEREP_MODE_NONE = 0, + MM_3GPP_CGEREP_MODE_DISCARD_URCS = 1 << 0, + MM_3GPP_CGEREP_MODE_DISCARD_URCS_IF_LINK_RESERVED = 1 << 1, + MM_3GPP_CGEREP_MODE_BUFFER_URCS_IF_LINK_RESERVED = 1 << 2, +} MM3gppCgerepMode; +gchar *mm_3gpp_build_cgerep_set_request (MM3gppCgerepMode mode); +gboolean mm_3gpp_parse_cgerep_test_response (const gchar *reply, + gpointer log_object, + MM3gppCgerepMode *supported_modes, + GError **error); + /* +CGEV indication parser */ typedef enum { MM_3GPP_CGEV_UNKNOWN, diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index a6755b0a..5ed5721d 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -2261,6 +2261,47 @@ test_cind_response_moto_v3m (void *f, gpointer d) } /*****************************************************************************/ +/* Test CGEREP test responses */ + +static void +test_cgerep_response (const gchar *str, + MM3gppCgerepMode expected_modes) +{ + gboolean ret; + MM3gppCgerepMode modes = MM_3GPP_CGEREP_MODE_NONE; + GError *error = NULL; + + ret = mm_3gpp_parse_cgerep_test_response (str, NULL, &modes, &error); + g_assert_no_error (error); + g_assert (ret); + + g_assert_cmpuint (modes, ==, expected_modes); +} + +static void +test_cgerep_response_telit_le910q1 (void) +{ + static const gchar *str = "+CGEREP: (0,1),(0)"; + static const MM3gppCgerepMode expected_modes = ( \ + MM_3GPP_CGEREP_MODE_DISCARD_URCS | \ + MM_3GPP_CGEREP_MODE_DISCARD_URCS_IF_LINK_RESERVED); + + test_cgerep_response (str, expected_modes); +} + +static void +test_cgerep_response_telit_ln920 (void) +{ + static const gchar *str = "+CGEREP: (0-2),(0,1)"; + static const MM3gppCgerepMode expected_modes = ( \ + MM_3GPP_CGEREP_MODE_DISCARD_URCS | \ + MM_3GPP_CGEREP_MODE_DISCARD_URCS_IF_LINK_RESERVED | \ + MM_3GPP_CGEREP_MODE_BUFFER_URCS_IF_LINK_RESERVED); + + test_cgerep_response (str, expected_modes); +} + +/*****************************************************************************/ /* Test +CGEV indication parsing */ typedef struct { @@ -5194,6 +5235,9 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_cind_response_linktop_lw273, NULL)); g_test_suite_add (suite, TESTCASE (test_cind_response_moto_v3m, NULL)); + g_test_suite_add (suite, TESTCASE (test_cgerep_response_telit_le910q1, NULL)); + g_test_suite_add (suite, TESTCASE (test_cgerep_response_telit_ln920, NULL)); + g_test_suite_add (suite, TESTCASE (test_cgev_indication, NULL)); g_test_suite_add (suite, TESTCASE (test_iccid_parse_quoted_swap_19_digit, NULL)); |