You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
7.2KB

  1. from telnetlib import Telnet
  2. import serial
  3. DEBUG = True
  4. class MAXPacketFactory:
  5. def create_packet(rec: str):
  6. pkt_type = int(rec[7:9], 16)
  7. if pkt_type == 0:
  8. return MAXPairPingPacket.from_received(rec)
  9. elif pkt_type == 1:
  10. return MAXPairPongPacket.from_received(rec)
  11. elif pkt_type == 2:
  12. return MAXAckPacket.from_received(rec)
  13. elif pkt_type == 0xF1:
  14. return MAXWakeUpPacket.from_received(rec)
  15. elif pkt_type == 0xF0:
  16. return MAXResetPacket.from_received(rec)
  17. else:
  18. print("Unknown message type: {}".format(pkt_type))
  19. return MAXPacket.from_received(rec)
  20. class MAXPacket:
  21. def __init__(self, length, message_counter: str, message_type: str, message_flag: str, sender_address: str, dest_address: str,
  22. group_id:str):
  23. self.length = length
  24. self.counter = message_counter
  25. self.type = message_type
  26. self.flag = message_flag
  27. self.sender_address = sender_address
  28. self.dest_address = dest_address
  29. self.group_id = group_id
  30. def from_received(rec: str):
  31. return MAXPacket(rec[1:3], rec[3:5], rec[5:7], rec[7:9], rec[9:15], rec[15:21], rec[21:23])
  32. def gen_header(self):
  33. header_str = "{}{}{}{}{}{}".format(self.counter, self.flag, self.type, self.sender_address,
  34. self.dest_address, self.group_id)
  35. return header_str
  36. def to_string(self):
  37. return "MAXPacket: len={}, counter={}, flag={}, type={}, sender_addr={}, dest_addr={}, group_id={}".format(
  38. self.length, self.counter, self.flag, self.type, self.sender_address, self.dest_address, self.group_id
  39. )
  40. class MAXPairPingPacket(MAXPacket):
  41. def from_received(rec: str):
  42. result = MAXPacket.from_received(rec)
  43. firmware_val = int(rec[23:25], 16)
  44. result.firmware_major = firmware_val // 16
  45. result.firmware_minor = firmware_val % 16
  46. result.device_type = rec[25:27]
  47. result.test_result = rec[27:29]
  48. result.serial = rec[29:-2]
  49. return result
  50. def __init__(self, length, message_counter: str, message_type: str, message_flag: str, sender_address: str, dest_address: str,
  51. group_id:str, firmware_major, firmware_minor, device_type, test_result, serial):
  52. MAXPacket.__init__(length, message_counter, message_type, message_flag, sender_address, dest_address, group_id)
  53. self.firmware_major = firmware_major
  54. self.firmware_minor = firmware_minor
  55. self.device_type = device_type
  56. self.test_result = test_result
  57. self.serial = serial
  58. def to_string(self):
  59. result = "{}\nMAXPairPingPacket: firmware_major={} firmware_minor={} device_type={} " \
  60. "test_result={} serial={}".format(super().to_string(), self.firmware_major, self.firmware_minor,
  61. self.device_type, self.test_result, self.serial)
  62. return result
  63. class MAXPairPongPacket(MAXPacket):
  64. # def __init__(self, rec):
  65. # super().__init__(rec)
  66. def __init__(self, message_counter: str, message_flag: str, sender_address: str, dest_address: str,
  67. group_id:str):
  68. MAXPacket.__init__(message_counter, "01", message_flag, sender_address, dest_address, group_id)
  69. self.payload = "00"
  70. def serialize(self):
  71. header = self.gen_header()
  72. length = (len(header) + len(self.payload))/2
  73. return "Zs{}{}{}".format(length, header, self.payload)
  74. class MAXAckPacket(MAXPacket):
  75. def __init__(self, rec):
  76. super().__init__(rec)
  77. class MAXWakeUpPacket(MAXPacket):
  78. def __init__(self, rec):
  79. super().__init__(rec)
  80. class MAXResetPacket(MAXPacket):
  81. def __init__(self, rec):
  82. super().__init__(rec)
  83. class CUL:
  84. def __init__(self):
  85. self.client: serial.Serial = None
  86. def connect(self, port):
  87. if self.client is None:
  88. self.client = serial.Serial(port, 38400, timeout=1)
  89. def disconnect(self):
  90. if self.client is not None:
  91. self.client.close()
  92. self.client = None
  93. def request(self, req):
  94. if self.client is not None:
  95. self.client.write(req.encode())
  96. self.client.write(b"\n")
  97. if DEBUG:
  98. print(">>> {}".format(req))
  99. else:
  100. print("Request while not connected!")
  101. def response(self):
  102. if self.client is not None:
  103. response = self.client.read(100).decode()
  104. if DEBUG:
  105. print("<<< {}".format(response))
  106. return response
  107. else:
  108. print("Waiting for response while not connected!")
  109. return None
  110. def version_string(self):
  111. self.request("V")
  112. return self.response()
  113. def is_connected(self):
  114. return self.client is not None
  115. def set_moritz_mode(self, moritz_mode_enable):
  116. if moritz_mode_enable:
  117. self.request("Zr")
  118. #return self.response()
  119. else:
  120. self.request("Zx")
  121. class CUN:
  122. def __init__(self):
  123. self.client: Telnet = None
  124. def connect(self, host, ip):
  125. if self.client is None:
  126. self.client = Telnet(host, ip)
  127. def disconnect(self):
  128. if self.client is not None:
  129. self.client.close()
  130. self.client = None
  131. def version_string(self):
  132. self.request("V")
  133. return self.response()
  134. def request(self, req):
  135. if self.client is not None:
  136. self.client.write(req.encode())
  137. self.client.write(b"\n")
  138. if DEBUG:
  139. print(">>> {}".format(req))
  140. else:
  141. print("Request while not connected!")
  142. def response(self):
  143. if self.client is not None:
  144. response = self.client.read_some().decode()
  145. if DEBUG:
  146. print("<<< {}".format(response))
  147. return response
  148. else:
  149. print("Waiting for response while not connected!")
  150. return None
  151. def set_moritz_mode(self, moritz_mode_enable):
  152. if moritz_mode_enable:
  153. self.request("Zr")
  154. #return self.response()
  155. else:
  156. self.request("Zx")
  157. def configure(self, ip, netmask, gateway, ):
  158. # ToDo: NYI
  159. pass
  160. def h_request(self):
  161. self.request("H?")
  162. return self.response()
  163. def send_moritz(self, packet: MAXPacket):
  164. # llnnccttssssssddddddpp...
  165. # ll - length
  166. # nn - msg counter
  167. # cc - control byte
  168. # tt - msg type
  169. # ss - sender address(3 byte)
  170. # dd - destination address(3 byte - 000000 for broadcast)
  171. # pp - payload...
  172. len_str = packet.length
  173. msg_counter_str = packet.ms
  174. control_byte_str = "00"
  175. message_type_str = "02"
  176. sender_addr_str = "000000"
  177. dest_addr_str = "000000"
  178. payload = "l:"
  179. self.request("Zs{}{}{}{}{}{}{}".format(packet.length, packet.message_counter, control_byte_str,
  180. message_type_str, sender_addr_str,
  181. dest_addr_str, payload))
  182. #self.request("l:")
  183. return self.response()