summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-08-15 12:14:19 +0200
committerAleksander Morgado <aleksander@aleksander.es>2016-10-12 13:24:09 +0200
commite6e53467ee738b493cc89c750818ccb688fb5d5f (patch)
tree1a1d75ebee4d2012bb5911257a78257743fec3fd
parent1775544dbc737c40aae31516f8ecc4d1822aac22 (diff)
downloadModemManager-e6e53467ee738b493cc89c750818ccb688fb5d5f.tar.gz
ublox: new +UGCNTRD? response parser
The parser returns only the results for the CID being specified as input. This is so that we can just query the statistics of the CID currently in use by the bearer.
-rw-r--r--plugins/ublox/mm-modem-helpers-ublox.c90
-rw-r--r--plugins/ublox/mm-modem-helpers-ublox.h11
-rw-r--r--plugins/ublox/tests/test-modem-helpers-ublox.c80
3 files changed, 181 insertions, 0 deletions
diff --git a/plugins/ublox/mm-modem-helpers-ublox.c b/plugins/ublox/mm-modem-helpers-ublox.c
index 0dc71c06c..2e314675d 100644
--- a/plugins/ublox/mm-modem-helpers-ublox.c
+++ b/plugins/ublox/mm-modem-helpers-ublox.c
@@ -956,3 +956,93 @@ mm_ublox_build_urat_set_command (MMModemMode allowed,
return g_string_free (command, FALSE);
}
+
+/*****************************************************************************/
+/* +UGCNTRD response parser */
+
+gboolean
+mm_ublox_parse_ugcntrd_response_for_cid (const gchar *response,
+ guint in_cid,
+ guint *out_session_tx_bytes,
+ guint *out_session_rx_bytes,
+ guint *out_total_tx_bytes,
+ guint *out_total_rx_bytes,
+ GError **error)
+{
+ GRegex *r;
+ GMatchInfo *match_info;
+ GError *inner_error = NULL;
+ guint session_tx_bytes = 0;
+ guint session_rx_bytes = 0;
+ guint total_tx_bytes = 0;
+ guint total_rx_bytes = 0;
+ gboolean matched = FALSE;
+
+ /* Response may be e.g.:
+ * +UGCNTRD: 31,2704,1819,2724,1839
+ * We assume only ONE line is returned.
+ */
+ r = g_regex_new ("\\+UGCNTRD:\\s*(\\d+),\\s*(\\d+),\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)",
+ 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);
+ while (!inner_error && g_match_info_matches (match_info)) {
+ guint cid = 0;
+
+ /* Matched CID? */
+ if (!mm_get_uint_from_match_info (match_info, 1, &cid) || cid != in_cid) {
+ g_match_info_next (match_info, &inner_error);
+ continue;
+ }
+
+ if (out_session_tx_bytes && !mm_get_uint_from_match_info (match_info, 2, &session_tx_bytes)) {
+ inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing session TX bytes");
+ goto out;
+ }
+
+ if (out_session_rx_bytes && !mm_get_uint_from_match_info (match_info, 3, &session_rx_bytes)) {
+ inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing session RX bytes");
+ goto out;
+ }
+
+ if (out_total_tx_bytes && !mm_get_uint_from_match_info (match_info, 4, &total_tx_bytes)) {
+ inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing total TX bytes");
+ goto out;
+ }
+
+ if (out_total_rx_bytes && !mm_get_uint_from_match_info (match_info, 5, &total_rx_bytes)) {
+ inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Error parsing total RX bytes");
+ goto out;
+ }
+
+ matched = TRUE;
+ break;
+ }
+
+ if (!matched) {
+ inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "No statistics found for CID %u", in_cid);
+ goto out;
+ }
+
+out:
+
+ if (match_info)
+ g_match_info_free (match_info);
+ g_regex_unref (r);
+
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ return FALSE;
+ }
+
+ if (out_session_tx_bytes)
+ *out_session_tx_bytes = session_tx_bytes;
+ if (out_session_rx_bytes)
+ *out_session_rx_bytes = session_rx_bytes;
+ if (out_total_tx_bytes)
+ *out_total_tx_bytes = total_tx_bytes;
+ if (out_total_rx_bytes)
+ *out_total_rx_bytes = total_rx_bytes;
+ return TRUE;
+}
diff --git a/plugins/ublox/mm-modem-helpers-ublox.h b/plugins/ublox/mm-modem-helpers-ublox.h
index 065205976..fc25feedd 100644
--- a/plugins/ublox/mm-modem-helpers-ublox.h
+++ b/plugins/ublox/mm-modem-helpers-ublox.h
@@ -126,4 +126,15 @@ gchar *mm_ublox_build_urat_set_command (MMModemMode allowed,
MMModemMode preferred,
GError **error);
+/*****************************************************************************/
+/* +UGCNTRD response parser */
+
+gboolean mm_ublox_parse_ugcntrd_response_for_cid (const gchar *response,
+ guint in_cid,
+ guint *session_tx_bytes,
+ guint *session_rx_bytes,
+ guint *total_tx_bytes,
+ guint *total_rx_bytes,
+ GError **error);
+
#endif /* MM_MODEM_HELPERS_UBLOX_H */
diff --git a/plugins/ublox/tests/test-modem-helpers-ublox.c b/plugins/ublox/tests/test-modem-helpers-ublox.c
index 67620a237..34896afc0 100644
--- a/plugins/ublox/tests/test-modem-helpers-ublox.c
+++ b/plugins/ublox/tests/test-modem-helpers-ublox.c
@@ -725,6 +725,84 @@ test_ubandsel_request_1800 (void)
}
/*****************************************************************************/
+/* Test +UGCNTRD responses */
+
+typedef struct {
+ const gchar *str;
+ guint cid;
+ guint session_tx_bytes;
+ guint session_rx_bytes;
+ guint total_tx_bytes;
+ guint total_rx_bytes;
+} UgcntrdResponseTest;
+
+static const UgcntrdResponseTest ugcntrd_response_tests[] = {
+ {
+ .str = "+UGCNTRD: 1, 100, 0, 100, 0",
+ .cid = 1,
+ .session_tx_bytes = 100,
+ .session_rx_bytes = 0,
+ .total_tx_bytes = 100,
+ .total_rx_bytes = 0
+ },
+ {
+ .str = "+UGCNTRD: 31,2704,1819,2724,1839",
+ .cid = 31,
+ .session_tx_bytes = 2704,
+ .session_rx_bytes = 1819,
+ .total_tx_bytes = 2724,
+ .total_rx_bytes = 1839
+ },
+ {
+ .str = "+UGCNTRD: 1, 100, 0, 100, 0\r\n"
+ "+UGCNTRD: 31,2704,1819,2724,1839\r\n",
+ .cid = 1,
+ .session_tx_bytes = 100,
+ .session_rx_bytes = 0,
+ .total_tx_bytes = 100,
+ .total_rx_bytes = 0
+ },
+ {
+ .str = "+UGCNTRD: 1, 100, 0, 100, 0\r\n"
+ "+UGCNTRD: 31,2704,1819,2724,1839\r\n",
+ .cid = 31,
+ .session_tx_bytes = 2704,
+ .session_rx_bytes = 1819,
+ .total_tx_bytes = 2724,
+ .total_rx_bytes = 1839
+ }
+};
+
+static void
+test_ugcntrd_response (void)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (ugcntrd_response_tests); i++) {
+ GError *error = NULL;
+ gboolean success;
+ guint session_tx_bytes = G_MAXUINT;
+ guint session_rx_bytes = G_MAXUINT;
+ guint total_tx_bytes = G_MAXUINT;
+ guint total_rx_bytes = G_MAXUINT;
+
+ success = mm_ublox_parse_ugcntrd_response_for_cid (ugcntrd_response_tests[i].str,
+ ugcntrd_response_tests[i].cid,
+ &session_tx_bytes,
+ &session_rx_bytes,
+ &total_tx_bytes,
+ &total_rx_bytes,
+ &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert_cmpuint (ugcntrd_response_tests[i].session_tx_bytes, ==, session_tx_bytes);
+ g_assert_cmpuint (ugcntrd_response_tests[i].session_rx_bytes, ==, session_rx_bytes);
+ g_assert_cmpuint (ugcntrd_response_tests[i].total_tx_bytes, ==, total_tx_bytes);
+ g_assert_cmpuint (ugcntrd_response_tests[i].total_rx_bytes, ==, total_rx_bytes);
+ }
+}
+
+/*****************************************************************************/
void
_mm_log (const char *loc,
@@ -780,5 +858,7 @@ int main (int argc, char **argv)
g_test_add_func ("/MM/ublox/ubandsel/request/2g", test_ubandsel_request_2g);
g_test_add_func ("/MM/ublox/ubandsel/request/1800", test_ubandsel_request_1800);
+ g_test_add_func ("/MM/ublox/ugcntrd/response", test_ugcntrd_response);
+
return g_test_run ();
}