diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2019-09-25 11:28:53 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2019-10-17 10:51:50 +0200 |
commit | d6f9d5e9ec36e403be9836c55c8ffd19422605ef (patch) | |
tree | 04252ff9a7d3d8bf2bda8b1fb102a5f3873eb4ed /src/mm-modem-helpers.c | |
parent | 1f6c006976211111c1ccdbe7cbbd146c8338ba38 (diff) |
sim: load emergency numbers from EF_ECC
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, |