226 lines
7.2 KiB
Python
226 lines
7.2 KiB
Python
from telnetlib import Telnet
|
|
import serial
|
|
|
|
DEBUG = True
|
|
|
|
|
|
class MAXPacketFactory:
|
|
def create_packet(rec: str):
|
|
pkt_type = int(rec[7:9], 16)
|
|
if pkt_type == 0:
|
|
return MAXPairPingPacket.from_received(rec)
|
|
elif pkt_type == 1:
|
|
return MAXPairPongPacket.from_received(rec)
|
|
elif pkt_type == 2:
|
|
return MAXAckPacket.from_received(rec)
|
|
elif pkt_type == 0xF1:
|
|
return MAXWakeUpPacket.from_received(rec)
|
|
elif pkt_type == 0xF0:
|
|
return MAXResetPacket.from_received(rec)
|
|
else:
|
|
print("Unknown message type: {}".format(pkt_type))
|
|
return MAXPacket.from_received(rec)
|
|
|
|
|
|
class MAXPacket:
|
|
def __init__(self, length, message_counter: str, message_type: str, message_flag: str, sender_address: str, dest_address: str,
|
|
group_id:str):
|
|
self.length = length
|
|
self.counter = message_counter
|
|
self.type = message_type
|
|
self.flag = message_flag
|
|
self.sender_address = sender_address
|
|
self.dest_address = dest_address
|
|
self.group_id = group_id
|
|
|
|
def from_received(rec: str):
|
|
return MAXPacket(rec[1:3], rec[3:5], rec[5:7], rec[7:9], rec[9:15], rec[15:21], rec[21:23])
|
|
|
|
def gen_header(self):
|
|
header_str = "{}{}{}{}{}{}".format(self.counter, self.flag, self.type, self.sender_address,
|
|
self.dest_address, self.group_id)
|
|
return header_str
|
|
|
|
def to_string(self):
|
|
return "MAXPacket: len={}, counter={}, flag={}, type={}, sender_addr={}, dest_addr={}, group_id={}".format(
|
|
self.length, self.counter, self.flag, self.type, self.sender_address, self.dest_address, self.group_id
|
|
)
|
|
|
|
|
|
class MAXPairPingPacket(MAXPacket):
|
|
def from_received(rec: str):
|
|
result = MAXPacket.from_received(rec)
|
|
firmware_val = int(rec[23:25], 16)
|
|
result.firmware_major = firmware_val // 16
|
|
result.firmware_minor = firmware_val % 16
|
|
result.device_type = rec[25:27]
|
|
result.test_result = rec[27:29]
|
|
result.serial = rec[29:-2]
|
|
return result
|
|
|
|
def __init__(self, length, message_counter: str, message_type: str, message_flag: str, sender_address: str, dest_address: str,
|
|
group_id:str, firmware_major, firmware_minor, device_type, test_result, serial):
|
|
MAXPacket.__init__(length, message_counter, message_type, message_flag, sender_address, dest_address, group_id)
|
|
self.firmware_major = firmware_major
|
|
self.firmware_minor = firmware_minor
|
|
self.device_type = device_type
|
|
self.test_result = test_result
|
|
self.serial = serial
|
|
|
|
def to_string(self):
|
|
result = "{}\nMAXPairPingPacket: firmware_major={} firmware_minor={} device_type={} " \
|
|
"test_result={} serial={}".format(super().to_string(), self.firmware_major, self.firmware_minor,
|
|
self.device_type, self.test_result, self.serial)
|
|
return result
|
|
|
|
|
|
class MAXPairPongPacket(MAXPacket):
|
|
# def __init__(self, rec):
|
|
# super().__init__(rec)
|
|
|
|
def __init__(self, message_counter: str, message_flag: str, sender_address: str, dest_address: str,
|
|
group_id:str):
|
|
MAXPacket.__init__(message_counter, "01", message_flag, sender_address, dest_address, group_id)
|
|
self.payload = "00"
|
|
|
|
def serialize(self):
|
|
header = self.gen_header()
|
|
length = (len(header) + len(self.payload))/2
|
|
return "Zs{}{}{}".format(length, header, self.payload)
|
|
|
|
|
|
class MAXAckPacket(MAXPacket):
|
|
def __init__(self, rec):
|
|
super().__init__(rec)
|
|
|
|
|
|
class MAXWakeUpPacket(MAXPacket):
|
|
def __init__(self, rec):
|
|
super().__init__(rec)
|
|
|
|
|
|
class MAXResetPacket(MAXPacket):
|
|
def __init__(self, rec):
|
|
super().__init__(rec)
|
|
|
|
|
|
class CUL:
|
|
def __init__(self):
|
|
self.client: serial.Serial = None
|
|
|
|
def connect(self, port):
|
|
if self.client is None:
|
|
self.client = serial.Serial(port, 38400, timeout=1)
|
|
|
|
def disconnect(self):
|
|
if self.client is not None:
|
|
self.client.close()
|
|
self.client = None
|
|
|
|
def request(self, req):
|
|
if self.client is not None:
|
|
self.client.write(req.encode())
|
|
self.client.write(b"\n")
|
|
if DEBUG:
|
|
print(">>> {}".format(req))
|
|
else:
|
|
print("Request while not connected!")
|
|
|
|
def response(self):
|
|
if self.client is not None:
|
|
response = self.client.read(100).decode()
|
|
if DEBUG:
|
|
print("<<< {}".format(response))
|
|
return response
|
|
else:
|
|
print("Waiting for response while not connected!")
|
|
return None
|
|
|
|
def version_string(self):
|
|
self.request("V")
|
|
return self.response()
|
|
|
|
def is_connected(self):
|
|
return self.client is not None
|
|
|
|
def set_moritz_mode(self, moritz_mode_enable):
|
|
if moritz_mode_enable:
|
|
self.request("Zr")
|
|
#return self.response()
|
|
else:
|
|
self.request("Zx")
|
|
|
|
|
|
class CUN:
|
|
def __init__(self):
|
|
self.client: Telnet = None
|
|
|
|
def connect(self, host, ip):
|
|
if self.client is None:
|
|
self.client = Telnet(host, ip)
|
|
|
|
def disconnect(self):
|
|
if self.client is not None:
|
|
self.client.close()
|
|
self.client = None
|
|
|
|
def version_string(self):
|
|
self.request("V")
|
|
return self.response()
|
|
|
|
def request(self, req):
|
|
if self.client is not None:
|
|
self.client.write(req.encode())
|
|
self.client.write(b"\n")
|
|
if DEBUG:
|
|
print(">>> {}".format(req))
|
|
else:
|
|
print("Request while not connected!")
|
|
|
|
def response(self):
|
|
if self.client is not None:
|
|
response = self.client.read_some().decode()
|
|
if DEBUG:
|
|
print("<<< {}".format(response))
|
|
return response
|
|
else:
|
|
print("Waiting for response while not connected!")
|
|
return None
|
|
|
|
def set_moritz_mode(self, moritz_mode_enable):
|
|
if moritz_mode_enable:
|
|
self.request("Zr")
|
|
#return self.response()
|
|
else:
|
|
self.request("Zx")
|
|
|
|
def configure(self, ip, netmask, gateway, ):
|
|
# ToDo: NYI
|
|
pass
|
|
|
|
def h_request(self):
|
|
self.request("H?")
|
|
return self.response()
|
|
|
|
def send_moritz(self, packet: MAXPacket):
|
|
# llnnccttssssssddddddpp...
|
|
# ll - length
|
|
# nn - msg counter
|
|
# cc - control byte
|
|
# tt - msg type
|
|
# ss - sender address(3 byte)
|
|
# dd - destination address(3 byte - 000000 for broadcast)
|
|
# pp - payload...
|
|
len_str = packet.length
|
|
msg_counter_str = packet.ms
|
|
control_byte_str = "00"
|
|
message_type_str = "02"
|
|
sender_addr_str = "000000"
|
|
dest_addr_str = "000000"
|
|
payload = "l:"
|
|
self.request("Zs{}{}{}{}{}{}{}".format(packet.length, packet.message_counter, control_byte_str,
|
|
message_type_str, sender_addr_str,
|
|
dest_addr_str, payload))
|
|
#self.request("l:")
|
|
return self.response()
|