#include "StdAfx.h" #include "PktAssembleBuff.h" #include void PktAssembleBuff::Resize(BYTE*& pData, int& iLen, int iNewSize) { //拷贝原始数据 BYTE* pNewData = new (std::nothrow)BYTE[iNewSize]; if (pData && iLen && pNewData) memcpy_s(pNewData, iNewSize, pData, min(iLen, iNewSize)); delete[] pData; //修改缓存对象 pData = pNewData; iLen = pNewData == nullptr ? 0 : iNewSize; } void PktAssembleBuff::ResizeStreamBuff(int iNewSize) { Resize(m_tcpStreamData, m_iStreaBuffSize, iNewSize); } void PktAssembleBuff::ResizePopPktBuff(int iNewSize) { Resize(pkt, iPktBuffSize, iNewSize); } void PktAssembleBuff::PushStream(BYTE* pData, int iLen) { if (m_tcpStreamData == nullptr) { m_iStreaBuffSize = 0; m_iStreamLen = 0; } if (m_iStreamLen + iLen > m_iStreaBuffSize) ResizeStreamBuff(m_iStreamLen + iLen); memcpy_s(m_tcpStreamData + m_iStreamLen, m_iStreaBuffSize, pData, iLen); m_iStreamLen += iLen; } BOOL PktAssembleBuff::PopPkt(APP_LAYER_PROTO_TYPE cpt) { if (m_tcpStreamData == nullptr) { m_iStreamLen = 0; m_iStreaBuffSize = 0; return FALSE; } for (int i = 0; i < m_iStreamLen; i++) { int ilen = 0; //if (ilen == 0 && // (cpt == PROTOCOL_UNKNOWN || cpt == PROTOCOL_DSP)) //{ // ilen = IsValidPkt_DSP(m_tcpStreamData + i, m_iStreamLen - i); // if (ilen > 0) // { // m_protocolType = PROTOCOL_DSP; // } //} if (ilen == 0 && (cpt == PROTOCOL_UNKNOWN || cpt == PROTOCOL_315)) { ilen = IsValidPkt_315(m_tcpStreamData + i, m_iStreamLen - i); if (ilen > 0) { m_protocolType = PROTOCOL_315; } } //if (ilen == 0 && // (cpt == PROTOCOL_UNKNOWN || cpt == PROTOCOL_JEP)) //{ // ilen = IsValidPkt_JEP(m_tcpStreamData + i, m_iStreamLen - i); // if (ilen > 0) // { // m_protocolType = PROTOCOL_JEP; // } //} //if (ilen == 0 && // (cpt == PROTOCOL_UNKNOWN || cpt == PROTOCOL_MODBUS_RTU)) //{ // //modbus数据每一次回调pushStream都认为是完整包。如果校验失败,则为错误数据,因此不在每一个位置上进行modbus校验 // //modbus的通讯方式是发送前清空AssenbleBuff,并认为回调回来的一定是完整包,因此只对整个buff进行一次校验 // if (i == 0) // { // ilen = IsValidPkt_ModbusRTU(m_tcpStreamData + i, m_iStreamLen - i); // if (ilen > 0) // { // m_protocolType = PROTOCOL_MODBUS_RTU; // } // } //} //if (ilen == 0 && // (cpt == PROTOCOL_UNKNOWN || cpt == PROTOCOL_JDSP)) //{ // if (i == 0) // { // ilen = IsValidPkt_JDSP(m_tcpStreamData + i, m_iStreamLen - i); // if (ilen > 0) // { // m_protocolType = PROTOCOL_JDSP; // } // } //} //if (ilen == 0 && // (cpt == PROTOCOL_WEBSOCKET)) //{ // if (i > 0) // break; // ilen = IsValidPkt_WEBSOCKET(m_tcpStreamData + i, m_iStreamLen - i); // if (ilen > 0) // { // m_protocolType = PROTOCOL_WEBSOCKET; // } //} //如果成功检测到包,拷贝出包数据。从原始的stream的buff中删除 if (ilen) { if (ilen > iPktBuffSize) ResizePopPktBuff(ilen); //拷贝有效包到输出pkt memcpy_s(pkt, iPktBuffSize, m_tcpStreamData + i, ilen); iPktLen = ilen; //从组包缓冲中删除提取出的包 和 包前面的无效数据 memcpy_s(m_tcpStreamData, m_iStreaBuffSize, m_tcpStreamData + i + ilen, m_iStreamLen - i - ilen); m_iStreamLen -= i + ilen; iAbandonBytes += i; //释放无用的内存 ResizeStreamBuff(m_iStreamLen); return TRUE; } } return FALSE; } BOOL PktAssembleBuff::PopAllAs(APP_LAYER_PROTO_TYPE cpt) { if (m_iStreamLen > iPktBuffSize) ResizePopPktBuff(m_iStreamLen); memcpy_s(pkt, m_iStreamLen, m_tcpStreamData, m_iStreamLen); iPktLen = m_iStreamLen; m_iStreamLen = 0; ResizeStreamBuff(m_iStreamLen); m_protocolType = cpt; if (iPktLen > 0) return 1; return 0; } // //int PktAssembleBuff::IsValidPkt_DSP(BYTE* pData, int iLen) //{ // if (iLen < 26)//dsp协议数据包最短长度 // return 0; // // if (pData[0] != 0x55 || pData[1] != 0xBB) // return 0; // // const DWORD len = *((DWORD*)(pData + 2)); // // if (len + 6 > iLen) // return 0; // // if (pData[len + 4] != 0xAA) // return 0; // // return (len + 6); //} int PktAssembleBuff::IsValidPkt_315(BYTE* pData, int iLen) { if (iLen < 16) return 0;//315协议数据包最短长度 if (pData[0] != 0x71 || pData[1] != 0x6B || pData[2] != 0x6E || pData[3] != 0x65 || pData[4] != 0x74) return 0;//帧头校验 if (pData[5] != 0x02 && pData[5] != 0x80) return 0; auto a = pData[7]; if (a != FRAME_TYPE_DATA && a != FRAME_TYPE_HEARTBEAT) return 0; //2023.5.18 新增JSON数据帧 scz DWORD frameLen = *(DWORD*)(pData + 8); if (frameLen + 16 > iLen) return 0; BYTE* pFrameEnd = pData + frameLen + 12; if (pFrameEnd[0] != 0xFF || pFrameEnd[1] != 0xFF || pFrameEnd[2] != 0xFF || pFrameEnd[3] != 0xFF) return 0; return frameLen + 16; } // //int PktAssembleBuff::IsValidPkt_JEP(BYTE* pData, int iLen) //{ // if (iLen < 7)//最短长度 // return 0; // // if (pData[0] != 0x68) // return 0; // // JEP_LEN_REGION* plr = (JEP_LEN_REGION*)(pData + 1); // int icmdlen = plr->dlen; // // if (icmdlen + 7 > iLen) // return 0; // // if (pData[icmdlen + 6] != 0x97) // return 0; // // // BYTE check = 0; // BYTE* pos = (LPBYTE)pData; // for (int i = 0; (UINT)i < 1 + 4 + icmdlen; ++i) // check += pos[i]; // // if (pData[icmdlen + 5] != check) // return 0; // // return icmdlen + 7; //} // //BOOL PktAssembleBuff::Request315Pkt(BYTE cmd, BYTE* pPkt, int& iLen, void* pInData) //{ // pPkt[0] = 0x71; // pPkt[1] = 0x6B; // pPkt[2] = 0x6E; // pPkt[3] = 0x65; // pPkt[4] = 0x74; // // pPkt[5] = 0x02;//协议码 // pPkt[6] = 0x00;//未处理 // pPkt[7] = 0x8F; // // DWORD dwFrameLen = 0; // switch (cmd) // { // case CMD_CODE_GAPCFG: // { // dwFrameLen = 1; // memcpy_s(pPkt + 8, iPktBuffSize - 8, &dwFrameLen, 4); // pPkt[12] = CMD_CODE_GAPCFG; // break; // } // case CMD_CODE_GAPVAL: // { // dwFrameLen = 1; // memcpy_s(pPkt + 8, iPktBuffSize - 8, &dwFrameLen, 4); // pPkt[12] = CMD_CODE_GAPVAL; // break; // } // case CMD_CODE_IMGINFO: // { // dwFrameLen = 11; // memcpy_s(pPkt + 8, iPktBuffSize - 8, &dwFrameLen, 4); // pPkt[12] = CMD_CODE_IMGINFO; // ImgInfoRequest* pInfo = (ImgInfoRequest*)pInData; // memcpy_s(pPkt + 13, iPktBuffSize - 13, &pInfo->iZZJNo, 2); // memcpy_s(pPkt + 15, iPktBuffSize - 15, &pInfo->time, 4); // pPkt[16] = 0; // memset(pPkt + 17, 0xFF, 3); // break; // } // case CMD_CODE_LASTGAPIMG: // { // dwFrameLen = 3; // memcpy_s(pPkt + 8, iPktBuffSize - 8, &dwFrameLen, 4); // pPkt[12] = CMD_CODE_LASTGAPIMG; // LastImgInfoRequest* pInfo = (LastImgInfoRequest*)pInData; // WORD iZZJNo = pInfo->iZZJNo; // memcpy_s(pPkt + 13, iPktBuffSize - 13, &iZZJNo, 2); // break; // } // case CMD_CODE_IMGLIST: // { // dwFrameLen = 19; // memcpy_s(pPkt + 8, iPktBuffSize - 8, &dwFrameLen, 4); // pPkt[12] = CMD_CODE_IMGLIST; // ImgListRequest* pInfo = (ImgListRequest*)pInData; // memcpy_s(pPkt + 13, iPktBuffSize - 13, &pInfo->iZZJNo, 2); // memcpy_s(pPkt + 15, iPktBuffSize - 15, &pInfo->time, 4); // memcpy_s(pPkt + 19, iPktBuffSize - 19, &pInfo->endTime, 4); // memcpy_s(pPkt + 23, iPktBuffSize - 23, &pInfo->imgType, 1); // memset(pPkt + 24, 0xFF, 3); // break; // } // default: // { // return FALSE; // break; // } // } // memset(pPkt + 12 + dwFrameLen, 0xFF, 4); // iLen = dwFrameLen + 16; // return TRUE; //} // //int PktAssembleBuff::IsValidPkt_ModbusRTU(BYTE* pData, int iLen) //{ // if (iLen < 4) // return 0; // // WORD crc1 = *(WORD*)(pData + iLen - 2); // WORD crc2 = GetCRC(pData, iLen - 2); // if (crc1 == crc2) // return iLen; // else // return 0; //} /* int PktAssembleBuff::IsValidPkt_JDSP(BYTE* pData, int iLen) { if (iLen < 26) return 0; char head[30] = { 0 }; memcpy(head, pData, 29); string strHead = head; char tail[30] = { 0 }; memcpy(tail, pData + iLen - 1 - 28, 29); string strTail = tail; if (strHead.find("\"<\"") != std::string::npos) { if (strTail.find("\">\"") != std::string::npos) { return iLen; } } return 0; }*/ //int PktAssembleBuff::IsValidPkt_JDSP(BYTE* pData, int iLen) //{ // if (iLen < 15)//{"<":"",">":""} 至少15个, formated可能会额外有回车 空格字符 // return 0; // if (pData[0] != '{') //头尾先检测,提高大数据包的检测效率,避免不断寻找 > 字符 // return 0; // // //支持两个\r\n分包 // for (int i = 0; i < iLen - 3; i++) // { // if (pData[i] == '\r' && pData[i + 1] == '\n' && pData[i + 2] == '\r' && pData[i + 3] == '\n') // { // return i + 4; // } // } // //支持两个\n分包 // for (int i = 0; i < iLen - 3; i++) // { // if (pData[i] == '\n' && pData[i + 1] == '\n') // { // return i + 2; // } // } // // char* pBuf = new char[iLen + 1]; // memcpy(pBuf, pData, iLen); // pBuf[iLen] = 0;//否则下面这行会有潜在的bug // string strBuf = pBuf; // delete[] pBuf; // string::size_type pos = 0; // if (strBuf.find("\"<\"") != std::string::npos) { // if ((pos = strBuf.find("\">\"")) != std::string::npos) { // string::size_type pos1 = 0; // string strBufTmp = strBuf.substr(pos, iLen - pos); // if ((pos1 = strBufTmp.find("}")) != std::string::npos) { // return (pos + pos1 + 1); // } // } // } // return 0; //} // //int PktAssembleBuff::IsValidPkt_WEBSOCKET(BYTE* pData, int iLen) //{ // CWSPPkt req; // if (WS_ERROR_FRAME != req.UnPackWS((char*)pData, iLen)) // { // return req.iFrmLen; // } // return 0; //}