Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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)