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