/* * ProtocolParser.cpp * * Created on: Sep 7, 2017 * Author: guoxs */ #include #include #include #include #include "CommDef.h" #include "uart/ProtocolParser.h" #include "utils/Log.h" static Mutex sLock; static std::vector 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::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::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 split(const std::string& str, const std::string& delim) { std::vector 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 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; }