Exemple #1
0
    def decode(self, data):
        """Decode given data as a message of this type.

        >>> foo = db.messages[0]
        >>> foo.decode(b'\\x01\\x45\\x23\\x00\\x11')
        {'Bar': 1, 'Fum': 5.0}

        """

        data += b'\x00' * (8 - len(data))

        if self.is_multiplexed():
            mux = bitstruct.unpack(self._multiplexer[1], data[::-1])[0]

            if mux not in self._multiplexer_message_by_id:
                raise KeyError('Invalid multiplex message id {}.'.format(mux))

            signals = self._multiplexer_message_by_id[mux]['signals']
            fmt = self._multiplexer_message_by_id[mux]['fmt']
        else:
            signals = self._signals
            fmt = self._fmt

        unpacked_data = bitstruct.unpack(fmt, data[::-1])
        decoded_signals = {}

        for signal, value in zip(signals, unpacked_data):
            scaled_value = (signal.scale * value + signal.offset)

            try:
                decoded_signals[signal.name] = signal.choices[scaled_value]
            except (KeyError, TypeError):
                decoded_signals[signal.name] = scaled_value

        return decoded_signals
Exemple #2
0
    def load(cls, data):
        if not isinstance(data, DataReader):  # pragma: nocover
            data = DataReader(data)

        frame_start = data.tell()

        sync, version_id, layer_index, protection = bitstruct.unpack(
            'u11 u2 u2 b1', data.read(2))
        # sync, flags, indexes, remainder = struct.unpack('BBBB', data.read(4))

        if sync != 2047:
            raise InvalidFrame('Not a valid MPEG audio frame.')

        version = [2.5, None, 2, 1][version_id]

        layer = 4 - layer_index

        protected = not protection

        bitrate_index, sample_rate_index, padded = bitstruct.unpack(
            'u4 u2 u1', data.read(1))

        if (version_id == 1 or layer_index == 0 or bitrate_index == 0
                or bitrate_index == 15 or sample_rate_index == 3):
            raise InvalidFrame('Not a valid MPEG audio frame.')

        channel_mode = MP3ChannelMode(bitstruct.unpack('u2', data.read(1))[0])
        channels = 1 if channel_mode == 3 else 2

        bitrate = MP3Bitrates[(version, layer)][bitrate_index] * 1000
        sample_rate = MP3SampleRates[version][sample_rate_index]

        samples_per_frame, slot_size = MP3SamplesPerFrame[(version, layer)]

        frame_size = (((samples_per_frame // 8 * bitrate) // sample_rate) +
                      padded) * slot_size

        xing_header = None
        if layer == 3:
            if version == 1:
                if channel_mode != 3:
                    xing_header_start = 36
                else:
                    xing_header_start = 21
            elif channel_mode != 3:
                xing_header_start = 21
            else:
                xing_header_start = 13

            data.seek(frame_start + xing_header_start, os.SEEK_SET)

            t = data.read(4)
            if t in [b'Xing', b'Info']:
                data.seek(-4, os.SEEK_CUR)
                xing_header = XingHeader.load(data.read(frame_size))

        return cls(frame_start, frame_size, xing_header, version, layer,
                   protected, padded, bitrate, channel_mode, channels,
                   sample_rate)
Exemple #3
0
    def load(cls, data):
        frame_start = data.tell()

        sync, version_id, layer_index, protection = bitstruct.unpack(
            'u11 u2 u2 b1', data.read(2))

        if sync != 2047:
            raise InvalidFrame('Not a valid MPEG audio frame.')

        version = [2.5, None, 2, 1][version_id]

        layer = 4 - layer_index

        protected = not protection

        bitrate_index, sample_rate_index, padded = bitstruct.unpack(
            'u4 u2 u1', data.read(1))

        if (version_id == 1 or layer_index == 0 or bitrate_index == 0
                or bitrate_index == 15 or sample_rate_index == 3):
            raise InvalidFrame('Not a valid MPEG audio frame.')

        channel_mode = MP3ChannelMode(bitstruct.unpack('u2', data.read(1))[0])
        channels = 1 if channel_mode == 3 else 2

        bitrate = MP3Bitrates[(version, layer)][bitrate_index] * 1000
        sample_rate = MP3SampleRates[version][sample_rate_index]

        samples_per_frame, slot_size = MP3SamplesPerFrame[(version, layer)]

        frame_size = (((samples_per_frame // 8 * bitrate) // sample_rate) +
                      padded) * slot_size

        vbri_header = None
        xing_header = None
        if layer == 3:
            if version == 1:
                if channel_mode != 3:
                    xing_header_start = 36
                else:
                    xing_header_start = 21
            elif channel_mode != 3:
                xing_header_start = 21
            else:
                xing_header_start = 13

            data.seek(frame_start + xing_header_start, os.SEEK_SET)

            if data.peek(4) in [b'Xing', b'Info']:
                xing_header = XingHeader.load(data.read(frame_size))

            data.seek(frame_start + 36, os.SEEK_SET)

            if data.peek(4) == b'VBRI':
                vbri_header = VBRIHeader.load(data)

        return cls(frame_start, frame_size, vbri_header, xing_header, version,
                   layer, protected, padded, bitrate, channel_mode, channels,
                   sample_rate)
Exemple #4
0
    def load(cls, data, xing_quality):
        encoder = data.read(9)
        if not encoder.startswith(b'LAME'):
            raise InvalidHeader('Valid LAME header not found.')

        version_match = re.search(rb'LAME(\d+)\.(\d+)', encoder)
        if version_match:
            version = tuple(int(part) for part in version_match.groups())
        else:
            version = None

        revision, bitrate_mode_ = bitstruct.unpack('u4 u4', data.read(1))
        bitrate_mode = LAMEBitrateMode(bitrate_mode_)

        # TODO: Decide what, if anything, to do with the different meanings in LAME.
        # quality = (100 - xing_quality) % 10
        # vbr_quality = (100 - xing_quality) // 10

        lowpass_filter = struct.unpack('B', data.read(1))[0] * 100

        replay_gain = LAMEReplayGain.load(data)

        flags_ath = bitstruct.unpack_dict('b1 b1 b1 b1 u4', [
            'nogap_continuation', 'nogap_continued', 'nssafejoint',
            'nspsytune', 'ath_type'
        ], data.read(1))

        ath_type = flags_ath.pop('ath_type')
        encoding_flags = LAMEEncodingFlags(flags_ath['nogap_continuation'],
                                           flags_ath['nogap_continued'],
                                           flags_ath['nssafejoint'],
                                           flags_ath['nspsytune'])

        # TODO: Different representation for VBR minimum bitrate vs CBR/ABR specified bitrate?
        # Can only go up to 255.
        bitrate = struct.unpack('B', data.read(1))[0] * 1000

        delay, padding = bitstruct.unpack('u12 u12', data.read(3))

        source_sample_rate, unwise_settings_used, channel_mode_, noise_shaping = bitstruct.unpack(
            'u2 u1 u3 u2', data.read(1))
        channel_mode = LAMEChannelMode(channel_mode_)

        mp3_gain = bitstruct.unpack('s8', data.read(1))[0]

        surround_info_, preset_used_ = bitstruct.unpack(
            'p2 u3 u11', data.read(2))
        surround_info = LAMESurroundInfo(surround_info_)

        preset = LAMEPreset(preset_used_)

        audio_size, audio_crc, lame_crc = struct.unpack('>I2s2s', data.read(8))

        return cls(lame_crc, version, revision, ath_type, audio_crc,
                   audio_size, bitrate, bitrate_mode, channel_mode, delay,
                   encoding_flags, lowpass_filter, mp3_gain, noise_shaping,
                   padding, preset, replay_gain, source_sample_rate,
                   surround_info, unwise_settings_used)
Exemple #5
0
    def unpack(self, data):
        if isinstance(data, bytearray):
            bits = bytearray_to_bits(data)
        else:
            bits = data

        # TODO: the % seems fishy
        if self.bytes > 1 and len(bits) % bits_per_byte == 0:
            # TODO: CAMPid 08793287728743824372437983526631513679
            bits = ''.join(
                itertools.chain(*reversed(list(grouper(bits, bits_per_byte)))))

        if self.format.is_integer():
            if self.format.is_unsigned_integer():
                pad = '0'
                type = 'u'
            else:
                pad = bits[0]
                type = 's'

            padding = pad * (self.bytes * bits_per_byte - len(bits))

            padded_bits = padding + bits

            format = '>{}{}'.format(type, str(len(bits)))

            if len(padding) > 0:
                format = '>u{}{}'.format(str(len(padding)), format)

            return bitstruct.unpack(
                format,
                int(padded_bits, 2).to_bytes(self.bytes * bits_per_byte // 8,
                                             byteorder='big'))[-1]

        elif self.format.is_floating_point():
            # TODO: CAMPid 097897541967932453154321546542175421549

            # note that this is hardcoded for two bytes/address fudge
            types = {4: 'f', 8: 'd'}
            try:
                type = types[self.bytes * (bits_per_byte / 8)]
            except KeyError:
                raise Exception(
                    'float type only supports lengths in [{}]'.format(
                        ', '.join([str(t) for t in types.keys()])))

            format = '{}{}{}>'.format('>', type, self.bytes * bits_per_byte)

            return bitstruct.unpack(
                format,
                bytes(
                    int(''.join(b), 2)
                    for b in epyqlib.utils.general.grouper(bits, 8)),
            )[-1]

        raise Exception('Unsupported type format: {}'.format(self.type))
Exemple #6
0
def readbit(bits, start, end):
    '''
    function to read variables bitwise, where applicable
    '''
    try:
        if start == 0:
            return bitstruct.unpack('<u'+str(end+1), bits)[0]
        else:
            return bitstruct.unpack('<p'+str(start)+'u'+str(end-start), bits)[0]
    except:
        print('error reading bits')
Exemple #7
0
def read_char(b_stream):
    """
    read_char()
    :param b_stream: 1 byte hex string
    :return:
    """

    __name__ = "char"

    if isinstance(b_stream, types.IntType):
        return bs.unpack('s8', b_stream)[0]
    elif isinstance(b_stream, types.StringType):
        return bs.unpack('t8', b_stream)[0]
Exemple #8
0
 def dict_from_bytes(data: bytes):
     assert ipFrame.is_m17(data)
     d = {}
     d["streamid"] = bitstruct.unpack("u16", data[4:6])[0]
     lich_start = 6
     lich_end = lich_start + initialLICH.sz
     payload_start = lich_end + 2
     payload_end = payload_start + 16
     d["LICH"] = initialLICH.from_bytes(data[lich_start:lich_end])
     d["frame_number"] = bitstruct.unpack("u16",
                                          data[lich_end:payload_start])[0]
     d["payload"] = data[payload_start:payload_end]
     # d["crc"] = bitstruct.unpack("u16", ...
     return d
Exemple #9
0
 def deserialize_bitfield():
     nonlocal bit_fmt, bit_fields, remainder
     if bit_fmt == '':
         return
     bit_length = bitstruct.calcsize(bit_fmt) // 8
     bit_data, remainder = remainder[:bit_length], remainder[bit_length:]
     logging.debug(f'{self.__class__.__name__}: parse {bit_fmt} from {bin2hex_helper(bit_data)}')
     if not self._mergeBitfield:
         values = bitstruct.unpack(bit_fmt + '<', bit_data)
     else:
         values = bitstruct.unpack(bit_fmt, bit_data[::-1])
     for f, v in zip(bit_fields, values):
         f.from_serialized(v)
     bit_fmt = ''
     bit_fields = []
def getUnknownHitboxBits(datJson):
    # original:
    fmt = "u3p5u7p2u9 u16s16s16s16 u9u9u9p3u2u9 u5p1u7u8b1b1"
    fmt = fmt.replace("p", "X") # mark the old paddings
    fmt = fmt.replace("u", "p") # make unsigned ints padding
    fmt = fmt.replace("s", "p") # make signed ints padding
    fmt = fmt.replace("b", "p") # make bools padding
    fmt = fmt.replace("X", "u") # turn old padding into uint
    #print(fmt)

    # simplified
    fmt = "p6p3 u1u1u1u1u1 p7 u1u1 p100 u1u1u1 p16 u1 p17"
    #print(fmt)

    fmt = fmt.replace(" ", "")

    ret = []
    for i, subaction in enumerate(datJson["nodes"][0]["data"]["subactions"]):
        hitboxCounter = 1
        hitboxes = []
        for event in subaction["events"]:
            if "name" in event and event["name"] == "hitbox":
                cmd = bytes.fromhex(event["bytes"])
                values = bitstruct.unpack(fmt, cmd)
                hitboxes.append((hitboxCounter, values))
                hitboxCounter += 1
        ret.append((i, subaction["shortName"], hitboxes))

    return ret
Exemple #11
0
def decode_kernel_path(entry_type, word_int, capreg_int):
    """Decode some easily-decodable kernel paths - i.e ordinary system calls"""
    if entry_type == KernelEntryType.Interrupt:
        return "IRQ #{}".format(word_int)
    elif entry_type == KernelEntryType.UnknownSyscall:
        if word_int & 0xF == SyscallType.DebugPutChar.value[0]:
            return "DebugPutChar: {}".format(chr(capreg_int))
        else:
            return "word = {}".format(word_int)
    elif entry_type == KernelEntryType.VMFault:
        return "fault_type = {}".format(word_int)
    elif entry_type == KernelEntryType.UserLevelFault:
        return "fault_number = {}".format(word_int)
    elif entry_type == KernelEntryType.DebugFault:
        return "fault_vaddr = {}".format(hex(word_int))
    elif entry_type == KernelEntryType.Syscall:
        word_int <<= 3
        word_bytes = word_int.to_bytes(4, byteorder='big')
        tuple_of_data = unpack("u17u1u7u4u3", word_bytes)
        (invoc_tag, is_fastpath, cap_type, syscall_no, _) = tuple_of_data
        invoc = ""
        cap = ""
        try:
            invoc = InvocationType(invoc_tag)
        except:
            invoc = "?"
        try:
            cap = CapType(cap_type)
        except:
            cap = "?"
        return "{} - [{}, fp:{}, {}]".format(SyscallType(syscall_no), cap,
                                             is_fastpath, invoc)

    return "Unknown"
Exemple #12
0
def pgn_pack(reserved, data_page, pdu_format, pdu_specific=0):
    """Pack given values as a parameter group number (PGN) and return it
    as an integer.

    """

    if pdu_format < 240 and pdu_specific != 0:
        raise Error(
            'Expected PDU specific 0 when PDU format is 0..239, but got {}.'.
            format(pdu_specific))

    try:
        packed = bitstruct.pack('u1u1u8u8', reserved, data_page, pdu_format,
                                pdu_specific)
    except bitstruct.Error:
        if reserved > 1:
            raise Error('Expected reserved 0..1, but got {}.'.format(reserved))
        elif data_page > 1:
            raise Error(
                'Expected data page 0..1, but got {}.'.format(data_page))
        elif pdu_format > 255:
            raise Error(
                'Expected PDU format 0..255, but got {}.'.format(pdu_format))
        elif pdu_specific > 255:
            raise Error('Expected PDU specific 0..255, but got {}.'.format(
                pdu_specific))
        else:
            raise Error('Internal error.')

    return bitstruct.unpack('u18', packed)[0]
Exemple #13
0
    def pgn(self):
        if self.pdu_format < 240 and self.pdu_specific != 0:
            raise Error('Expected PDU specific 0 when PDU format is '
                        '0..239, but got {}.'.format(self.pdu_specific))

        try:
            packed = bitstruct.pack('u1u1u8u8', self.reserved, self.data_page,
                                    self.pdu_format, self.pdu_specific)
        except bitstruct.Error:
            if self.reserved > 1:
                raise Error('Expected reserved 0..1, but got {}.'.format(
                    self.reserved))
            elif self.data_page > 1:
                raise Error('Expected data page 0..1, but got {}.'.format(
                    self.data_page))
            elif self.pdu_format > 255:
                raise Error('Expected PDU format 0..255, but got {}.'.format(
                    self.pdu_format))
            elif self.pdu_specific > 255:
                raise Error('Expected PDU specific 0..255, but got {}.'.format(
                    self.pdu_specific))
            else:
                raise Error('Internal error.')

        return bitstruct.unpack('u18', packed)[0]
Exemple #14
0
    def parse(cls, data):
        start = data.tell()

        (oggs, version, flags, position, serial_number, sequence_number, crc,
         num_segments) = struct.unpack(
             '<4sBsqIIIB',
             data.read(27),
         )

        if oggs != b'OggS':
            raise FormatError("Valid Ogg page header not found.")

        if version != 0:
            raise UnsupportedFormat(
                f"Ogg version '{version}' is not supported.")

        is_last, is_first, is_continued = bitstruct.unpack(
            '<p5 b1 b1 b1', flags)

        return cls(
            start=start,
            version=version,
            is_continued=is_continued,
            is_first=is_first,
            is_last=is_last,
            position=position,
            serial_number=serial_number,
            sequence_number=sequence_number,
            crc=crc,
            num_segments=num_segments,
        )
Exemple #15
0
def frame_id_pack(priority, reserved, data_page, pdu_format, pdu_specific,
                  source_address):
    """Pack given values as a frame id and return it as an integer.

    """

    try:
        packed = bitstruct.pack('u3u1u1u8u8u8', priority, reserved, data_page,
                                pdu_format, pdu_specific, source_address)
    except bitstruct.Error:
        if priority > 7:
            raise Error('Expected priority 0..7, but got {}.'.format(priority))
        elif reserved > 1:
            raise Error('Expected reserved 0..1, but got {}.'.format(reserved))
        elif data_page > 1:
            raise Error(
                'Expected data page 0..1, but got {}.'.format(data_page))
        elif pdu_format > 255:
            raise Error(
                'Expected PDU format 0..255, but got {}.'.format(pdu_format))
        elif pdu_specific > 255:
            raise Error('Expected PDU specific 0..255, but got {}.'.format(
                pdu_specific))
        elif source_address > 255:
            raise Error('Expected source address 0..255, but got {}.'.format(
                source_address))
        else:
            raise Error('Internal error.')

    return bitstruct.unpack('u29', packed)[0]
Exemple #16
0
    def frame_id(self):
        try:
            packed = bitstruct.pack('u3u1u1u8u8u8', self.priority,
                                    self.reserved, self.data_page,
                                    self.pdu_format, self.pdu_specific,
                                    self.source_address)
        except bitstruct.Error:
            if self.priority > 7:
                raise Error('Expected priority 0..7, but got {}.'.format(
                    self.priority))
            elif self.reserved > 1:
                raise Error('Expected reserved 0..1, but got {}.'.format(
                    self.reserved))
            elif self.data_page > 1:
                raise Error('Expected data page 0..1, but got {}.'.format(
                    self.data_page))
            elif self.pdu_format > 255:
                raise Error('Expected PDU format 0..255, but got {}.'.format(
                    self.pdu_format))
            elif self.pdu_specific > 255:
                raise Error('Expected PDU specific 0..255, but got {}.'.format(
                    self.pdu_specific))
            elif self.source_address > 255:
                raise Error(
                    'Expected source address 0..255, but got {}.'.format(
                        self.source_address))
            else:
                raise Error('Internal error.')

        return bitstruct.unpack('u29', packed)[0]
Exemple #17
0
def decode_msm_head(payload, _sys):  #, sync, iod, h, hsize):
    if _sys != 'GPS':
        print('unknown system')
        return
    # 12 bits message type
    # 12 bits station ID
    # 30 bits Time of Week (in milli-seconds)
    #  1 bit sync
    #  3 bits iod
    #  7 bits time_s
    #  2 bits clk_str
    #  2 bits clk_ext
    #  1 bit smooth
    #  3 bits tint_s
    # 64 bits Satellite mask
    msg_type, staid, tow_ms, sync, iod, time_s, clk_str, clk_ext, smooth, tint_s, \
        satmask = bitstruct.unpack('u12u12u30u1u3u7u2u2u1u3u64', payload)

    print('station id:', staid)
    print('sync:', sync)
    print('iod:', iod)
    print('time_s:', time_s)
    print('clk_str:', clk_str)
    print('clk_ext:', clk_ext)
    print('smooth:', smooth)
    print('tint_s:', tint_s)
    print('tow:', tow_ms * 0.001)

    print('satmask:', satmask)
    total_sats = 0
    for i in range(64):
        if ((satmask >> i) & 1) == 1:
            total_sats += 1
    print("Total sats:", total_sats)
Exemple #18
0
def pgn_pack(reserved, data_page, pdu_format, pdu_specific=0):
    """Pack given values as a parameter group number (PGN) and return it
    as an integer.

    """

    if pdu_format < 240 and pdu_specific != 0:
        raise Error(
            'Expected PDU specific 0 when PDU format is 0..239, but got {}.'.format(
                pdu_specific))

    try:
        packed = bitstruct.pack('u1u1u8u8',
                                reserved,
                                data_page,
                                pdu_format,
                                pdu_specific)
    except bitstruct.Error:
        if reserved > 1:
            raise Error('Expected reserved 0..1, but got {}.'.format(reserved))
        elif data_page > 1:
            raise Error('Expected data page 0..1, but got {}.'.format(
                data_page))
        elif pdu_format > 255:
            raise Error('Expected PDU format 0..255, but got {}.'.format(
                pdu_format))
        elif pdu_specific > 255:
            raise Error('Expected PDU specific 0..255, but got {}.'.format(
                pdu_specific))
        else:
            raise Error('Internal error.')

    return bitstruct.unpack('u18', packed)[0]
Exemple #19
0
 def deser_bcd_plus(val: bytearray) -> str:
     result = ''
     for v in val:
         tmp = bitstruct.unpack('u4' * 2, bytes((v, )))
         for x in tmp:
             result += self.bcdplus_lookup.inverse[x]
     return result
Exemple #20
0
def decode_type1006(payload):
    '''
    Parse message type 1006:
        stationary rtk reference station ARP (antenna reference point) + antenna height
    '''
    # 12 bits message type == 1006
    # 12 bits station ID
    #  6 bits itrf
    #  4 bits nothing?
    # 38 bits ecef-X (signed)
    #  2 bits nothing?
    # 38 bits ecef-Y (signed)
    #  2 bits nothing?
    # 38 bits ecef-Z (signed)
    # 16 bits anth (antenna height?)

    assert len(payload) == 21

    msg_type, staid, itrf, _nothing, rrX, _nothing2, rrY, _nothing3, rrZ, \
        anth = bitstruct.unpack('u12u12u6u4s38u2s38u2s38u16', payload)

    print("\n * RTK base station ARP and antenna height")
    print("    - ECEF, meters: %.04f %.04f %.04f" %
          (rrX * 0.0001, rrY * 0.0001, rrZ * 0.0001))
    lat, lon, alt = ecef2geodetic(rrX * 0.0001, rrY * 0.0001, rrZ * 0.0001)

    print("    - Lat, Lon:", lat, lon)
    print("    - elevation, meters: %.04f" % (alt))
    print("    - antenna height:", anth)
    print()
Exemple #21
0
 def deser_6bit(val: bytearray) -> str:
     result = b''
     for chunk in _grouper(3, val, padvalue=' '):
         tmp = bitstruct.unpack('u6' * 4, bytearray(reversed(chunk)))
         for x in tmp[::-1]:
             result += bytes((x + 0x20, ))
     return result.decode('utf-8')
Exemple #22
0
    def load(cls, data):
        if not isinstance(data, DataReader):  # pragma: nocover
            data = DataReader(data)

        peak_data = struct.unpack('>I', data.read(4))[0]

        if peak_data == b'\x00\x00\x00\x00':
            gain_peak = None
        else:
            gain_peak = (peak_data - 0.5) / 2**23

        gain_type_, gain_origin_, gain_sign, gain_adjustment_ = bitstruct.unpack(
            'u3 u3 u1 u9', data.read(2))

        gain_type = LAMEReplayGainType(gain_type_)
        gain_origin = LAMEReplayGainOrigin(gain_origin_)
        gain_adjustment = gain_adjustment_ / 10.0

        if gain_sign:
            gain_adjustment *= -1

        if not gain_type:
            return None

        return cls(gain_type, gain_origin, gain_adjustment, gain_peak)
Exemple #23
0
def readtime(bits):
    '''
    function to read dates bitwise.
    this is a colossally stupid way of storing dates.
    I have no idea if I'm unpacking them correctly, and every indication that I'm not
    '''
    garbagedate = datetime(1980, 1, 1, 0, 0, 0, 0, tzinfo=pytz.UTC)
    if bits == '\x00\x00\x00\x00':
        return garbagedate  # if there is no date information, return arbitrary datetime
    else:
        try:
            sec2, mins, hr, day, mo, yr = bitstruct.unpack(
                '<u5u6u5u5u4u7', bits)  # if there is date info, try to unpack
            # year+1980 should equal real year
            # sec2 * 2 should equal real seconds
            return datetime(yr + 1980,
                            mo,
                            day,
                            hr,
                            mins,
                            sec2 * 2,
                            0,
                            tzinfo=pytz.UTC)
        except:
            return garbagedate  # most of the time the info returned is garbage, so we return arbitrary datetime again
Exemple #24
0
 def dict_from_bytes(data: bytes):
     d = {}
     d["dst"], d["src"], d["streamtype"] = bitstruct.unpack(
         "u48u48u16", data[:14])
     d["dst"] = Address(addr=d["dst"])
     d["src"] = Address(addr=d["src"])
     d["nonce"] = data[14:14 + 14]
     return d
Exemple #25
0
    def from_frame_id(cls, frame_id):
        try:
            packed = bitstruct.pack('u29', frame_id)
        except bitstruct.Error:
            raise Error('Expected a frame id 0..0x1fffffff, '
                        'but got {}.'.format(hex(frame_id)))

        return cls(*bitstruct.unpack('u3u1u1u8u8u8', packed))
Exemple #26
0
 def dict_from_bytes(data: bytes):
     d = {}
     d["lich_chunk"] = data[0:6]
     d["frame_number"] = bitstruct.unpack("u16", data[6:8])[0]
     d["payload"] = data[8:8 + 16]
     #ignore the CRC, it's not implemented yet
     # d["chksum"] = bitstruct.unpack("u16", data[8+16:8+16+2])[0]
     return d
Exemple #27
0
def do_device_status_print(args):
    status = execute_command(
        serial_open_ensure_connected_to_programmer(args.port),
        PROGRAMMER_COMMAND_TYPE_DEVICE_STATUS)
    unpacked = bitstruct.unpack('u1p1u1p1u1u1p1u1', status)
    status = struct.unpack('B', status)[0]

    print(DEVICE_STATUS_FMT.format(status, *unpacked))
Exemple #28
0
    def enqueue_message(self, data, message):
        if self.db_config is not None and not self.group_monitor:
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
            try:
                # remove additional cEMI data
                header_len = bitstruct.unpack('>u8', data[0:1])[0]
                add_len = bitstruct.unpack('>u8',
                                           data[header_len:header_len + 1])[0]
                cemi = data[header_len + add_len:]

                # parse cEMI and create Telegram/AckTelegram object
                parsed_telegram = knx_parser.parse_knx_telegram(cemi)
                if isinstance(parsed_telegram, knx_parser.KnxBaseTelegram):
                    t = Telegram()
                    t.timestamp = str(timestamp)
                    t.source_addr = str(parsed_telegram.src)
                    t.destination_addr = str(parsed_telegram.dest)
                    t.extended_frame = 1 if parsed_telegram.frame_type == knx_parser.const.FrameType.EXTENDED_FRAME else 0
                    t.priority = str(parsed_telegram.priority)
                    t.repeat = int(parsed_telegram.repeat)
                    t.ack_req = int(parsed_telegram.ack_req)
                    t.confirm = int(parsed_telegram.confirm)
                    t.system_broadcast = int(parsed_telegram.system_broadcast)
                    t.hop_count = int(parsed_telegram.hop_count)
                    t.tpci = str(parsed_telegram.tpci[0])
                    t.tpci_sequence = int(parsed_telegram.tpci[1])
                    t.apci = str(parsed_telegram.apci)
                    t.payload_data = str(parsed_telegram.payload_data)
                    t.payload_length = int(parsed_telegram.payload_length)
                    t.is_manipulated = 0
                    self.telegram_queue.put(t)
                else:
                    t = AckTelegram()
                    t.timestamp = str(timestamp)
                    t.apci = str(parsed_telegram.acknowledgement)
                    t.is_manipulated = 0
                    self.telegram_queue.put(t)
            except Exception as ex:
                LOGGER.error(
                    "Failed to parse telegram: {0} with following exception: {1}"
                    .format(str(message.cemi.raw_frame.hex()), ex))
                t = UnknownTelegram()
                t.timestamp = str(timestamp)
                t.cemi = str(message.cemi.raw_frame.hex())
                self.telegram_queue.put(t)
Exemple #29
0
def read_long(b_stream):
    """
    :param b_stream: 4 byte hex string
    :return: tuple (SInt32)
    """

    __name__ = "long"

    return bs.unpack('s32', b_stream)[0]
Exemple #30
0
def _decode_data(data, signals, formats, decode_choices, scaling):
    big_unpacked = list(bitstruct.unpack(formats.big_endian, data))
    big_signals = [
        signal for signal in signals if signal.byte_order == 'big_endian'
    ]
    little_unpacked = list(
        bitstruct.unpack(formats.little_endian, data[::-1])[::-1])
    little_signals = [
        signal for signal in signals if signal.byte_order == 'little_endian'
    ]
    unpacked = big_unpacked + little_unpacked
    signals = big_signals + little_signals

    return {
        signal.name: _decode_signal(signal, unpacked.pop(0), decode_choices,
                                    scaling)
        for signal in signals
    }
Exemple #31
0
    def decode(self, data):
        """Decode given data as a message of this type.

        """

        return self.decoded(*[
            v[0].scale * v[1] + v[0].offset
            for v in zip(self.signals, bitstruct.unpack(self.fmt, data))
        ])
Exemple #32
0
def frame_id_unpack(frame_id):
    """Unpack given frame id and return a tuple of priority, reserved,
    data page, PDU format, PDU specific and source address.

    """

    try:
        packed = bitstruct.pack('u29', frame_id)
    except bitstruct.Error:
        raise Error(
            'Expected a frame id 0..0x1fffffff, but got {}.'.format(
                hex(frame_id)))

    return FrameId(*bitstruct.unpack('u3u1u1u8u8u8', packed))
Exemple #33
0
def pgn_unpack(pgn):
    """Unpack given parameter group number (PGN) and return a tuple of
    Reserved, Data Page, PDU Format and PDU Specific.

    """

    try:
        packed = bitstruct.pack('u18', pgn)
    except bitstruct.Error:
        raise Error(
            'Expected a parameter group number 0..0x3ffff, but got {}.'.format(
                hex(pgn)))

    return PGN(*bitstruct.unpack('u1u1u8u8', packed))
Exemple #34
0
def unpack_section(section, data):
    """
    Unpacks bytes into data, including the endian swap

    :param section: The definition of the format, byteswap and namedtuple for this section
    :param data: The bytes to unpack into the tuple
    :returns: namedtuple -- A namedtuple containing the data from the section
    """

    # Bitstruct only takes byte arrays, some things give us strings
    if type(data) != bytearray:
        data = bytearray(data)

    unpacked = unpack(section['format'], byteswap(section['byteswap'], data))
    return section['fields'](*unpacked)
Exemple #35
0
def build_steamid(steamid_unparsed):
    if str(steamid_unparsed).isdigit():
        universe, steam_type, instance, account_number = bitstruct.unpack(
            "u8u4u20u32", bitstruct.pack("u64", long(steamid_unparsed))
        )

        # Bit confusing, but convert from ID64 to STEAM_0:A:B format
        # See https://developer.valvesoftware.com/wiki/SteamID
        instance = 0
        if account_number % 2 == 1:
            instance = 1
            account_number -= 1
        account_number = long(account_number / 2)

        return SteamID(account_number, instance, steam_type, universe)

    return SteamID.from_text(steamid_unparsed)
Exemple #36
0
def frame_id_pack(priority,
                  reserved,
                  data_page,
                  pdu_format,
                  pdu_specific,
                  source_address):
    """Pack given values as a frame id and return it as an integer.

    """

    try:
        packed = bitstruct.pack('u3u1u1u8u8u8',
                                priority,
                                reserved,
                                data_page,
                                pdu_format,
                                pdu_specific,
                                source_address)
    except bitstruct.Error:
        if priority > 7:
            raise Error('Expected priority 0..7, but got {}.'.format(priority))
        elif reserved > 1:
            raise Error('Expected reserved 0..1, but got {}.'.format(reserved))
        elif data_page > 1:
            raise Error('Expected data page 0..1, but got {}.'.format(data_page))
        elif pdu_format > 255:
            raise Error('Expected PDU format 0..255, but got {}.'.format(
                pdu_format))
        elif pdu_specific > 255:
            raise Error('Expected PDU specific 0..255, but got {}.'.format(
                pdu_specific))
        elif source_address > 255:
            raise Error('Expected source address 0..255, but got {}.'.format(
                source_address))
        else:
            raise Error('Internal error.')

    return bitstruct.unpack('u29', packed)[0]
import binstruct # GPL 3
@binstruct.big_endian
class Example(binstruct.StructTemplate):
    status =    binstruct.UInt16Field(0)
    greeting =  binstruct.StringField(2, 10)


example = Example(bytearray(s), start_offset=0)
print 'binstruct'
print '\t', example
print '\t', example.status, example.greeting


import bitstruct # MIT, appears to only support big-endian
print 'bitstruct'
print '\t', bitstruct.unpack('u16b80', bytearray(s))


import construct # MIT
PascalString = construct.Struct("PascalString",
    construct.UBInt8("length"),
    construct.Bytes("data", lambda ctx: ctx.length),
)
print 'construct'
print '\t', PascalString.parse("\x05helloXXX")
print '\t', PascalString.build(construct.Container(length=6, data="foobar"))

PascalString2 = construct.ExprAdapter(PascalString,
    encoder = lambda obj, ctx: construct.Container(length=len(obj), data=obj),
    decoder = lambda obj, ctx: obj.data,
)
Exemple #38
0
 def decode(self, data):
     return self.Decoded(*[v[0].scale * v[1] + v[0].offset
                           for v in zip(self.signals,
                                        bitstruct.unpack(self.fmt, data))])
	def unpackRect(self):
		data = self.handle.read(1)
		size, = bitstruct.unpack('u5', data)
		data += self.handle.read(math.ceil((size * 4 - 3) / 8))
		xmin, xmax, ymin, ymax = bitstruct.unpack('p5'+('s'+str(size))*4, data)
		return SWFRect(xmin, xmax, ymin, ymax)