예제 #1
0
    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)))
예제 #2
0
파일: huawei.py 프로젝트: crass/wader
        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)
예제 #3
0
    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)))
예제 #4
0
        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)
예제 #5
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 = 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)