cleanups for py3 migration
parent
c6168dd727
commit
20417bfd6b
133
py9b/link/ble.py
133
py9b/link/ble.py
|
@ -9,23 +9,23 @@ SCAN_TIMEOUT = 3
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import queue
|
import queue
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import Queue as queue
|
import Queue as queue
|
||||||
|
|
||||||
class Fifo():
|
class Fifo():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.q = queue.Queue()
|
self.q = queue.Queue()
|
||||||
|
|
||||||
def write(self, data): # put bytes
|
def write(self, data): # put bytes
|
||||||
for b in data:
|
for b in data:
|
||||||
self.q.put(b)
|
self.q.put(b)
|
||||||
|
|
||||||
def read(self, size=1, timeout=None): # but read string
|
def read(self, size=1, timeout=None): # but read string
|
||||||
res = ''
|
res = ''
|
||||||
for i in xrange(size):
|
for i in xrange(size):
|
||||||
res += chr(self.q.get(True, timeout))
|
res += chr(self.q.get(True, timeout))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
#_cccd_uuid = '00002902-0000-1000-8000-00805f9b34fb'
|
#_cccd_uuid = '00002902-0000-1000-8000-00805f9b34fb'
|
||||||
|
@ -35,76 +35,77 @@ _tx_char_uuid = '6e400003-b5a3-f393-e0a9-e50e24dcca9e'
|
||||||
_write_chunk_size = 20 # as in android dumps
|
_write_chunk_size = 20 # as in android dumps
|
||||||
|
|
||||||
class BLELink(BaseLink):
|
class BLELink(BaseLink):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(BLELink, self).__init__(*args, **kwargs)
|
super(BLELink, self).__init__(*args, **kwargs)
|
||||||
self._adapter = None
|
self._adapter = None
|
||||||
self._dev = None
|
self._dev = None
|
||||||
self._wr_handle = None
|
self._wr_handle = None
|
||||||
self._rx_fifo = Fifo()
|
self._rx_fifo = Fifo()
|
||||||
|
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
self._adapter = pygatt.GATTToolBackend()
|
self._adapter = pygatt.GATTToolBackend()
|
||||||
self._adapter.start()
|
self._adapter.start()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, traceback):
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
|
|
||||||
def _make_rx_cb(self): # this is a closure :)
|
def _make_rx_cb(self): # this is a closure :)
|
||||||
def rx_cb(handle, value):
|
def rx_cb(handle, value):
|
||||||
self._rx_fifo.write(value)
|
self._rx_fifo.write(value)
|
||||||
return rx_cb
|
return rx_cb
|
||||||
|
|
||||||
|
|
||||||
def scan(self):
|
def scan(self):
|
||||||
res = []
|
res = []
|
||||||
devices = self._adapter.scan(timeout=SCAN_TIMEOUT)
|
self._adapter.reset()
|
||||||
for dev in devices:
|
devices = self._adapter.scan(timeout=SCAN_TIMEOUT)
|
||||||
if dev['name'] and dev['name'].startswith((u'MISc', u'NBSc', u'JP2', u'Seg')):
|
for dev in devices:
|
||||||
res.append((dev['name'], dev['address']))
|
if dev['name'] and dev['name'].startswith((u'MISc', u'NBSc', u'JP2', u'Seg')):
|
||||||
return res
|
res.append((dev['name'], dev['address']))
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
def open(self, port):
|
def open(self, port):
|
||||||
try:
|
try:
|
||||||
self._dev = self._adapter.connect(port, address_type=pygatt.BLEAddressType.random)
|
self._dev = self._adapter.connect(port, address_type=pygatt.BLEAddressType.random)
|
||||||
self._dev.subscribe(_tx_char_uuid, callback=self._make_rx_cb())
|
self._dev.subscribe(_tx_char_uuid, callback=self._make_rx_cb())
|
||||||
self._wr_handle = self._dev.get_handle(_rx_char_uuid)
|
self._wr_handle = self._dev.get_handle(_rx_char_uuid)
|
||||||
except pygatt.exceptions.NotConnectedError:
|
except pygatt.exceptions.NotConnectedError:
|
||||||
raise LinkOpenException
|
raise LinkOpenException
|
||||||
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self._dev:
|
if self._dev:
|
||||||
self._dev.disconnect()
|
self._dev.disconnect()
|
||||||
self._dev = None
|
self._dev = None
|
||||||
if self._adapter:
|
if self._adapter:
|
||||||
self._adapter.stop()
|
self._adapter.stop()
|
||||||
|
|
||||||
|
|
||||||
def read(self, size):
|
def read(self, size):
|
||||||
try:
|
try:
|
||||||
data = self._rx_fifo.read(size, timeout=self.timeout)
|
data = self._rx_fifo.read(size, timeout=self.timeout)
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
raise LinkTimeoutException
|
raise LinkTimeoutException
|
||||||
if self.dump:
|
if self.dump:
|
||||||
print '<', hexlify(data).upper()
|
print('<', hexlify(data).upper())
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
if self.dump:
|
if self.dump:
|
||||||
print '>', hexlify(data).upper()
|
print('>', hexlify(data).upper())
|
||||||
size = len(data)
|
size = len(data)
|
||||||
ofs = 0
|
ofs = 0
|
||||||
while size:
|
while size:
|
||||||
chunk_sz = min(size, _write_chunk_size)
|
chunk_sz = min(size, _write_chunk_size)
|
||||||
self._dev.char_write_handle(self._wr_handle, bytearray(data[ofs:ofs+chunk_sz]))
|
self._dev.char_write_handle(self._wr_handle, bytearray(data[ofs:ofs+chunk_sz]))
|
||||||
ofs += chunk_sz
|
ofs += chunk_sz
|
||||||
size -= chunk_sz
|
size -= chunk_sz
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['BLELink']
|
__all__ = ['BLELink']
|
||||||
|
|
|
@ -48,13 +48,13 @@ class SerialLink(BaseLink):
|
||||||
if len(data)<size:
|
if len(data)<size:
|
||||||
raise LinkTimeoutException
|
raise LinkTimeoutException
|
||||||
if self.dump:
|
if self.dump:
|
||||||
print "<", hexlify(data).upper()
|
print("<", hexlify(data).upper())
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
if self.dump:
|
if self.dump:
|
||||||
print ">", hexlify(data).upper()
|
print(">", hexlify(data).upper())
|
||||||
self.com.write(data)
|
self.com.write(data)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ class TCPLink(BaseLink):
|
||||||
p = port.partition(':')
|
p = port.partition(':')
|
||||||
host = p[0]
|
host = p[0]
|
||||||
port = int(p[2], 10)
|
port = int(p[2], 10)
|
||||||
print host, port
|
print(host, port)
|
||||||
try:
|
try:
|
||||||
self.sock.connect((host, port))
|
self.sock.connect((host, port))
|
||||||
except socket.timeout:
|
except socket.timeout:
|
||||||
|
@ -61,13 +61,13 @@ class TCPLink(BaseLink):
|
||||||
def read(self, size):
|
def read(self, size):
|
||||||
data = recvall(self.sock, size)
|
data = recvall(self.sock, size)
|
||||||
if data and self.dump:
|
if data and self.dump:
|
||||||
print "<", hexlify(data).upper()
|
print("<", hexlify(data).upper())
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
if self.dump:
|
if self.dump:
|
||||||
print ">", hexlify(data).upper()
|
print(">", hexlify(data).upper())
|
||||||
size = len(data)
|
size = len(data)
|
||||||
ofs = 0
|
ofs = 0
|
||||||
while size:
|
while size:
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
def checksum(data):
|
def checksum(data):
|
||||||
s = 0
|
s = 0
|
||||||
for c in data:
|
for c in data:
|
||||||
s += ord(c)
|
s += c
|
||||||
return (s & 0xFFFF) ^ 0xFFFF
|
return (s & 0xFFFF) ^ 0xFFFF
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,16 @@ from binascii import hexlify
|
||||||
from .base import BaseTransport as BT
|
from .base import BaseTransport as BT
|
||||||
|
|
||||||
class BasePacket(object):
|
class BasePacket(object):
|
||||||
def __init__(self, src=0, dst=0, cmd=0, arg=0, data=""):
|
def __init__(self, src=0, dst=0, cmd=0, arg=0, data=""):
|
||||||
self.src = src
|
self.src = src
|
||||||
self.dst = dst
|
self.dst = dst
|
||||||
self.cmd = cmd
|
self.cmd = cmd
|
||||||
self.arg = arg
|
self.arg = arg
|
||||||
self.data = data
|
self.data = data
|
||||||
|
print(self.data)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "%s->%s: %02X @%02X %s" % (BT.GetDeviceName(self.src), BT.GetDeviceName(self.dst), self.cmd, self.arg, hexlify(self.data).upper())
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "%s->%s: %02X @%02X %s" % (BT.GetDeviceName(self.src), BT.GetDeviceName(self.dst), self.cmd, self.arg, hexlify(self.data).upper())
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["BasePacket"]
|
__all__ = ["BasePacket"]
|
||||||
|
|
|
@ -23,7 +23,7 @@ class XiaomiTransport(BT):
|
||||||
BT.MOTOR : {BT.HOST : MOTOR, BT.ESC : MOTOR, BT.BMS : MOTOR } }
|
BT.MOTOR : {BT.HOST : MOTOR, BT.ESC : MOTOR, BT.BMS : MOTOR } }
|
||||||
|
|
||||||
# TBC
|
# TBC
|
||||||
_BleAddr2SaDa = { MASTER2ESC : (BT.HOST, BT.ESC),
|
_BleAddr2SaDa = { MASTER2ESC : (BT.HOST, BT.ESC),
|
||||||
ESC2MASTER : (BT.ESC, BT.HOST),
|
ESC2MASTER : (BT.ESC, BT.HOST),
|
||||||
MASTER2BMS : (BT.HOST, BT.BMS),
|
MASTER2BMS : (BT.HOST, BT.BMS),
|
||||||
BMS2MASTER : (BT.BMS, BT.HOST),
|
BMS2MASTER : (BT.BMS, BT.HOST),
|
||||||
|
@ -31,7 +31,7 @@ class XiaomiTransport(BT):
|
||||||
BLE2MASTER : (BT.BLE, BT.HOST),
|
BLE2MASTER : (BT.BLE, BT.HOST),
|
||||||
MOTOR : (BT.MOTOR, BT.HOST) }
|
MOTOR : (BT.MOTOR, BT.HOST) }
|
||||||
|
|
||||||
_BmsAddr2SaDa = { MASTER2ESC : (BT.BMS, BT.ESC),
|
_BmsAddr2SaDa = { MASTER2ESC : (BT.BMS, BT.ESC),
|
||||||
ESC2MASTER : (BT.ESC, BT.BMS),
|
ESC2MASTER : (BT.ESC, BT.BMS),
|
||||||
MASTER2BMS : (BT.ESC, BT.BMS),
|
MASTER2BMS : (BT.ESC, BT.BMS),
|
||||||
BMS2MASTER : (BT.BMS, BT.ESC),
|
BMS2MASTER : (BT.BMS, BT.ESC),
|
||||||
|
@ -48,7 +48,7 @@ class XiaomiTransport(BT):
|
||||||
def _make_addr(self, src, dst):
|
def _make_addr(self, src, dst):
|
||||||
return XiaomiTransport._SaDa2Addr[src][dst]
|
return XiaomiTransport._SaDa2Addr[src][dst]
|
||||||
|
|
||||||
|
|
||||||
def _split_addr(self, addr):
|
def _split_addr(self, addr):
|
||||||
if self.device==BT.BMS:
|
if self.device==BT.BMS:
|
||||||
return XiaomiTransport._BmsAddr2SaDa[addr]
|
return XiaomiTransport._BmsAddr2SaDa[addr]
|
||||||
|
@ -60,13 +60,13 @@ class XiaomiTransport(BT):
|
||||||
while True:
|
while True:
|
||||||
while True:
|
while True:
|
||||||
c = self.link.read(1)
|
c = self.link.read(1)
|
||||||
if c=="\x55":
|
if c==b"\x55":
|
||||||
break
|
break
|
||||||
while True:
|
while True:
|
||||||
c = self.link.read(1)
|
c = self.link.read(1)
|
||||||
if c=="\xAA":
|
if c==b"\xAA":
|
||||||
return True
|
return True
|
||||||
if c!="\x55":
|
if c!=b"\x55":
|
||||||
break # start waiting 55 again, else - this is 55, so wait for AA
|
break # start waiting 55 again, else - this is 55, so wait for AA
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,21 +74,21 @@ class XiaomiTransport(BT):
|
||||||
self._wait_pre()
|
self._wait_pre()
|
||||||
pkt = self.link.read(1)
|
pkt = self.link.read(1)
|
||||||
l = ord(pkt)+3
|
l = ord(pkt)+3
|
||||||
for i in xrange(l):
|
for i in range(l):
|
||||||
pkt += self.link.read(1)
|
pkt.extend(self.link.read(1))
|
||||||
ck_calc = checksum(pkt[0:-2])
|
ck_calc = checksum(pkt[0:-2])
|
||||||
ck_pkt = unpack("<H", pkt[-2:])[0]
|
ck_pkt = unpack("<H", pkt[-2:])[0]
|
||||||
if ck_pkt!=ck_calc:
|
if ck_pkt!=ck_calc:
|
||||||
print "Checksum mismatch !"
|
print("Checksum mismatch !")
|
||||||
return None
|
return None
|
||||||
sa, da = self._split_addr(ord(pkt[1]))
|
sa, da = self._split_addr(pkt[1])
|
||||||
return BasePacket(sa, da, ord(pkt[2]), ord(pkt[3]), pkt[4:-2]) # sa, da, cmd, arg, data
|
return BasePacket(sa, da, pkt[2], pkt[3], pkt[4:-2]) # sa, da, cmd, arg, data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def send(self, packet):
|
def send(self, packet):
|
||||||
dev = self._make_addr(packet.src, packet.dst)
|
dev = self._make_addr(packet.src, packet.dst)
|
||||||
pkt = pack("<BBBB", len(packet.data)+2, dev, packet.cmd, packet.arg)+packet.data
|
pkt = pack("<BBBB", len(packet.data)+2, dev, packet.cmd, packet.arg)+packet.data
|
||||||
pkt = "\x55\xAA" + pkt + pack("<H", checksum(pkt))
|
pkt = b"\x55\xAA" + pkt + pack("<H", checksum(pkt))
|
||||||
self.link.write(pkt)
|
self.link.write(pkt)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue