Browse Source

解析函数:解析串口返回结果。

Jeff 4 năm trước cách đây
mục cha
commit
366edd148a
3 tập tin đã thay đổi với 94 bổ sung71 xóa
  1. 0 1
      Serail-Demo/Demo/Demo.cpp
  2. 79 69
      Serail-Demo/Demo/stdafx.cpp
  3. 15 1
      Serail-Demo/Demo/stdafx.h

+ 0 - 1
Serail-Demo/Demo/Demo.cpp

@@ -15,7 +15,6 @@ CWinApp theApp;
 
 using namespace std;
 
-extern VOID _dprintf(CHAR* pszStr, ...);
 int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
 {
 	int nRetCode = 0;

+ 79 - 69
Serail-Demo/Demo/stdafx.cpp

@@ -7,7 +7,7 @@
 // TODO: 在 STDAFX.H 中
 // 引用任何所需的附加头文件,而不是在此文件中引用
 
-VOID _dprintf(CHAR* pszStr, ...)
+std::string _dprintf(CHAR* pszStr, ...)
 {
 	const int LOGLEN = 3072;
 	char szData[LOGLEN] = { 0 };
@@ -32,6 +32,8 @@ VOID _dprintf(CHAR* pszStr, ...)
 		strcat_s(szData, "\n");
 #endif
 	OutputDebugStringA(szData);
+
+	return std::string(szData);
 }
 
 bool parse_key(std::string &RetValue, std::string strLine, TCHAR *lpszText)
@@ -386,15 +388,15 @@ std::string PackingCommand(CommandParam &cmdPara, std::string data, const int &d
 
 #define NoneOptLen 5
 
-void TheFirstPart(CommandParam& cmdPara, std::string data, const int& dataLen)
+bool TheFirstPart(CommandParam& cmdPara, std::string data)
 {
 	if (data.size() == NoneOptLen) {
 		if (data[0] == cmdPara._rtnCode) {
 			// 长度;
 			int nPackageLen = data[1];
 			if (nPackageLen != NoneOptLen) {
-				_dprintf("None长度错误:%ld", data[1]);
-				return;
+				cmdPara._rtnError = _dprintf("None长度错误:%ld", data[1]);
+				return false;
 			}
 
 			// 执行状态;
@@ -405,88 +407,96 @@ void TheFirstPart(CommandParam& cmdPara, std::string data, const int& dataLen)
 			unsigned short usCRCValue = CRC16Calculate((unsigned char*)data.data(), nPackageLen - 2);
 			if (((usCRCValue >> 8) & 0xFF) != (unsigned char)data[nPackageLen - 2] || (usCRCValue & 0xFF) != (unsigned char)data[nPackageLen - 1])
 			{
-				_dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, data[nPackageLen - 2], data[nPackageLen - 1]);
-				return;
+				cmdPara._rtnError = _dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, data[nPackageLen - 2], data[nPackageLen - 1]);
+				return false;
 			}
 		}
 		else {
-			_dprintf("返回码错误:%02X", data[0]);
+			cmdPara._rtnError = _dprintf("返回码错误:%02X", data[0]);
+			return false;
 		}
 	}
 	else {
-		_dprintf("长度对不上:Option.None");
+		cmdPara._rtnError = _dprintf("长度对不上:Option.None");
+		return false;
 	}
-}
-
-void TheSecondPart(CommandParam& cmdPara, std::string data, const int& dataLen)
-{
 
+	return true;
 }
 
