From 97d53bf0ecb6344b3cce2df7904275ea47dcaf23 Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Thu, 25 Jun 2009 19:15:50 -0500 Subject: [PATCH] Add DCS decoder for Cell Broadcast --- src/smsutil.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/smsutil.h | 28 +++++++++++++ 2 files changed, 136 insertions(+) diff --git a/src/smsutil.c b/src/smsutil.c index 3825f326..671ff710 100644 --- a/src/smsutil.c +++ b/src/smsutil.c @@ -2376,3 +2376,111 @@ GSList *sms_text_prepare(const char *utf8, guint16 ref, return r; } + +gboolean cbs_dcs_decode(guint8 dcs, gboolean *udhi, enum sms_class *cls, + enum sms_charset *charset, gboolean *compressed, + enum cbs_language *language, gboolean *iso639) +{ + guint8 upper = (dcs & 0xf0) >> 4; + guint8 lower = dcs & 0xf; + enum sms_charset ch; + enum sms_class cl; + enum cbs_language lang = CBS_LANGUAGE_UNSPECIFIED; + gboolean iso = FALSE; + gboolean comp = FALSE; + gboolean udh = FALSE; + + if (upper == 0x3 || upper == 0x8 || (upper >= 0xA && upper <= 0xE)) + return FALSE; + + switch (upper) { + case 0: + ch = SMS_CHARSET_7BIT; + cl = SMS_CLASS_UNSPECIFIED; + lang = (enum cbs_language)lower; + break; + case 1: + if (lower > 1) + return FALSE; + + if (lower == 0) + ch = SMS_CHARSET_7BIT; + else + ch = SMS_CHARSET_UCS2; + + cl = SMS_CLASS_UNSPECIFIED; + iso = TRUE; + + break; + case 2: + if (lower > 4) + return FALSE; + + ch = SMS_CHARSET_7BIT; + cl = SMS_CLASS_UNSPECIFIED; + lang = (enum cbs_language)dcs; + break; + case 4: + case 5: + case 6: + case 7: + comp = (dcs & 0x20) ? TRUE : FALSE; + + if (dcs & 0x10) + cl = (enum sms_class)(dcs & 0x03); + else + cl = SMS_CLASS_UNSPECIFIED; + + if (((dcs & 0x0c) >> 2) < 3) + ch = (enum sms_charset)((dcs & 0x0c) >> 2); + else + return FALSE; + case 9: + udh = TRUE; + cl = (enum sms_class)(dcs & 0x03); + if (((dcs & 0x0c) >> 2) < 3) + ch = (enum sms_charset)((dcs & 0x0c) >> 2); + else + return FALSE; + + break; + case 15: + if (lower & 0x8) + return FALSE; + + if (lower & 0x4) + ch = SMS_CHARSET_8BIT; + else + ch = SMS_CHARSET_7BIT; + + if (lower & 0x3) + cl = (enum sms_class)(lower & 0x3); + else + cl = SMS_CLASS_UNSPECIFIED; + + break; + default: + return FALSE; + }; + + if (udhi) + *udhi = udh; + + if (cls) + *cls = cl; + + if (charset) + *charset = ch; + + if (compressed) + *compressed = comp; + + if (language) + *language = lang; + + if (iso639) + *iso639 = iso; + + return TRUE; +} + diff --git a/src/smsutil.h b/src/smsutil.h index 77d3d3cb..5d647fdc 100644 --- a/src/smsutil.h +++ b/src/smsutil.h @@ -177,6 +177,30 @@ enum sms_pid_type { SMS_PID_TYPE_USIM_DOWNLOAD = 0x7f, }; +enum cbs_language { + CBS_LANGUAGE_GERMAN = 0x0, + CBS_LANGUAGE_ENGLISH = 0x1, + CBS_LANGUAGE_ITALIAN = 0x2, + CBS_LANGUAGE_FRENCH = 0x3, + CBS_LANGUAGE_SPANISH = 0x4, + CBS_LANGUAGE_DUTCH = 0x5, + CBS_LANGUAGE_SWEDISH = 0x6, + CBS_LANGUAGE_DANISH = 0x7, + CBS_LANGUAGE_PORTUGESE = 0x8, + CBS_LANGUAGE_FINNISH = 0x9, + CBS_LANGUAGE_NORWEGIAN = 0xA, + CBS_LANGUAGE_GREEK = 0xB, + CBS_LANGUAGE_TURKISH = 0xC, + CBS_LANGUAGE_HUNGARIAN = 0xD, + CBS_LANGUAGE_POLISH = 0xE, + CBS_LANGUAGE_UNSPECIFIED = 0xF, + CBS_LANGUAGE_CZECH = 0x20, + CBS_LANGUAGE_HEBREW = 0x21, + CBS_LANGUAGE_ARABIC = 0x22, + CBS_LANGUAGE_RUSSIAN = 0x23, + CBS_LANGUAGE_ICELANDIC = 0x24 +}; + struct sms_address { enum sms_number_type number_type; enum sms_numbering_plan numbering_plan; @@ -399,3 +423,7 @@ void sms_assembly_expire(struct sms_assembly *assembly, time_t before); GSList *sms_text_prepare(const char *utf8, guint16 ref, gboolean use_16bit, int *ref_offset); + +gboolean cbs_dcs_decode(guint8 dcs, gboolean *udhi, enum sms_class *cls, + enum sms_charset *charset, gboolean *compressed, + enum cbs_language *language, gboolean *iso639);