Add DCS decoder for Cell Broadcast
authorDenis Kenzior <denkenz@gmail.com>
Fri, 26 Jun 2009 00:15:50 +0000 (19:15 -0500)
committerDenis Kenzior <denkenz@gmail.com>
Fri, 3 Jul 2009 00:03:04 +0000 (19:03 -0500)
src/smsutil.c
src/smsutil.h

index 3825f32..671ff71 100644 (file)
@@ -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;
+}
+
index 77d3d3c..5d647fd 100644 (file)
@@ -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);