def publish(self, topic, msg, retain=False, qos=0): pkt = bytearray(b"\x30\0\0\0") pkt[0] |= qos << 1 | retain sz = 2 + len(topic) + len(msg) if qos > 0: sz += 2 assert sz < 2097152 i = 1 while sz > 0x7f: pkt[i] = (sz & 0x7f) | 0x80 sz >>= 7 i += 1 pkt[i] = sz #print(hex(len(pkt)), hexlify(pkt, ":")) self.sock.write(pkt, i + 1) self._send_str(topic) if qos > 0: self.pid += 1 pid = self.pid struct.pack_into("!H", pkt, 0, pid) self.sock.write(pkt, 2) self.sock.write(msg) if qos == 1: while 1: op = self.wait_msg() if op == 0x40: sz = self.sock.read(1) assert sz == b"\x02" rcv_pid = self.sock.read(2) rcv_pid = rcv_pid[0] << 8 | rcv_pid[1] if pid == rcv_pid: return elif qos == 2: assert 0
def _register_short(self, register, value=None, buf=bytearray(2)): if value is None: self.i2c.readfrom_mem_into(self.address, register, buf) return ustruct.unpack("<h", buf)[0] ustruct.pack_into("<h", buf, 0, value) return self.i2c.writeto_mem(self.address, register, buf)
def wait_msg(self): res = self.sock.read(1) self.sock.setblocking(True) if res is None: return None if res == b"": raise OSError(-1) if res == b"\xd0": # PINGRESP sz = self.sock.read(1)[0] assert sz == 0 return None op = res[0] if op & 0xf0 != 0x30: return op sz = self._recv_len() topic_len = self.sock.read(2) topic_len = (topic_len[0] << 8) | topic_len[1] topic = self.sock.read(topic_len) sz -= topic_len + 2 if op & 6: pid = self.sock.read(2) pid = pid[0] << 8 | pid[1] sz -= 2 msg = self.sock.read(sz) self.cb(topic, msg) if op & 6 == 2: pkt = bytearray(b"\x40\x02\0\0") struct.pack_into("!H", pkt, 2, pid) self.sock.write(pkt) elif op & 6 == 4: assert 0
def publish(self, topic, msg, retain=False, qos=0): pkt = bytearray(b"\x30\0\0") pkt[0] |= qos << 1 | retain sz = 2 + len(topic) + len(msg) if qos > 0: sz += 2 assert sz <= 16383 pkt[1] = (sz & 0x7f) | 0x80 pkt[2] = sz >> 7 #print(hex(len(pkt)), hexlify(pkt, ":")) self.sock.send(pkt) self._send_str(topic) if qos > 0: self.pid += 1 pid = self.pid buf = bytearray(b"\0\0") struct.pack_into("!H", buf, 0, pid) self.sock.send(buf) self.sock.send(msg) if qos == 1: while 1: op = self.wait_msg() if op == 0x40: sz = self.sock.recv(1) assert sz == b"\x02" rcv_pid = self.sock.recv(2) rcv_pid = rcv_pid[0] << 8 | rcv_pid[1] if pid == rcv_pid: return elif qos == 2: assert 0
def _register_char(self, register, value=None, buf=bytearray(1)): if value is None: self.i2c.readfrom_mem_into(self.address, register, buf) return buf[0] ustruct.pack_into("<b", buf, 0, value) return self.i2c.writeto_mem(self.address, register, buf)
def subscribe(self, topic): print("subscribe") pkt = bytearray(b"\x82\0\0\0") self.pid += 1 # B=1 byte; H = 2 bytes,!=network or big endian and offset is 1 struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic) + 1, self.pid) self.sock.send(pkt) self.send_str(topic.encode('utf-8')) self.sock.send(b"\0") resp = self.sock.recv(5) print(resp) assert resp[0] == 0x90 assert resp[2] == pkt[2] and resp[3] == pkt[3] assert resp[4] == 0
def subscribe(self, topic, qos=0): assert self.cb is not None, "Subscribe callback is not set" pkt = bytearray(b"\x82\0\0\0") self.pid += 1 struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic) + 1, self.pid) #print(hex(len(pkt)), hexlify(pkt, ":")) self.sock.send(pkt) self._send_str(topic) self.sock.send(qos.to_bytes(1)) resp = self.sock.recv(5) #print(resp) assert resp[0] == 0x90 assert resp[2] == pkt[2] and resp[3] == pkt[3] if resp[4] == 0x80: raise MQTTException(resp[4])
def subscribe(self,topic,qos=0): assert self.cb is not None,"Subscribe callback is not set" pkt=bytearray(b"\x82\0\0\0") self.pid+=1 struct.pack_into("!BH",pkt,1,2+2+len(topic)+1,self.pid) self.sock.write(pkt) self._send_str(topic) self.sock.write(qos.to_bytes(1,"little")) while 1: op=self.wait_msg() if op==0x90: resp=self.sock.read(4) assert resp[1]==pkt[2]and resp[2]==pkt[3] if resp[3]==0x80: raise MQTTException(resp[3]) return
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)
def _register_char(self,register,value=None,buf=bytearray(1)): if value is None: self.i2c.readfrom_mem_into(self.address,register,buf) return buf[0] ustruct.pack_into("<b",buf,0,value) return self.i2c.writeto_mem(self.address,register,buf)
def set_spi_win(self, x, y, w, h): pack_into('<BBBHHHHHHHH', self.buf19, 0, 2, 0x55, 10, x, y, x + w - 1, y + h - 1, 0, 0, 0, 0xffff) self._send(self.buf19)
def marshal(self, msg, is_duress=False, is_brickme=False, new_secret=None, new_pin=None, old_pin=None, get_duress_secret=False, is_secondary=False, ls_offset=None): # serialize our state, and maybe some arguments change_flags = 0 if new_secret is not None: change_flags |= CHANGE_SECRET if not is_duress else CHANGE_DURESS_SECRET assert len(new_secret) in (32, AE_SECRET_LEN) else: new_secret = bytes(AE_SECRET_LEN) # NOTE: pins should be bytes here. if get_duress_secret: # special case for reading duress secret from main wallet change_flags |= CHANGE_DURESS_SECRET if new_pin is not None: if is_duress: change_flags |= CHANGE_DURESS_PIN elif is_brickme: change_flags |= CHANGE_BRICKME_PIN elif is_secondary: change_flags |= CHANGE_SECONDARY_WALLET_PIN else: change_flags |= CHANGE_WALLET_PIN assert not old_pin or old_pin == self.pin old_pin = self.pin assert len(new_pin) <= MAX_PIN_LEN assert old_pin != None assert len(old_pin) <= MAX_PIN_LEN else: new_pin = b'' old_pin = old_pin if old_pin is not None else self.pin if ls_offset is not None: change_flags |= (ls_offset << 8) # see CHANGE_LS_OFFSET # can't send the V2 extra stuff if the bootrom isn't expecting it fields = [ self.magic_value, (1 if self.is_secondary else 0), self.pin, len(self.pin), self.delay_achieved, self.delay_required, self.num_fails, self.attempts_left, self.state_flags, self.private_state, self.hmac, change_flags, old_pin, len(old_pin), new_pin, len(new_pin), new_secret ] if version.has_608: fmt = PIN_ATTEMPT_FMT_V1 + PIN_ATTEMPT_FMT_V2_ADDITIONS fields.append(self.cached_main_pin) else: fmt = PIN_ATTEMPT_FMT_V1 ustruct.pack_into(fmt, msg, 0, *fields)
import usocket as socket
def eink_fill_circle(x, y, r): bcmd = bytearray(_cmd_fill_circle) pack_into('!hhh',bcmd,4,x,y,r) send(addparity(bcmd))
async def wait_msg(self): res = self._sock.read(1) # Throws OSError on WiFi fail if res is None: return if res == b'': raise OSError(-1) if res == b"\xd0": # PINGRESP await self._as_read(1) # Update .last_rx time return op = res[0] if op == 0x40: # PUBACK: save pid sz = await self._as_read(1) if sz != b"\x02": raise OSError(-1) rcv_pid = await self._as_read(2) pid = rcv_pid[0] << 8 | rcv_pid[1] if pid in self.rcv_pids: self.rcv_pids.discard(pid) else: raise OSError(-1) if op == 0x90: # SUBACK resp = await self._as_read(4) if resp[3] == 0x80: raise OSError(-1) pid = resp[2] | (resp[1] << 8) if pid in self.rcv_pids: self.rcv_pids.discard(pid) else: raise OSError(-1) if op == 0xB0: # UNSUBACK resp = await self._as_read(3) pid = resp[2] | (resp[1] << 8) if pid in self.rcv_pids: self.rcv_pids.discard(pid) else: raise OSError(-1) if op & 0xf0 != 0x30: return sz = await self._recv_len() topic_len = await self._as_read(2) topic_len = (topic_len[0] << 8) | topic_len[1] topic = await self._as_read(topic_len) sz -= topic_len + 2 if op & 6: pid = await self._as_read(2) pid = pid[0] << 8 | pid[1] sz -= 2 msg = await self._as_read(sz) retained = op & 0x01 self._cb(topic, msg, bool(retained)) if op & 6 == 2: # qos 1 pkt = bytearray(b"\x40\x02\0\0") # Send PUBACK struct.pack_into("!H", pkt, 2, pid) await self._as_write(pkt) elif op & 6 == 4: # qos 2 not supported raise OSError(-1)
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 set_spi_win(self, x, y, w, h): pack_into("<BBBHHHHHHHH", self.buf19, 0, 2, 0x55, 10, x, y, x + w - 1, y + h - 1, 0, 0, 0, 0xFFFF) self._send(self.buf19)
def write4(self, dev, mem, word): ustruct.pack_into(">i", self._buf4, 0, word) self._i2c.writeto_mem(dev, mem, self._buf4)
def write2(self, dev, mem, word): ustruct.pack_into(">H", self._buf2, 0, word) self._i2c.writeto_mem(dev, mem, self._buf2)
print('TypeError') # make sure that unknown types are detected try: struct.pack("z", 1) except: print("Unknown type") # Initially repitition counters were supported only for strings, # but later were implemented for all. print(struct.unpack("<3B2h", b"foo\x12\x34\xff\xff")) print(struct.pack("<3B", 1, 2, 3)) # pack_into buf = bytearray(b'>>>123<<<') struct.pack_into('<bbb', buf, 3, 0x41, 0x42, 0x43) print(buf) struct.pack_into('<bbb', buf, -6, 0x44, 0x45, 0x46) print(buf) # check that we get an error if the buffer is too small try: struct.pack_into('I', bytearray(1), 0, 0) except: print('struct.error') try: struct.pack_into('<bbb', buf, 7, 0x41, 0x42, 0x43) except: print('struct.error') try:
except SystemExit: raise except: pass try: struct.pack('1') print("FAIL") raise SystemExit except SystemExit: raise except: pass try: struct.pack_into('1', bytearray(4), 0, 'xx') print("FAIL") raise SystemExit except SystemExit: raise except: pass try: struct.unpack('1', 'xx') print("FAIL") raise SystemExit except SystemExit: raise except: pass
try:
def eink_fill_rect(x0, y0, x1, y1): bcmd = bytearray(_cmd_fill_rect) pack_into('!hhhh',bcmd,4,x0,y0,x1,y1) send(addparity(bcmd))
async def check_for_message(self): res = await self.read(1) if res == b'': return None res = res[0] if res == MQTT_PINGRESP: ping_resp = await self.read(1) if ping_resp[0] != 0x00: raise OSError("PINGRESP not returned from broker.") else: if self.debug: print(app, ": PINGRESP RECEIVED.") return res elif res == MQTT_PUBACK: if self.debug: print(app, ": Received: MQTT_PUBACK") sz = await self.read(1) if sz != b"\x02": raise OSError(-1) rcv_pid = await self.read(2) pid = rcv_pid[0] << 8 | rcv_pid[1] if pid == self.pid: if pid in self.unack_pid: self.unack_pid.remove(pid) return pid else: raise OSError(-1) elif res == MQTT_SUBACK: if self.debug: print(app, ": Received: MQTT_SUBACK") resp = await self.read(4) if resp[3] == MQTT_FAILURE: raise OSError(-1) pid = resp[2] | (resp[1] << 8) if pid == self.pid: if pid in self.unack_pid: self.unack_pid.remove(pid) return pid else: raise OSError(-1) elif res == MQTT_UNSUBACK: if self.debug: print(app, ": Received: MQTT_UNSUBACK") resp = await self.read(1) if resp[0] != 0x02: raise OSError(-1) rcv_pid = await self.read(2) pid = rcv_pid[0] << 8 | rcv_pid[1] if pid == self.pid: if pid in self.unack_pid: self.unack_pid.remove(pid) return pid else: raise OSError(-1) elif res & 0xF0 != 0x30: return res elif res == MQTT_PUB: if self.debug: print(app, ": Received: MQTT_PUB") sz = await self.recv_len() topic_len = await self.read(2) topic_len = (topic_len[0] << 8) | topic_len[1] topic = await self.read(topic_len) topic = str(topic, "utf-8") sz -= topic_len + 2 if res & 0x06: pid = await self.read(2) pid = pid[0] << 0x08 | pid[1] sz -= 0x02 msg = await self.read(sz) if self.on_message_cb is not None: self.on_message_cb(topic, str(msg, "utf-8")) if res & 0x06 == MQTT_SUCCES_QOS2: # Requesting PUBACK pkt = MQTT_PUBACK_MES struct.pack_into("!H", pkt, 2, pid) async with self.lock: await self.send(pkt) elif res & 6 == 4: raise OSError(-1) else: raise OSError(-1)
def eink_fill_triangle(x0, y0, x1, y1, x2, y2): bcmd = bytearray(_cmd_fill_triangle) pack_into('!hhhhhh',bcmd,4,x0,y0,x1,y1,x2,y2) send(addparity(bcmd))
def eink_set_baud(baud): bcmd = bytearray(_cmd_set_baud) pack_into('!i',bcmd,4,baud) send(addparity(bcmd))
print('TypeError') # make sure that unknown types are detected try: struct.pack("z", 1) except: print("Unknown type") # Initially repitition counters were supported only for strings, # but later were implemented for all. print(struct.unpack("<3B2h", b"foo\x12\x34\xff\xff")) print(struct.pack("<3B", 1, 2, 3)) # pack_into buf = bytearray(b'>>>123<<<') struct.pack_into('<bbb', buf, 3, 0x41, 0x42, 0x43) print(buf) struct.pack_into('<bbb', buf, -6, 0x44, 0x45, 0x46) print(buf) try: struct.pack_into('<bbb', buf, 7, 0x41, 0x42, 0x43) except: print('struct.error') try: struct.pack_into('<bbb', buf, -10, 0x41, 0x42, 0x43) except: print('struct.error') # unpack_from buf = b'0123456789'
def eink_screen_rotation(mode): bcmd = bytearray(_cmd_set_memory) pack_into('!B',bcmd,4,mode) send(addparity(bcmd))
async def wait_msg(self): try: res = await self._as_read(1) except Exception as e: # log.debug("wait_msg: {}".format(e)) # self.status = 0 return None if res is None: return None if res == b'': return None if res == b"\xd0": # PINGRESP await self._as_read(1) # Update .last_rx time return None # try: # res = await self._as_read(1) # except OSError as e: # log.debug("wait_msg: {}".format(e)) # # self.status = 0 # return None # # log.debug("wait_msg res: {}".format(res)) # # if res == b"": # return None # # if res is None and self.first_con == 0: # self.status = 0 # return None # # if res is None and self.first_con == 1: # self.first_con = 0 # return None op = res[0] if op & 0xf0 != 0x30: return op sz = await self._recv_len() topic_len = await self._as_read(2) if topic_len: topic_len = (topic_len[0] << 8) | topic_len[1] topic = await self._as_read(topic_len) sz -= topic_len + 2 pid = self.pid if op & 6: pid = await self._as_read(2) if not pid: return None pid = pid[0] << 8 | pid[1] sz -= 2 # msg = self._try_alloc_byte_array(sz) msg = await self._as_read(sz) if msg: # msg = self.sock.read(sz) # self.sock.readinto(msg) # self.sock.settimeout(self.timeout) # self.sock.setblocking(False) if self.cb: # self.cb(topic, bytes(msg)) self.cb(topic, msg) if op & 6 == 2: pkt = bytearray(b"\x40\x02\0\0") struct.pack_into("!H", pkt, 2, pid) await self.as_write(pkt) elif op & 6 == 4: return None return None
def pack(self, offset, size, format_string, *values): self.ensure(offset + size) _struct.pack_into(format_string, self._octets, offset, *values) return offset + size
def serialize_message_footer(data, checksum): if len(data) < _MSG_FOOTER_LEN: raise ValueError('Invalid buffer size') ustruct.pack_into(_MSG_FOOTER, data, 0, checksum)
def serialize_message_header(data, msg_type, msg_len): if len(data) < _REP_HEADER_LEN + _MSG_HEADER_LEN: raise ValueError('Invalid buffer size') ustruct.pack_into(_MSG_HEADER, data, _REP_HEADER_LEN, msg_type, msg_len)
def _register_short(self,register,value=None,buf=bytearray(2)): if value is None: self.i2c.readfrom_mem_into(self.address,register,buf) return ustruct.unpack("<h",buf)[0] ustruct.pack_into("<h",buf,0,value) return self.i2c.writeto_mem(self.address,register,buf)
def eink_draw_pixel(x, y): bcmd = bytearray(_cmd_draw_pixel) pack_into('!hh',bcmd,4,x,y) send(addparity(bcmd))
def set_scroll_win(self, win, x=-1, y=0, w=0, h=0, vec=0, pat=0, fill=0x07e0, color=0): pack_into('<BBBHHHHHHHH', self.buf19, 0, 2, 0x55, win, x, y, w, h, vec, pat, fill, color) self._send(self.buf19)
def eink_draw_line(x0, y0, x1, y1): bcmd = bytearray(_cmd_draw_line) pack_into('!hhhh',bcmd,4,x0,y0,x1,y1) send(addparity(bcmd))
def set_scroll_win(self, win, x=-1, y=0, w=0, h=0, vec=0, pat=0, fill=0x07E0, color=0): pack_into("<BBBHHHHHHHH", self.buf19, 0, 2, 0x55, win, x, y, w, h, vec, pat, fill, color) self._send(self.buf19)
def eink_set_color(colour, bkcolour): bcmd = bytearray(_cmd_set_colour) pack_into('!BB',bcmd,4,colour,bkcolour) send(addparity(bcmd))
def eink_set_ch_font(font): bcmd = bytearray(_cmd_set_ch_font) pack_into('!B',bcmd,4,font) send(addparity(bcmd))