def __init__(self, file_path, data_fmt, meta_fmt=None): self.DataSize = ustruct.calcsize(data_fmt) self.DataFmt = data_fmt self.UserMetaFmt = meta_fmt self.IteratorIndexStart = 0 self.IteratorIndexEnd = 0 self.IteratorCount = 0 self.Iterator = None self.OffsetUserMeta = 0 self.OffsetData = 0 if meta_fmt is not None: self.UserMetaSize = ustruct.calcsize(meta_fmt) Log.info("User meta size: {}".format(self.UserMetaSize)) else: self.UserMetaSize = 0 self.FilePath = file_path Log.info("Data size: {}".format(self.DataSize)) StructFile.META_SIZE = ustruct.calcsize(StructFile.META_FMT) StructFile.OffsetUserMeta = StructFile.META_SIZE self.OffsetData = self.OffsetUserMeta + self.UserMetaSize Log.info("Meta offset: {}".format(StructFile.FILE_OFFSET_META)) Log.info("User meta offset: {}".format(self.OffsetUserMeta)) Log.info("Data offset: {}".format(self.OffsetData)) self._FileCreate() self._FileInit()
def __init__(self): self.is_secondary = False self.pin = None self.secret = None self.is_empty = None self.magic_value = PA_MAGIC_V2 if version.has_608 else PA_MAGIC_V1 self.delay_achieved = 0 # so far, how much time wasted? self.delay_required = 0 # how much will be needed? self.num_fails = 0 # for UI: number of fails PINs self.attempts_left = 0 # ignore in mk1/2 case, only valid for mk3 self.state_flags = 0 # useful readback self.private_state = 0 # opaque data, but preserve self.cached_main_pin = bytearray(32) assert MAX_PIN_LEN == 32 # update FMT otherwise assert ustruct.calcsize(PIN_ATTEMPT_FMT_V1) == PIN_ATTEMPT_SIZE_V1, \ ustruct.calcsize(PIN_ATTEMPT_FMT) assert ustruct.calcsize(PIN_ATTEMPT_FMT_V2_ADDITIONS ) == PIN_ATTEMPT_SIZE - PIN_ATTEMPT_SIZE_V1 self.buf = bytearray( PIN_ATTEMPT_SIZE if version.has_608 else PIN_ATTEMPT_SIZE_V1) # check for bricked system early import callgate if callgate.get_is_bricked(): # die right away if it's not going to work callgate.enter_dfu(3)
class HCI_ACL(object): """HCI_ACL""" struct_format = "<I" struct_size = ustruct.calcsize(struct_format) def __init__(self, handle, pb=0, bc=0, data=b''): bin_str = "{:016b}{:02b}{:02b}{:012b}".format( len(data) if data else 0, bc, pb, handle) self._handle = handle self._pb = pb self._pb_name = PB_FLAGS[pb] self._bc = bc self._tobytes = int(bin_str, 2) self._data = data def __getattr__(self, name): if name == "handle": return self._handle elif name == "pb": return self._pb elif name == "pb_name": return self._pb_name elif name == "bc": return self._bc elif name == "tobytes": return self._tobytes elif name == "length": return len(self._data) if self._data else 0 elif name == "data": return self._data[:self.length] def __str__(self): desc_str = ("<{:s} " "handle=0x{:04x} pb={:s}(0x{:02x}) bc=0x{:02x} " "length={:d} data={:s}>") return desc_str.format(self.__class__.__name__, self.handle, self.pb_name, self.pb, self.bc, self.length, hexlify(self.data)) @staticmethod def from_buffer(data): """ Parse HCI ACL data References can be found here: * https://www.bluetooth.org/en-us/specification/adopted-specifications ** Core specification 4.1 ** [vol 2] Part E (Section 5) - HCI Data Formats ** [vol 2] Part E (Section 5.4) - Exchange of HCI-specific information """ hci_acl = uctypes.struct(uctypes.addressof(data[:HCI_ACL.struct_size]), HCI_ACL_STRUCT, uctypes.LITTLE_ENDIAN) data = data[HCI_ACL.struct_size:] return HCI_ACL(hci_acl.handle, hci_acl.pb, hci_acl.bc, data) def to_buffer(self): """ Get data string """ return ustruct.pack(self.struct_format, self.tobytes) + self.data
def _block(self, x0, y0, x1, y1, data=None): self._write(0x15, self._encode_pos(x0, x1)) self._write(0x75, self._encode_pos(y0, y1)) if data is None: size = ustruct.calcsize(">BBB") return self._read(0x5D, (x1 - x0 + 1) * (y1 - y0 + 1) * size) self._write(0x5C, data)
def readSeesaws(currentSeesaw): success = False #print('Requesting Info From Arduino') # START COMMAND arduinoUART.write(bytes([0xF0])) # ADDRESS arduinoUART.write(bytes([0x10 + currentSeesaw])) # COMMAND arduinoUART.write(bytes([0xA0])) print('Request sent to arduino') time.sleep(1) while arduinoUART.any() >= ustruct.calcsize(seesawDataFormat): sawBuf = arduinoUART.readline() if not sawBuf: print('No data received') else: #print('sawBuf:', sawBuf) #resultBuf = ustruct.unpack('BHffbb', binascii.unhexlify(sawBuf)) try: data = struct.unpack(seesawDataFormat, sawBuf) # binascii.unhexlify(sawBuf) #print('Result:', data) uploadData(sawBuf) success = True except ValueError: print('Incomplete Data...') # Attempt to clear buffer? arduinoUART.readall() #print('SUCCESS?', success) return success
def getpwnam(user): passwd = getpwnam_(user) if not passwd: raise KeyError("getpwnam(): name not found: {}".format(user)) passwd_fmt = "SSIISSS" passwd = uctypes.bytes_at(passwd, ustruct.calcsize(passwd_fmt)) passwd = ustruct.unpack(passwd_fmt, passwd) return struct_passwd(*passwd)
def _registers(self, register, values=None, struct='B'): if values is None: size = ustruct.calcsize(struct) data = self.i2c.readfrom_mem(self.address, register, size) values = ustruct.unpack(struct, data) return values data = ustruct.pack(struct, *values) self.i2c.writeto_mem(self.address, register, data)
def _block(self, x0, y0, x1, y1, data=None): """Read or write a block of data.""" self._write(self._COLUMN_SET, self._encode_pos(x0, x1)) self._write(self._PAGE_SET, self._encode_pos(y0, y1)) if data is None: size = ustruct.calcsize(self._DECODE_PIXEL) return self._read(self._RAM_READ, (x1 - x0 + 1) * (y1 - y0 + 1) * size) # noqa: E501 self._write(self._RAM_WRITE, data)
def test_ConstructorWithUserMeta(self): user_meta_fmt = "<II" os.remove(test_StructFile.TEST_FILE) sf = StructFile.StructFile(test_StructFile.TEST_FILE, test_StructFile.TEST_FMT, user_meta_fmt) self.assertEqual(sf.DataSize, ustruct.calcsize(test_StructFile.TEST_FMT)) file_exists = TestUtil.FileExists(test_StructFile.TEST_FILE) self.assertTrue(file_exists)
def read(cls, f): fmt = '<6sBBL' bits = f.read(calcsize(fmt)) self = cls() self.bits = bits self.magic, self.major, self.minor, self.crc = unpack(fmt, bits) return self
class HCI_SCO(object): """HCI_SCO""" struct_format = "<HB" struct_size = ustruct.calcsize(struct_format) def __init__(self, handle, ps=0, xx=0, data=b''): bin_str = "{:016b}{:02b}{:02b}{:012b}".format( len(data) if data else 0, xx, ps, handle) self._handle = handle self._ps = ps self._xx = xx self._tobytes = int(bin_str, 2) self._data = data def __getattr__(self, name): if name == "handle": return self._handle elif name == "ps": return self._ps elif name == "xx": return self._xx elif name == "tobytes": return self._tobytes elif name == "length": return len(self._data) if self._data else 0 elif name == "data": return self._data[:self.length] def __str__(self): desc_str = ("<{:s} " "handle=0x{:04x} ps=0x{:02x} xx=0x{:02x} " "length={:d} data={:s}>") return desc_str.format(self.__class__.__name__, self.handle, self.ps, self.xx, self.length, hexlify(self.data)) @staticmethod def from_buffer(data): """ Parse HCI SCO data References can be found here: * https://www.bluetooth.org/en-us/specification/adopted-specifications ** Core specification 4.1 ** [vol 2] Part E (Section 5) - HCI Data Formats ** [vol 2] Part E (Section 5.4) - Exchange of HCI-specific information """ hci_sco = uctypes.struct(uctypes.addressof(data[:HCI_SCO.struct_size]), HCI_SCO_STRUCT, uctypes.LITTLE_ENDIAN) data = data[HCI_SCO.struct_size:] return HCI_SCO(hci_sco.handle, hci_sco.ps, hci_sco.xx, data) def to_buffer(self): """ Get data string """ return ustruct.pack(self.struct_format, self.tobytes) + self.data
def _packetDecode(self, _id, _packet): _packet = _packet[8:] if _id in wm_codes: if len(self.active_codes) > 0 and _id not in self.active_codes: return None _format = wm_codes[_id][0] _sub_f = wm_codes[_id][1] if len(wm_codes[_id]) > 1 else False _len = struct.calcsize(_format) _data = struct.unpack(_format, _packet[:_len]) _remaining = _packet[_len:] if _sub_f: _sub_d = [] _sub_l = struct.calcsize(_sub_f) while len(_remaining) > 0: _d = struct.unpack(_sub_f, _remaining[:_sub_l]) _sub_d.append(_d) _remaining = _remaining[_sub_l:] _data = [_data, _sub_d] return _data
def parseNtpResponse(data): ubinascii.hexlify(data[40:44]) try: unpacked = ustruct.unpack(_PACKET_FORMAT, data[0:ustruct.calcsize(_PACKET_FORMAT)]) except ustruct.error: print("struct unpack error") ntp = unpacked[-2] ntp = ntp - 2208988800 utime.localtime(ntp)
def _registers(self, register, struct, value=None, scale=1): if value is None: size = ustruct.calcsize(struct) data = self.i2c.mem_read(size, self.address, register) value = ustruct.unpack(struct, data) if scale != 1: value = tuple(v * scale for v in value) return value if scale != 1: value = tuple(v / scale for v in value) data = ustruct.pack(struct, *value) self.i2c.mem_write(data, self.address, register)
class HCI_UART(object): """HCI_UART""" struct_format = "<B" struct_size = ustruct.calcsize(struct_format) def __init__(self, pkt_type, data=b''): self._pkt_type = pkt_type self._pkt_type_name = HCI_UART_PKT_TYPES[pkt_type] self._data = data def __getattr__(self, name): if name == "pkt_type": return self._pkt_type elif name == "pkt_type_name": return self._pkt_type_name elif name == "data": return self._data else: raise AttributeError(name) def __str__(self): return "<{:s} pkt_type={:s}(0x{:02x}) data={:s}>".format( self.__class__.__name__, self.pkt_type_name, self.pkt_type, hexlify(self.data)) @staticmethod def from_buffer(data): """ Parse a hci information from the specified data string There are four kinds of HCI packets that can be sent via the UART Transport Layer; i.e. HCI Command Packet, HCI Event Packet, HCI ACL Data Packet and HCI Synchronous Data Packet (see Host Controller Interface Functional Specification in Volume 2, Part E). HCI Command Packets can only be sent to the Bluetooth Host Controller, HCI Event Packets can only be sent from the Bluetooth Host Controller, and HCI ACL/Synchronous Data Packets can be sent both to and from the Bluetooth Host Controller. References can be found here: * https://www.bluetooth.org/en-us/specification/adopted-specifications ** Core specification 4.1 ** [vol 4] Part A (Section 2) Protocol """ pkt_type = ustruct.unpack(HCI_UART.struct_format, data[:HCI_UART.struct_size])[0] return HCI_UART(pkt_type, data[HCI_UART.struct_size:]) def to_buffer(self): """ Get data string """ return ustruct.pack(HCI_UART.struct_format, self.pkt_type) + self.data
def read(cls, f): # read only next one; ftell has to be on first byte already fmt = '<QQL' sz = calcsize(fmt) bits = f.read(sz) if not bits: return rv = cls(*unpack(fmt, bits)) rv.bits = bits return rv
def ilistdir_ex(path="."): dir = opendir_(path) if not dir: raise_error() res = [] dirent_fmt = "LLHB256s" while True: dirent = readdir_(dir) if not dirent: break dirent = ffi.as_bytearray(dirent, struct.calcsize(dirent_fmt)) dirent = struct.unpack(dirent_fmt, dirent) yield dirent
def __init__(self): self.is_secondary = False self.pin = None self.secret = None self.is_empty = None self.delay_achieved = 0 # so far, how much time wasted? self.delay_required = 0 # how much will be needed? self.num_fails = 0 # for UI: number of fails PINs self.attempt_target = 0 # counter number from chip self.state_flags = 0 # useful readback self.private_state = 0 # opaque data, but preserve assert MAX_PIN_LEN == 32 # update FMT otherwise assert ustruct.calcsize( PIN_ATTEMPT_FMT) == PIN_ATTEMPT_SIZE, ustruct.calcsize( PIN_ATTEMPT_FMT) self.buf = bytearray(PIN_ATTEMPT_SIZE) # check for bricked system early import callgate if callgate.get_is_bricked(): # die right away if it's not going to work callgate.enter_dfu(3)
class SMP(object): """SMP""" struct_format = "<B" struct_size = ustruct.calcsize(struct_format) def __init__(self, code, data=b''): self._code = code self._code_name = SMP_PDUS[code] self._data = data def __getattr__(self, name): if name == "code": return self._code elif name == "code_name": return self._code_name elif name == "length": return len(self._data) elif name == "data": return self._data def __str__(self): desc_str = ("<{:s} " "code={:s}(0x{:02x}) length={:d} data={:s}>") return desc_str.format(self.__class__.__name__, self.code_name, self.code, self.length, hexlify(self.data)) @staticmethod def from_buffer(data): """ SMP code is the first octet of the PDU 0 1 2 3 4 5 6 7 ----------------- | code | ----------------- References can be found here: * https://www.bluetooth.org/en-us/specification/adopted-specifications ** Core specification 4.1 ** [vol 3] Part H (Section 3.3) - Command Format """ code = ustruct.unpack(SMP.struct_format, data[:SMP.struct_size])[0] data = data[SMP.struct_size:] return SMP(code, data) def to_buffer(self): """ Get data string """ return ustruct.pack(self.struct_format, self.code) + self.data
def _registers(self, register, struct, value=None, scale=1): if value is None: size = ustruct.calcsize(struct) self._verbose("i2c.read", hex(register), "->") data = self.i2c.readfrom_mem(self.address, register, size) value = ustruct.unpack(struct, data) self._verbose(" ", data) if scale != 1: value = tuple(v * scale for v in value) return value if scale != 1: value = tuple(v / scale for v in value) data = ustruct.pack(struct, *value) self._verbose("i2c.write", hex(register), "<-", data) self.i2c.writeto_mem(self.address, register, data)
def get_ntp(self): addr_info = getaddrinfo(self.NTP_HOST, self.NTP_PORT) addr = addr_info[0][-1] s = socket(AF_INET, SOCK_DGRAM) s.sendto(self.NTP_QUERY, addr) msg, address = s.recvfrom(self.NTP_BUFFSIZE) s.close() unpacked = struct.unpack( self.NTP_PACKET_FORMAT, msg[0:struct.calcsize(self.NTP_PACKET_FORMAT)]) # this won't work right on nodemcu - not enough bits for int ot something like that #ts = unpacked[10] + float(unpacked[11]) / 2**32 - NTP_DELTA # this will be good enough ts = unpacked[10] - self.NTP_DELTA return ts
def ilistdir(path="."): dir = opendir_(path) if not dir: raise_error() res = [] dirent_fmt = "LLHB256s" while True: dirent = readdir_(dir) if not dirent: break import uctypes dirent = uctypes.bytes_at(dirent, struct.calcsize(dirent_fmt)) dirent = struct.unpack(dirent_fmt, dirent) dirent = (dirent[-1].split(b'\0', 1)[0], dirent[-2], dirent[0]) yield dirent
def ntp_sync(self, ntp_server): try: NTP_QUERY = bytearray(48) NTP_QUERY[0] = 0x1b addr = socket.getaddrinfo(ntp_server, 123)[0][-1] s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.settimeout(1) res = s.sendto(NTP_QUERY, addr) msg = s.recv(48) del(s) #s.close() unpacked = struct.unpack(NTP_PACKET_FORMAT, msg[0:struct.calcsize(NTP_PACKET_FORMAT)]) self.ntp_epoch = (unpacked[10] + float(unpacked[11]) / 2**32 - NTP_DELTA) self.ntp_sync_clk = time.time() self.synced_ = True except Exception as e: print("Something wrong with the ntp-server: " + str(e)) return
def bytes_to_nums(self, b): ret = [] i = 0 while i < len(b): try: t = ustruct.unpack('>s', b[i:i + 1]) # type t = t[0].decode('utf-8') fmt = '>' + t try: num = ustruct.unpack(fmt, b[i + 1:]) ret.append(num[0]) i = i + 1 + ustruct.calcsize(str(t)) except: i = i + 1 except: i = i + 1 return ret
def from_data(self, data): print('from_data(', data) # """Populate this instance from a NTP packet payload received from # the network. # Parameters: # data -- buffer payload # Raises: # NTPException -- in case of invalid packet format # """ try: csize = struct.calcsize(NTPPacket._PACKET_FORMAT) print('csize=', csize) print('len(data)=', len(data)) unpacked = struct.unpack(NTPPacket._PACKET_FORMAT, data[0:csize]) except Exception as e213: raise NTPException("220 Invalid NTP packet. " + str(e213)) self.leap = unpacked[0] >> 6 & 0x3 self.version = unpacked[0] >> 3 & 0x7 self.mode = unpacked[0] & 0x7 self.stratum = unpacked[1] self.poll = unpacked[2] self.precision = unpacked[3] self.root_delay = float(unpacked[4]) / 2**16 self.root_dispersion = float(unpacked[5]) / 2**16 self.ref_id = unpacked[6] self.ref_timestamp = _to_time(unpacked[7], unpacked[8]) self.orig_timestamp = _to_time(unpacked[9], unpacked[10]) self.orig_timestamp_high = unpacked[9] self.orig_timestamp_low = unpacked[10] self.recv_timestamp = _to_time(unpacked[11], unpacked[12]) self.tx_timestamp = _to_time(unpacked[13], unpacked[14]) self.tx_timestamp_high = unpacked[13] self.tx_timestamp_low = unpacked[14]
# test ustruct with a count specified before the type try: import ustruct as struct except: try: import struct except ImportError: print("SKIP") raise SystemExit print(struct.calcsize('0s')) print(struct.unpack('0s', b'')) print(struct.pack('0s', b'123')) print(struct.calcsize('2s')) print(struct.unpack('2s', b'12')) print(struct.pack('2s', b'123')) print(struct.calcsize('2H')) print(struct.unpack('<2H', b'1234')) print(struct.pack('<2H', 258, 515)) print(struct.calcsize('0s1s0H2H')) print(struct.unpack('<0s1s0H2H', b'01234')) print(struct.pack('<0s1s0H2H', b'abc', b'abc', 258, 515)) # check that unknown types raise an exception try: struct.unpack('z', b'1') except:
def _fcmd2b(self, fmt, a0, a1, a2, a3, a4=0): buf = self.buf[calcsize(fmt)] pack_into(fmt, buf, 0, 2, a0, a1, a2, a3, a4) self._send(buf)
def _fcmd2(self, fmt, a0, a1=0, a2=0): buf = self.buf[calcsize(fmt)] pack_into(fmt, buf, 0, 2, a0, a1, a2) self._send(buf)
class ATT(object): """ATT""" struct_format = "<B" struct_size = ustruct.calcsize(struct_format) def __init__(self, opcode, data=b''): self._opcode = opcode self._opcode_name = ATT_PDUS[opcode] self._data = data def __getattr__(self, name): if name == "opcode": return self._opcode elif name == "opcode_name": return self._opcode_name elif name == "length": return len(self._data) elif name == "data": return self._data def __str__(self): desc_str = ("<{:s} " "opcode={:s}(0x{:02x}) length={:d} data={:s}>") return desc_str.format(self.__class__.__name__, self.opcode_name, self.opcode, self.length, hexlify(self.data)) @staticmethod def from_buffer(data): """ Attribute opcode is the first octet of the PDU 0 1 2 3 4 5 6 7 ----------------- | att opcode | ----------------- | a |b|c| ----------------- a - method b - command flag c - authentication signature flag References can be found here: * https://www.bluetooth.org/en-us/specification/adopted-specifications ** Core specification 4.1 ** [vol 3] Part F (Section 3.3) - Attribute PDU """ opcode = ustruct.unpack(ATT.struct_format, data[:ATT.struct_size])[0] # att = uctypes.struct( # uctypes.addressof(data[:ATT.struct_size]), # ATT_STRUCT, # uctypes.LITTLE_ENDIAN # ) data = data[ATT.struct_size:] return ATT(opcode, data) def to_buffer(self): """ Get data string """ return ustruct.pack(self.struct_format, self.opcode) + self._data
# check cases converting float to int, relying only on single precision float try: import ustruct as struct except: import struct # work out configuration values is_64bit = struct.calcsize("P") == 8 # 0 = none, 1 = long long, 2 = mpz try: dummy = 0x7fffffffffffffff try: if (0xffffffffffffffff + 1) > 0: ll_type = 2 else: ll_type = 1 except: # in case the sum in the if statement above changes to raising an exception on overflow ll_type = 1 except: ll_type = 0 # basic conversion print(int(14187745.)) print("%d" % 14187745.) if ll_type == 2: print(int(2.**100)) print("%d" % 2.**100) testpass = True
def test_Constructor(self): self.assertEqual(self.Sf.DataSize, ustruct.calcsize(test_StructFile.TEST_FMT)) file_exists = TestUtil.FileExists(test_StructFile.TEST_FILE) self.assertTrue(file_exists)
# test ustruct with a count specified before the type try: import ustruct as struct except: try: import struct except ImportError: import sys print("SKIP") sys.exit() print(struct.calcsize('0s')) print(struct.unpack('0s', b'')) print(struct.pack('0s', b'123')) print(struct.calcsize('2s')) print(struct.unpack('2s', b'12')) print(struct.pack('2s', b'123')) print(struct.calcsize('2H')) print(struct.unpack('<2H', b'1234')) print(struct.pack('<2H', 258, 515)) print(struct.calcsize('0s1s0H2H')) print(struct.unpack('<0s1s0H2H', b'01234')) print(struct.pack('<0s1s0H2H', b'abc', b'abc', 258, 515)) # check that unknown types raise an exception try: struct.unpack('z', b'1')
def payload_size(cls): return ustruct.calcsize(cls.fmt) # Size of subclass packed data
EPOLLONESHOT = 1 << 30 EPOLLET = 1 << 31 EPOLL_CTL_ADD = 1 EPOLL_CTL_DEL = 2 EPOLL_CTL_MOD = 3 # TODO: struct epoll_event's 2nd member is union of uint64_t, etc. # On x86, uint64_t is 4-byte aligned, on many other platforms - 8-byte. # Until uctypes module can assign native struct offset, use dirty hack # below. # TODO: Get rid of all this dirtiness, move it on C side if _libc.bitness > 32: # On x86_64, epoll_event is packed struct epoll_event = "<IO" elif struct.calcsize("IQ") == 12: epoll_event = "IO" else: epoll_event = "QO" class Epoll: def __init__(self, epfd): self.epfd = epfd self.evbuf = struct.pack(epoll_event, 0, None) self.registry = {} def register(self, fd, eventmask=EPOLLIN|EPOLLPRI|EPOLLOUT, retval=None): "retval is extension to stdlib, value to use in results from .poll()." if retval is None: retval = fd
try: import ustruct as struct except: try: import struct except ImportError: import sys print("SKIP") sys.exit() print(struct.calcsize("<bI")) print(struct.unpack("<bI", b"\x80\0\0\x01\0")) print(struct.calcsize(">bI")) print(struct.unpack(">bI", b"\x80\0\0\x01\0")) # 32-bit little-endian specific #print(struct.unpack("bI", b"\x80\xaa\x55\xaa\0\0\x01\0")) print(struct.pack("<l", 1)) print(struct.pack(">l", 1)) print(struct.pack("<i", 1)) print(struct.pack(">i", 1)) print(struct.pack("<h", 1)) print(struct.pack(">h", 1)) print(struct.pack("<b", 1)) print(struct.pack(">b", 1)) print(struct.pack("<bI", -128, 256)) print(struct.pack(">bI", -128, 256)) print(struct.calcsize("100sI"))