#pragma once #include "stdafx.h" #include "CommonFun.h" //map比较函数 #if 0 //有的设备指令ID并非统一长度,所以自定义map的key的比较规则 template <> struct std::less { public: bool operator()(const std::string& p1, const std::string& p2) const { if (p1.at(0) == FullUCB_Com_STX) { mLog::FDEBUG("less1:[{$}][{$}]", p1.c_str(), p2.c_str()); int smallLengh = p1.length() <= p2.length() ? p1.length() : p2.length(); int res = p1.compare(1, smallLengh, p2, 0, smallLengh); if (res < 0) return true; else return false; } else if (p2.at(0) == FullUCB_Com_STX) { mLog::FDEBUG("less2:[{$}][{$}]", p1.c_str(), p2.c_str()); int smallLengh = p1.length() <= p2.length() ? p1.length() : p2.length(); int res = p1.compare(0, smallLengh, p2, 1, smallLengh); if (res < 0) return true; else return false; } else { return p1 < p2; } } }; #endif namespace DIOS::Dev::Detail::SYNBOX { /* 指令编码格式: +命令头(0x3A) +命令对象(S表示同步盒,P表示电脑,其他的的再定) +命令字节(由2个字节组合形成) +数据格式(‘A’表示ASIIC码,‘B’表示二进制码,‘C’表示混合或其他模式) +数据长度(由2个字节组合,数据区可以(0~255)) +数据区(根据数据长度发送的结果或数据) +校验和(由2个字节组成,详见注1) +结束位1(0x0D)+结束位2(0x0A) */ //校验和计算 //校验和:等于其前面的几个字节的总和%256,例如算出的校验和等于0X1A,我们发送的校验和为0x31和0X41 int CalChecksum(const char* cCmd, int nCmdSize) { int nSum = 0; for (int i = 0; i < nCmdSize; ++i) { nSum += cCmd[i]; } return nSum % 256; } //指令格式化 bool FormatCmd(char* cCmd, int& nSize) { if (nSize < 6 || nSize > FullUCB_Com_NormalLen - 1) { return false; } char temp[FullUCB_Com_NormalLen]{0}; temp[0] = FullUCB_Com_STX; for (int i = 0; i < nSize; ++i) { temp[i+1] = toupper(cCmd[i]); } nSize++; int nsum = CalChecksum((char*)temp, nSize); char strSum[3]{0}; sprintf_s(strSum, "%02X", nsum); temp[nSize] = strSum[0]; nSize++; temp[nSize] = strSum[1]; nSize++; temp[nSize] = FullUCB_Com_ETX; nSize++; temp[nSize] = FullUCB_Com_EOT; nSize++; memcpy((void*)cCmd, (void*)temp, nSize); return true; } //把指令转成字符串用以日志输出 bool CmdtoString(const char* cCmd, int nCmdSize, std::string& strCmd) { std::string strTemp; strCmd.clear(); for (int i = 0; i < nCmdSize; i++) { strTemp = ""; if ((cCmd[i] == '\r') || (cCmd[i] == '\n') || (cCmd[i] == ':')) // strTemp = ""; else strTemp = toupper(cCmd[i]); strCmd += strTemp; } return true; } //目标字符串按指定分隔符截取第一个目标字段 std::string GetContentFromString(std::string& strContent, char ch) { std::string strTemp; int nPos = strContent.find(ch); if (nPos == std::string::npos) { strTemp = strContent; strContent.clear(); } else { strTemp = strContent.substr(0, nPos); strContent = strContent.substr(nPos + 1, strContent.length() - nPos - 1); } return strTemp; } //尝试按16进制解读字符串,并将解读成功的部分转换为10进制返回 //例如str="169acegh12547",则会解读出"169ace",返回 1481422 int String2Hex(std::string str) { int base = 16; char* entptr; int nRes = strtol(str.c_str(), &entptr, base); return nRes; } //Hex字符转化到Int int ChartoInt(char uc) { int nValue; if ('0' <= uc && uc <= '9') { nValue = uc - '0'; } else if ('A' <= uc && uc <= 'F') { nValue = 10 + uc - 'A'; } else if ('a' <= uc && uc <= 'f') { nValue = 10 + uc - 'a'; } else { nValue = -1; } return nValue; } //Hex字符转化到Int int HexUCtoInt(UCHAR uc) { int nValue; if ('0' <= uc && uc <= '9') { nValue = uc - '0'; } else if ('A' <= uc && uc <= 'F') { nValue = 10 + uc - 'A'; } else if ('a' <= uc && uc <= 'f') { nValue = 10 + uc - 'a'; } else { nValue = -1; } return nValue; } //Int转化成Hex字符 char InttoHexUC(int ni) { char c; string str; if (ni < 0 || ni > 15) { c = 0x20; } else { str = std::format("%X", ni); c = str.at(0); } return c; } //串口指令映射表 tFrameMapping::tFrameMapping() { m_eOverType = OverType_directly; m_bLogFlag = false; m_fFun = NULL; m_nWaitTime = 0; m_hAckEvent = NULL; } tFrameMapping::tFrameMapping(cmdFun fun, CMDOverType type, bool logFlag, int waitTime) { m_bLogFlag = logFlag; switch (type) { case OverType_directly: { m_eOverType = OverType_directly; m_nWaitTime = 0; m_hAckEvent = NULL; } break; case OverType_WaitTime: { m_eOverType = OverType_WaitTime; m_nWaitTime = waitTime; m_hAckEvent = NULL; } break; case OverType_WaitACK: { m_eOverType = OverType_WaitACK; m_nWaitTime = 0; m_hAckEvent = CreateEvent(NULL, TRUE, FALSE, NULL); } break; default: break; } m_fFun = fun; } tFrameMapping::~tFrameMapping() { CloseHandle(m_hAckEvent); m_fFun = NULL; } tFrameMapping& tFrameMapping::operator =(const tFrameMapping& value) { m_eOverType = value.m_eOverType; m_bLogFlag = value.m_bLogFlag; m_fFun = value.m_fFun; m_nWaitTime = value.m_nWaitTime; m_hAckEvent = CreateEvent(NULL, TRUE, FALSE, NULL); return *this; } void tFrameMapping::tSetWaitState(const char* CMD) { switch (m_eOverType) { case OverType_directly: { if (m_bLogFlag) { if (CMD != NULL) mLog::FDEBUG("tSetWaitState:[{$}]Exit directly", CMD); else mLog::FDEBUG("tSetWaitState:Exit directly"); } } break; case OverType_WaitTime: { if (m_bLogFlag) { if (CMD != NULL) mLog::FDEBUG("tSetWaitState:[{$}]wait[{$}]ms", CMD, m_nWaitTime); else mLog::FDEBUG("tSetWaitState:wait[{$}]ms", m_nWaitTime); } Sleep(m_nWaitTime); } break; case OverType_WaitACK: { if (m_bLogFlag) { if (CMD != NULL) mLog::FDEBUG("tSetWaitState:[{$}]wait AckEvent 500ms", CMD); else mLog::FDEBUG("tSetWaitState:wait AckEvent 500ms"); } DWORD reasult = WaitForSingleObject(m_hAckEvent, 500); if (WAIT_OBJECT_0 == reasult) { if (m_bLogFlag) { if (CMD != NULL) mLog::FDEBUG("tSetWaitState:[{$}]wait AckEvent successful", CMD); else mLog::FDEBUG("tSetWaitState:wait AckEvent successful"); } //ResetEvent(m_hAckEvent); } else if (WAIT_TIMEOUT == reasult) { if (m_bLogFlag) { if (CMD != NULL) mLog::FWARN("tSetWaitState:[{$}]wait AckEvent timeout", CMD); else mLog::FWARN("tSetWaitState:wait AckEvent timeout"); } } } break; default: break; } } void tFrameMapping::tCheckWaitState(const char* CMD) { switch (m_eOverType) { case OverType_directly: { if (m_bLogFlag) { if (CMD != NULL) mLog::FDEBUG("tCheckWaitState:[{$}]Exit directly", CMD); else mLog::FDEBUG("tCheckWaitState:Exit directly"); } } break; case OverType_WaitTime: { if (m_bLogFlag) { if (CMD != NULL) mLog::FDEBUG("tCheckWaitState:[{$}]wait ms", CMD); else mLog::FDEBUG("tCheckWaitState:wait ms"); } } break; case OverType_WaitACK: { if (m_bLogFlag) { if (CMD != NULL) mLog::FDEBUG("tCheckWaitState:[{$}]activate AckEvent", CMD); else mLog::FDEBUG("tCheckWaitState:activate AckEvent"); } //SetEvent(m_hAckEvent); PulseEvent(m_hAckEvent); } break; default: break; } } //----------------------------------------------------------------------------- // DecodeFrame //----------------------------------------------------------------------------- std::map arFrame; bool DecodeFrame(const char* strFrame, int length) { string data(strFrame+1, 3); auto found = arFrame.find(data); if (found == arFrame.end()) { mLog::FERROR("DecodeFrame:not find[{$}]", data.c_str()); return false; } //found->second.tCheckWaitState(strFrame); found->second.m_fFun(strFrame, length-4);//第二个参数 不重要 return true; } bool SetWaitAction(const char* strFrame) { char data[4] = { 0 }; strncpy_s(data, strFrame+1, 3); auto found = arFrame.find(data); if (found == arFrame.end()) { mLog::FWARN("SetWaitAction:[{$}] not find", strFrame); return false; } found->second.tSetWaitState(strFrame); return true; } bool CheckWaitState(const char* strFrame) { char data[4] = { 0 }; strncpy_s(data, strFrame+1, 3); auto found = arFrame.find(data); if (found == arFrame.end()) { mLog::FWARN("CheckWaitState:[{$}] not find", strFrame); return false; } found->second.tCheckWaitState(strFrame); return true; } }