def _process_message(self, data): # Now get message body msgl = data.pop(0) msg = encode_bytes(data[:msgl]) # check for header headlen = ud_len = 0 if self.mtype & 0x40: # UDHI present ud_len = data.pop(0) self.udh = UserDataHeader.from_bytes(data[:ud_len]) headlen = (ud_len + 1) * 8 if self.fmt == 0x00: while headlen % 7: headlen += 1 headlen /= 7 headlen = int(headlen) if self.fmt == 0x00: self.text = unpack_msg(msg)[headlen:msgl].decode("gsm0338") elif self.fmt == 0x04: self.text = data[ud_len:].tobytes() elif self.fmt == 0x08: data = data[ud_len:].tolist() _bytes = [ int("%02X%02X" % (data[i], data[i + 1]), 16) for i in range(0, len(data), 2) ] self.text = ''.join(list(map(chr, _bytes)))
def convert_response(response): index = response[0].group('index') if index == '1': self.device.set_property( consts.USD_INTFACE, 'State', 'user-response') else: self.device.set_property(consts.USD_INTFACE, 'State', 'idle') resp = response[0].group('resp') code = response[0].group('code') if code is not None: code = int(code) if ((code & 0x10) == 0x10): log.err("We don't yet handle ISO 639 encoded USSD" " - please report") raise E.MalformedUssdPduError(resp) if ((code & 0xf4) == 0xf4): log.err("We don't yet handle 8 bit encoded USSD" " - please report") raise E.MalformedUssdPduError(resp) ret = unpack_msg(resp) if is_gsm_text(ret): return ret try: return resp.decode('hex') except TypeError: raise E.MalformedUssdPduError(resp)
def _process_message(self, data): # Now get message body msgl = data.pop(0) msg = encode_bytes(data[:msgl]) # check for header headlen = ud_len = 0 if self.mtype & 0x40: # UDHI present ud_len = data.pop(0) self.udh = UserDataHeader.from_bytes(data[:ud_len]) headlen = (ud_len + 1) * 8 if self.fmt == 0x00: while headlen % 7: headlen += 1 headlen /= 7 headlen = int(headlen) if self.fmt == 0x00: # XXX: Use unpack_msg2 data = data[ud_len:].tolist() #self.text = unpack_msg2(data).decode("gsm0338") self.text = unpack_msg(msg)[headlen:msgl].decode("gsm0338") elif self.fmt == 0x04: self.text = data[ud_len:].tostring() elif self.fmt == 0x08: data = data[ud_len:].tolist() _bytes = [int("%02X%02X" % (data[i], data[i + 1]), 16) for i in range(0, len(data), 2)] self.text = u''.join(list(map(unichr, _bytes)))
def convert_response(response): index = response[0].group('index') if index == '1': self.device.set_property( consts.USD_INTFACE, 'State', 'user-response') else: self.device.set_property(consts.USD_INTFACE, 'State', 'idle') resp = response[0].group('resp') if resp is None: return "" # returning the Empty string is valid try: ret = unpack_msg(resp).decode("gsm0338") if is_gsm_text(ret): return ret except UnicodeError: pass try: return resp.decode('hex') except TypeError: raise MalformedUssdPduError(resp)
def _set_pdu(self, pdu): if not self._strict and len(pdu) % 2: # if not strict and PDU-length is odd, remove the last character # and make it even. See the discussion of this bug at # http://github.com/pmarti/python-messaging/issues#issue/7 pdu = pdu[:-1] if len(pdu) % 2: raise ValueError("Can not decode an odd-length pdu") # XXX: Should we keep the original PDU or the modified one? self._pdu = pdu data = hex_to_int_array(self._pdu) # Service centre address smscl = data.pop(0) if smscl > 0: smscertype = data.pop(0) smscl -= 1 self.csca = swap_number(encode_bytes(data[:smscl])) if (smscertype >> 4) & 0x07 == consts.INTERNATIONAL: self.csca = '+%s' % self.csca data = data[smscl:] else: self.csca = None # 1 byte(octet) == 2 char # Message type TP-MTI bits 0,1 # More messages to send/deliver bit 2 # Status report request indicated bit 5 # User Data Header Indicator bit 6 # Reply path set bit 7 try: self.mtype = data.pop(0) except TypeError: raise ValueError("Decoding this type of SMS is not supported yet") mtype = self.mtype & 0x03 if mtype == 0x02: return self._decode_status_report_pdu(data) if mtype == 0x01: raise ValueError("Cannot decode a SmsSubmitReport message yet") sndlen = data.pop(0) if sndlen % 2: sndlen += 1 sndlen = int(sndlen / 2.0) sndtype = (data.pop(0) >> 4) & 0x07 if sndtype == consts.ALPHANUMERIC: # coded according to 3GPP TS 23.038 [9] GSM 7-bit default alphabet sender = unpack_msg(data[:sndlen]).decode("gsm0338") else: # Extract phone number of sender sender = swap_number(encode_bytes(data[:sndlen])) if sndtype == consts.INTERNATIONAL: sender = '+%s' % sender self.number = sender data = data[sndlen:] # 1 byte TP-PID (Protocol IDentifier) self.pid = data.pop(0) # 1 byte TP-DCS (Data Coding Scheme) self.dcs = data.pop(0) if self.dcs & (0x04 | 0x08) == 0: self.fmt = 0x00 elif self.dcs & 0x04: self.fmt = 0x04 elif self.dcs & 0x08: self.fmt = 0x08 datestr = '' # Get date stamp (sender's local time) date = list(encode_bytes(data[:6])) for n in range(1, len(date), 2): date[n - 1], date[n] = date[n], date[n - 1] data = data[6:] # Get sender's offset from GMT (TS 23.040 TP-SCTS) tz = data.pop(0) offset = ((tz & 0x07) * 10 + ((tz & 0xf0) >> 4)) * 15 if (tz & 0x08): offset = offset * -1 # 02/08/26 19:37:41 datestr = "%s%s/%s%s/%s%s %s%s:%s%s:%s%s" % tuple(date) outputfmt = '%y/%m/%d %H:%M:%S' sndlocaltime = datetime.strptime(datestr, outputfmt) sndoffset = timedelta(minutes=offset) # date as UTC self.date = sndlocaltime - sndoffset self._process_message(data)