aboutsummaryrefslogtreecommitdiff
path: root/plugins/cinterion/mm-modem-helpers-cinterion.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/cinterion/mm-modem-helpers-cinterion.c')
-rw-r--r--plugins/cinterion/mm-modem-helpers-cinterion.c134
1 files changed, 70 insertions, 64 deletions
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c
index 6312e782..b9693b80 100644
--- a/plugins/cinterion/mm-modem-helpers-cinterion.c
+++ b/plugins/cinterion/mm-modem-helpers-cinterion.c
@@ -489,77 +489,83 @@ mm_cinterion_parse_sind_response (const gchar *response,
/*****************************************************************************/
/* ^SWWAN read parser
+ *
* Description: Parses <cid>, <state>[, <WWAN adapter>] or CME ERROR from SWWAN.
- * Return: False if error occured while trying to parse SWWAN.
- * Read Command
- * AT^SWWAN?
- * Response(s)
- * [^SWWAN: <cid>, <state>[, <WWAN adapter>]]
- * [^SWWAN: ...]
- * OK
- * ERROR
- * +CME ERROR: <err>
- *
- * Examples:
- * OK - If no WWAN connection is active, then read command just returns OK
- * ^SWWAN: 3,1,1 - 3rd PDP Context, Activated, First WWAN Adaptor
- * +CME ERROR: ? -
-*/
-
-gboolean
-mm_cinterion_parse_swwan_response (const gchar *response,
- GList **result,
- GError **error)
+ *
+ * The method returns a MMSwwanState with the connection status of a single
+ * PDP context, the one being queried via the cid given as input.
+ *
+ * Note that we use CID for matching because the WWAN adapter field is optional
+ * it seems.
+ *
+ * Read Command
+ * AT^SWWAN?
+ * Response(s)
+ * [^SWWAN: <cid>, <state>[, <WWAN adapter>]]
+ * [^SWWAN: ...]
+ * OK
+ * ERROR
+ * +CME ERROR: <err>
+ *
+ * Examples:
+ * OK - If no WWAN connection is active, then read command just returns OK
+ * ^SWWAN: 3,1,1 - 3rd PDP Context, Activated, First WWAN Adaptor
+ * +CME ERROR: ? -
+ */
+MMSwwanState
+mm_cinterion_parse_swwan_response (const gchar *response,
+ guint cid,
+ GError **error)
{
- if (*error)
- return FALSE;
-
- if (!response) {
- g_set_error (error,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Recieved NULL from SWWAN response.");
- return FALSE;
+ GRegex *r;
+ GMatchInfo *match_info;
+ GError *inner_error = NULL;
+ MMSwwanState state;
+
+ g_assert (response);
+
+ /* If no WWAN connection is active, then ^SWWAN read command just returns OK
+ * (which we receive as an empty string) */
+ if (!response[0])
+ return MM_SWWAN_STATE_DISCONNECTED;
+
+ if (!g_str_has_prefix (response, "^SWWAN:")) {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Couldn't parse ^SWWAN response: '%s'", response);
+ return MM_SWWAN_STATE_UNKNOWN;
}
- /* Parse for [^SWWAN: <cid>, <state>[, <WWAN adapter>]] */
- if (strcasestr (response, "SWWAN")) {
- gint matched;
- guint cid, state, wwan_adapter;
- matched = sscanf (response, "^SWWAN: %d,%d,%d",
- &cid,
- &state,
- &wwan_adapter);
-
- if (matched != 3 ||
- cid < 1 || cid > 16 ||
- state < 0 || state > 1 ||
- wwan_adapter < 1 || wwan_adapter > 2) {
- g_set_error (error,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Invalid format for SWWAN response: '%s'",
- response);
- return FALSE;
+ r = g_regex_new ("\\^SWWAN:\\s*(\\d+),\\s*(\\d+)(?:,\\s*(\\d+))?(?:\\r\\n)?",
+ G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW, 0, NULL);
+ g_assert (r != NULL);
+
+ state = MM_SWWAN_STATE_UNKNOWN;
+ g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, &inner_error);
+ while (!inner_error && g_match_info_matches (match_info)) {
+ guint read_state;
+ guint read_cid;
+
+ if (!mm_get_uint_from_match_info (match_info, 1, &read_cid))
+ mm_warn ("Couldn't read cid in ^SWWAN response: '%s'", response);
+ else if (!mm_get_uint_from_match_info (match_info, 2, &read_state))
+ mm_warn ("Couldn't read state in ^SWWAN response: '%s'", response);
+ else if (read_cid == cid) {
+ if (read_state == MM_SWWAN_STATE_CONNECTED || read_state == MM_SWWAN_STATE_DISCONNECTED) {
+ state = (MMSwwanState) read_state;
+ break;
+ }
+ mm_warn ("Invalid state read in ^SWWAN response: %u", read_state);
}
- *result = g_list_append (*result, GINT_TO_POINTER(cid));
- *result = g_list_append (*result, GINT_TO_POINTER(state));
- *result = g_list_append (*result, GINT_TO_POINTER(wwan_adapter));
- }
- /* TODO: It'd be nice to get 'OK' from response so we don't have to assume that
- * zero length response means 'OK' or am I doing it wrong?... */
- else if (!g_utf8_strlen (response, 100))
- *result = g_list_append (*result, GINT_TO_POINTER(0));
- else {
- g_set_error (error,
- MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "Could not parse SWWAN response: '%s'",
- response);
- return FALSE;
+ g_match_info_next (match_info, &inner_error);
}
+ g_match_info_free (match_info);
+ g_regex_unref (r);
- return TRUE;
+ if (state == MM_SWWAN_STATE_UNKNOWN)
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "No state returned for CID %u", cid);
+
+ return state;
}