| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 | #include "StdAfx.h"#include "PktAssembleBuff.h"#include <CSM315Protocol.h>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;//}
 |