aboutsummaryrefslogtreecommitdiff
path: root/src/mm-modem-helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-modem-helpers.c')
-rw-r--r--src/mm-modem-helpers.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
index 69e8823e..ec07aada 100644
--- a/src/mm-modem-helpers.c
+++ b/src/mm-modem-helpers.c
@@ -4353,6 +4353,70 @@ mm_3gpp_parse_operator_id (const gchar *operator_id,
}
/*************************************************************************/
+/* Emergency numbers (+CRSM output) */
+
+GStrv
+mm_3gpp_parse_emergency_numbers (const char *raw, GError **error)
+{
+ gsize rawlen;
+ guint8 *bin;
+ gsize binlen;
+ gsize max_items;
+ GPtrArray *out;
+ guint i;
+
+ /* The emergency call code is of a variable length with a maximum length of
+ * 6 digits. Each emergency call code is coded on three bytes, with each
+ * digit within the code being coded on four bits. If a code of less that 6
+ * digits is chosen, then the unused nibbles shall be set to 'F'. */
+
+ rawlen = strlen (raw);
+ if (!rawlen) {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
+ "empty emergency numbers list");
+ return NULL;
+ }
+
+ if (rawlen % 6 != 0) {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
+ "invalid raw emergency numbers list length: %" G_GSIZE_FORMAT, rawlen);
+ return NULL;
+ }
+
+ bin = (guint8 *) mm_utils_hexstr2bin (raw, &binlen);
+ if (!bin) {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
+ "invalid raw emergency numbers list contents: %s", raw);
+ return NULL;
+ }
+
+ max_items = binlen / 3;
+ out = g_ptr_array_sized_new (max_items + 1);
+
+ for (i = 0; i < max_items; i++) {
+ gchar *number;
+
+ number = mm_bcd_to_string (&bin[i*3], 3);
+ if (number && number[0])
+ g_ptr_array_add (out, number);
+ else
+ g_free (number);
+ }
+
+ g_free (bin);
+
+ if (!out->len) {
+ g_ptr_array_unref (out);
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
+ "uninitialized emergency numbers list");
+ return NULL;
+ }
+
+ g_ptr_array_add (out, NULL);
+ return (GStrv) g_ptr_array_free (out, FALSE);
+}
+
+/*************************************************************************/
gboolean
mm_cdma_parse_spservice_read_response (const gchar *reply,