Esempio n. 1
0
    def _parse_packet(self, packet_bytes):
        '''
        Parse a raw udp packet and return a list of parsed messages.
        '''

        byte_buffer = ByteBuffer(packet_bytes)
        parsed_messages = []

        while not byte_buffer.is_empty():

            message_id, sequence_number, message_flags = \
                byte_buffer.read_struct(self.MESSAGE_TRANSPORT_HEADER)

            message_type_id = messages.BaseMessage.read_header_from_byte_buffer(
                byte_buffer)[0]
            message = self.message_factory.get_by_id(message_type_id)()
            message.read_from_byte_buffer(byte_buffer)

            # - These flags are for consumption by .update()
            message_flags_bf = bitfield(message_flags)
            message.is_reliable = message_flags_bf[1]
            message.is_ordered = message_flags_bf[0]

            message.sequence_number = sequence_number
            message.message_id = message_id

            parsed_messages.append(message)

        return parsed_messages
    def _sendCmd(self, pacType, cmdID, data):
        bb = None
        payload = None
        out = None
        seq = 0
        len = 0

        if cmdID == self.TELLO_CMD_CONN:
            out = ByteBuffer.allocate(11)
            out.clear()
            out.put_bytes('conn_req:'.encode())
            out.put_ULInt16(self.TELLO_PORT_VIDEO)
            self.seqID = self.seqID + 1
        elif cmdID == self.TELLO_CMD_STICK:
            now = datetime.datetime.now()
            bb = ByteBuffer.allocate(11)
            bb.clear()

            # put 64bit stick data
            pp = ByteBuffer.allocate(8)
            pp.put_ULInt64(self.stickData)
            pp.flip()

            # get 48bit data only
            bb.put(pp.get_array(), 0, 6)
            bb.put_ULInt8(now.hour)
            bb.put_ULInt8(now.minute)
            bb.put_ULInt8(now.second)
            bb.put_ULInt16(now.microsecond & 0xffff)
            seq = 0
        elif cmdID == self.TELLO_CMD_DATE_TIME:
            seq = self.seqID
            now = datetime.datetime.now()
            bb = ByteBuffer.allocate(15)
            bb.clear()
            bb.put_ULInt8(0x00)
            bb.put_ULInt16(now.year)
            bb.put_ULInt16(now.month)
            bb.put_ULInt16(now.day)
            bb.put_ULInt16(now.hour)
            bb.put_ULInt16(now.minute)
            bb.put_ULInt16(now.second)
            bb.put_ULInt16(now.microsecond & 0xffff)
            self.seqID = self.seqID + 1
        elif cmdID == self.TELLO_CMD_REQ_VIDEO_SPS_PPS:
            seq = 0
        else:
            seq = self.seqID
            self.seqID = self.seqID + 1

        if bb != None:
            payload = bb.get_array()
        else:
            payload = data

        if out == None:
            out = self._buildPacket(pacType, cmdID, seq, payload)

        self.sockCmd.sendto(out.get_array(), self.addrCmd)
        return None
Esempio n. 3
0
 def __init__(self, sock):
     self._sock = sock
     self._in_buffer = ByteBuffer()
     self._out_buffer = ByteBuffer()
     self._read_thread = Thread(target=self._recv)
     self._write_thread = Thread(target=self._send)
     self._open = True
     self._read_thread.start()
     self._write_thread.start()
Esempio n. 4
0
 def __init__(self, sock, main_interrupt=False):
     self._inter_main = main_interrupt
     self._sock = sock
     self._sock.settimeout(1)
     self._in_buffer = ByteBuffer()
     self._out_buffer = ByteBuffer()
     self._read_thread = Thread(target=self._recv)
     self._write_thread = Thread(target=self._send)
     self._open = True
     self._read_thread.start()
     self._write_thread.start()
