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