diff --git a/fwupd.py b/fwupd.py new file mode 100644 index 0000000..64ea53d --- /dev/null +++ b/fwupd.py @@ -0,0 +1,74 @@ +#!python2-32 +from sys import argv, exit +from os.path import getsize +from py9b.link.base import LinkOpenException, LinkTimeoutException +from py9b.link.tcp import TCPLink +from py9b.link.ble import BLELink +from py9b.link.serial import SerialLink +from py9b.transport.base import BaseTransport as BT +from py9b.transport.xiaomi import XiaomiTransport +from py9b.command.regio import ReadRegs, WriteRegs +from py9b.command.update import * + +def checksum(s, data): + for c in data: + s += ord(c) + return (s & 0xFFFFFFFF) + + +fw_dev = BT.BMS +fw_name = "bms.bin" +fw_size = getsize(fw_name) +fw_page_size = 0x80 + +link = SerialLink(timeout=0.5) +#link = TCPLink() +#link = BLELink() + +with link: + print "Scanning..." + ports = link.scan() + print ports + + tran = XiaomiTransport(link) + + #link.open(("192.168.1.45", 6000)) + link.open(ports[0][1]) + print "Connected" + + print "Pinging..." + for retry in xrange(20): + print ".", + try: + tran.execute(ReadRegs(BT.BMS, 0x10, "14s")) + except LinkTimeoutException: + continue + break + else: + exit("Timed out !") + print "" + + hfi = open(fw_name, "rb") + + print "Starting..." + tran.execute(StartUpdate(fw_dev, fw_size)) + + print "Writing..." + page = 0 + chk = 0 + while fw_size: + print "{0:X}".format(page*0x80) + chunk_sz = min(fw_size, fw_page_size) + data = hfi.read(chunk_sz) + chk = checksum(chk, data) + tran.execute(WriteUpdate(fw_dev, page, data)) + page += 1 + fw_size -= chunk_sz + hfi.close() + + print "Finalizing..." + tran.execute(FinishUpdate(fw_dev, chk ^ 0xFFFFFFFF)) + + print "Reboot" + tran.execute(RebootUpdate(fw_dev)) + diff --git a/py9b/command/__init__.py b/py9b/command/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/py9b/command/base.py b/py9b/command/base.py new file mode 100644 index 0000000..3f4b71d --- /dev/null +++ b/py9b/command/base.py @@ -0,0 +1,19 @@ +from ..transport.packet import BasePacket as PKT +from ..transport.base import BaseTransport as BT + + +class InvalidResponse(Exception): + pass + + +class BaseCommand(object): + def __init__(self, src=BT.HOST, dst=0, cmd=0, arg=0, data="", has_response=True): + self.has_response = has_response + self.request = PKT(src, dst, cmd, arg, data) + + + def handle_response(self, response): + return True + + +__all__ = ["BaseCommand", "InvalidResponse"] diff --git a/py9b/command/custom.py b/py9b/command/custom.py new file mode 100644 index 0000000..322acb3 --- /dev/null +++ b/py9b/command/custom.py @@ -0,0 +1,17 @@ +from struct import pack, unpack, calcsize +from .base import BaseCommand, InvalidResponse + + +class ReadMem(BaseCommand): + def __init__(self, dev, addr, format): + super(ReadMem, self).__init__(dst=dev, cmd=0x80, arg=calcsize(format), data=pack("%02X: %02X @%02X %s" % (self.src, self.dst, self.cmd, self.reg, hexlify(self.data).upper()) + return "%02X->%02X: %02X @%02X %s" % (self.src, self.dst, self.cmd, self.arg, hexlify(self.data).upper()) __all__ = ["BasePacket"] diff --git a/py9b/transport/xiaomi.py b/py9b/transport/xiaomi.py index 1896929..c9f9e68 100644 --- a/py9b/transport/xiaomi.py +++ b/py9b/transport/xiaomi.py @@ -83,7 +83,7 @@ class XiaomiTransport(BT): def send(self, packet): dev = self._make_addr(packet.src, packet.dst) - pkt = pack(">1, "16s"))[0] + except LinkTimeoutException: + continue + break + else: + print "No response !" + break + hfo.write(data) + + hfo.close() + link.close() diff --git a/read_bms_ll.py b/read_bms_ll.py new file mode 100644 index 0000000..1ac6c86 --- /dev/null +++ b/read_bms_ll.py @@ -0,0 +1,46 @@ +#!python2-32 +from py9b.link.base import LinkOpenException, LinkTimeoutException +from py9b.link.tcp import TCPLink +from py9b.link.ble import BLELink +from py9b.link.serial import SerialLink +from py9b.transport.base import BaseTransport as BT +from py9b.transport.packet import BasePacket as PKT +from py9b.transport.xiaomi import XiaomiTransport + +READ_CHUNK_SIZE = 0x10 + +link = SerialLink(dump=True) +#link = TCPLink() +#link = BLELink() + +with link: + print "Scanning..." + ports = link.scan() + print ports + + tran = XiaomiTransport(link) + + #link.open(("192.168.1.45", 6000)) + link.open(ports[0][1]) + print "Connected" + + req = PKT(src=BT.HOST, dst=BT.BMS, cmd=0x01, arg=0, data=chr(READ_CHUNK_SIZE)) + + hfo = open("BmsRegs.bin", "wb") + for i in xrange(0x0, 0x100, READ_CHUNK_SIZE): + print ".", + req.arg = i>>1 + for retry in xrange(5): + tran.send(req) + try: + rsp = tran.recv() + except LinkTimeoutException: + continue + break + else: + print "No response !" + break + hfo.write(rsp.data) + + hfo.close() + link.close() diff --git a/read_bms_mem.py b/read_bms_mem.py new file mode 100644 index 0000000..c6b08b3 --- /dev/null +++ b/read_bms_mem.py @@ -0,0 +1,45 @@ +#!python2-32 +from py9b.link.base import LinkOpenException, LinkTimeoutException +from py9b.link.tcp import TCPLink +from py9b.link.ble import BLELink +from py9b.link.serial import SerialLink +from py9b.transport.base import BaseTransport as BT +from py9b.transport.packet import BasePacket as PKT +from py9b.transport.xiaomi import XiaomiTransport +from py9b.command.custom import ReadMem + +ADDR = 0x1000 +SIZE = 0x800 +READ_CHUNK_SIZE = 0x10 + +link = SerialLink(dump=True) +#link = TCPLink() +#link = BLELink() + +with link: + print "Scanning..." + ports = link.scan() + print ports + + tran = XiaomiTransport(link) + + #link.open(("192.168.1.45", 6000)) + link.open(ports[0][1]) + print "Connected" + + hfo = open("BmsEep.bin", "wb") + for i in xrange(ADDR, ADDR+SIZE, READ_CHUNK_SIZE): + print ".", + for retry in xrange(5): + try: + data = tran.execute(ReadMem(BT.BMS, i, "16s"))[0] + except LinkTimeoutException: + continue + break + else: + print "No response !" + break + hfo.write(data) + + hfo.close() + link.close() diff --git a/read_esc.py b/read_esc.py index 2c0f96a..5000004 100644 --- a/read_esc.py +++ b/read_esc.py @@ -1,3 +1,4 @@ +#!python2-32 from py9b.link.base import LinkOpenException, LinkTimeoutException from py9b.link.tcp import TCPLink from py9b.link.ble import BLELink @@ -22,12 +23,12 @@ with link: link.open(ports[0][1]) print "Connected" - req = PKT(src=BT.HOST, dst=BT.ESC, cmd=0x01, reg=0, data=chr(READ_CHUNK_SIZE)) + req = PKT(src=BT.HOST, dst=BT.ESC, cmd=0x01, arg=0, data=chr(READ_CHUNK_SIZE)) hfo = open("EscRegs.bin", "wb") for i in xrange(0, 0x200, READ_CHUNK_SIZE): print ".", - req.reg = i>>1 + req.arg = i>>1 for retry in xrange(3): tran.send(req) try: diff --git a/tcp_test.py b/tcp_test.py index c9c6de9..9151678 100644 --- a/tcp_test.py +++ b/tcp_test.py @@ -14,8 +14,8 @@ with TCPLink() as link: #link.open(("192.168.1.45", 6000)) link.open(ports[0][1]) - #req = PKT(src=BT.HOST, dst=BT.ESC, cmd=0x01, reg=0x10, data="\x10") - req = PKT(src=BT.HOST, dst=BT.BMS, cmd=0x01, reg=0x10, data="\x10") + #req = PKT(src=BT.HOST, dst=BT.ESC, cmd=0x01, arg=0x10, data="\x10") + req = PKT(src=BT.HOST, dst=BT.BMS, cmd=0x01, arg=0x10, data="\x10") while raw_input("Press ENTER to send...")!="q": tran.send(req) diff --git a/wr_esc.py b/wr_esc.py new file mode 100644 index 0000000..6348504 --- /dev/null +++ b/wr_esc.py @@ -0,0 +1,31 @@ +from py9b.link.base import LinkOpenException, LinkTimeoutException +from py9b.link.tcp import TCPLink +from py9b.link.ble import BLELink +from py9b.transport.base import BaseTransport as BT +from py9b.transport.packet import BasePacket as PKT +from py9b.transport.xiaomi import XiaomiTransport + +#link = SerialLink() +#link = TCPLink() +link = BLELink() + +with link: + print "Scanning..." + ports = link.scan() + print ports + + tran = XiaomiTransport(link) + + #link.open(("192.168.1.45", 6000)) + link.open(ports[0][1]) + print "Connected" + + req = PKT(src=BT.HOST, dst=BT.ESC, cmd=0x02, arg=0x41, data="\xCE\xAB\x00\x00") + + tran.send(req) + try: + rsp = tran.recv() + finally: + link.close() + + print rsp