diff options
Diffstat (limited to 'src/mm-modem-helpers.c')
-rw-r--r-- | src/mm-modem-helpers.c | 64 |
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, |