cinterion: new 'AT+CNMI=?' parser helper
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include "ModemManager.h"
|
||||
#define _LIBMM_INSIDE_MM
|
||||
#include <libmm-glib.h>
|
||||
#include "mm-log.h"
|
||||
#include "mm-charsets.h"
|
||||
#include "mm-errors-types.h"
|
||||
#include "mm-modem-helpers-cinterion.h"
|
||||
@@ -234,6 +235,154 @@ mm_cinterion_parse_scfg_response (const gchar *response,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* +CNMI test parser
|
||||
*
|
||||
* Example (PHS8):
|
||||
* AT+CNMI=?
|
||||
* +CNMI: (0,1,2),(0,1),(0,2),(0),(1)
|
||||
*/
|
||||
|
||||
static GArray *
|
||||
read_number_list (const gchar *str)
|
||||
{
|
||||
GError *inner_error = NULL;
|
||||
GArray *out = NULL;
|
||||
GRegex *r;
|
||||
GMatchInfo *match_info;
|
||||
|
||||
if (!str)
|
||||
return NULL;
|
||||
|
||||
r = g_regex_new ("(\\d),?", G_REGEX_UNGREEDY, 0, NULL);
|
||||
g_assert (r != NULL);
|
||||
|
||||
g_regex_match_full (r, str, strlen (str), 0, 0, &match_info, &inner_error);
|
||||
while (!inner_error && g_match_info_matches (match_info)) {
|
||||
guint aux;
|
||||
|
||||
if (mm_get_uint_from_match_info (match_info, 1, &aux)) {
|
||||
if (!out)
|
||||
out = g_array_sized_new (FALSE, FALSE, sizeof (guint), 3);
|
||||
g_array_append_val (out, aux);
|
||||
}
|
||||
g_match_info_next (match_info, &inner_error);
|
||||
}
|
||||
|
||||
if (inner_error) {
|
||||
mm_warn ("Unexpected error matching +CNMI response: '%s'", inner_error->message);
|
||||
g_error_free (inner_error);
|
||||
}
|
||||
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (r);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
gboolean
|
||||
mm_cinterion_parse_cnmi_test (const gchar *response,
|
||||
GArray **supported_mode,
|
||||
GArray **supported_mt,
|
||||
GArray **supported_bm,
|
||||
GArray **supported_ds,
|
||||
GArray **supported_bfr,
|
||||
GError **error)
|
||||
{
|
||||
GRegex *r;
|
||||
GMatchInfo *match_info;
|
||||
GError *inner_error = NULL;
|
||||
|
||||
if (!response) {
|
||||
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
r = g_regex_new ("\\+CNMI:\\s*\\((.*)\\),\\((.*)\\),\\((.*)\\),\\((.*)\\),\\((.*)\\)",
|
||||
G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW,
|
||||
0, NULL);
|
||||
g_assert (r != NULL);
|
||||
|
||||
g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error);
|
||||
if (!inner_error && g_match_info_matches (match_info)) {
|
||||
if (supported_mode) {
|
||||
gchar *str;
|
||||
|
||||
str = mm_get_string_unquoted_from_match_info (match_info, 1);
|
||||
*supported_mode = read_number_list (str);
|
||||
g_free (str);
|
||||
}
|
||||
if (supported_mt) {
|
||||
gchar *str;
|
||||
|
||||
str = mm_get_string_unquoted_from_match_info (match_info, 2);
|
||||
*supported_mt = read_number_list (str);
|
||||
g_free (str);
|
||||
}
|
||||
if (supported_bm) {
|
||||
gchar *str;
|
||||
|
||||
str = mm_get_string_unquoted_from_match_info (match_info, 3);
|
||||
*supported_bm = read_number_list (str);
|
||||
g_free (str);
|
||||
}
|
||||
if (supported_ds) {
|
||||
gchar *str;
|
||||
|
||||
str = mm_get_string_unquoted_from_match_info (match_info, 4);
|
||||
*supported_ds = read_number_list (str);
|
||||
g_free (str);
|
||||
}
|
||||
if (supported_bfr) {
|
||||
gchar *str;
|
||||
|
||||
str = mm_get_string_unquoted_from_match_info (match_info, 5);
|
||||
*supported_bfr = read_number_list (str);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
if (match_info)
|
||||
g_match_info_free (match_info);
|
||||
g_regex_unref (r);
|
||||
|
||||
if ((supported_mode && *supported_mode == NULL) ||
|
||||
(supported_mt && *supported_mt == NULL) ||
|
||||
(supported_bm && *supported_bm == NULL) ||
|
||||
(supported_ds && *supported_ds == NULL) ||
|
||||
(supported_bfr && *supported_bfr == NULL))
|
||||
inner_error = g_error_new (MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_FAILED,
|
||||
"Error parsing +CNMI=? response");
|
||||
|
||||
if (inner_error) {
|
||||
if (supported_mode && *supported_mode) {
|
||||
g_array_unref (*supported_mode);
|
||||
*supported_mode = NULL;
|
||||
}
|
||||
if (supported_mt && *supported_mt) {
|
||||
g_array_unref (*supported_mt);
|
||||
*supported_mt = NULL;
|
||||
}
|
||||
if (supported_bm && *supported_bm) {
|
||||
g_array_unref (*supported_bm);
|
||||
*supported_bm = NULL;
|
||||
}
|
||||
if (supported_ds && *supported_ds) {
|
||||
g_array_unref (*supported_ds);
|
||||
*supported_ds = NULL;
|
||||
}
|
||||
if (supported_bfr && *supported_bfr) {
|
||||
g_array_unref (*supported_bfr);
|
||||
*supported_bfr = NULL;
|
||||
}
|
||||
g_propagate_error (error, inner_error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Build Cinterion-specific band value */
|
||||
|
||||
|
@@ -34,6 +34,17 @@ gboolean mm_cinterion_parse_scfg_response (const gchar *response,
|
||||
GArray **bands,
|
||||
GError **error);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* +CNMI test parser */
|
||||
|
||||
gboolean mm_cinterion_parse_cnmi_test (const gchar *response,
|
||||
GArray **supported_mode,
|
||||
GArray **supported_mt,
|
||||
GArray **supported_bm,
|
||||
GArray **supported_ds,
|
||||
GArray **supported_bfr,
|
||||
GError **error);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Build Cinterion-specific band value */
|
||||
|
||||
|
@@ -212,6 +212,123 @@ test_scfg_response_3g (void)
|
||||
g_array_unref (expected_bands);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Test ^SCFG test */
|
||||
|
||||
static void
|
||||
compare_arrays (const GArray *supported,
|
||||
const GArray *expected)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_assert_cmpuint (supported->len, ==, expected->len);
|
||||
for (i = 0; i < supported->len; i++) {
|
||||
gboolean found = FALSE;
|
||||
guint j;
|
||||
|
||||
for (j = 0; j < expected->len && !found; j++) {
|
||||
if (g_array_index (supported, guint, i) == g_array_index (expected, guint, j))
|
||||
found = TRUE;
|
||||
}
|
||||
g_assert (found);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
common_test_cnmi (const gchar *response,
|
||||
const GArray *expected_mode,
|
||||
const GArray *expected_mt,
|
||||
const GArray *expected_bm,
|
||||
const GArray *expected_ds,
|
||||
const GArray *expected_bfr)
|
||||
{
|
||||
GArray *supported_mode = NULL;
|
||||
GArray *supported_mt = NULL;
|
||||
GArray *supported_bm = NULL;
|
||||
GArray *supported_ds = NULL;
|
||||
GArray *supported_bfr = NULL;
|
||||
GError *error = NULL;
|
||||
gboolean res;
|
||||
|
||||
g_assert (expected_mode != NULL);
|
||||
g_assert (expected_mt != NULL);
|
||||
g_assert (expected_bm != NULL);
|
||||
g_assert (expected_ds != NULL);
|
||||
g_assert (expected_bfr != NULL);
|
||||
|
||||
res = mm_cinterion_parse_cnmi_test (response,
|
||||
&supported_mode,
|
||||
&supported_mt,
|
||||
&supported_bm,
|
||||
&supported_ds,
|
||||
&supported_bfr,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (res == TRUE);
|
||||
g_assert (supported_mode != NULL);
|
||||
g_assert (supported_mt != NULL);
|
||||
g_assert (supported_bm != NULL);
|
||||
g_assert (supported_ds != NULL);
|
||||
g_assert (supported_bfr != NULL);
|
||||
|
||||
compare_arrays (supported_mode, expected_mode);
|
||||
compare_arrays (supported_mt, expected_mt);
|
||||
compare_arrays (supported_bm, expected_bm);
|
||||
compare_arrays (supported_ds, expected_ds);
|
||||
compare_arrays (supported_bfr, expected_bfr);
|
||||
|
||||
g_array_unref (supported_mode);
|
||||
g_array_unref (supported_mt);
|
||||
g_array_unref (supported_bm);
|
||||
g_array_unref (supported_ds);
|
||||
g_array_unref (supported_bfr);
|
||||
}
|
||||
|
||||
static void
|
||||
test_cnmi_phs8 (void)
|
||||
{
|
||||
GArray *expected_mode;
|
||||
GArray *expected_mt;
|
||||
GArray *expected_bm;
|
||||
GArray *expected_ds;
|
||||
GArray *expected_bfr;
|
||||
guint val;
|
||||
const gchar *response =
|
||||
"+CNMI: (0,1,2),(0,1),(0,2),(0),(1)\r\n"
|
||||
"\r\n";
|
||||
|
||||
expected_mode = g_array_sized_new (FALSE, FALSE, sizeof (guint), 3);
|
||||
val = 0, g_array_append_val (expected_mode, val);
|
||||
val = 1, g_array_append_val (expected_mode, val);
|
||||
val = 2, g_array_append_val (expected_mode, val);
|
||||
|
||||
expected_mt = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2);
|
||||
val = 0, g_array_append_val (expected_mt, val);
|
||||
val = 1, g_array_append_val (expected_mt, val);
|
||||
|
||||
expected_bm = g_array_sized_new (FALSE, FALSE, sizeof (guint), 2);
|
||||
val = 0, g_array_append_val (expected_bm, val);
|
||||
val = 2, g_array_append_val (expected_bm, val);
|
||||
|
||||
expected_ds = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
|
||||
val = 0, g_array_append_val (expected_ds, val);
|
||||
|
||||
expected_bfr = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
|
||||
val = 1, g_array_append_val (expected_bfr, val);
|
||||
|
||||
common_test_cnmi (response,
|
||||
expected_mode,
|
||||
expected_mt,
|
||||
expected_bm,
|
||||
expected_ds,
|
||||
expected_bfr);
|
||||
|
||||
g_array_unref (expected_mode);
|
||||
g_array_unref (expected_mt);
|
||||
g_array_unref (expected_bm);
|
||||
g_array_unref (expected_ds);
|
||||
g_array_unref (expected_bfr);}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Test ^SIND responses */
|
||||
|
||||
@@ -281,6 +398,7 @@ int main (int argc, char **argv)
|
||||
g_test_add_func ("/MM/cinterion/scfg/response/3g", test_scfg_response_3g);
|
||||
g_test_add_func ("/MM/cinterion/scfg/response/2g", test_scfg_response_2g);
|
||||
g_test_add_func ("/MM/cinterion/scfg/response/2g/ucs2", test_scfg_response_2g_ucs2);
|
||||
g_test_add_func ("/MM/cinterion/cnmi/phs8", test_cnmi_phs8);
|
||||
g_test_add_func ("/MM/cinterion/sind/response/simstatus", test_sind_response_simstatus);
|
||||
|
||||
return g_test_run ();
|
||||
|
Reference in New Issue
Block a user