def test_user_data_header(self): data = to_array("08049f8e020105040b8423f0") udh = UserDataHeader.from_bytes(data) self.assertEqual(udh.concat.seq, 1) self.assertEqual(udh.concat.cnt, 2) self.assertEqual(udh.concat.ref, 40846) self.assertEqual(udh.ports.dest_port, 2948) self.assertEqual(udh.ports.orig_port, 9200) data = to_array("0003190201") udh = UserDataHeader.from_bytes(data) self.assertEqual(udh.concat.seq, 1) self.assertEqual(udh.concat.cnt, 2) self.assertEqual(udh.concat.ref, 25)
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 = to_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 SmsSubmit message") 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_msg2(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)
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: # print pdu # raise ValueError("Can not decode an odd-length pdu") # XXX: Should we keep the original PDU or the modified one? print "pdu", pdu self._pdu = pdu data = to_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_msg2(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)