Upacker.java 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package ltd.zlink.ae_tracer.msg;
  2. public class Upacker {
  3. // 最长消息长度
  4. private final int MAX_PACK_SIZE = 5012;
  5. private final byte STX_L = 0X55;
  6. private final int RET_FAILED = -1;
  7. private final int RET_SUCCESS = 0;
  8. private final int RET_PROCESS = 1;
  9. //cmd数据
  10. private byte[] data;
  11. // cmd长度
  12. private int flen;
  13. // cmd 校验
  14. private int check;
  15. // cmd 校验计算值
  16. private int calc;
  17. // cmd 解析状态
  18. private int state;
  19. // cmd数据接收cnt
  20. private int cnt;
  21. private MsgCallback msgCallback;
  22. Upacker(final MsgCallback cb) {
  23. msgCallback = cb;
  24. }
  25. /**
  26. * 解析封包
  27. *
  28. * @param buff
  29. */
  30. public void unpack(byte[] buff) {
  31. int ret = 0;
  32. for (byte i : buff) {
  33. ret = frameDecode(i);
  34. if (ret == RET_SUCCESS) {
  35. msgCallback.onMsgPrased(data, flen);
  36. } else if (ret == RET_FAILED) {
  37. msgCallback.onMsgFailed();
  38. }
  39. }
  40. }
  41. private int frameDecode(byte d) {
  42. if (state == 0 && d == STX_L) {
  43. state = 1;
  44. calc = STX_L;
  45. } else if (state == 1) {
  46. flen = d & 0xff;
  47. calc ^= d & 0xff;
  48. state = 2;
  49. } else if (state == 2) {
  50. flen |= (d & 0xff) << 8;
  51. calc ^= d & 0x3F;
  52. // 数据包超长得情况下直接丢包
  53. if ((flen & 0x3FFF) > MAX_PACK_SIZE) {
  54. state = 0;
  55. return RET_FAILED;
  56. } else {
  57. data = new byte[flen & 0x3FFF];
  58. }
  59. state = 3;
  60. cnt = 0;
  61. } else if (state == 3) {
  62. int header_crc = ((d & 0x03) << 4) | ((flen & 0xC000) >> 12);
  63. check = d;
  64. if (header_crc != (calc & 0X3C)) {
  65. state = 0;
  66. return RET_FAILED;
  67. }
  68. state = 4;
  69. flen &= 0x3FFF;
  70. } else if (state == 4) {
  71. data[cnt++] = d;
  72. calc ^= d;
  73. if (cnt == flen) {
  74. state = 0;
  75. //接收完,检查check
  76. if ((calc & 0xFC) == (check & 0XFC)) {
  77. return RET_SUCCESS;
  78. } else {
  79. return RET_FAILED;
  80. }
  81. }
  82. } else {
  83. state = 0;
  84. }
  85. return RET_PROCESS;
  86. }
  87. /**
  88. * 打包数据,静态方法
  89. *
  90. * @param data
  91. * @return
  92. */
  93. public static byte[] frameEncode(byte[] data) {
  94. byte tmp[] = new byte[4 + data.length];
  95. int crc = 0;
  96. tmp[0] = 0x55;
  97. tmp[1] = (byte) (data.length & 0xff);
  98. tmp[2] = (byte) ((data.length >> 8) & 0xff);
  99. crc = tmp[0] ^ tmp[1] ^ tmp[2];
  100. tmp[2] |= (byte) ((crc & 0x0C) << 4);
  101. tmp[3] = (byte) (0x03 & (crc >> 4));
  102. for (int i = 0; i < data.length; i++) {
  103. crc ^= data[i];
  104. }
  105. tmp[3] |= (crc & 0xfc);
  106. System.arraycopy(data, 0, tmp, 4, data.length);
  107. return tmp;
  108. }
  109. }