-void ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen)
+bool TheSecondPart(CommandParam& cmdPara, std::string data)
 {
-	// Tag:[返回头][全数据长度][返回码]<返回码子项><附加数据>[crc1][crc2]
-	if ( data.size() < 5) {
-		return;
-	}
-
-	byte rtnCode = 0xAB;
-	std::string head = cmdPara.head.substr(0, 2);
-	if ( !_tcsicmp(_T("AA"), head.c_str()) ) { // 调试用命令代码引导码;
-		rtnCode = 0xAB;
-	}
-	else if (!_tcsicmp(_T("AC"), head.c_str())) { // 软件配屏参数调整命令代码引导码;
-		rtnCode = 0xAD;
-	}
-	else if (!_tcsicmp(_T("AE"), head.c_str())) { // 保留命令发送类型引导码;
-		rtnCode = 0xAF;
-	}
-
-	int nTakenLen = 0;				// 已取出的长度;
-	unsigned short usCRCValue;		// CRC验证值;
-	// 一个完整的包段;
+	int nDataPos = 0;
 	int nPackageLen = 0;
-	std::string packaged;
-
-	// None可以看作是第一段数据包;
-	if ( cmdPara.nOption == CMDOPT::CMDOPT_None ) {
-		if ( data.size() == NoneOptLen) {
-			if (data[0] == rtnCode) {
-				if (data[1] == 0xFE) { // None中不应该出现,配置出错;
-					_dprintf("类型配置错误:%02X %02X", data[0], data[1]);
-					return;
-				}
-
-				// 长度;
-				nPackageLen = data[1];
-				if (nPackageLen != NoneOptLen) {
-					_dprintf("None长度错误:%ld", data[1]);
-					return;
-				}
-
-				// 执行状态;
-
-				// 校验crc;
-				usCRCValue = CRC16Calculate((unsigned char*)data.data(), nPackageLen - 2);
-				if (((usCRCValue >> 8) & 0xFF) != (unsigned char)data[nPackageLen - 2] || (usCRCValue & 0xFF) != (unsigned char)data[nPackageLen - 1])
-				{
-					_dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, data[nPackageLen - 2], data[nPackageLen - 1]);
-					return;
-				}
+	if (data[0] == cmdPara._rtnCode) {
+		// 获取长度;
+		if ( data[1] == 0xFE ) {
+			nDataPos = 4;
+			nPackageLen = data[2] << 8 | data[3];
+			if ( data.size() < 255 && data[2] != 0 ) {	
+				cmdPara._rtnError = _dprintf(_T("长度异常"));
+				return false;
 			}
-			else {
-				_dprintf("返回码错误:%02X", data[0]);
+		}
+		else
+		{
+			nDataPos = 2;
+			nPackageLen = data[1];
+#if 0 // 如果数据包含有非协议包内的数据,会判断异常;
+			if ( data.size() > 255 ){	
+				//nPackageLen = data[1] << 8 | data[2];
+				cmdPara._rtnError = _dprintf(_T("长度异常"));
+				return false;
 			}
-		} else {
-			_dprintf("长度对不上:Option.None");
+#endif
 		}
-	}
-	else if ( cmdPara.nOption == CMDOPT::CMDOPT_Get )
-	{
 
+#if 0
+		// 计算出的长度,必等于包长;// 如果包含有其他非包数据,会判断异常;
+		if ( nPackageLen != data.size() )
+			return false;
+#endif
+
+		// 执行状态;
+		cmdPara._rtnData = data.substr(nDataPos, nPackageLen - nDataPos - 2); //2=crc;
+		_dprintf(_T("rtnData=%s"), cmdPara._rtnData.c_str());
+
+		// 校验crc;
+		unsigned short usCRCValue = CRC16Calculate((unsigned char*)data.data(), nPackageLen - 2);
+		if (((usCRCValue >> 8) & 0xFF) != (unsigned char)data[nPackageLen - 2] || (usCRCValue & 0xFF) != (unsigned char)data[nPackageLen - 1])
+		{
+			cmdPara._rtnError = _dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, data[nPackageLen - 2], data[nPackageLen - 1]);
+			return false;
+		}
+
+#if 1
+		if ( data.size() > nPackageLen )
+			_dprintf("带有脏数据:%s", data.substr(nPackageLen));
+#endif
+	}
+	else {
+		cmdPara._rtnError = _dprintf("返回码错误:%02X", data[0]);
+		return false;
 	}
-	else if ( cmdPara.nOption == CMDOPT::CMDOPT_Set )
-	{
 
+	return true;
+}
+
+void ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen)
+{
+	// Tag:[返回头][全数据长度][返回码]<返回码子项><附加数据>[crc16]
+	if ( !TheFirstPart(cmdPara, data.substr(0, 5)) )
+		return;
+
+	switch ( cmdPara.nOption )
+	{
+	case CMDOPT_None:
+		break;
+	case CMDOPT_Get:
+	case CMDOPT_Set:
+		TheSecondPart(cmdPara, data.substr(5));
+		break;
+	default:
+		break;
 	}
 }

+ 15 - 1
Serail-Demo/Demo/stdafx.h

@@ -53,6 +53,7 @@ typedef struct __CMDPARAM__ {
 	byte _rtnCode;
 	byte _rtnStatus;
 	std::string _rtnData;
+	std::string _rtnError;
 	void UpdateRtnCode()
 	{
 		if (!_tcsicmp(_T("AA"), head.c_str())) { // µ÷ÊÔÓÃÃüÁî´úÂëÒýµ¼Âë;
@@ -66,6 +67,19 @@ typedef struct __CMDPARAM__ {
 		}
 	}
 
+	void Clean()
+	{
+		//_rtnCode = 0;
+		_rtnStatus = 0;
+#if _MSC_VER >= 1200 && _MSC_VER < 1500
+		_rtnData = "";
+		_rtnError = "";
+#elif _MSC_VER >= 1500
+		_rtnData.clear();
+		_rtnError.clear();
+#endif
+	}
+
 	__CMDPARAM__() {
 		_rtnCode = 0;
 		_rtnStatus = 0;
@@ -76,7 +90,7 @@ typedef struct __CMDPARAM__ {
 	}
 } CommandParam, *pCommandParam;
 
-VOID _dprintf(CHAR* pszStr, ...);
+std::string _dprintf(CHAR* pszStr, ...);
 int pares_time_value(std::string strTime);
 bool parse_key(std::string &value, std::string strLine, TCHAR *lpszText);
 int parse_cmd_param_from_file(TCHAR*file_name, std::vector<CommandParam> &vtCommandParams);