aboutsummaryrefslogtreecommitdiff
path: root/plugins/cinterion/mm-modem-helpers-cinterion.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2014-06-25 15:04:09 +0200
committerAleksander Morgado <aleksander@aleksander.es>2014-06-25 15:04:09 +0200
commit58d2806f4cceba6adde76d5df8f0781129bc7e1f (patch)
treeb677e64d2041029b2663953e7b2807a40fbea978 /plugins/cinterion/mm-modem-helpers-cinterion.c
parent08ecc147221b6f02c6db83d16b7c241efdfbc91e (diff)
cinterion: new 'AT+CNMI=?' parser helper
Diffstat (limited to 'plugins/cinterion/mm-modem-helpers-cinterion.c')
-rw-r--r--plugins/cinterion/mm-modem-helpers-cinterion.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c
index 118cbb67..bffe00a9 100644
--- a/plugins/cinterion/mm-modem-helpers-cinterion.c
+++ b/plugins/cinterion/mm-modem-helpers-cinterion.c
@@ -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"
@@ -235,6 +236,154 @@ mm_cinterion_parse_scfg_response (const gchar *response,
}
/*****************************************************************************/
+/* +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 */
gboolean