diff options
-rw-r--r-- | libmm-common/mm-common-helpers.c | 96 | ||||
-rw-r--r-- | libmm-common/mm-common-helpers.h | 16 | ||||
-rw-r--r-- | plugins/generic/mm-plugin-generic.c | 1 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 65 | ||||
-rw-r--r-- | src/mm-modem-helpers.c | 135 | ||||
-rw-r--r-- | src/mm-modem-helpers.h | 1 |
6 files changed, 166 insertions, 148 deletions
diff --git a/libmm-common/mm-common-helpers.c b/libmm-common/mm-common-helpers.c index d7209cb2..efc86d34 100644 --- a/libmm-common/mm-common-helpers.c +++ b/libmm-common/mm-common-helpers.c @@ -14,6 +14,8 @@ */ #include <string.h> +#include <errno.h> +#include <stdlib.h> #include <gio/gio.h> #include <ModemManager.h> @@ -500,3 +502,97 @@ mm_common_parse_key_value_string (const gchar *str, return TRUE; } + +/*****************************************************************************/ + +gboolean +mm_get_int_from_str (const gchar *str, + gint *out) +{ + glong num; + + errno = 0; + num = strtol (str, NULL, 10); + if (!errno && num >= G_MININT && num <= G_MAXINT) { + *out = (gint)num; + return TRUE; + } + return FALSE; +} + +gboolean +mm_get_int_from_match_info (GMatchInfo *match_info, + guint32 match_index, + gint *out) +{ + gchar *s; + gboolean ret; + + s = g_match_info_fetch (match_info, match_index); + g_return_val_if_fail (s != NULL, FALSE); + + ret = mm_get_int_from_str (s, out); + g_free (s); + + return ret; +} + +gboolean +mm_get_uint_from_str (const gchar *str, + guint *out) +{ + gulong num; + + errno = 0; + num = strtoul (str, NULL, 10); + if (!errno && num <= G_MAXUINT) { + *out = (guint)num; + return TRUE; + } + return FALSE; +} + +gboolean +mm_get_uint_from_match_info (GMatchInfo *match_info, + guint32 match_index, + guint *out) +{ + gchar *s; + gboolean ret; + + s = g_match_info_fetch (match_info, match_index); + g_return_val_if_fail (s != NULL, FALSE); + + ret = mm_get_uint_from_str (s, out); + g_free (s); + + return ret; +} + +gchar * +mm_get_string_unquoted_from_match_info (GMatchInfo *match_info, + guint32 match_index) +{ + gchar *str; + gsize len; + + str = g_match_info_fetch (match_info, match_index); + if (!str) + return NULL; + + len = strlen (str); + + /* Unquote the item if needed */ + if ((len >= 2) && (str[0] == '"') && (str[len - 1] == '"')) { + str[0] = ' '; + str[len - 1] = ' '; + str = g_strstrip (str); + } + + if (!str[0]) { + g_free (str); + return NULL; + } + + return str; +} diff --git a/libmm-common/mm-common-helpers.h b/libmm-common/mm-common-helpers.h index 30c82ffd..cec65f34 100644 --- a/libmm-common/mm-common-helpers.h +++ b/libmm-common/mm-common-helpers.h @@ -10,7 +10,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * - * Copyright (C) 2011 - Google, Inc. + * Copyright (C) 2011 - 2012 Google, Inc. + * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> */ #include <glib.h> @@ -56,5 +57,18 @@ gboolean mm_common_parse_key_value_string (const gchar *str, MMParseKeyValueForeachFn callback, gpointer user_data); +/* Common parsers */ +gboolean mm_get_int_from_str (const gchar *str, + gint *out); +gboolean mm_get_int_from_match_info (GMatchInfo *match_info, + guint32 match_index, + gint *out); +gboolean mm_get_uint_from_str (const gchar *str, + guint *out); +gboolean mm_get_uint_from_match_info (GMatchInfo *match_info, + guint32 match_index, + guint *out); +gchar *mm_get_string_unquoted_from_match_info (GMatchInfo *match_info, + guint32 match_index); #endif /* MM_COMMON_HELPERS_H */ diff --git a/plugins/generic/mm-plugin-generic.c b/plugins/generic/mm-plugin-generic.c index 41c56e25..02430838 100644 --- a/plugins/generic/mm-plugin-generic.c +++ b/plugins/generic/mm-plugin-generic.c @@ -17,7 +17,6 @@ #include <termios.h> #include <unistd.h> #include <fcntl.h> -#include <errno.h> #include <stdio.h> #include <string.h> #include <stdlib.h> diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index e7a95383..ec13e495 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -19,7 +19,6 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <errno.h> #include <string.h> #include <ctype.h> @@ -4225,51 +4224,6 @@ modem_messaging_load_initial_sms_parts_finish (MMIfaceModemMessaging *self, return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } -static gboolean -get_match_uint (GMatchInfo *m, - guint match_index, - guint *out_val) -{ - gchar *s; - gulong num; - - g_return_val_if_fail (out_val != NULL, FALSE); - - s = g_match_info_fetch (m, match_index); - g_return_val_if_fail (s != NULL, FALSE); - - errno = 0; - num = strtoul (s, NULL, 10); - g_free (s); - - if (num <= 1000 && errno == 0) { - *out_val = (guint) num; - return TRUE; - } - return FALSE; -} - -static gchar * -get_match_string_unquoted (GMatchInfo *m, - guint match_index) -{ - gchar *s, *p, *q, *ret = NULL; - - q = s = g_match_info_fetch (m, match_index); - g_return_val_if_fail (s != NULL, FALSE); - - /* remove quotes */ - if (*q == '"') - q++; - p = strchr (q, '"'); - if (p) - *p = '\0'; - if (*q) - ret = g_strdup (q); - g_free (s); - return ret; -} - static MMSmsState sms_state_from_str (const gchar *str) { @@ -4332,13 +4286,13 @@ sms_text_part_list_ready (MMBroadbandModem *self, goto next; } - if (!get_match_uint (match_info, 1, &idx)) { + if (!mm_get_uint_from_match_info (match_info, 1, &idx)) { mm_dbg ("Failed to convert message index"); goto next; } /* Get and parse number */ - number = get_match_string_unquoted (match_info, 3); + number = mm_get_string_unquoted_from_match_info (match_info, 3); if (!number) { mm_dbg ("Failed to get message sender number"); goto next; @@ -4348,7 +4302,7 @@ sms_text_part_list_ready (MMBroadbandModem *self, number); /* Get part state */ - stat = get_match_string_unquoted (match_info, 2); + stat = mm_get_string_unquoted_from_match_info (match_info, 2); if (!stat) { mm_dbg ("Failed to get part status"); g_free (number); @@ -4356,7 +4310,7 @@ sms_text_part_list_ready (MMBroadbandModem *self, } /* Get and parse timestamp (always expected in ASCII) */ - timestamp = get_match_string_unquoted (match_info, 5); + timestamp = mm_get_string_unquoted_from_match_info (match_info, 5); /* Get and parse text */ text = mm_broadband_modem_take_and_convert_to_utf8 (MM_BROADBAND_MODEM (self), @@ -4948,7 +4902,8 @@ css_query_ready (MMIfaceModemCdma *self, /* sid */ str = g_match_info_fetch (match_info, 3); - sid = mm_cdma_convert_sid (str); + if (!mm_get_int_from_str (str, &sid)) + sid = MM_MODEM_CDMA_SID_UNKNOWN; g_free (str); success = TRUE; @@ -5126,13 +5081,11 @@ cad_query_ready (MMIfaceModemCdma *self, if (error) g_simple_async_result_take_error (simple, error); else { - gulong int_cad; + guint cad; /* Strip any leading command tag and spaces */ result = mm_strip_tag (result, "+CAD:"); - errno = 0; - int_cad = strtol (result, NULL, 10); - if ((errno == EINVAL) || (errno == ERANGE)) + if (!mm_get_uint_from_str (result, &cad)) g_simple_async_result_set_error (simple, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, @@ -5140,7 +5093,7 @@ cad_query_ready (MMIfaceModemCdma *self, result); else /* 1 == CDMA service */ - g_simple_async_result_set_op_res_gboolean (simple, (int_cad == 1)); + g_simple_async_result_set_op_res_gboolean (simple, (cad == 1)); } g_simple_async_result_complete (simple); diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index 9a4a37ae..7302155e 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -22,7 +22,6 @@ #include <string.h> #include <ctype.h> #include <stdlib.h> -#include <errno.h> #include <ModemManager.h> #include <libmm-common.h> @@ -317,33 +316,6 @@ get_mm_access_tech_from_etsi_access_tech (guint act) } } -static gchar * -get_unquoted_scan_value (GMatchInfo *info, guint32 num) -{ - gchar *quoted; - gsize len; - - quoted = g_match_info_fetch (info, num); - if (!quoted) - return NULL; - - len = strlen (quoted); - - /* Unquote the item if needed */ - if ((len >= 2) && (quoted[0] == '"') && (quoted[len - 1] == '"')) { - quoted[0] = ' '; - quoted[len - 1] = ' '; - quoted = g_strstrip (quoted); - } - - if (!strlen (quoted)) { - g_free (quoted); - return NULL; - } - - return quoted; -} - static MMModem3gppNetworkAvailability parse_network_status (const gchar *str) { @@ -462,18 +434,18 @@ mm_3gpp_parse_cops_test_response (const gchar *reply, info = g_new0 (MM3gppNetworkInfo, 1); - tmp = get_unquoted_scan_value (match_info, 1); + tmp = mm_get_string_unquoted_from_match_info (match_info, 1); info->status = parse_network_status (tmp); g_free (tmp); - info->operator_long = get_unquoted_scan_value (match_info, 2); - info->operator_short = get_unquoted_scan_value (match_info, 3); - info->operator_code = get_unquoted_scan_value (match_info, 4); + info->operator_long = mm_get_string_unquoted_from_match_info (match_info, 2); + info->operator_short = mm_get_string_unquoted_from_match_info (match_info, 3); + info->operator_code = mm_get_string_unquoted_from_match_info (match_info, 4); /* Only try for access technology with UMTS-format matches. * If none give, assume GSM */ tmp = (umts_format ? - get_unquoted_scan_value (match_info, 5) : + mm_get_string_unquoted_from_match_info (match_info, 5) : NULL); info->access_tech = (tmp ? parse_access_tech (tmp) : @@ -569,14 +541,17 @@ mm_3gpp_parse_cgdcont_read_response (const gchar *reply, while (!inner_error && g_match_info_matches (match_info)) { MM3gppPdpContext *pdp; - gchar *cid; pdp = g_new0 (MM3gppPdpContext, 1); - cid = g_match_info_fetch (match_info, 1); - pdp->cid = (guint)atoi (cid); - pdp->pdp_type = get_unquoted_scan_value (match_info, 2); - pdp->apn = get_unquoted_scan_value (match_info, 3); - g_free (cid); + if (!mm_get_uint_from_match_info (match_info, 1, &pdp->cid)) { + inner_error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Couldn't parse CID from reply: '%s'", + reply); + break; + } + pdp->pdp_type = mm_get_string_unquoted_from_match_info (match_info, 2); + pdp->apn = mm_get_string_unquoted_from_match_info (match_info, 3); list = g_list_prepend (list, pdp); @@ -1240,33 +1215,29 @@ mm_3gpp_parse_cind_read_response (const gchar *reply, GError **error) { GByteArray *array = NULL; - const gchar *p = reply; GRegex *r = NULL; GMatchInfo *match_info; - guint8 t = 0; + GError *inner_error = NULL; + guint8 t; g_return_val_if_fail (reply != NULL, NULL); - if (!g_str_has_prefix (p, CIND_TAG)) { - g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not parse the +CIND response"); + if (!g_str_has_prefix (reply, CIND_TAG)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not parse the +CIND response '%s': no CIND tag found", + reply); return NULL; } - p += strlen (CIND_TAG); - while (isspace (*p)) - p++; + reply = mm_strip_tag (reply, CIND_TAG); r = g_regex_new ("(\\d+)[^0-9]+", G_REGEX_UNGREEDY, 0, NULL); - if (!r) { - g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Internal failure attempting to parse +CIND response"); - return NULL; - } + g_assert (r != NULL); - if (!g_regex_match_full (r, p, strlen (p), 0, 0, &match_info, NULL)) { - g_set_error_literal (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Failure parsing the +CIND response"); + if (!g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, NULL)) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not parse the +CIND response '%s': didn't match", + reply); goto done; } @@ -1275,27 +1246,34 @@ mm_3gpp_parse_cind_read_response (const gchar *reply, /* Add a zero element so callers can use 1-based indexes returned by * mm_3gpp_cind_response_get_index(). */ + t = 0; g_byte_array_append (array, &t, 1); - while (g_match_info_matches (match_info)) { + while (!inner_error && + g_match_info_matches (match_info)) { gchar *str; - gulong val; + guint val = 0; str = g_match_info_fetch (match_info, 1); - - errno = 0; - val = strtoul (str, NULL, 10); - - t = 0; - if ((errno == 0) && (val < 255)) + if (mm_get_uint_from_str (str, &val) && val < 255) { t = (guint8) val; - /* FIXME: indicate errors somehow? */ - g_byte_array_append (array, &t, 1); + g_byte_array_append (array, &t, 1); + } else { + inner_error = g_error_new (MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Could not parse the +CIND response: invalid index '%s'", + str); + } g_free (str); g_match_info_next (match_info, NULL); } + if (inner_error) { + g_propagate_error (error, inner_error); + g_byte_array_unref (array); + array = NULL; + } + done: g_match_info_free (match_info); g_regex_unref (r); @@ -1677,19 +1655,17 @@ static const EriItem eris[] = { gboolean mm_cdma_parse_speri_read_response (const gchar *reply, gboolean *out_roaming, - guint32 *out_ind, + guint *out_ind, const gchar **out_desc) { - glong ind; + guint ind; const EriItem *iter = &eris[0]; gboolean found = FALSE; g_return_val_if_fail (reply != NULL, FALSE); g_return_val_if_fail (out_roaming != NULL, FALSE); - errno = 0; - ind = strtol (reply, NULL, 10); - if (errno == 0) { + if (mm_get_uint_from_str (reply, &ind)) { if (out_ind) *out_ind = ind; @@ -1864,22 +1840,3 @@ mm_cdma_normalize_band (const gchar *long_band, /* Unknown/not registered */ return 'Z'; } - -/*************************************************************************/ - -gint -mm_cdma_convert_sid (const gchar *sid) -{ - glong tmp_sid; - - g_return_val_if_fail (sid != NULL, MM_MODEM_CDMA_SID_UNKNOWN); - - errno = 0; - tmp_sid = strtol (sid, NULL, 10); - if ((errno == EINVAL) || (errno == ERANGE)) - return MM_MODEM_CDMA_SID_UNKNOWN; - else if (tmp_sid < G_MININT || tmp_sid > G_MAXINT) - return MM_MODEM_CDMA_SID_UNKNOWN; - - return (gint) tmp_sid; -} diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 88a15247..10ec800e 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -186,6 +186,5 @@ guint mm_cdma_get_index_from_rm_protocol (MMModemCdmaRmProtocol protocol, gint mm_cdma_normalize_class (const gchar *orig_class); gchar mm_cdma_normalize_band (const gchar *long_band, gint *out_class); -gint mm_cdma_convert_sid (const gchar *sid); #endif /* MM_MODEM_HELPERS_H */ |