Esempio n. 5
0
    def __init__(self, path):
        with open(path, 'rb') as f:
            self.contents = ByteBuffer(f.read(), endian='<')
        self.name = self.contents.get('16s')
        self.header_size = self.contents.get_u32()
        self.filecount = self.contents.get_u32()
        self.contents.offset += 48  # random padding/flags/title bytes

        offsets = []
        for _ in range(self.filecount):
            offsets.append(self.contents.get_u32())

        self.tracks = []
        for off in offsets:
            self.contents.offset = off
            self.tracks.append(self.Track(self.contents))
    def _parsePacket(self, buf):
        dataSize = 0
        cmdID = 0

        if len(buf) >= 11:
            bb = ByteBuffer.wrap(buf)
            mark = bb.get_ULInt8()
            if mark == 0xCC:
                size = bb.get_ULInt16() >> 3
                crc8 = bb.get_ULInt8()
                calcCRC8 = self._calcCRC8(buf, 3)
                if crc8 != calcCRC8:
                    print('wrong CRC8 {0:02x / 1:02x}'.format(crc8, calcCRC8))

                pacType = bb.get_ULInt8()
                cmdID = bb.get_ULInt16()
                seqID = bb.get_ULInt16()
                dataSize = size - 11
                data = None
                # if dataSize > 0:
                #    data = bytearray(dataSize)
                #    bb.get(data)
                bb.set_position(size - 2)
                crc16 = bb.get_ULInt16()
                calcCRC16 = self._calcCRC16(buf, size - 2)
                if crc16 != calcCRC16:
                    print('wrong CRC8 {0:04x / 1:04x}'.format(
                        crc16, calcCRC16))
                # print 'pt:{0:02x}, cmd:{1:4d}={2:04x}, seq:{3:04x}, data_sz:{4:d} - '.format(pacType, cmdID, cmdID, seqID, dataSize)
            else:
                if mark == 0x63:
                    ack = ByteBuffer.allocate(11)
                    ack.put_bytes('conn_ack:'.encode())
                    ack.put_ULInt16(self.TELLO_PORT_VIDEO)
                    ack.flip()
                    if ack.get_array() == buf:
                        cmdID = self.TELLO_CMD_CONN_ACK
                    else:
                        print('wrong video port !!')
                else:
                    print('wrong mark !! {0:02x}'.format(mark))
        elif buf != None:
            print('wrong packet length={0:d}, 1st byte={1:02x}'.format(
                len(buf), buf[0]))

        return cmdID
Esempio n. 7
0
class Client:
    def __init__(self, sock):
        self._sock = sock
        self._in_buffer = ByteBuffer()
        self._out_buffer = ByteBuffer()
        self._read_thread = Thread(target=self._recv)
        self._write_thread = Thread(target=self._send)
        self._open = True
        self._read_thread.start()
        self._write_thread.start()
    def _recv(self):
        '''
        reads constantly into the buffer
        '''
        while self._open:
            self._in_buffer.write_bytes(self._sock.recv(4096))
    def _send(self):
        '''
        writes the out buffer to the socket
        '''
        while self._open:
            self._sock.send(self._out_buffer.flush())
    def get_buffers(self):
        return self._in_buffer, self._out_buffer
    def close(self):
        self._open = False
        self._sock.close()
        self._in_buffer.close()
        self._out_buffer.close()
Esempio n. 8
0
class BM2DX(object):
    class Track(object):
        def __init__(self, buff):
            assert buff.get('4s') == b'2DX9'
            assert buff.get_u32() == 24
            wav_size = buff.get_u32()
            unk1 = buff.get_u16()
            self.id = buff.get_u16()
            unk2 = buff.get_u16()
            self.attenuation = buff.get_u16()
            self.loop_point = buff.get_u32()
            self.data = buff.get_bytes(wav_size)

        def __str__(self):
            return 'Track ID:{} attenuation:{} loop:{}'.format(
                self.id, self.attenuation, self.loop_point)

    def __init__(self, path):
        with open(path, 'rb') as f:
            self.contents = ByteBuffer(f.read(), endian='<')
        self.name = self.contents.get('16s')
        self.header_size = self.contents.get_u32()
        self.filecount = self.contents.get_u32()
        self.contents.offset += 48  # random padding/flags/title bytes

        offsets = []
        for _ in range(self.filecount):
            offsets.append(self.contents.get_u32())

        self.tracks = []
        for off in offsets:
            self.contents.offset = off
            self.tracks.append(self.Track(self.contents))

    def __str__(self):
        ret = '2dx: "{}", {} track(s)'.format(self.name, len(self.tracks))
        for t in self.tracks:
            ret += '\n\t{}'.format(str(t))
        return ret
