diff options
author | Andrzej Zaborowski <andrew.zaborowski@intel.com> | 2010-06-07 12:08:32 +0200 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2010-06-09 12:43:27 -0500 |
commit | 9f925b3620efbc88b31d6e651b3306a0b980e810 (patch) | |
tree | 9554aab9b9ec1237cc6c997033b752c0edd8614d /src | |
parent | 6120e487b5d8cc946ea35a68cdda2a3897adde68 (diff) | |
download | ofono-9f925b3620efbc88b31d6e651b3306a0b980e810.tar.bz2 |
util: Add a "sim string" encoding utility.
Diffstat (limited to 'src')
-rw-r--r-- | src/simutil.c | 25 | ||||
-rw-r--r-- | src/util.c | 46 | ||||
-rw-r--r-- | src/util.h | 3 |
3 files changed, 59 insertions, 15 deletions
diff --git a/src/simutil.c b/src/simutil.c index f980bf69..7291729e 100644 --- a/src/simutil.c +++ b/src/simutil.c @@ -1232,29 +1232,24 @@ void sim_adn_build(unsigned char *data, int length, const char *identifier) { int number_len = strlen(ph->number); - unsigned char *gsm_identifier = NULL; - long gsm_bytes; - long alpha_length; + unsigned char *alpha = NULL; + int alpha_written = 0; + int alpha_length; alpha_length = length - 14; /* Alpha-Identifier field */ if (alpha_length > 0) { - memset(data, 0xff, alpha_length); - if (identifier) - gsm_identifier = convert_utf8_to_gsm(identifier, - -1, NULL, &gsm_bytes, 0); - - if (gsm_identifier) { - memcpy(data, gsm_identifier, - MIN(gsm_bytes, alpha_length)); - g_free(gsm_identifier); + alpha = utf8_to_sim_string(identifier, alpha_length, + &alpha_written); + if (alpha) { + memcpy(data, alpha, alpha_written); + g_free(alpha); } - /* TODO: figure out when the identifier needs to - * be encoded in UCS2 and do this. - */ + memset(data + alpha_written, 0xff, + alpha_length - alpha_written); data += alpha_length; } @@ -1215,3 +1215,49 @@ char *sim_string_to_utf8(const unsigned char *buffer, int length) return utf8; } + +unsigned char *utf8_to_sim_string(const char *utf, + int max_length, int *out_length) +{ + unsigned char *result; + unsigned char *ucs2; + long gsm_bytes; + gsize converted; + + result = convert_utf8_to_gsm(utf, -1, NULL, &gsm_bytes, 0); + if (result) { + if (gsm_bytes > max_length) { + gsm_bytes = max_length; + while (gsm_bytes && result[gsm_bytes - 1] == 0x1b) + gsm_bytes -= 1; + } + + *out_length = gsm_bytes; + return result; + } + + /* NOTE: UCS2 formats with an offset are never used */ + + ucs2 = (guint8 *) g_convert(utf, -1, "UCS-2BE//TRANSLIT", "UTF-8", + NULL, &converted, NULL); + + if (!ucs2) + return NULL; + + if (max_length != -1 && (int) converted + 1 > max_length) + converted = (max_length - 1) & ~1; + + result = g_try_malloc(converted + 1); + if (!result) { + g_free(ucs2); + return NULL; + } + + *out_length = converted + 1; + + result[0] = 0x80; + memcpy(&result[1], ucs2, converted); + g_free(ucs2); + + return result; +} @@ -77,3 +77,6 @@ unsigned char *pack_7bit(const unsigned char *in, long len, int byte_offset, long *items_written, unsigned char terminator); char *sim_string_to_utf8(const unsigned char *buffer, int length); + +unsigned char *utf8_to_sim_string(const char *utf, + int max_length, int *out_length); |