More robust and stable
[ussd-widget] / ussd-common / src / usr / lib / python2.5 / gsmdecode.py
1 LANG_DE = 0x0
2 LANG_EN = 0x1
3 LANG_IT = 0x2
4 LANG_FR = 0x3
5 LANG_ES = 0x4
6 LANG_NL = 0x5
7 LANG_SE = 0x6
8 LANG_DA = 0x7
9 LANG_PO = 0x8
10 LANG_FI = 0x9
11 LANG_NO = 0xa
12 LANG_GR = 0xb
13 LANG_TR = 0xc
14 LANG_UNSPECIFIED = 0xf
15
16
17 GSM_DEFAULT_ALPHABET = [
18     u"@",
19     u"\u00a3",
20     u"$",
21     u"\u00a5",
22     u"\u00e8",
23     u"\u00e9",
24     u"\u00f9",
25     u"\u00ec",
26     u"\u00f2",
27     u"\u00c7",
28     u"\n",
29     u"\u00d8",
30     u"\u00f8",
31     u"\r",
32     u"\u00c5",
33     u"\u00e5",
34     
35     u"\u0394",
36     u"_",
37     u"\u03a6",
38     u"\u0393",
39     u"\u039b",
40     u"\u03a9",
41     u"\u03a0",
42     u"\u03a8",
43     u"\u03a3",
44     u"\u0398",
45     u"\u039e",
46     u" ",
47     u"\u00c6",
48     u"\u00e6",
49     u"\u00df",
50     u"\u00c9",
51     
52     u" ",
53     u"!",
54     u"\"",
55     u"#",
56     u"\u00a4",
57     u"%",
58     u"&",
59     u"'",
60     u"(",
61     u")",
62     u"*",
63     u"+",
64     u",",
65     u"-",
66     u".",
67     u"/",
68     
69     u"0",
70     u"1",
71     u"2",
72     u"3",
73     u"4",
74     u"5",
75     u"6",
76     u"7",
77     u"8",
78     u"9",
79     u":",
80     u";",
81     u"<",
82     u"=",
83     u">",
84     u"?",
85     
86     u"\u00a1",
87     u"A",
88     u"B",
89     u"C",
90     u"D",
91     u"E",
92     u"F",
93     u"G",
94     u"H",
95     u"I",
96     u"J",
97     u"K",
98     u"L",
99     u"M",
100     u"N",
101     u"O",
102     
103     u"P",
104     u"Q",
105     u"R",
106     u"S",
107     u"T",
108     u"U",
109     u"V",
110     u"W",
111     u"X",
112     u"Y",
113     u"Z",
114     u"\u00c4",
115     u"\u00d6",
116     u"\u00d1",
117     u"\u00dc",
118     u"\u00a7",
119
120     u"\u00bf",
121     u"a",
122     u"b",
123     u"c",
124     u"d",
125     u"e",
126     u"f",
127     u"g",
128     u"h",
129     u"i",
130     u"j",
131     u"k",
132     u"l",
133     u"m",
134     u"n",
135     u"o",
136
137     u"p",
138     u"q",
139     u"r",
140     u"s",
141     u"t",
142     u"u",
143     u"v",
144     u"w",
145     u"x",
146     u"y",
147     u"z",
148     u"\u00e4",
149     u"\u00f6",
150     u"\u00f1",
151     u"\u00fc",
152     u"\u00e0"
153 ]
154
155
156 def decode(s, n):
157     """
158     Decodes the given string using the given cell broadcast data coding scheme.
159     
160     @param s: string to decode
161     @param n: GSM cell broadcast data coding scheme
162     @return: UTF-8 string
163     """
164
165     # separate into nibbles
166     hbits = (n & 0xf0) >> 4
167     lbits = (n & 0x0f)
168     
169     if (hbits == 0x0):
170         # language
171         return _decode_language(s, lbits)
172
173     elif (0x1 <= hbits <= 0x3):
174         # reserved language
175         return s
176         
177     elif (0x4 <= hbits <= 0x7):
178         # general data coding indication
179         return _decode_general_data_coding(s, hbits, lbits)
180         
181     elif (0x8 <= hbits <= 0xe):
182         # reserved coding group
183         return s
184         
185     elif (hbits == 0xf):
186         # data coding / message handling
187         return s
188
189
190 def _decode_language(s, lang):
191
192     return _decode_default_alphabet(s)
193
194
195 def _decode_default_alphabet(s):
196     
197     # TODO: we really might have to do 7 bit character unpacking here
198     
199     # ought to be all in the 7 bit GSM character map
200     chars = [ GSM_DEFAULT_ALPHABET[ord(c)] for c in s ]
201     u_str = "".join(chars)
202     return u_str.encode("utf-8")
203
204
205 def _decode_hex(s):
206
207     return s.decode("hex")
208
209
210 def _decode_usc2(s):
211
212     return s.decode("hex").decode("utf-16-be").encode("utf-8")
213
214
215 def _decode_general_data_coding(s, h, l):
216
217     is_compressed = (h & 0x2)
218     
219     alphabet = (l & 0xc) >> 2
220
221     if (alphabet == 0x0):
222         # default alphabet
223         return _decode_defaul_alphabet(s)
224         
225     elif (alphabet == 0x1):
226         # 8 bit
227         # actually, encoding is user-defined, but let's assume hex'd ASCII
228         # for now
229         return _decode_hex(s)
230         
231     elif (alphabet == 0x2):
232         # USC2 (16 bit, BE)
233         return _decode_usc2(s)
234     elif (alphabet == 0x3):
235         # reserved
236         return s
237