upacker.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import struct
  2. class Upacker():
  3. def __init__(self):
  4. self._STX_L = 0x55
  5. self._MAX_PACK_SIZE = 1024 + 4 + 128
  6. self._calc = 0
  7. self._check = 0
  8. self._cnt = 0
  9. self._flen = 0
  10. self._state = 0
  11. self._data = bytearray()
  12. def _decode(self, d):
  13. if (self._state == 0 and d == self._STX_L):
  14. self._state = 1
  15. self._calc = self._STX_L
  16. elif self._state == 1:
  17. self._flen = d & 0xff
  18. self._calc ^= d & 0xff
  19. self._state = 2
  20. elif self._state == 2:
  21. self._flen |= (d & 0xff) << 8
  22. self._calc ^= d & 0x3F
  23. # 数据包超长得情况下直接丢包
  24. if ((self._flen & 0x3FFF) > self._MAX_PACK_SIZE):
  25. self._state = 0
  26. return -1
  27. else:
  28. self._data = bytearray(self._flen & 0x3FFF)
  29. self._state = 3
  30. self._cnt = 0
  31. elif self._state == 3:
  32. header_crc = ((d & 0x03) << 4) | ((self._flen & 0xC000) >> 12)
  33. self._check = d
  34. if (header_crc != (self._calc & 0X3C)):
  35. self._state = 0
  36. return -1
  37. self._state = 4
  38. self._flen &= 0x3FFF
  39. elif self._state == 4:
  40. self._data[self._cnt] = d
  41. self._cnt += 1
  42. self._calc ^= d
  43. if self._cnt == self._flen:
  44. self._state = 0
  45. #接收完,检查check
  46. if ((self._calc & 0xFC) == (self._check & 0XFC)):
  47. return 0
  48. else:
  49. return -1
  50. else:
  51. self._state = 0
  52. return 1
  53. # 解包
  54. def unpack(self, bytes_data, callback):
  55. ret = 0
  56. for i in bytes_data:
  57. ret = self._decode(i)
  58. if ret == 0:
  59. callback(self._data)
  60. # print(self._data)
  61. elif ret == -1:
  62. # callback(None)
  63. print("err")
  64. # 打包
  65. def enpack(self, data):
  66. tmp = bytearray(4)
  67. tmp[0] = 0x55
  68. tmp[1] = len(data) & 0xff
  69. tmp[2] = (len(data) >> 8) & 0xff
  70. crc = tmp[0] ^ tmp[1] ^ tmp[2]
  71. tmp[2] |= (crc & 0x0c) << 4
  72. tmp[3] = 0x03 & (crc >> 4)
  73. for i in range(len(data)):
  74. crc ^= data[i]
  75. tmp[3] |= (crc & 0xfc)
  76. frame = struct.pack("BBBB%ds" % len(data), tmp[0], tmp[1], tmp[2],
  77. tmp[3], data)
  78. print(frame.hex())
  79. return frame
  80. def print_hex(bytes):
  81. hex_byte = [hex(i) for i in bytes]
  82. print(" ".join(hex_byte))
  83. if __name__ == '__main__':
  84. buf = bytearray([0x00, 0x01, 0x02,0x03])
  85. pack = Upacker()
  86. pkt = pack.enpack(buf)
  87. pack.unpack(pkt, print_hex)