305 lines
9.6 KiB
Python
305 lines
9.6 KiB
Python
|
||
import serial
|
||
import serial.tools.list_ports
|
||
import threading
|
||
import time
|
||
import socket
|
||
|
||
|
||
|
||
|
||
|
||
def crc8(data:bytearray,seed:int=0xff):
|
||
poly=0x0135
|
||
crc=seed
|
||
length=len(data)
|
||
for i in range(length):
|
||
d=data[i]
|
||
for j in range(8):
|
||
bit=(crc^d)&0x01
|
||
crc>>= 1
|
||
if(bit>0):
|
||
crc^=poly
|
||
crc=crc&0xff
|
||
d>>=1
|
||
return crc
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
# 把tcp封装为串口
|
||
class utcp:
|
||
is_open=False
|
||
def __init__(self,port:int)->None:
|
||
self.ser = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
self.ser.bind(("",port))
|
||
self.ser.settimeout(10)
|
||
self.ser.listen(128)
|
||
print("wait for mcu connect.")
|
||
self.client,self.client_addr=self.ser.accept()
|
||
print("client:",self.client_addr)
|
||
self.is_open=True
|
||
def read(self,len:int):
|
||
return self.client.recv(len)
|
||
def write(self,data:bytearray):
|
||
return self.client.send(data)
|
||
def close(self):
|
||
self.client.close()
|
||
self.ser.close()
|
||
self.is_open=False
|
||
|
||
|
||
|
||
class port:
|
||
def __init__(self) -> None:
|
||
pass
|
||
def open(self,name:str,bsp:int):
|
||
if(name!="utcp"):
|
||
self.ser = serial.Serial(port=name, baudrate=bsp,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,
|
||
stopbits=serial.STOPBITS_ONE,timeout=None)
|
||
else:
|
||
self.ser=utcp(9527)
|
||
def start_recv(self):
|
||
self.thread_ = threading.Thread(target=self.recv, args=())
|
||
self.thread_.start()
|
||
def recv(self):
|
||
d=bytearray()
|
||
while(True):
|
||
try:
|
||
d+=self.ser.read(1)
|
||
except Exception as a:
|
||
# print("err:",str(a))
|
||
print("port closed")
|
||
return 0,bytearray()
|
||
if(d[0]!=0x23):
|
||
d=d[1:]
|
||
if((len(d)>=4) and (len(d)>=((d[2]<<8)|d[3]))):
|
||
print("recv code:",d.hex(" "))
|
||
return self.decode(d)
|
||
def send(self,type:int,data:bytearray):
|
||
print("send:",self.encode(type,data).hex(" "))
|
||
self.ser.write(self.encode(type,data))
|
||
def encode(self,type:int,data:bytearray):
|
||
table=b"0123456789"
|
||
d=bytearray()
|
||
d.append(0x23)
|
||
d.append(table[type])
|
||
length=len(data)+7
|
||
d.append((length>>8)&0xff)
|
||
d.append(length&0xff)
|
||
d+=data
|
||
d.append(crc8(d))
|
||
d.append(0x0d)
|
||
d.append(0x0a)
|
||
return d
|
||
# 解码 返回指令类型,内容
|
||
def decode(self,data:bytearray):
|
||
d=data[0:-3]
|
||
if(crc8(d)==data[-3]):
|
||
return d[1]-0x30,d[4:]
|
||
else:
|
||
print("crc failed.")
|
||
return 0,bytearray()
|
||
def calc_shell_code(self,id:int):
|
||
shell=bytearray()
|
||
# shell+=b"58"
|
||
shell+=b"61"
|
||
shell+=b"30815A"
|
||
shell+="{d:05d}".format(d=id).encode("utf-8")
|
||
return shell
|
||
# 打包pc到密码终端注码指令
|
||
def pack_code_cmd(self,id_start:int,data_other:bytearray=bytearray()):
|
||
d=bytearray()
|
||
# d+=b"AD"
|
||
d+=b"A0"
|
||
d.append(0)
|
||
d.append(10)
|
||
for i in range(10):
|
||
d.append(0)
|
||
d.append(i+1)
|
||
d.append(0)
|
||
d.append(13)
|
||
leng=len(data_other)
|
||
d.append((leng>>8)&0xff)
|
||
d.append((leng&0xff))
|
||
shell_code=self.calc_shell_code(id_start+i)
|
||
print("shell_code:",shell_code.decode("utf-8"))
|
||
d+=shell_code
|
||
d+=data_other
|
||
return d
|
||
# 打包pc到密码终端注码指令,生成uid
|
||
def pack_code2_cmd(self,id_start:int,data_other:bytearray=bytearray()):
|
||
d=bytearray()
|
||
fact_chip=b"A0"
|
||
year=b"23"
|
||
d+=fact_chip
|
||
d.append(0)
|
||
d.append(10)
|
||
for i in range(10):
|
||
d.append(0)
|
||
d.append(i+1)
|
||
d.append(0)
|
||
d.append(13)
|
||
shell_code=self.calc_shell_code(id_start+i)
|
||
uid_code=fact_chip+year+shell_code[0:2]+shell_code[3:]
|
||
leng=len(uid_code)
|
||
d.append((leng>>8)&0xff)
|
||
d.append((leng&0xff))
|
||
leng=len(data_other)
|
||
d.append((leng>>8)&0xff)
|
||
d.append((leng&0xff))
|
||
d+=shell_code
|
||
d+=uid_code
|
||
d+=data_other
|
||
return d
|
||
# 根据管壳码生成uid和密码
|
||
def pack_psw_cmd(self,data:bytearray,year:bytearray=b"23"):
|
||
d=bytearray()
|
||
fact_chip=data[0:2]
|
||
num=(data[2]<<8)|data[3]
|
||
data=data[4:]
|
||
d+=fact_chip
|
||
d.append((num>>8)&0xff)
|
||
d.append(num&0xff)
|
||
for i in range(num):
|
||
index=(data[0]<<8)|data[1]
|
||
shell_len=(data[2]<<8)|data[3]
|
||
other_len=(data[4]<<8)|data[5]
|
||
shell_code=data[6:6+shell_len]
|
||
other=data[6+shell_len:6+shell_len+other_len]
|
||
# print("shell code:",shell_code.decode("utf-8"))
|
||
# print("other:",other.decode("utf-8"))
|
||
# 一位年份扩展为两位年份,需考虑计划年份与生产时年份不同的情况
|
||
# uid为16位,包含芯片厂家代码和两位年份
|
||
uid_code=fact_chip+year+shell_code[0:2]+shell_code[3:]
|
||
uid_len=len(uid_code)
|
||
# 默认生成的密码
|
||
psw_code=b"12345678"
|
||
psw_len=len(psw_code)
|
||
d.append((index>>8)&0xff)
|
||
d.append(index&0xff)
|
||
d.append((shell_len>>8)&0xff)
|
||
d.append(shell_len&0xff)
|
||
d.append((uid_len>>8)&0xff)
|
||
d.append(uid_len&0xff)
|
||
d.append((psw_len>>8)&0xff)
|
||
d.append(psw_len&0xff)
|
||
d.append((other_len>>8)&0xff)
|
||
d.append(other_len&0xff)
|
||
d+=shell_code
|
||
d+=uid_code
|
||
d+=psw_code
|
||
d+=other
|
||
data=data[6+shell_len+other_len:]
|
||
return d
|
||
# 根据管壳码密码注码,生成注码结果
|
||
def code_write(self,data:bytearray):
|
||
d=bytearray()
|
||
fact_chip=data[0:2]
|
||
num=(data[2]<<8)|data[3]
|
||
data=data[4:]
|
||
d+=fact_chip
|
||
d.append((num>>8)&0xff)
|
||
d.append(num&0xff)
|
||
for i in range(num):
|
||
index=(data[0]<<8)|data[1]
|
||
shell_len=(data[2]<<8)|data[3]
|
||
uid_len=(data[4]<<8)|data[5]
|
||
psw_len=(data[6]<<8)|data[7]
|
||
other_len=(data[8]<<8)|data[9]
|
||
shell_code=data[10:10+shell_len]
|
||
uid_code=data[10+shell_len:10+shell_len+uid_len]
|
||
psw_code=data[10+shell_len+uid_len:10+shell_len+uid_len+psw_len]
|
||
other=data[10+shell_len+uid_len+psw_len:10+shell_len+uid_len+psw_len+other_len]
|
||
ack=bytearray([0])
|
||
ack_len=len(ack)
|
||
|
||
print("shell_code:",shell_code.decode("utf-8"))
|
||
print("uid_code:",uid_code.decode("utf-8"))
|
||
print("psw_code:",psw_code.decode("utf-8"))
|
||
print("other:",other.decode("utf-8"))
|
||
|
||
d.append((index>>8)&0xff)
|
||
d.append(index&0xff)
|
||
d.append((shell_len>>8)&0xff)
|
||
d.append(shell_len&0xff)
|
||
d.append((uid_len>>8)&0xff)
|
||
d.append(uid_len&0xff)
|
||
d.append((other_len>>8)&0xff)
|
||
d.append(other_len&0xff)
|
||
# d.append((ack_len>>8)&0xff)
|
||
d.append(ack_len&0xff)
|
||
d+=shell_code
|
||
d+=uid_code
|
||
d+=other
|
||
d+=ack
|
||
data=data[10+shell_len+uid_len+psw_len+other_len:]
|
||
return d
|
||
# 解析注码结果
|
||
def code_wirte_end(self,data:bytearray):
|
||
fact_chip=data[0:2]
|
||
num=(data[2]<<8)|data[3]
|
||
data=data[4:]
|
||
print("fact_chip:",fact_chip)
|
||
print("num:",num)
|
||
for i in range(num):
|
||
index=(data[0]<<8)|data[1]
|
||
shell_len=(data[2]<<8)|data[3]
|
||
uid_len=(data[4]<<8)|data[5]
|
||
other_len=(data[6]<<8)|data[7]
|
||
ack_len=(data[8]<<8)|data[9]
|
||
shell_code=data[10:10+shell_len]
|
||
uid_code=data[10+shell_len:10+shell_len+uid_len]
|
||
other=data[10+shell_len+uid_len:10+shell_len+uid_len+other_len]
|
||
ack=data[10+shell_len+uid_len+other_len:10+shell_len+uid_len+other_len+ack_len]
|
||
|
||
|
||
if __name__ == "__main__":
|
||
p=port()
|
||
# p.open("com11",115200)
|
||
# print("生成透传任意指令")
|
||
# d_send=p.encode(5,b"123456789aaaddddggd")
|
||
# print(d_send.hex(" "))
|
||
d_send=p.encode(6,b"987654321ssddffghhf")
|
||
print(d_send.hex(" "))
|
||
# print("解析透传任意指令")
|
||
# typ,d_recv=p.decode(d_send)
|
||
# print(typ,d_recv.hex(" "))
|
||
|
||
print("生成管壳码注码命令")
|
||
d_send=p.encode(1,p.pack_code_cmd(987,b"asdfgk"))
|
||
print(d_send.hex(" "))
|
||
# print("生成管壳码UID注码命令")
|
||
# d_send=p.encode(7,p.pack_code2_cmd(0,b"asdfgk"))
|
||
# print(d_send.hex(" "))
|
||
# print("解析管壳码注码命令,生成UID密码注码命令")
|
||
# typ,d_recv=p.decode(d_send)
|
||
# d_send=p.encode(2,p.pack_psw_cmd(d_recv))
|
||
# print(d_send.hex(" "))
|
||
# while (True):
|
||
# typ,d_recv=p.recv()
|
||
# start = time.perf_counter()
|
||
# print("解析uid密码注码命令,生成注码结果")
|
||
# # d_send=p.encode(3,p.code_write(d_recv))
|
||
# # print(d_send.hex(" "))
|
||
# # time.sleep(0.1)
|
||
# if(typ==2):
|
||
# print("返回透传数据")
|
||
# p.send(6,b"sssss")
|
||
# print("发送注码成功")
|
||
# p.send(3,p.code_write(d_recv))
|
||
# end = time.perf_counter()
|
||
# print("赋码耗时:",end-start)
|
||
# elif(typ==5):
|
||
# print("返回透传数据")
|
||
# p.send(6,b"hello world.")
|
||
# end = time.perf_counter()
|
||
# print("透传耗时:",end-start)
|