PDU decoding support
authorkibergus <kibergus@gmail.com>
Fri, 12 Mar 2010 22:16:09 +0000 (22:16 +0000)
committerkibergus <kibergus@gmail.com>
Fri, 12 Mar 2010 22:16:09 +0000 (22:16 +0000)
git-svn-id: file:///svnroot/ussd-widget/trunk@24 d197f4d6-dc93-42ad-8354-0da1f58e353f

ussd-common/build_ussd-common.py
ussd-common/src/usr/lib/python2.5/gsmdecode.py

index 93301ab..398423d 100644 (file)
@@ -38,9 +38,9 @@ if __name__ == "__main__":
 chmod +s /usr/bin/pnatd
 """ #Set here your post install script
 
 chmod +s /usr/bin/pnatd
 """ #Set here your post install script
 
-    version = "0.0.7"
+    version = "0.0.9"
     build = "0" 
     build = "0" 
-    changeloginformation = "Fixed decoding of german language." 
+    changeloginformation = "Added support for SMS PDU decoding." 
    
     dir_name = "src"     
 
    
     dir_name = "src"     
 
index b5510ee..5a8d3e3 100644 (file)
@@ -5,6 +5,7 @@
 ## by the Free Software Foundation; version 2 and higer.
 ##
 ## Martin Grimme (martin.grimme # gmail.com) 2010
 ## by the Free Software Foundation; version 2 and higer.
 ##
 ## Martin Grimme (martin.grimme # gmail.com) 2010
+## Guseynov Alexey (kibergus # gmail.com) 2010
 
 LANG_DE = 0x0
 LANG_EN = 0x1
 
 LANG_DE = 0x0
 LANG_EN = 0x1
@@ -202,9 +203,8 @@ def _decode_language(s, lang):
 
 def _decode_default_alphabet(s):
     
 
 def _decode_default_alphabet(s):
     
-    # TODO: we really might have to do 7 bit character unpacking here
-    
     # ought to be all in the 7 bit GSM character map
     # ought to be all in the 7 bit GSM character map
+    # modem is in 8 bit mode, so it makes 7 bit unpacking itself
     chars = [ GSM_DEFAULT_ALPHABET[ord(c)] for c in s ]
     u_str = "".join(chars)
     return u_str.encode("utf-8")
     chars = [ GSM_DEFAULT_ALPHABET[ord(c)] for c in s ]
     u_str = "".join(chars)
     return u_str.encode("utf-8")
@@ -228,7 +228,7 @@ def _decode_general_data_coding(s, h, l):
 
     if (alphabet == 0x0):
         # default alphabet
 
     if (alphabet == 0x0):
         # default alphabet
-        return _decode_defaul_alphabet(s)
+        return _decode_default_alphabet(s)
         
     elif (alphabet == 0x1):
         # 8 bit
         
     elif (alphabet == 0x1):
         # 8 bit
@@ -243,3 +243,63 @@ def _decode_general_data_coding(s, h, l):
         # reserved
         return s
 
         # reserved
         return s
 
+def decode_number(number):
+       dnumber = ""
+       for i in number:
+               if i & 0xf < 10:
+                       dnumber += str(int((i & 0xf)))
+               if (i & 0xf0) >> 4 < 10:
+                       dnumber += str(int((i & 0xf0) >> 4))
+       return dnumber
+
+def decode_timestamp(timestamp):
+       res = {}
+       res['year'] =  str(timestamp[0] & 0xf) + str((timestamp[0] & 0xf0) >> 4)
+       res['month'] = str(timestamp[1] & 0xf) + str((timestamp[1] & 0xf0) >> 4)
+       res['day'] = str(timestamp[2] & 0xf) + str((timestamp[2] & 0xf0) >> 4)
+       res['hour'] = str(timestamp[3] & 0xf) + str((timestamp[3] & 0xf0) >> 4)
+       res['minute'] = str(timestamp[4] & 0xf) + str((timestamp[4] & 0xf0) >> 4)
+       res['second'] = str(timestamp[5] & 0xf) + str((timestamp[5] & 0xf0) >> 4)
+       res['timezone'] = str(timestamp[6] & 0xf) + str((timestamp[6] & 0xf0) >> 4)
+       return res
+
+def decode_pdu (pdumsg):
+       pdu = {}
+       pdu['type'] = int(pdumsg[0])
+       if pdu['type'] & 0x3 == 0x0:
+               pdu['address_len'] = int(pdumsg[1])
+               pdu['type_of_address'] = int(pdumsg[2])
+               base = 3+(pdu['address_len']+1)/2
+               pdu['sender'] = decode_number(pdumsg[3:base])
+               pdu['pid'] = int(pdumsg[base])
+               pdu['dcs'] = int(pdumsg[base+1])
+               pdu['timestamp'] = decode_timestamp (pdumsg[base+2:base+9]);
+               pdu['udl'] = int(pdumsg[base+9])
+               pdu['user_data'] = pdumsg[base+10:len(pdumsg)]
+
+               alphabet = (pdu['dcs'] & 0xc) >> 2
+               if alphabet == 0x0:
+                       # This is 7-bit data. Taking of only pdu['udl'] bytes is important because we can't distinguish 0 at the end from @ if only one bit is used in last bite
+                       pdu['user_data'] = _decode_default_alphabet(deoctify(pdu['user_data']))[0:pdu['udl']]
+               elif alphabet == 0x1:
+                       # actually, encoding is user-defined, but let's assume ASCII
+                       pdu['user_data'] = ''.join([chr(i) for i in pdu['user_data']])
+               elif (alphabet == 0x2):
+                       # USC2 (16 bit, BE)
+                       pdu['user_data'] = (''.join([chr(i) for i in pdu['user_data'][6:len(pdu['user_data'])]])).decode("utf-16-be").encode("utf-8")
+               elif (alphabet == 0x3):
+                       # reserved
+                       pdu['user_data'] = ''.join([chr(i) for i in pdu['user_data']])
+
+               if pdu['type'] & 0x4 == 0:
+                       pdu['part'] = True
+               else:
+                       pdu['part'] = False
+       else:
+               # TODO support other types of messages
+               # This is not incoming message
+               # pdu['type'] & 0x3 == 2 means delivery report
+               return None
+
+       return pdu
+