ProtocolParser.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. * ProtocolParser.cpp
  3. *
  4. * Created on: Sep 7, 2017
  5. * Author: guoxs
  6. */
  7. #include <vector>
  8. #include <iostream>
  9. #include <string.h>
  10. #include <system/Mutex.h>
  11. #include "CommDef.h"
  12. #include "uart/ProtocolParser.h"
  13. #include "utils/Log.h"
  14. static Mutex sLock;
  15. static std::vector<OnProtocolDataUpdateFun> sProtocolDataUpdateListenerList;
  16. void registerProtocolDataUpdateListener(OnProtocolDataUpdateFun pListener) {
  17. Mutex::Autolock _l(sLock);
  18. LOGD("registerProtocolDataUpdateListener\n");
  19. if (pListener != NULL) {
  20. sProtocolDataUpdateListenerList.push_back(pListener);
  21. }
  22. }
  23. void unregisterProtocolDataUpdateListener(OnProtocolDataUpdateFun pListener) {
  24. Mutex::Autolock _l(sLock);
  25. LOGD("unregisterProtocolDataUpdateListener\n");
  26. if (pListener != NULL) {
  27. std::vector<OnProtocolDataUpdateFun>::iterator iter = sProtocolDataUpdateListenerList.begin();
  28. for (; iter != sProtocolDataUpdateListenerList.end(); iter++) {
  29. if ((*iter) == pListener) {
  30. sProtocolDataUpdateListenerList.erase(iter);
  31. return;
  32. }
  33. }
  34. }
  35. }
  36. static void notifyProtocolDataUpdate(const SProtocolData &data) {
  37. Mutex::Autolock _l(sLock);
  38. std::vector<OnProtocolDataUpdateFun>::const_iterator iter = sProtocolDataUpdateListenerList.begin();
  39. for (; iter != sProtocolDataUpdateListenerList.end(); iter++) {
  40. (*iter)(data);
  41. }
  42. }
  43. static SProtocolData sProtocolData;
  44. SProtocolData& getProtocolData() {
  45. return sProtocolData;
  46. }
  47. /**
  48. * 获取校验码
  49. * Get checksum code
  50. */
  51. BYTE getCheckSum(const BYTE *pData, int len) {
  52. int sum = 0;
  53. for (int i = 0; i < len; ++i) {
  54. sum += pData[i];
  55. }
  56. return (BYTE) (~sum + 1);
  57. }
  58. std::vector<std::string> split(const std::string& str, const std::string& delim) {
  59. std::vector<std::string> res;
  60. if("" == str) return res;
  61. //先将要切割的字符串从string类型转换为char*类型
  62. char * strs = new char[str.length() + 1] ; //不要忘了
  63. strcpy(strs, str.c_str());
  64. char * d = new char[delim.length() + 1];
  65. strcpy(d, delim.c_str());
  66. char *p = strtok(strs, d);
  67. while(p) {
  68. std::string s = p; //分割得到的字符串转换为string类型
  69. res.push_back(s); //存入结果数组
  70. p = strtok(NULL, d);
  71. }
  72. return res;
  73. }
  74. void buildProtocolData(std::string info){
  75. LOGD("<<< %s", info.c_str());
  76. std::vector<std::string> res = split(info,",");
  77. sProtocolData.cmd = res[0];
  78. if (strlen(res[1].c_str()) < 5){
  79. sProtocolData.state = res[1];
  80. } else {
  81. sProtocolData.msg = res[1];
  82. }
  83. notifyProtocolDataUpdate(sProtocolData);
  84. }
  85. /**
  86. * 解析每一帧数据
  87. * Parse each frame of data
  88. */
  89. static void procParse(const BYTE *pData, UINT len) {
  90. // 通知协议数据更新
  91. // Notify protocol data update
  92. notifyProtocolDataUpdate(sProtocolData);
  93. }
  94. /**
  95. * 功能:解析协议
  96. * Function: Parse protocol
  97. * 参数:pData 协议数据,len 数据长度
  98. * Parameters: pData - protocol data, len - data length
  99. * 返回值:实际解析协议的长度
  100. * Return value: the length of the actual resolution protocol
  101. */
  102. int parseProtocol(const BYTE *pData, UINT len) {
  103. UINT remainLen = len; // 剩余数据长度
  104. UINT frameLen; // 帧长度
  105. /**
  106. * 当收到的
  107. */
  108. while (remainLen >= DATA_PACKAGE_MIN_LEN) {
  109. // 找到一帧数据的数据头
  110. while ((remainLen >= 2) && pData[0] != CMD_HEAD) {
  111. pData++;
  112. remainLen--;
  113. continue;
  114. }
  115. //小于最小帧长度,丢弃
  116. if (remainLen < DATA_PACKAGE_MIN_LEN) {
  117. break;
  118. }
  119. // 是否有帧尾
  120. if (pData[remainLen-1]==0x00){
  121. frameLen = remainLen;
  122. } else {
  123. break;
  124. }
  125. // 打印一帧数据,需要时在CommDef.h文件中打开DEBUG_PRO_DATA宏
  126. // To print a data of frame, open the DEBUG_PRO_DATA macro in the CommDef.h file when needed
  127. #ifdef DEBUG_PRO_DATA
  128. for (UINT i = 0; i < frameLen; ++i) {
  129. LOGD("%x ", pData[i]);
  130. }
  131. LOGD("\n");
  132. #endif
  133. // 支持checksum校验,需要时在CommDef.h文件中打开PRO_SUPPORT_CHECK_SUM宏
  134. // Support checksum verification, open the PRO_SUPPORT_CHECK_SUM macro in CommDef.h file when needed
  135. #ifdef PRO_SUPPORT_CHECK_SUM
  136. // 检测校验码 Checksum
  137. if (getCheckSum(pData, frameLen - 1) == pData[frameLen - 1]) {
  138. // 解析一帧数据
  139. // Parse a data of frame
  140. procParse(pData, frameLen);
  141. } else {
  142. LOGE("CheckSum error!!!!!!\n");
  143. }
  144. #else
  145. // 解析一帧数据
  146. // Parse a data of frame
  147. //procParse(pData, frameLen);
  148. #endif
  149. pData += frameLen;
  150. remainLen -= frameLen;
  151. }
  152. return len - remainLen;
  153. }