#include "ps.h" #include "maindlg.h" static quint16 s_crc_table[16] = {0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef}; //构造函数 Ps::Ps(QObject *parent) : QObject{parent} { m_pMainDlg = static_cast(parent);//保存主窗口指针 memset(&m_stDataBuf, 0, sizeof(PS_DATA_BUF_T)); PsInit();//模块初始化 } //初始化协议栈 void Ps::PsInit(){ m_byPacketNo = 100; memset(m_abyPsBuf, 0, sizeof(quint8)*PS_FRAME_MAX_LEN); memset(m_abyTempData, 0, sizeof(quint8)*PS_FRAME_MAX_LEN); m_wListLen = 0; QObject::connect(this, this->PsUlRespSignalQueryOk, m_pMainDlg, &m_pMainDlg->PsUlRespSignaQueryOkSlot); QObject::connect(this, this->PsUlRespSignalQueryFail, m_pMainDlg, &m_pMainDlg->PsUlRespSignaQueryFailSlot); QObject::connect(this, this->PsUlRespSignalConfigOk, m_pMainDlg, &m_pMainDlg->PsUlRespSignalConfigOkSlot); QObject::connect(this, this->PsUlRespSignalConfigFail, m_pMainDlg, &m_pMainDlg->PsUlRespSignalConfigFailSlot); QObject::connect(this, this->PsUlRespSignalUpgradeSuccess, m_pMainDlg, &m_pMainDlg->PsUlRespSignalUpgradeOkSlot); QObject::connect(this, this->PsUlRespSignalUpgradeFail, m_pMainDlg, &m_pMainDlg->PsUlRespSignalUpgradeFailSlot); } //从串口接收数据 //bydataList:数据队列 //wLen:数据队列长度 quint8 Ps::PsReceiveData(QByteArray bydataList, quint16 wLen){ quint8 byFlag = 0; quint8 byData = 0; quint16 wListLen = 0; quint16 wConsumeIndex = 0; quint16 wCounter = 0; quint8 byHeadTailFlag = 0; //按帧缓存数据 for(quint16 i = 0; i < wLen; i++){ byData = bydataList.at(i); if(byData == PS_AP_HEAD_FLAG){ if(!m_stDataBuf.byHeadFlag){ m_stDataBuf.byHeadFlag = 1; m_stDataBuf.byTailFlag = 0; m_stDataBuf.wFrameHeadIndex = m_stDataBuf.wGenerateIndex;//保存帧头 }else{ m_stDataBuf.byTailFlag = 1; } m_stDataBuf.abyDataList[m_stDataBuf.wGenerateIndex] = byData; m_stDataBuf.wGenerateIndex++; m_stDataBuf.wListLen++; if(m_stDataBuf.wGenerateIndex>= PS_FRAME_MAX_LEN){ m_stDataBuf.wGenerateIndex = 0; } }else{ if(m_stDataBuf.byHeadFlag){ m_stDataBuf.abyDataList[m_stDataBuf.wGenerateIndex] = byData; m_stDataBuf.wGenerateIndex++; m_stDataBuf.wListLen++; if(m_stDataBuf.wGenerateIndex>= PS_FRAME_MAX_LEN){ m_stDataBuf.wGenerateIndex = 0; } }else{ byFlag = 0; } } } //缓存中没有一帧完整的数据 if(!m_stDataBuf.byHeadFlag || !m_stDataBuf.byTailFlag){ return 0; } //抽取数据帧 wListLen = m_stDataBuf.wListLen; wConsumeIndex = m_stDataBuf.wFrameHeadIndex; while(byHeadTailFlag<2){ byData = m_stDataBuf.abyDataList[wConsumeIndex]; if(byData == PS_AP_HEAD_FLAG){ byHeadTailFlag++; m_abyPsMsg[wCounter] = byData; wCounter++; }else{ if(byHeadTailFlag==1){ m_abyPsMsg[wCounter] = byData; wCounter++; } } wConsumeIndex++; if(wConsumeIndex >= PS_FRAME_MAX_LEN){ wConsumeIndex = 0; } } m_stDataBuf.wConsumeIndex = wConsumeIndex; m_stDataBuf.wListLen -= wCounter; m_stDataBuf.byHeadFlag = 0; m_stDataBuf.byTailFlag = 0; //把该帧数据发送给协议栈上行主控单元 byFlag = PsUlMain(m_abyPsMsg, wCounter); if(!byFlag){ memset(m_abyPsMsg, 0, PS_FRAME_MAX_LEN); return 0; } memset(m_abyPsMsg, 0, PS_FRAME_MAX_LEN); return 1; } //协议栈上行主模块 quint8 Ps::PsUlMain(quint8 *pbyData, quint16 wLen){ quint8 byFlag = 0; quint16 wNewLen = wLen; PS_HEAD_T *pstHead = (PS_HEAD_T*)pbyData; quint8 *pbyPayload = NULL; //AP层处理 byFlag = PsUlAp(pbyData, &wNewLen); if(!byFlag){ return 0; } pbyPayload = (quint8*)(pbyData + sizeof(PS_HEAD_T)); //VP层解析 if (MCP_A == pstHead->stVpHead.byMcpType){ // MCP-A switch (pstHead->stVpHead.byVpFlag){ case (quint8)VP_RESP: //应答 //判断是查询应答还是设置应答 if(pstHead->stMcpHead.byComd == (quint8) MCP_A_QUERY){//查询应答 if(pstHead->stMcpHead.byResp == (quint8)MCP_RESP_SUCC){//查询成功 emit PsUlRespSignalQueryOk(pbyPayload, (wNewLen - PS_FRAME_MIN_LEN)); }else{//查询失败 emit PsUlRespSignalQueryFail(); } }else if(pstHead->stMcpHead.byComd == (quint8) MCP_A_CONFIGURE){//设置应答 if(pstHead->stMcpHead.byResp == (quint8)MCP_RESP_SUCC){//设置成功 emit PsUlRespSignalConfigOk(pbyPayload, (wNewLen - PS_FRAME_MIN_LEN)); }else{//设置失败 emit PsUlRespSignalConfigFail(); } } break; default: byFlag = 0; break; } } else if (MCP_B == pstHead->stVpHead.byMcpType){// MCP-B(设备在线升级) switch (pstHead->stVpHead.byVpFlag){ case (quint8)VP_RESP: //应答 if(pstHead->stMcpHead.byResp == (quint8)MCP_RESP_SUCC){//应答成功 emit PsUlRespSignalUpgradeSuccess(pbyPayload); }else{//应答失败 emit PsUlRespSignalUpgradeFail(); } break; default: byFlag = 0; break; } byFlag = 1; } else{ // 监控控制层协议类型错误 byFlag = 0; } return 1; } //AP层处理主函数 //pbyData:数据 //wLen:数据长度 quint8 Ps::PsUlAp(quint8 *pbyData, quint16 *pwLen){ quint8 byFlag = 0; PS_HEAD_T *pstPsHead = (PS_HEAD_T*)pbyData;//帧头 PS_TAIL_T *pstPsTail = NULL;//帧尾 quint16 wNewLen = *pwLen; quint16 wCrc = 0; //判断帧头 if(pstPsHead->stApHead.byStartFlag != PS_AP_HEAD_FLAG){ return 0; } //转义逆向处理 byFlag = psApTransferReverse(pbyData, &wNewLen); if(!byFlag){ return byFlag; } //判断帧头 pstPsTail = (PS_TAIL_T*)(pbyData + (wNewLen - 3));//帧尾 if(pstPsTail->byStopFlag != PS_AP_TAIL_FLAG){ return 0; } //检查CRC校验 wCrc =PsApGenCrc16((pbyData+1), (wNewLen - 4), 0); if(pstPsTail->wCRC != wCrc){ return 0; } *pwLen = wNewLen;//队列长度 return 1; } // 对数据进行转义处理 // pbyData: 待转义数据 // wLen: 数据长度 quint8 Ps::psApTransfer(quint8 *pbyData, quint16 *wLen) { quint16 i = 0; quint16 wCounter = 0; // 转移处理 memset(m_abyTempData, 0, PS_FRAME_MAX_LEN); for (i = 1; i < (*wLen - 1); i++) { if (0x5E == pbyData[i]) // 将0x5E转义成0x5E,0x5D { m_abyTempData[wCounter] = 0x5E; wCounter++; m_abyTempData[wCounter] = 0x5D; wCounter++; } else if (0x7E == pbyData[i]) // 将0x7E转义成0x5,E0x7D { m_abyTempData[wCounter] = 0x5E; wCounter++; m_abyTempData[wCounter] = 0x7D; wCounter++; } else // 其它字符直接拷贝,不做转义处理 { m_abyTempData[wCounter] = pbyData[i]; wCounter++; } // 长度超长 if ((wCounter + 2) > PS_FRAME_MAX_LEN) { return 0; } } // 将数据拷贝回pbyData中 for (i = 0; i < wCounter; i++) { pbyData[i + 1] = m_abyTempData[i]; } pbyData[wCounter + 1] = pbyData[0]; // 保存结尾字符 *wLen = wCounter + 2; return 1; } //对输入数据实施转义逆向操作 //pbyData:待逆转义数据 //wLen:数据长度 quint8 Ps::psApTransferReverse(quint8 *pbyData, quint16 *wLen) { quint16 i = 0; quint16 wCounter = 0; // 逆向转义处理 memset(m_abyTempData, 0, PS_FRAME_MAX_LEN); for (i = 1; i < (*wLen - 1); i++) { if ((0x5E == pbyData[i]) && (0x5D == pbyData[i + 1])) //处理0x5E和0x5D两个连续字符 { m_abyTempData[wCounter] = 0x5E; i++; wCounter++; } else if ((0x5E == pbyData[i]) && (0x7D == pbyData[i + 1])) //处理0x5E和0x7D两个连续字符 { m_abyTempData[wCounter] = 0x7E; i++; wCounter++; } else /*处理其它字符*/ { m_abyTempData[wCounter] = pbyData[i]; wCounter++; } //数据过长退出转移处理 if ((wCounter + 2) > PS_FRAME_MAX_LEN) { return 0; } } // 将保存在abyTmp中的临时数据拷贝回pbyData指针中 for (i = 0; i < wCounter; i++) { pbyData[i + 1] = m_abyTempData[i]; } pbyData[wCounter + 1] = pbyData[0]; // 保存结束标识符 *wLen = wCounter + 2; return 1; } //生成CRC16校验码 quint16 Ps::PsApGenCrc16(quint8 *data, quint16 len, quint16 def_crc) { quint16 crc = def_crc; quint8 crc_h4; quint8 *ptr = data; while (len--) { crc_h4 = (quint8)(crc >> 12); crc <<= 4; crc ^= s_crc_table[crc_h4 ^ (*ptr >> 4)]; crc_h4 = (quint8)(crc >> 12); crc <<= 4; crc ^= s_crc_table[crc_h4 ^ (*ptr & 0x0f)]; ptr++; } return crc; } //产生AP层报文 //byMcpType:1:MCPA,2:MCPB //byMsgType:通信报文,MCPA包括(0x01:上报,0x02:配置,0x03:查询),MCPB包括(0x80:升级控制命令,0x81:升级文件传输命令) //pbyData:载荷数据 //wLen:载荷数据长度 //pbyApFrame:AP层帧 //pwApFrameLen:AP层帧长度 quint8 Ps::PsGenApMsg(quint8 byMcpType, quint8 byMsgType, quint8 *pbyData, quint16 wLen, quint8 *pbyApFrame,quint16 *pwApFrameLen){ quint8 byFlag = 0; quint16 wApFrameLen = wLen + PS_FRAME_MIN_LEN; quint8 *pbyDataHead = pbyApFrame; PS_HEAD_T stHead; PS_TAIL_T stTail; quint16 wCrc = 0; //AP头 stHead.stApHead.byStartFlag = PS_AP_HEAD_FLAG; //VP头 stHead.stVpHead.dwProjectId = 0; stHead.stVpHead.byPacketNo = m_byPacketNo; stHead.stVpHead.dwDeviceId = 0; stHead.stVpHead.byVpFlag = VP_CMMD; stHead.stVpHead.byMcpType = byMcpType; //MCP头 stHead.stMcpHead.byComd = byMsgType; stHead.stMcpHead.byResp = MCP_CMD; //保存协议头数据 memcpy(pbyDataHead, &stHead, sizeof(PS_HEAD_T)); pbyDataHead += sizeof(PS_HEAD_T); //组织协议载荷 memcpy(pbyDataHead, pbyData, wLen); pbyDataHead += wLen; //组织协议尾 wCrc = PsApGenCrc16((pbyApFrame+1), (wApFrameLen - 4), 0);//生成CRC校验码 stTail.wCRC = wCrc; stTail.byStopFlag = PS_AP_TAIL_FLAG; memcpy(pbyDataHead, &stTail, sizeof(PS_TAIL_T)); //实施转义处理 byFlag = psApTransfer(pbyApFrame, &wApFrameLen); if(!byFlag){ return byFlag; } *pwApFrameLen = wApFrameLen;//新队列长度 return m_byPacketNo;//当前通信包号 } //产生升级报文 //byMsgType:通信报文,0x80:升级控制命令,0x81:升级文件传输命令 quint8 Ps::PsGenUpgradeMsg(quint8 byMsgType, quint8 *pbyData, quint16 wLen, quint8 *pbyOamData){ quint8 *pbyAddress = pbyOamData; PS_HEAD_T stHead; PS_TAIL_T stTail; //组织协议头 //m_byPacketNo++; stHead.stApHead.byStartFlag = PS_AP_HEAD_FLAG; stHead.stVpHead.byPacketNo = m_byPacketNo; stHead.stVpHead.byVpFlag = VP_CMMD; stHead.stVpHead.byMcpType = MCP_B; stHead.stMcpHead.byComd = byMsgType; stHead.stMcpHead.byResp = MCP_CMD; memcpy(pbyAddress, &stHead, sizeof(PS_HEAD_T)); pbyAddress = pbyAddress + sizeof(PS_HEAD_T); //组织协议载荷 memcpy(pbyAddress, pbyData, sizeof(quint8)*wLen); pbyAddress = pbyAddress + wLen; //组织协议尾 stTail.wCRC = 0; stTail.byStopFlag = PS_AP_TAIL_FLAG; memcpy(pbyAddress, &stTail, sizeof(PS_TAIL_T)); return m_byPacketNo;//当前通信包号 }