On 22/05/17 14:43, Aleksander Morgado wrote: > --- > > Hey Colin, > > Please try now with this v3 patch. I modified the helper method to allow the > comma-separated number sequence you get in your EHS5 for the modes, i.e.: > "(1,2)". The regex wasn't catching that logic, so instead of complicating it > too much, I switched to splitting the response into groups and then parsing > the groups we want independently. > > See if you get +CMER setting correctly run now. > > Cheers! >
This has been merged to git master. > --- > src/mm-modem-helpers.c | 123 > +++++++++++++++++++++++++++++++++++++++++ > src/mm-modem-helpers.h | 25 +++++++++ > src/tests/test-modem-helpers.c | 68 +++++++++++++++++++++++ > 3 files changed, 216 insertions(+) > > diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c > index 679f9252..ddf69406 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,119 @@ 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) > +{ > + gchar **split; > + GError *inner_error = 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) > + * > + * AT+CMER=? > + * +CMER: (1,2),0,0,(0-1),0 > + */ > + > + split = mm_split_string_groups (mm_strip_tag (response, "+CMER:")); > + if (!split) { > + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, > "Couldn't split +CMER test response in groups"); > + goto out; > + } > + > + /* We want 1st and 4th groups */ > + if (g_strv_length (split) < 4) { > + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, > "Missing groups in +CMER test response (%u < 4)", g_strv_length (split)); > + goto out; > + } > + > + /* Modes in 1st group */ > + if (!(array_supported_modes = mm_parse_uint_list (split[0], > &inner_error))) > + goto out; > + g_clear_pointer (&aux, g_free); > + > + /* Ind settings in 4th group */ > + if (!(array_supported_inds = mm_parse_uint_list (split[3], > &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_strfreev (split); > + > + 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..d6984d2d 100644 > --- a/src/tests/test-modem-helpers.c > +++ b/src/tests/test-modem-helpers.c > @@ -1867,6 +1867,70 @@ 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); > +} > + > +static void > +test_cmer_response_cinterion_ehs5 (void) > +{ > + static const gchar *str = "+CMER: (1,2),0,0,(0-1),0"; > + static const MM3gppCmerMode expected_modes = ( \ > + MM_3GPP_CMER_MODE_DISCARD_URCS_IF_LINK_RESERVED | \ > + MM_3GPP_CMER_MODE_BUFFER_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 +3790,10 @@ 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_cmer_response_cinterion_ehs5, > 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 > -- Aleksander https://aleksander.es _______________________________________________ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel