123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- #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<MainDlg*>(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;//当前通信包号
- }
|