123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- /*
- * ProtocolParser.cpp
- *
- * Created on: Sep 7, 2017
- * Author: guoxs
- */
- #include <vector>
- #include <iostream>
- #include <string.h>
- #include <system/Mutex.h>
- #include "CommDef.h"
- #include "uart/ProtocolParser.h"
- #include "utils/Log.h"
- static Mutex sLock;
- static std::vector<OnProtocolDataUpdateFun> sProtocolDataUpdateListenerList;
- void registerProtocolDataUpdateListener(OnProtocolDataUpdateFun pListener) {
- Mutex::Autolock _l(sLock);
- LOGD("registerProtocolDataUpdateListener\n");
- if (pListener != NULL) {
- sProtocolDataUpdateListenerList.push_back(pListener);
- }
- }
- void unregisterProtocolDataUpdateListener(OnProtocolDataUpdateFun pListener) {
- Mutex::Autolock _l(sLock);
- LOGD("unregisterProtocolDataUpdateListener\n");
- if (pListener != NULL) {
- std::vector<OnProtocolDataUpdateFun>::iterator iter = sProtocolDataUpdateListenerList.begin();
- for (; iter != sProtocolDataUpdateListenerList.end(); iter++) {
- if ((*iter) == pListener) {
- sProtocolDataUpdateListenerList.erase(iter);
- return;
- }
- }
- }
- }
- static void notifyProtocolDataUpdate(const SProtocolData &data) {
- Mutex::Autolock _l(sLock);
- std::vector<OnProtocolDataUpdateFun>::const_iterator iter = sProtocolDataUpdateListenerList.begin();
- for (; iter != sProtocolDataUpdateListenerList.end(); iter++) {
- (*iter)(data);
- }
- }
- static SProtocolData sProtocolData;
- SProtocolData& getProtocolData() {
- return sProtocolData;
- }
- /**
- * 获取校验码
- * Get checksum code
- */
- BYTE getCheckSum(const BYTE *pData, int len) {
- int sum = 0;
- for (int i = 0; i < len; ++i) {
- sum += pData[i];
- }
- return (BYTE) (~sum + 1);
- }
- std::vector<std::string> split(const std::string& str, const std::string& delim) {
- std::vector<std::string> res;
- if("" == str) return res;
- //先将要切割的字符串从string类型转换为char*类型
- char * strs = new char[str.length() + 1] ; //不要忘了
- strcpy(strs, str.c_str());
- char * d = new char[delim.length() + 1];
- strcpy(d, delim.c_str());
- char *p = strtok(strs, d);
- while(p) {
- std::string s = p; //分割得到的字符串转换为string类型
- res.push_back(s); //存入结果数组
- p = strtok(NULL, d);
- }
- return res;
- }
- void buildProtocolData(std::string info){
- LOGD("<<< %s", info.c_str());
- std::vector<std::string> res = split(info,",");
- sProtocolData.cmd = res[0];
- if (strlen(res[1].c_str()) < 5){
- sProtocolData.state = res[1];
- } else {
- sProtocolData.msg = res[1];
- }
- notifyProtocolDataUpdate(sProtocolData);
- }
- /**
- * 解析每一帧数据
- * Parse each frame of data
- */
- static void procParse(const BYTE *pData, UINT len) {
- // 通知协议数据更新
- // Notify protocol data update
- notifyProtocolDataUpdate(sProtocolData);
- }
- /**
- * 功能:解析协议
- * Function: Parse protocol
- * 参数:pData 协议数据,len 数据长度
- * Parameters: pData - protocol data, len - data length
- * 返回值:实际解析协议的长度
- * Return value: the length of the actual resolution protocol
- */
- int parseProtocol(const BYTE *pData, UINT len) {
- UINT remainLen = len; // 剩余数据长度
- UINT frameLen; // 帧长度
- /**
- * 当收到的
- */
- while (remainLen >= DATA_PACKAGE_MIN_LEN) {
- // 找到一帧数据的数据头
- while ((remainLen >= 2) && pData[0] != CMD_HEAD) {
- pData++;
- remainLen--;
- continue;
- }
- //小于最小帧长度,丢弃
- if (remainLen < DATA_PACKAGE_MIN_LEN) {
- break;
- }
- // 是否有帧尾
- if (pData[remainLen-1]==0x00){
- frameLen = remainLen;
- } else {
- break;
- }
- // 打印一帧数据,需要时在CommDef.h文件中打开DEBUG_PRO_DATA宏
- // To print a data of frame, open the DEBUG_PRO_DATA macro in the CommDef.h file when needed
- #ifdef DEBUG_PRO_DATA
- for (UINT i = 0; i < frameLen; ++i) {
- LOGD("%x ", pData[i]);
- }
- LOGD("\n");
- #endif
- // 支持checksum校验,需要时在CommDef.h文件中打开PRO_SUPPORT_CHECK_SUM宏
- // Support checksum verification, open the PRO_SUPPORT_CHECK_SUM macro in CommDef.h file when needed
- #ifdef PRO_SUPPORT_CHECK_SUM
- // 检测校验码 Checksum
- if (getCheckSum(pData, frameLen - 1) == pData[frameLen - 1]) {
- // 解析一帧数据
- // Parse a data of frame
- procParse(pData, frameLen);
- } else {
- LOGE("CheckSum error!!!!!!\n");
- }
- #else
- // 解析一帧数据
- // Parse a data of frame
- //procParse(pData, frameLen);
- #endif
- pData += frameLen;
- remainLen -= frameLen;
- }
- return len - remainLen;
- }
|