Esempio n. 9
0
def byte_log_generator(log_file):
    postfix = datetime.now().strftime("%Y%m%d")
    with open(log_file + "." + postfix, "rb") as f_in:
        delimiter_len = len(LOG_DELIMITER)
        bf = ByteBuffer.allocate(MAX_UDP_DATA_LEN)
        while True:
            curr_position = f_in.tell()
            n = 0
            # 重试10次,尽量把buffer读满
            for _ in xrange(10):
                n += bf.read_from_file(f_in)
                if bf.get_remaining() == 0:
                    break
            if n <= 0:
                break

            bf.flip()  # bf由写入变为读出状态,即把position置为0

            idx = 0
            target = LOG_DELIMITER[idx]  # 当前要寻找LOG_DELIMITER中的哪个字符

            bf.mark()  # 记下当前位置,reset时会回到这个位置
            begin = 0  # 以delimiter结束上一段后,下一段的开始位置
            length = 0  # 上一次delimiter结束后,又从buffer中读了几个字节

            while True:
                if bf.get_remaining() == 0:
                    break
                b = bf.get_bytes(1)[0]  # 逐个字节地读buffer
                length += 1
                if b == target:
                    idx += 1
                    if idx == delimiter_len:  # 遇到了完整的LOG_DELIMITER
                        begin = bf.get_position()  # 下一次读buffer的开始位置
                        bf.reset()  # 回到本段的开始位置
                        idx = 0
                        bytes = bf.get_bytes(length - delimiter_len)
                        yield bytes
                        bf.set_position(begin)  # 显式回到指定位置
                        bf.mark()
                        length = 0
                    target = LOG_DELIMITER[idx]  # 下一个寻找目标
                else:
                    if idx > 0:  # 重置idx和target
                        idx = 0
                        target = LOG_DELIMITER[idx]

            f_in.seek(curr_position + begin)
            bf.clear()  # 回到0位置
Esempio n. 10
0
def tradingviewx(transport):  ##{
    buffer = ByteBuffer()
    xhr = next(transport)

    while True:
        try:
            data = xhr.raw.read(XHR_READ_SIZE)
        except Exception:
            xhr = next(transport)
            continue

        buffer.write(data)
        line = buffer.read_until(b"\r\n", consume=True)

        if not line: continue
        if line == ": -1": continue
        if line.startswith("data: "): line = line[6:]

        try:
            pkg = jsload(line)
        except Exception:
            continue

        channel = pkg.get("text", {}).get("channel")
        if channel != "chat_bitcoin": continue

        content = pkg.get("text").get("content")
        login = content.get('username')
        msg = content.get("text", "").encode("utf-8", errors="replace")
        meta = content.get("meta", {})
        url = meta.get("url", "").encode("utf-8", errors="replace")
        if url:
            msg = "{}\n{:<19}{}{}{}".format(msg, "", COLOR_10, url, COLOR_0)
        if not msg: continue

        yield (login, msg)
def tradingviewx(transport):##{
    buffer = ByteBuffer()
    xhr = next(transport)

    while True:
        try:
            data = xhr.raw.read(XHR_READ_SIZE)
        except Exception:
            xhr = next(transport)
            continue

        buffer.write(data)
        line = buffer.read_until(b"\r\n", consume=True)

        if not line: continue
        if line == ": -1": continue
        if line.startswith("data: "): line = line[6:]

        try:
            pkg = jsload(line)
        except Exception:
            continue

        channel = pkg.get("text", {}).get("channel")
        if channel != "chat_bitcoin": continue

        content = pkg.get("text").get("content")
        login = content.get('username')
        msg = content.get("text", "").encode("utf-8", errors="replace")
        meta = content.get("meta", {})
        url = meta.get("url", "").encode("utf-8", errors="replace")
        if url:
            msg = "{}\n{:<19}{}{}{}".format(msg, "", COLOR_10, url, COLOR_0)
        if not msg: continue

        yield(login, msg)
    def _buildPacket(self, pacType, cmdID, seqID, data):
        size = len(data) if data != None else 0
        size = 11 + size

        bb = ByteBuffer.allocate(size)
        bb.clear()
        bb.put_ULInt8(0xCC)
        bb.put_ULInt16(size << 3)
        crc8 = self._calcCRC8(bb.get_array(), 3)
        bb.put_ULInt8(crc8)
        bb.put_ULInt8(pacType)
        bb.put_ULInt16(cmdID)
        bb.put_ULInt16(seqID)
        if data:
            bb.put(data)
        crc16 = self._calcCRC16(bb.get_array(), size - 2)
        bb.put_ULInt16(crc16)
        bb.flip()
        return bb
