## 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
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
+ # 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")
if (alphabet == 0x0):
# default alphabet
- return _decode_defaul_alphabet(s)
+ return _decode_default_alphabet(s)
elif (alphabet == 0x1):
# 8 bit
# 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
+