2019-10-09 10:07:59 +08:00
|
|
|
import binascii
|
2020-06-12 07:42:21 +08:00
|
|
|
import time
|
2019-10-09 10:07:59 +08:00
|
|
|
|
2017-10-01 10:20:33 +08:00
|
|
|
DEBUG = False
|
|
|
|
|
2017-10-01 03:21:36 +08:00
|
|
|
def msg(x):
|
2017-10-01 10:20:33 +08:00
|
|
|
if DEBUG:
|
2019-10-09 10:07:59 +08:00
|
|
|
print("S:", binascii.hexlify(x))
|
2023-08-07 05:59:22 +08:00
|
|
|
assert len(x) <= 7
|
|
|
|
ret = bytes([len(x)]) + x
|
2019-10-09 10:07:59 +08:00
|
|
|
return ret.ljust(8, b"\x00")
|
2017-10-01 03:21:36 +08:00
|
|
|
|
2018-01-23 13:15:41 +08:00
|
|
|
kmsgs = []
|
|
|
|
def recv(panda, cnt, addr, nbus):
|
|
|
|
global kmsgs
|
|
|
|
ret = []
|
|
|
|
|
|
|
|
while len(ret) < cnt:
|
|
|
|
kmsgs += panda.can_recv()
|
|
|
|
nmsgs = []
|
|
|
|
for ids, ts, dat, bus in kmsgs:
|
|
|
|
if ids == addr and bus == nbus and len(ret) < cnt:
|
|
|
|
ret.append(dat)
|
|
|
|
else:
|
|
|
|
# leave around
|
|
|
|
nmsgs.append((ids, ts, dat, bus))
|
|
|
|
kmsgs = nmsgs[-256:]
|
2019-10-09 10:07:59 +08:00
|
|
|
return ret
|
2018-01-23 13:15:41 +08:00
|
|
|
|
2018-03-10 09:37:47 +08:00
|
|
|
def isotp_recv_subaddr(panda, addr, bus, sendaddr, subaddr):
|
|
|
|
msg = recv(panda, 1, addr, bus)[0]
|
|
|
|
|
2019-07-20 10:35:50 +08:00
|
|
|
# TODO: handle other subaddr also communicating
|
2019-10-09 10:07:59 +08:00
|
|
|
assert msg[0] == subaddr
|
2018-03-10 09:37:47 +08:00
|
|
|
|
2020-06-01 16:49:26 +08:00
|
|
|
if msg[1] & 0xf0 == 0x10:
|
2018-03-10 09:37:47 +08:00
|
|
|
# first
|
2019-10-09 10:07:59 +08:00
|
|
|
tlen = ((msg[1] & 0xf) << 8) | msg[2]
|
2018-03-10 09:37:47 +08:00
|
|
|
dat = msg[3:]
|
|
|
|
|
|
|
|
# 0 block size?
|
2020-06-01 16:49:26 +08:00
|
|
|
CONTINUE = bytes([subaddr]) + b"\x30" + b"\x00" * 6
|
2018-03-10 09:37:47 +08:00
|
|
|
panda.can_send(sendaddr, CONTINUE, bus)
|
|
|
|
|
|
|
|
idx = 1
|
2020-06-01 16:49:26 +08:00
|
|
|
for mm in recv(panda, (tlen - len(dat) + 5) // 6, addr, bus):
|
2019-10-09 10:07:59 +08:00
|
|
|
assert mm[0] == subaddr
|
2020-06-01 16:49:26 +08:00
|
|
|
assert mm[1] == (0x20 | (idx & 0xF))
|
2018-03-10 09:37:47 +08:00
|
|
|
dat += mm[2:]
|
|
|
|
idx += 1
|
2020-06-01 16:49:26 +08:00
|
|
|
elif msg[1] & 0xf0 == 0x00:
|
2018-03-10 09:37:47 +08:00
|
|
|
# single
|
2019-10-09 10:07:59 +08:00
|
|
|
tlen = msg[1] & 0xf
|
2018-03-10 09:37:47 +08:00
|
|
|
dat = msg[2:]
|
|
|
|
else:
|
2019-10-09 10:07:59 +08:00
|
|
|
print(binascii.hexlify(msg))
|
2023-08-07 05:59:22 +08:00
|
|
|
raise AssertionError
|
2018-03-10 09:37:47 +08:00
|
|
|
|
|
|
|
return dat[0:tlen]
|
|
|
|
|
|
|
|
# **** import below this line ****
|
|
|
|
|
2020-06-12 07:42:21 +08:00
|
|
|
def isotp_send(panda, x, addr, bus=0, recvaddr=None, subaddr=None, rate=None):
|
2018-01-23 10:55:10 +08:00
|
|
|
if recvaddr is None:
|
2020-06-01 16:49:26 +08:00
|
|
|
recvaddr = addr + 8
|
2018-01-23 10:55:10 +08:00
|
|
|
|
2018-03-09 06:39:36 +08:00
|
|
|
if len(x) <= 7 and subaddr is None:
|
2017-10-01 03:21:36 +08:00
|
|
|
panda.can_send(addr, msg(x), bus)
|
2018-03-09 06:39:36 +08:00
|
|
|
elif len(x) <= 6 and subaddr is not None:
|
2019-10-14 09:15:04 +08:00
|
|
|
panda.can_send(addr, bytes([subaddr]) + msg(x)[0:7], bus)
|
2017-10-01 03:21:36 +08:00
|
|
|
else:
|
2018-03-09 06:39:36 +08:00
|
|
|
if subaddr:
|
2019-10-16 03:05:33 +08:00
|
|
|
ss = bytes([subaddr, 0x10 + (len(x) >> 8), len(x) & 0xFF]) + x[0:5]
|
2018-03-09 06:39:36 +08:00
|
|
|
x = x[5:]
|
|
|
|
else:
|
2019-10-16 03:05:33 +08:00
|
|
|
ss = bytes([0x10 + (len(x) >> 8), len(x) & 0xFF]) + x[0:6]
|
2018-03-09 06:39:36 +08:00
|
|
|
x = x[6:]
|
2017-10-01 03:21:36 +08:00
|
|
|
idx = 1
|
|
|
|
sends = []
|
|
|
|
while len(x) > 0:
|
2018-03-09 06:39:36 +08:00
|
|
|
if subaddr:
|
2024-02-25 05:56:28 +08:00
|
|
|
sends.append((bytes([subaddr, 0x20 + (idx & 0xF)]) + x[0:6]).ljust(8, b"\x00"))
|
2018-03-09 06:39:36 +08:00
|
|
|
x = x[6:]
|
|
|
|
else:
|
2024-02-25 05:56:28 +08:00
|
|
|
sends.append((bytes([0x20 + (idx & 0xF)]) + x[0:7]).ljust(8, b"\x00"))
|
2018-03-09 06:39:36 +08:00
|
|
|
x = x[7:]
|
2017-10-01 03:21:36 +08:00
|
|
|
idx += 1
|
|
|
|
|
|
|
|
# actually send
|
|
|
|
panda.can_send(addr, ss, bus)
|
2018-01-23 10:55:10 +08:00
|
|
|
rr = recv(panda, 1, recvaddr, bus)[0]
|
2019-10-09 10:07:59 +08:00
|
|
|
if rr.find(b"\x30\x01") != -1:
|
2018-03-09 07:10:35 +08:00
|
|
|
for s in sends[:-1]:
|
|
|
|
panda.can_send(addr, s, 0)
|
|
|
|
rr = recv(panda, 1, recvaddr, bus)[0]
|
|
|
|
panda.can_send(addr, sends[-1], 0)
|
|
|
|
else:
|
2020-06-12 07:42:21 +08:00
|
|
|
if rate is None:
|
|
|
|
panda.can_send_many([(addr, None, s, bus) for s in sends])
|
|
|
|
else:
|
|
|
|
for dat in sends:
|
|
|
|
panda.can_send(addr, dat, bus)
|
|
|
|
time.sleep(rate)
|
2017-10-01 03:21:36 +08:00
|
|
|
|
2018-03-09 06:39:36 +08:00
|
|
|
def isotp_recv(panda, addr, bus=0, sendaddr=None, subaddr=None):
|
|
|
|
if sendaddr is None:
|
2020-06-01 16:49:26 +08:00
|
|
|
sendaddr = addr - 8
|
2018-03-09 06:39:36 +08:00
|
|
|
|
|
|
|
if subaddr is not None:
|
|
|
|
dat = isotp_recv_subaddr(panda, addr, bus, sendaddr, subaddr)
|
|
|
|
else:
|
|
|
|
msg = recv(panda, 1, addr, bus)[0]
|
|
|
|
|
2019-10-14 09:15:04 +08:00
|
|
|
if msg[0] & 0xf0 == 0x10:
|
2018-03-09 06:39:36 +08:00
|
|
|
# first
|
2019-10-09 10:07:59 +08:00
|
|
|
tlen = ((msg[0] & 0xf) << 8) | msg[1]
|
2018-03-09 06:39:36 +08:00
|
|
|
dat = msg[2:]
|
|
|
|
|
|
|
|
# 0 block size?
|
2020-06-01 16:49:26 +08:00
|
|
|
CONTINUE = b"\x30" + b"\x00" * 7
|
2018-03-09 06:39:36 +08:00
|
|
|
|
|
|
|
panda.can_send(sendaddr, CONTINUE, bus)
|
|
|
|
|
|
|
|
idx = 1
|
2020-06-01 16:49:26 +08:00
|
|
|
for mm in recv(panda, (tlen - len(dat) + 6) // 7, addr, bus):
|
|
|
|
assert mm[0] == (0x20 | (idx & 0xF))
|
2018-03-09 06:39:36 +08:00
|
|
|
dat += mm[1:]
|
|
|
|
idx += 1
|
2019-10-11 03:34:52 +08:00
|
|
|
elif msg[0] & 0xf0 == 0x00:
|
2018-03-09 06:39:36 +08:00
|
|
|
# single
|
2019-10-09 10:07:59 +08:00
|
|
|
tlen = msg[0] & 0xf
|
2018-03-09 06:39:36 +08:00
|
|
|
dat = msg[1:]
|
|
|
|
else:
|
2023-08-07 05:59:22 +08:00
|
|
|
raise AssertionError
|
2018-03-09 06:39:36 +08:00
|
|
|
dat = dat[0:tlen]
|
2017-10-01 03:21:36 +08:00
|
|
|
|
2017-10-01 10:20:33 +08:00
|
|
|
if DEBUG:
|
2019-10-09 10:07:59 +08:00
|
|
|
print("R:", binascii.hexlify(dat))
|
2017-10-01 03:21:36 +08:00
|
|
|
|
|
|
|
return dat
|