Esempio n. 13
0
    def from_binary(self, input):
        self.xml_doc = minidom.Document()
        node = self.xml_doc

        self.nodeBuf = ByteBuffer(input)
        assert self.nodeBuf.get_u8() == SIGNATURE

        compress = self.nodeBuf.get_u8()
        assert compress in (SIG_COMPRESSED, SIG_UNCOMPRESSED)
        self.compressed = compress == SIG_COMPRESSED

        encoding_key = self.nodeBuf.get_u8()
        assert self.nodeBuf.get_u8() == 0xFF ^ encoding_key
        self.encoding = encoding_strings[encoding_key]

        nodeEnd = self.nodeBuf.get_u32() + 8
        self.nodeBuf.end = nodeEnd

        self.dataBuf = ByteBuffer(input, nodeEnd)
        dataSize = self.dataBuf.get_u32()
        # This is all no fun
        self.dataByteBuf = ByteBuffer(input, nodeEnd)
        self.dataWordBuf = ByteBuffer(input, nodeEnd)

        nodesLeft = True
        while nodesLeft and self.nodeBuf.hasData():
            while self.nodeBuf.peek_u8() == 0:
                debug_print("Skipping 0 node ID")
                self.nodeBuf.get_u8()

            nodeType = self.nodeBuf.get_u8()
            isArray = nodeType & 64
            nodeType &= ~64

            nodeFormat = xml_formats.get(nodeType, {'name':'Unknown'})
            debug_print('Node type is {} ({})'.format(nodeFormat['name'], nodeType))

            # node or attribute name
            name = ''
            if nodeType != xml_types['nodeEnd'] and nodeType != xml_types['endSection']:
                if self.compressed:
                    name = unpack_sixbit(self.nodeBuf)
                else:
                    length = self.nodeBuf.get_u8()
                    name = self.nodeBuf.get('s', length)
                debug_print(name)

            skip = True

            if nodeType == xml_types['attr']:
                value = self.data_grab_string()
                node.setAttribute(name, value)
            elif nodeType == xml_types['nodeEnd']:
                if node.parentNode:
                    node = node.parentNode
            elif nodeType == xml_types['endSection']:
                nodesLeft = False
            elif nodeType not in xml_formats:
                raise NotImplementedError('Implement node {}'.format(nodeType))
            else: # inner value to process
                skip = False

            if skip:
                continue

            child = self.xml_doc.createElement(name)
            node.appendChild(child)
            node = child

            if nodeType == xml_types['nodeStart']:
                continue

            node.setAttribute('__type', nodeFormat['name'])

            varCount = nodeFormat['count']
            arrayCount = 1
            if varCount == -1: # the 2 cannot be combined
                varCount = self.dataBuf.get_u32()
                isArray = True
            elif isArray:
                arrayCount = self.dataBuf.get_u32() // (calcsize(nodeFormat['type'] * varCount))
                node.setAttribute('__count', str(arrayCount))
            totalCount = arrayCount * varCount

            if isArray:
                data = self.dataBuf.get(nodeFormat['type'], totalCount)
                self.dataBuf.realign_reads()
            else:
                data = self.data_grab_aligned(nodeFormat['type'], totalCount)

            if nodeType == xml_types['binary']:
                node.setAttribute('__size', str(totalCount))
                string = ''.join(('{0:02x}'.format(x) for x in data))
            elif nodeType == xml_types['string']:
                string = bytes(data[:-1]).decode(self.encoding)
            else:
                string = ' '.join(map(nodeFormat.get('toStr', str), data))

            node.appendChild(self.xml_doc.createTextNode(string))
        ))
        for iteration, count, estimate, cumulative in rs:
            print('-' * 80)
            print(' {:>3d} | {:>8d} | {:>13} | {:>13.9f} | {:>13.9f} | {:>13.3f} '.format(
                iteration, count, 'estimate', estimate, estimate / count, count / estimate,
            ))
            print(' {:>3} | {:>8} | {:>13} | {:>13.9f} | {:>13.9f} | {:>13.3f} '.format(
                '', '', 'cumulative', cumulative, cumulative / count, count / cumulative
            ))
        print('=' * 80)
        print()
        print()


test = PerformanceTest(10 ** 3, 10 ** 5, 10, 10.0)
buf = ByteBuffer.allocate(5 * 10 ** 8)

for name in dir(buf):
    if name.startswith('get_'):
        suffix = name.replace('get_', '')

        if suffix in ('capacity', 'position', 'limit', 'remaining', 'bytes'):
            continue

        putter = getattr(buf, 'put_' + suffix)
        getter = getattr(buf, name)
        buf.clear()
        test.run_and_print(putter, 1)
        buf.flip()
        test.run_and_print(getter)
Esempio n. 15
0
    def to_binary(self):
        self.encoding = BIN_ENCODING

        header = ByteBuffer()
        header.append_u8(SIGNATURE)
        header.append_u8(SIG_COMPRESSED)
        header.append_u8(encoding_vals[self.encoding])
        # Python's ints are big, so can't just bitwise invert
        header.append_u8(0xFF ^ encoding_vals[self.encoding])
        self.nodeBuf = ByteBuffer()
        self.dataBuf = ByteBuffer()
        self.dataByteBuf = ByteBuffer(self.dataBuf.data)
        self.dataWordBuf = ByteBuffer(self.dataBuf.data)

        for child in self.xml_doc.childNodes:
            self._node_to_binary(child)

        # always has the isArray bit set
        self.nodeBuf.append_u8(xml_types['endSection'] | 64)
        self.nodeBuf.realign_writes()
        header.append_u32(len(self.nodeBuf))
        self.nodeBuf.append_u32(len(self.dataBuf))
        return bytes(header.data + self.nodeBuf.data + self.dataBuf.data)
Esempio n. 16
0
class Client:
    def __init__(self, sock, main_interrupt=False):
        self._inter_main = main_interrupt
        self._sock = sock
        self._sock.settimeout(1)
        self._in_buffer = ByteBuffer()
        self._out_buffer = ByteBuffer()
        self._read_thread = Thread(target=self._recv)
        self._write_thread = Thread(target=self._send)
        self._open = True
        self._read_thread.start()
        self._write_thread.start()
    def _recv(self):
        '''
        reads constantly into the buffer
        '''
        try:
            while self._open:
                try:
                    bts = self._sock.recv(4096)
                    if not len(bts):
                        raise OSError()
                    self._in_buffer.write_bytes(bts)
                except timeout:
                    pass
        except OSError:
            print("Socket closed")
            self.close()
    def _send(self):
        '''
        writes the out buffer to the socket
        '''
        try:
            while self._open:
                bts = self._out_buffer.flush()
                while len(bts):
                    sent = self._sock.send(bts)
                    bts = bts[sent:]
        except OSError:
            self._close()
    def get_buffers(self):
        return self._in_buffer, self._out_buffer
    def close(self):
        if self._open:
            self._open = False
            self._out_buffer.close()
            try:
                self._sock.shutdown(SHUT_WR)
                self._sock.close()
            except OSError:
                pass
            print("Closing input buffer")
            self._in_buffer.close()
            print("Closed input buffer")
            try:
                self._read_thread.join()
                self._write_thread.join()
            except RuntimeError:
                if self._inter_main:
                    print("Interrupting main thread")
                    kill(getpid(), SIGINT)
def covert_string_to_byte(content):
    return ByteBuffer.wrap(bytes(content, encoding="utf8"))
