--- Hey,
(resent to include in CC the mailing list) This v2 patch includes a correct "underscore_name" for the new enums defined in the helpers header, needed if we want to use the _build_string_from_mask() methods. Cheers, --- src/mm-modem-helpers.c | 136 +++++++++++++++++++++++++++++++++++++++++ src/mm-modem-helpers.h | 25 ++++++++ src/tests/test-modem-helpers.c | 53 ++++++++++++++++ 3 files changed, 214 insertions(+) diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index 679f9252..f092d223 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -240,6 +240,16 @@ mm_count_bits_set (gulong number) return c; } +guint +mm_find_bit_set (gulong number) +{ + guint c = 0; + + for (c = 0; !(number & 0x1); c++) + number >>= 1; + return c; +} + /*****************************************************************************/ gchar * @@ -2847,6 +2857,132 @@ mm_3gpp_parse_cnum_exec_response (const gchar *reply, /*************************************************************************/ +gchar * +mm_3gpp_build_cmer_set_request (MM3gppCmerMode mode, + MM3gppCmerInd ind) +{ + guint mode_val; + guint ind_val; + + if (mode == MM_3GPP_CMER_MODE_DISCARD_URCS) + return g_strdup ("+CMER=0"); + if (mode < MM_3GPP_CMER_MODE_DISCARD_URCS || mode > MM_3GPP_CMER_MODE_FORWARD_URCS) + return NULL; + mode_val = mm_find_bit_set (mode); + + if (ind < MM_3GPP_CMER_IND_DISABLE || ind > MM_3GPP_CMER_IND_ENABLE_ALL) + return NULL; + ind_val = mm_find_bit_set (ind); + + return g_strdup_printf ("+CMER=%u,0,0,%u", mode_val, ind_val); +} + +gboolean +mm_3gpp_parse_cmer_test_response (const gchar *response, + MM3gppCmerMode *out_supported_modes, + MM3gppCmerInd *out_supported_inds, + GError **error) +{ + GRegex *r; + GError *inner_error = NULL; + GMatchInfo *match_info = NULL; + GArray *array_supported_modes = NULL; + GArray *array_supported_inds = NULL; + gchar *aux = NULL; + gboolean ret = FALSE; + MM3gppCmerMode supported_modes = 0; + MM3gppCmerInd supported_inds = 0; + guint i; + + /* + * AT+CMER=? + * +CMER: 1,0,0,(0-1),0 + * + * AT+CMER=? + * +CMER: (0-3),(0),(0),(0-1),(0-1) + */ + + r = g_regex_new ("\\+CMER:\\s*" + "\\(?([0-9-]+)\\)?," + "\\(?(?:[0-9-]+)\\)?," + "\\(?(?:[0-9-]+)\\)?," + "\\(?([0-9-]+)\\)?," + "\\(?(?:[0-9-]+)\\)?" + "(?:\\r\\n)?", 0, 0, NULL); + g_assert (r != NULL); + + g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error); + if (inner_error) + goto out; + + if (!g_match_info_matches (match_info)) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Couldn't match response"); + goto out; + } + + if (!(aux = mm_get_string_unquoted_from_match_info (match_info, 1))) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Error retrieving list of supported +CMER modes"); + goto out; + } + + if (!(array_supported_modes = mm_parse_uint_list (aux, &inner_error))) + goto out; + g_clear_pointer (&aux, g_free); + + if (!(aux = mm_get_string_unquoted_from_match_info (match_info, 2))) { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Error retrieving list of supported +CMER inds"); + goto out; + } + + if (!(array_supported_inds = mm_parse_uint_list (aux, &inner_error))) + goto out; + g_clear_pointer (&aux, g_free); + + 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 >= 0 && mode_val <= 3) + supported_modes |= (MM3gppCmerMode) (1 << mode_val); + else + mm_dbg ("Unknown +CMER mode reported: %u", mode_val); + } + + for (i = 0; i < array_supported_inds->len; i++) { + guint ind_val; + + ind_val = g_array_index (array_supported_inds, guint, i); + if (ind_val >= 0 && ind_val <= 2) + supported_inds |= (MM3gppCmerInd) (1 << ind_val); + else + mm_dbg ("Unknown +CMER ind reported: %u", ind_val); + } + + if (out_supported_modes) + *out_supported_modes = supported_modes; + if (out_supported_inds) + *out_supported_inds = supported_inds; + ret = TRUE; + +out: + if (array_supported_modes) + g_array_unref (array_supported_modes); + if (array_supported_inds) + g_array_unref (array_supported_inds); + g_clear_pointer (&aux, g_free); + g_clear_pointer (&match_info, g_match_info_free); + g_regex_unref (r); + + if (inner_error) + g_propagate_error (error, inner_error); + + return ret; +} + +/*************************************************************************/ + struct MM3gppCindResponse { gchar *desc; guint idx; diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 297e15df..ab566539 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -57,6 +57,7 @@ GArray *mm_parse_uint_list (const gchar *str, GError **error); guint mm_count_bits_set (gulong number); +guint mm_find_bit_set (gulong number); gchar *mm_create_device_identifier (guint vid, guint pid, @@ -228,6 +229,30 @@ gboolean mm_3gpp_parse_clck_write_response (const gchar *reply, GStrv mm_3gpp_parse_cnum_exec_response (const gchar *reply, GError **error); +/* AT+CMER=? (Mobile Equipment Event Reporting) response parser */ +typedef enum { /*< underscore_name=mm_3gpp_cmer_mode >*/ + MM_3GPP_CMER_MODE_NONE = 0, + MM_3GPP_CMER_MODE_DISCARD_URCS = 1 << 0, + MM_3GPP_CMER_MODE_DISCARD_URCS_IF_LINK_RESERVED = 1 << 1, + MM_3GPP_CMER_MODE_BUFFER_URCS_IF_LINK_RESERVED = 1 << 2, + MM_3GPP_CMER_MODE_FORWARD_URCS = 1 << 3, +} MM3gppCmerMode; +typedef enum { /*< underscore_name=mm_3gpp_cmer_ind >*/ + MM_3GPP_CMER_IND_NONE = 0, + /* no indicator event reporting */ + MM_3GPP_CMER_IND_DISABLE = 1 << 0, + /* Only indicator events that are not caused by +CIND */ + MM_3GPP_CMER_IND_ENABLE_NOT_CAUSED_BY_CIND = 1 << 1, + /* All indicator events */ + MM_3GPP_CMER_IND_ENABLE_ALL = 1 << 2, +} MM3gppCmerInd; +gchar *mm_3gpp_build_cmer_set_request (MM3gppCmerMode mode, + MM3gppCmerInd ind); +gboolean mm_3gpp_parse_cmer_test_response (const gchar *reply, + MM3gppCmerMode *supported_modes, + MM3gppCmerInd *supported_inds, + GError **error); + /* AT+CIND=? (Supported indicators) response parser */ typedef struct MM3gppCindResponse MM3gppCindResponse; GHashTable *mm_3gpp_parse_cind_test_response (const gchar *reply, diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index b59c5900..3c058951 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -1867,6 +1867,56 @@ test_devid_item (void *f, gpointer d) } /*****************************************************************************/ +/* Test CMER test responses */ + +static void +test_cmer_response (const gchar *str, + MM3gppCmerMode expected_modes, + MM3gppCmerInd expected_inds) +{ + gboolean ret; + MM3gppCmerMode modes = MM_3GPP_CMER_MODE_NONE; + MM3gppCmerInd inds = MM_3GPP_CMER_IND_NONE; + GError *error = NULL; + + ret = mm_3gpp_parse_cmer_test_response (str, &modes, &inds, &error); + g_assert_no_error (error); + g_assert (ret); + + g_assert_cmpuint (modes, ==, expected_modes); + g_assert_cmpuint (inds, ==, expected_inds); +} + +static void +test_cmer_response_cinterion_pls8 (void) +{ + static const gchar *str = "+CMER: (0-3),(0),(0),(0-1),(0-1)"; + static const MM3gppCmerMode expected_modes = ( \ + MM_3GPP_CMER_MODE_DISCARD_URCS | \ + MM_3GPP_CMER_MODE_DISCARD_URCS_IF_LINK_RESERVED | \ + MM_3GPP_CMER_MODE_BUFFER_URCS_IF_LINK_RESERVED | \ + MM_3GPP_CMER_MODE_FORWARD_URCS); + static const MM3gppCmerInd expected_inds = ( \ + MM_3GPP_CMER_IND_DISABLE | \ + MM_3GPP_CMER_IND_ENABLE_NOT_CAUSED_BY_CIND); + + test_cmer_response (str, expected_modes, expected_inds); +} + +static void +test_cmer_response_sierra_em7345 (void) +{ + static const gchar *str = "+CMER: 1,0,0,(0-1),0"; + static const MM3gppCmerMode expected_modes = ( \ + MM_3GPP_CMER_MODE_DISCARD_URCS_IF_LINK_RESERVED); + static const MM3gppCmerInd expected_inds = ( \ + MM_3GPP_CMER_IND_DISABLE | \ + MM_3GPP_CMER_IND_ENABLE_NOT_CAUSED_BY_CIND); + + test_cmer_response (str, expected_modes, expected_inds); +} + +/*****************************************************************************/ /* Test CIND responses */ typedef struct { @@ -3726,6 +3776,9 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_cscs_buslink_support_response, NULL)); g_test_suite_add (suite, TESTCASE (test_cscs_blackberry_support_response, NULL)); + g_test_suite_add (suite, TESTCASE (test_cmer_response_cinterion_pls8, NULL)); + g_test_suite_add (suite, TESTCASE (test_cmer_response_sierra_em7345, NULL)); + g_test_suite_add (suite, TESTCASE (test_cind_response_linktop_lw273, NULL)); g_test_suite_add (suite, TESTCASE (test_cind_response_moto_v3m, NULL)); -- 2.12.2 _______________________________________________ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel