diff options
author | Aki Niemi <aki.niemi@nokia.com> | 2009-09-04 17:36:54 +0300 |
---|---|---|
committer | Aki Niemi <aki.niemi@nokia.com> | 2009-09-08 14:16:24 +0300 |
commit | dab84882afc1285c9680b0fb065259d6d0f9875b (patch) | |
tree | 40e348095b44c9d2e7eff443dec8a4d1b44777b2 | |
parent | a8fb6bf356b29524b3eae35b07145c0f40200720 (diff) | |
download | ofono-dab84882afc1285c9680b0fb065259d6d0f9875b.tar.bz2 |
Use SMS national language identifier when decoding
Adds support for decoding SMSs encoded using national language single
shift and locking shift tables.
-rw-r--r-- | src/smsutil.c | 63 | ||||
-rw-r--r-- | src/smsutil.h | 2 |
2 files changed, 63 insertions, 2 deletions
diff --git a/src/smsutil.c b/src/smsutil.c index fcff9aa6..573bc170 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -1936,6 +1936,59 @@ gboolean sms_extract_concatenation(const struct sms *sms, guint16 *ref_num, return TRUE; } +gboolean sms_extract_language_variant(const struct sms *sms, guint8 *locking, + guint8 *single) +{ + struct sms_udh_iter iter; + enum sms_iei iei; + guint8 variant; + + /* We must ignore the entire user_data header here: + * If the length of the User Data Header is such that there + * are too few or too many octets in the final Information + * Element then the whole User Data Header shall be ignored. + */ + if (!sms_udh_iter_init(sms, &iter)) + return FALSE; + + /* According to the specification, we have to use the last + * useable header: + * In the event that IEs determined as not repeatable are + * duplicated, the last occurrence of the IE shall be used. + * In the event that two or more IEs occur which have mutually + * exclusive meanings (e.g. an 8bit port address and a 16bit + * port address), then the last occurring IE shall be used. + */ + while ((iei = sms_udh_iter_get_ie_type(&iter)) != + SMS_IEI_INVALID) { + switch (iei) { + case SMS_IEI_NATIONAL_LANGUAGE_SINGLE_SHIFT: + if (sms_udh_iter_get_ie_length(&iter) != 1) + break; + + sms_udh_iter_get_ie_data(&iter, &variant); + if (single) + *single = variant; + break; + + case SMS_IEI_NATIONAL_LANGUAGE_LOCKING_SHIFT: + if (sms_udh_iter_get_ie_length(&iter) != 1) + break; + + sms_udh_iter_get_ie_data(&iter, &variant); + if (locking) + *locking = variant; + break; + default: + break; + } + + sms_udh_iter_next(&iter); + } + + return TRUE; +} + /*! * Decodes a list of SMSes that contain a datagram. The list must be * sorted in order of the sequence number. This function assumes that @@ -2063,6 +2116,8 @@ char *sms_decode_text(GSList *sms_list) if (charset == SMS_CHARSET_7BIT) { unsigned char buf[160]; long written; + guint8 locking_shift = 0; + guint8 single_shift = 0; int max_chars = sms_text_capacity_gsm(udl, taken); unpack_7bit_own_buf(ud + taken, udl_in_bytes - taken, @@ -2073,8 +2128,12 @@ char *sms_decode_text(GSList *sms_list) if (buf[written-1] == 0x1b) written = written - 1; - converted = convert_gsm_to_utf8(buf, written, - NULL, NULL, 0); + sms_extract_language_variant(sms, &locking_shift, &single_shift); + + converted = convert_gsm_to_utf8_with_lang(buf, written, + NULL, NULL, 0, + locking_shift, + single_shift); } else { const gchar *from = (const gchar *)(ud + taken); /* According to the spec: A UCS2 character shall not be diff --git a/src/smsutil.h b/src/smsutil.h index 95d0c78e..93cdf973 100644 --- a/src/smsutil.h +++ b/src/smsutil.h @@ -450,6 +450,8 @@ gboolean sms_extract_app_port(const struct sms *sms, int *dst, int *src, gboolean *is_8bit); gboolean sms_extract_concatenation(const struct sms *sms, guint16 *ref_num, guint8 *max_msgs, guint8 *seq_num); +gboolean sms_extract_language_variant(const struct sms *sms, guint8 *locking, + guint8 *single); unsigned char *sms_decode_datagram(GSList *sms_list, long *out_len); char *sms_decode_text(GSList *sms_list); |