Esempio n. 18
0
class KBinXML():

    def __init__(self, input):
        if isinstance(input, minidom.Document):
            self.xml_doc = input
        elif KBinXML.is_binary_xml(input):
            self.from_binary(input)
        else:
            self.from_text(input)

    def to_text(self):
        return self.xml_doc.toprettyxml(indent = "    ", encoding = XML_ENCODING)

    def from_text(self, input):
        self.xml_doc = minidom.parseString(input)

    @staticmethod
    def is_binary_xml(input):
        nodeBuf = ByteBuffer(input)
        return (nodeBuf.get_u8() == SIGNATURE and
            nodeBuf.get_u8() in (SIG_COMPRESSED, SIG_UNCOMPRESSED))

    def data_grab_auto(self):
        size = self.dataBuf.get_s32()
        ret = self.dataBuf.get('b', size)
        self.dataBuf.realign_reads()
        return ret

    def data_append_auto(self, data):
        self.dataBuf.append_s32(len(data))
        self.dataBuf.append(data, 'b', len(data))
        self.dataBuf.realign_writes()

    def data_grab_string(self):
        data = self.data_grab_auto()
        return bytes(data[:-1]).decode(self.encoding)

    def data_append_string(self, string):
        string = bytes(string.encode(self.encoding) + b'\0')
        self.data_append_auto(string)

    # has its own separate state and other assorted garbage
    def data_grab_aligned(self, type, count):
        if self.dataByteBuf.offset % 4 == 0:
            self.dataByteBuf.offset = self.dataBuf.offset
        if self.dataWordBuf.offset % 4 == 0:
            self.dataWordBuf.offset = self.dataBuf.offset
        # multiply by count since 2u2 reads from the 16 bit buffer, for example
        size = calcsize(type) * count
        if size == 1:
            ret = self.dataByteBuf.get(type, count)
        elif size == 2:
            ret = self.dataWordBuf.get(type, count)
        else:
            ret = self.dataBuf.get(type, count)
            self.dataBuf.realign_reads()
        trailing = max(self.dataByteBuf.offset, self.dataWordBuf.offset)
        if self.dataBuf.offset < trailing:
            self.dataBuf.offset = trailing
            self.dataBuf.realign_reads()
        return ret

    def data_append_aligned(self, data, type, count):
        if self.dataByteBuf.offset % 4 == 0:
            self.dataByteBuf.offset = self.dataBuf.offset
        if self.dataWordBuf.offset % 4 == 0:
            self.dataWordBuf.offset = self.dataBuf.offset
        # multiply by count since 2u2 reads from the 16 bit buffer, for example
        size = calcsize(type) * count
        if size == 1:
            # make room for our stuff if fresh dword
            if self.dataByteBuf.offset % 4 == 0:
                self.dataBuf.append_u32(0)
            self.dataByteBuf.set(data, self.dataByteBuf.offset, type, count)
        elif size == 2:
            if self.dataWordBuf.offset % 4 == 0:
                self.dataBuf.append_u32(0)
            self.dataWordBuf.set(data, self.dataWordBuf.offset, type, count)
        else:
            self.dataBuf.append(data, type, count)
            self.dataBuf.realign_writes()

    def _node_to_binary(self, node):
        if node.nodeType == node.TEXT_NODE or node.nodeType == node.COMMENT_NODE:
            return
        nodeType = node.getAttribute('__type')
        if not nodeType:
            nodeType = 'void'
        nodeId = xml_types[nodeType]

        isArray = 0
        count = node.getAttribute('__count')
        if count:
            count = int(count)
            isArray = 64 # bit position for array flag

        self.nodeBuf.append_u8(nodeId | isArray)

        name = node.nodeName
        pack_sixbit(name, self.nodeBuf)

        if nodeType != 'void':
            fmt = xml_formats[nodeId]

            val = node.firstChild.nodeValue
            if fmt['name'] == 'bin':
                data = bytes(bytearray.fromhex(val))
            elif fmt['name'] == 'str':
                data = bytes(val.encode(self.encoding) + b'\0')
            else:
                val = val.split(' ')
                data = list(map(fmt.get('fromStr', int), val))
                if count and len(data) / fmt['count'] != count:
                    raise ValueError('Array length does not match __count attribute')

            if isArray or fmt['count'] == -1:
                self.dataBuf.append_u32(len(data) * calcsize(fmt['type']))
                self.dataBuf.append(data, fmt['type'], len(data))
                self.dataBuf.realign_writes()
            else:
                self.data_append_aligned(data, fmt['type'], fmt['count'])

        # for test consistency and to be more faithful, sort the attrs
        sorted_attrs = sorted(node.attributes.items(), key=operator.itemgetter(0))
        for key, value in sorted_attrs:
            if key not in ['__type', '__size', '__count']:
                self.data_append_string(value)
                self.nodeBuf.append_u8(xml_types['attr'])
                pack_sixbit(key, self.nodeBuf)

        for child in node.childNodes:
            self._node_to_binary(child)

        # always has the isArray bit set
        self.nodeBuf.append_u8(xml_types['nodeEnd'] | 64)

    def to_binary(self):
        self.encoding = BIN_ENCODING

        header = ByteBuffer()
        header.append_u8(SIGNATURE)
        header.append_u8(SIG_COMPRESSED)
        header.append_u8(encoding_vals[self.encoding])
        # Python's ints are big, so can't just bitwise invert
        header.append_u8(0xFF ^ encoding_vals[self.encoding])
        self.nodeBuf = ByteBuffer()
        self.dataBuf = ByteBuffer()
        self.dataByteBuf = ByteBuffer(self.dataBuf.data)
        self.dataWordBuf = ByteBuffer(self.dataBuf.data)

        for child in self.xml_doc.childNodes:
            self._node_to_binary(child)

        # always has the isArray bit set
        self.nodeBuf.append_u8(xml_types['endSection'] | 64)
        self.nodeBuf.realign_writes()
        header.append_u32(len(self.nodeBuf))
        self.nodeBuf.append_u32(len(self.dataBuf))
        return bytes(header.data + self.nodeBuf.data + self.dataBuf.data)

    def from_binary(self, input):
        self.xml_doc = minidom.Document()
        node = self.xml_doc

        self.nodeBuf = ByteBuffer(input)
        assert self.nodeBuf.get_u8() == SIGNATURE

        compress = self.nodeBuf.get_u8()
        assert compress in (SIG_COMPRESSED, SIG_UNCOMPRESSED)
        self.compressed = compress == SIG_COMPRESSED

        encoding_key = self.nodeBuf.get_u8()
        assert self.nodeBuf.get_u8() == 0xFF ^ encoding_key
        self.encoding = encoding_strings[encoding_key]

        nodeEnd = self.nodeBuf.get_u32() + 8
        self.nodeBuf.end = nodeEnd

        self.dataBuf = ByteBuffer(input, nodeEnd)
        dataSize = self.dataBuf.get_u32()
        # This is all no fun
        self.dataByteBuf = ByteBuffer(input, nodeEnd)
        self.dataWordBuf = ByteBuffer(input, nodeEnd)

        nodesLeft = True
        while nodesLeft and self.nodeBuf.hasData():
            while self.nodeBuf.peek_u8() == 0:
                debug_print("Skipping 0 node ID")
                self.nodeBuf.get_u8()

            nodeType = self.nodeBuf.get_u8()
            isArray = nodeType & 64
            nodeType &= ~64

            nodeFormat = xml_formats.get(nodeType, {'name':'Unknown'})
            debug_print('Node type is {} ({})'.format(nodeFormat['name'], nodeType))

            # node or attribute name
            name = ''
            if nodeType != xml_types['nodeEnd'] and nodeType != xml_types['endSection']:
                if self.compressed:
                    name = unpack_sixbit(self.nodeBuf)
                else:
                    length = self.nodeBuf.get_u8()
                    name = self.nodeBuf.get('s', length)
                debug_print(name)

            skip = True

            if nodeType == xml_types['attr']:
                value = self.data_grab_string()
                node.setAttribute(name, value)
            elif nodeType == xml_types['nodeEnd']:
                if node.parentNode:
                    node = node.parentNode
            elif nodeType == xml_types['endSection']:
                nodesLeft = False
            elif nodeType not in xml_formats:
                raise NotImplementedError('Implement node {}'.format(nodeType))
            else: # inner value to process
                skip = False

            if skip:
                continue

            child = self.xml_doc.createElement(name)
            node.appendChild(child)
            node = child

            if nodeType == xml_types['nodeStart']:
                continue

            node.setAttribute('__type', nodeFormat['name'])

            varCount = nodeFormat['count']
            arrayCount = 1
            if varCount == -1: # the 2 cannot be combined
                varCount = self.dataBuf.get_u32()
                isArray = True
            elif isArray:
                arrayCount = self.dataBuf.get_u32() // (calcsize(nodeFormat['type'] * varCount))
                node.setAttribute('__count', str(arrayCount))
            totalCount = arrayCount * varCount

            if isArray:
                data = self.dataBuf.get(nodeFormat['type'], totalCount)
                self.dataBuf.realign_reads()
            else:
                data = self.data_grab_aligned(nodeFormat['type'], totalCount)

            if nodeType == xml_types['binary']:
                node.setAttribute('__size', str(totalCount))
                string = ''.join(('{0:02x}'.format(x) for x in data))
            elif nodeType == xml_types['string']:
                string = bytes(data[:-1]).decode(self.encoding)
            else:
                string = ' '.join(map(nodeFormat.get('toStr', str), data))

            node.appendChild(self.xml_doc.createTextNode(string))
