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
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)
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)
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)
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))
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')
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]
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
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
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"
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]
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]
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, )
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]
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]
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)
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]
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
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()
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')
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)
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
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
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))
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
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))
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)
def read_long(b_stream): """ :param b_stream: 4 byte hex string :return: tuple (SInt32) """ __name__ = "long" return bs.unpack('s32', b_stream)[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 }
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)) ])
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))
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))
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)
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)
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, )
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)