123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- #pragma once
- #include "stdafx.h"
- #include "CommonFun.h"
- //map比较函数
- #if 0 //有的设备指令ID并非统一长度,所以自定义map的key的比较规则
- template <>
- struct std::less<std::string>
- {
- 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 <std::string, tFrameMapping> 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;
- }
- }
|