Esempio n. 19
0
 def is_binary_xml(input):
     nodeBuf = ByteBuffer(input)
     return (nodeBuf.get_u8() == SIGNATURE and
         nodeBuf.get_u8() in (SIG_COMPRESSED, SIG_UNCOMPRESSED))
    def _threadCmdRX(self, stop_event, arg):
        # print '_threadCmdRX started !!!'
        statusCtr = 0
        data = bytearray(1024)
        payload = None

        while not stop_event.is_set():
            try:
                size, addr = self.sockCmd.recvfrom_into(data)
            except socket.timeout as e:
                time.sleep(.5)
                continue
            except socket.error as e:
                print(e)
                continue
            else:
                cmdID = self._parsePacket(data[:size])
                payload = ByteBuffer.wrap(data[9:size - 1])

                if cmdID == self.TELLO_CMD_CONN_ACK:
                    print('connection successful !')
                    # self._printArray(data[:size])

                elif cmdID == self.TELLO_CMD_DATE_TIME:
                    self._sendCmd(0x50, cmdID, None)

                elif cmdID == self.TELLO_CMD_STATUS:
                    if statusCtr == 3:
                        self._sendCmd(0x60, self.TELLO_CMD_REQ_VIDEO_SPS_PPS,
                                      None)
                        self._sendCmd(0x48, self.TELLO_CMD_VERSION_STRING,
                                      None)
                        self._sendCmd(0x48, self.TELLO_CMD_SET_VIDEO_BIT_RATE,
                                      None)
                        self._sendCmd(0x48, self.TELLO_CMD_ALT_LIMIT, None)
                        self._sendCmd(0x48, self.TELLO_CMD_LOW_BATT_THRESHOLD,
                                      None)
                        self._sendCmd(0x48, self.TELLO_CMD_ATT_ANGLE, None)
                        self._sendCmd(0x48, self.TELLO_CMD_REGION, None)
                        self._sendCmd(0x48, self.TELLO_CMD_SET_EV,
                                      bytearray([0x00]))
                    statusCtr = statusCtr + 1

                elif cmdID == self.TELLO_CMD_VERSION_STRING:
                    if size >= 42:
                        print('Version:' + data[10:30].decode())

                elif cmdID == self.TELLO_CMD_SMART_VIDEO_START:
                    if payload.get_remaining() > 0:
                        print('smart video start')

                elif cmdID == self.TELLO_CMD_ALT_LIMIT:
                    if payload.get_remaining() > 0:
                        payload.get_ULInt8()  # 0x00
                        height = payload.get_ULInt16()
                        print('alt limit : {0:2d} meter'.format(height))

                        if height != self.NEW_ALT_LIMIT:
                            print('set new alt limit : {0:2d} meter'.format(
                                self.NEW_ALT_LIMIT))
                            self._sendCmd(
                                0x68, self.TELLO_CMD_SET_ALT_LIMIT,
                                bytearray([
                                    self.NEW_ALT_LIMIT & 0xff,
                                    (self.NEW_ALT_LIMIT >> 8) & 0xff
                                ]))

                elif cmdID == self.TELLO_CMD_SMART_VIDEO_STATUS:
                    if payload.get_remaining() > 0:
                        resp = payload.get_ULInt8()
                        dummy = resp & 0x07
                        start = (resp >> 3) & 0x03
                        mode = (resp >> 5) & 0x07
                        print('smart video status - mode:{0:d}, start:{1:d}'.
                              format(mode, start))
                        self._sendCmd(0x50, self.TELLO_CMD_SMART_VIDEO_STATUS,
                                      bytearray([0x00]))
Esempio n. 21
0
        statusCtr = 0
        data = bytearray(1024)
        payload = None

        while not stop_event.is_set():
            try:
                size, addr = self.sockCmd.recvfrom_into(data)
            except socket.timeout, e:
                time.sleep(.5)
                continue
            except socket.error, e:
                print e
                continue
            else:
                cmdID = self._parsePacket(data[:size])
                payload = ByteBuffer.wrap(data[9:size - 1])

                if cmdID == self.TELLO_CMD_CONN_ACK:
                    print 'connection successful !'
                    # self._printArray(data[:size])

                elif cmdID == self.TELLO_CMD_DATE_TIME:
                    self._sendCmd(0x50, cmdID, None)

                elif cmdID == self.TELLO_CMD_STATUS:
                    if statusCtr == 3:
                        self._sendCmd(0x60, self.TELLO_CMD_REQ_VIDEO_SPS_PPS,
                                      None)
                        self._sendCmd(0x48, self.TELLO_CMD_VERSION_STRING,
                                      None)
                        self._sendCmd(0x48, self.TELLO_CMD_SET_VIDEO_BIT_RATE,