summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2014-02-26 15:51:11 +0100
committerAleksander Morgado <aleksander@aleksander.es>2014-02-28 16:35:18 +0100
commite6430acaaaa56eae95206a564109e2a04c99e7c5 (patch)
tree00e494a98dc76df790df293d34e413810d8da6ae
parent82067915d16a5e367346a3b62489b6efcb19f834 (diff)
cinterion: add helper to parse AT^SCFG="Radio/Band" response in 3G devices
-rw-r--r--plugins/cinterion/mm-broadband-modem-cinterion.c68
-rw-r--r--plugins/cinterion/mm-modem-helpers-cinterion.c71
-rw-r--r--plugins/cinterion/mm-modem-helpers-cinterion.h7
-rw-r--r--plugins/cinterion/tests/test-modem-helpers-cinterion.c60
4 files changed, 146 insertions, 60 deletions
diff --git a/plugins/cinterion/mm-broadband-modem-cinterion.c b/plugins/cinterion/mm-broadband-modem-cinterion.c
index ae43493c..688cd2e0 100644
--- a/plugins/cinterion/mm-broadband-modem-cinterion.c
+++ b/plugins/cinterion/mm-broadband-modem-cinterion.c
@@ -1102,72 +1102,22 @@ get_2g_band_ready (MMBroadbandModemCinterion *self,
static void
get_3g_band_ready (MMBroadbandModemCinterion *self,
GAsyncResult *res,
- GSimpleAsyncResult *operation_result)
+ GSimpleAsyncResult *simple)
{
const gchar *response;
GError *error = NULL;
- GArray *bands_array = NULL;
- GRegex *regex;
- GMatchInfo *match_info = NULL;
+ GArray *bands = NULL;
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
- if (!response) {
- /* Let the error be critical. */
- g_simple_async_result_take_error (operation_result, error);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
- return;
- }
-
- /* The AT^SCFG? command replies a list of several different config
- * values. We will only look for 'Radio/Band".
- *
- * AT+SCFG="Radio/Band"
- * ^SCFG: "Radio/Band",127
- *
- * Note that in this case, the <rba> replied is a number, not a string.
- */
- regex = g_regex_new ("\\^SCFG:\\s*\"Radio/Band\",\\s*(\\d*)", 0, 0, NULL);
- g_assert (regex != NULL);
-
- if (g_regex_match_full (regex, response, strlen (response), 0, 0, &match_info, NULL)) {
- gchar *current;
-
- current = g_match_info_fetch (match_info, 1);
- if (current) {
- guint32 current_int;
- guint i;
-
- current_int = (guint32) atoi (current);
-
- for (i = 0; i < G_N_ELEMENTS (bands_3g); i++) {
- if (current_int & bands_3g[i].cinterion_band_flag) {
- if (G_UNLIKELY (!bands_array))
- bands_array = g_array_new (FALSE, FALSE, sizeof (MMModemBand));
- g_array_append_val (bands_array, bands_3g[i].mm_band);
- }
- }
-
- g_free (current);
- }
- }
-
- if (match_info)
- g_match_info_free (match_info);
- g_regex_unref (regex);
-
- if (!bands_array)
- g_simple_async_result_set_error (operation_result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Couldn't parse current bands reply");
+ if (!response)
+ g_simple_async_result_take_error (simple, error);
+ else if (!mm_cinterion_parse_scfg_3g_response (response, &bands, &error))
+ g_simple_async_result_take_error (simple, error);
else
- g_simple_async_result_set_op_res_gpointer (operation_result,
- bands_array,
- (GDestroyNotify)g_array_unref);
+ g_simple_async_result_set_op_res_gpointer (simple, bands, (GDestroyNotify)g_array_unref);
- g_simple_async_result_complete (operation_result);
- g_object_unref (operation_result);
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
}
static void
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c
index 7e350512..8fe641b7 100644
--- a/plugins/cinterion/mm-modem-helpers-cinterion.c
+++ b/plugins/cinterion/mm-modem-helpers-cinterion.c
@@ -15,6 +15,7 @@
#include <config.h>
#include <string.h>
+#include <stdlib.h>
#include "ModemManager.h"
#define _LIBMM_INSIDE_MM
@@ -98,6 +99,8 @@ mm_cinterion_parse_scfg_3g_test (const gchar *response,
}
}
}
+
+ g_free (maxbandstr);
}
if (match_info)
@@ -119,3 +122,71 @@ mm_cinterion_parse_scfg_3g_test (const gchar *response,
return TRUE;
}
+
+/*****************************************************************************/
+/* ^SCFG (3G) response parser
+ *
+ * Example:
+ * AT^SCFG="Radio/Band"
+ * ^SCFG: "Radio/Band",127
+ */
+
+gboolean
+mm_cinterion_parse_scfg_3g_response (const gchar *response,
+ GArray **current_bands,
+ GError **error)
+{
+ GRegex *r;
+ GMatchInfo *match_info;
+ GError *inner_error = NULL;
+ GArray *bands = NULL;
+
+ if (!response) {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Missing response");
+ return FALSE;
+ }
+
+ r = g_regex_new ("\\^SCFG:\\s*\"Radio/Band\",\\s*(\\d*)", 0, 0, NULL);
+ g_assert (r != NULL);
+
+ if (g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, NULL)) {
+ gchar *current;
+
+ current = g_match_info_fetch (match_info, 1);
+ if (current) {
+ guint32 current_int;
+ guint i;
+
+ current_int = (guint32) atoi (current);
+
+ for (i = 0; i < G_N_ELEMENTS (bands_3g); i++) {
+ if (current_int & bands_3g[i].cinterion_band_flag) {
+ if (G_UNLIKELY (!bands))
+ bands = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 4);
+ g_array_append_val (bands, bands_3g[i].mm_band);
+ }
+ }
+
+ g_free (current);
+ }
+ }
+
+ if (match_info)
+ g_match_info_free (match_info);
+ g_regex_unref (r);
+
+ if (!bands)
+ inner_error = g_error_new (MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "No valid bands found in ^SCFG=? response");
+
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return FALSE;
+ }
+
+ g_assert (bands != NULL && bands->len > 0);
+ *current_bands = bands;
+
+ return TRUE;
+}
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.h b/plugins/cinterion/mm-modem-helpers-cinterion.h
index f71f951f..aa9f96aa 100644
--- a/plugins/cinterion/mm-modem-helpers-cinterion.h
+++ b/plugins/cinterion/mm-modem-helpers-cinterion.h
@@ -25,4 +25,11 @@ gboolean mm_cinterion_parse_scfg_3g_test (const gchar *response,
GArray **supported_bands,
GError **error);
+/*****************************************************************************/
+/* ^SCFG response parser */
+
+gboolean mm_cinterion_parse_scfg_3g_response (const gchar *response,
+ GArray **bands,
+ GError **error);
+
#endif /* MM_MODEM_HELPERS_CINTERION_H */
diff --git a/plugins/cinterion/tests/test-modem-helpers-cinterion.c b/plugins/cinterion/tests/test-modem-helpers-cinterion.c
index 4f9436f0..cc603992 100644
--- a/plugins/cinterion/tests/test-modem-helpers-cinterion.c
+++ b/plugins/cinterion/tests/test-modem-helpers-cinterion.c
@@ -115,6 +115,63 @@ test_scfg (void)
}
/*****************************************************************************/
+/* Test ^SCFG responses */
+
+static void
+common_test_scfg_response (const gchar *response,
+ GArray *expected_bands)
+{
+ GArray *bands = NULL;
+ gchar *expected_bands_str;
+ gchar *bands_str;
+ GError *error = NULL;
+ gboolean res;
+
+ res = mm_cinterion_parse_scfg_3g_response (response, &bands, &error);
+ g_assert_no_error (error);
+ g_assert (res == TRUE);
+ g_assert (bands != NULL);
+
+ g_array_sort (bands, (GCompareFunc)sort_band);
+ g_array_sort (expected_bands, (GCompareFunc)sort_band);
+
+ expected_bands_str = mm_common_build_bands_string ((const MMModemBand *)expected_bands->data,
+ expected_bands->len);
+ bands_str = mm_common_build_bands_string ((const MMModemBand *)bands->data,
+ bands->len);
+
+ /* Instead of comparing the array one by one, compare the strings built from the mask
+ * (we get a nicer error if it fails) */
+ g_assert_cmpstr (bands_str, ==, expected_bands_str);
+
+ g_free (bands_str);
+ g_free (expected_bands_str);
+}
+
+static void
+test_scfg_response (void)
+{
+ GArray *expected_bands;
+ MMModemBand single;
+ const gchar *response =
+ "^SCFG: \"Radio/Band\",127\r\n"
+ "\r\n";
+
+ expected_bands = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 9);
+ single = MM_MODEM_BAND_EGSM, g_array_append_val (expected_bands, single);
+ single = MM_MODEM_BAND_DCS, g_array_append_val (expected_bands, single);
+ single = MM_MODEM_BAND_PCS, g_array_append_val (expected_bands, single);
+ single = MM_MODEM_BAND_G850, g_array_append_val (expected_bands, single);
+ single = MM_MODEM_BAND_U2100, g_array_append_val (expected_bands, single);
+ single = MM_MODEM_BAND_U1900, g_array_append_val (expected_bands, single);
+ single = MM_MODEM_BAND_U850, g_array_append_val (expected_bands, single);
+
+ common_test_scfg_response (response, expected_bands);
+
+ g_array_unref (expected_bands);
+}
+
+/*****************************************************************************/
void
_mm_log (const char *loc,
@@ -143,7 +200,8 @@ int main (int argc, char **argv)
g_type_init ();
g_test_init (&argc, &argv, NULL);
- g_test_add_func ("/MM/cinterion/scfg", test_scfg);
+ g_test_add_func ("/MM/cinterion/scfg", test_scfg);
+ g_test_add_func ("/MM/cinterion/scfg/response", test_scfg_response);
return g_test_run ();
}