CommonFun.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. #pragma once
  2. #include "stdafx.h"
  3. #include "CommonFun.h"
  4. //map比较函数
  5. #if 0 //有的设备指令ID并非统一长度,所以自定义map的key的比较规则
  6. template <>
  7. struct std::less<std::string>
  8. {
  9. public:
  10. bool operator()(const std::string& p1, const std::string& p2) const
  11. {
  12. if (p1.at(0) == FullUCB_Com_STX)
  13. {
  14. mLog::FDEBUG("less1:[{$}][{$}]", p1.c_str(), p2.c_str());
  15. int smallLengh = p1.length() <= p2.length() ? p1.length() : p2.length();
  16. int res = p1.compare(1, smallLengh, p2, 0, smallLengh);
  17. if (res < 0)
  18. return true;
  19. else
  20. return false;
  21. }
  22. else if (p2.at(0) == FullUCB_Com_STX)
  23. {
  24. mLog::FDEBUG("less2:[{$}][{$}]", p1.c_str(), p2.c_str());
  25. int smallLengh = p1.length() <= p2.length() ? p1.length() : p2.length();
  26. int res = p1.compare(0, smallLengh, p2, 1, smallLengh);
  27. if (res < 0)
  28. return true;
  29. else
  30. return false;
  31. }
  32. else
  33. {
  34. return p1 < p2;
  35. }
  36. }
  37. };
  38. #endif
  39. namespace DIOS::Dev::Detail::SYNBOX
  40. {
  41. /*
  42. 指令编码格式:
  43. +命令头(0x3A)
  44. +命令对象(S表示同步盒,P表示电脑,其他的的再定)
  45. +命令字节(由2个字节组合形成)
  46. +数据格式(‘A’表示ASIIC码,‘B’表示二进制码,‘C’表示混合或其他模式)
  47. +数据长度(由2个字节组合,数据区可以(0~255))
  48. +数据区(根据数据长度发送的结果或数据)
  49. +校验和(由2个字节组成,详见注1)
  50. +结束位1(0x0D)+结束位2(0x0A)
  51. */
  52. //校验和计算
  53. //校验和:等于其前面的几个字节的总和%256,例如算出的校验和等于0X1A,我们发送的校验和为0x31和0X41
  54. int CalChecksum(const char* cCmd, int nCmdSize)
  55. {
  56. int nSum = 0;
  57. for (int i = 0; i < nCmdSize; ++i)
  58. {
  59. nSum += cCmd[i];
  60. }
  61. return nSum % 256;
  62. }
  63. //指令格式化
  64. bool FormatCmd(char* cCmd, int& nSize)
  65. {
  66. if (nSize < 6 || nSize > FullUCB_Com_NormalLen - 1)
  67. {
  68. return false;
  69. }
  70. char temp[FullUCB_Com_NormalLen]{0};
  71. temp[0] = FullUCB_Com_STX;
  72. for (int i = 0; i < nSize; ++i)
  73. {
  74. temp[i+1] = toupper(cCmd[i]);
  75. }
  76. nSize++;
  77. int nsum = CalChecksum((char*)temp, nSize);
  78. char strSum[3]{0};
  79. sprintf_s(strSum, "%02X", nsum);
  80. temp[nSize] = strSum[0];
  81. nSize++;
  82. temp[nSize] = strSum[1];
  83. nSize++;
  84. temp[nSize] = FullUCB_Com_ETX;
  85. nSize++;
  86. temp[nSize] = FullUCB_Com_EOT;
  87. nSize++;
  88. memcpy((void*)cCmd, (void*)temp, nSize);
  89. return true;
  90. }
  91. //把指令转成字符串用以日志输出
  92. bool CmdtoString(const char* cCmd, int nCmdSize, std::string& strCmd)
  93. {
  94. std::string strTemp;
  95. strCmd.clear();
  96. for (int i = 0; i < nCmdSize; i++)
  97. {
  98. strTemp = "";
  99. if ((cCmd[i] == '\r') || (cCmd[i] == '\n') || (cCmd[i] == ':')) //
  100. strTemp = "";
  101. else
  102. strTemp = toupper(cCmd[i]);
  103. strCmd += strTemp;
  104. }
  105. return true;
  106. }
  107. //目标字符串按指定分隔符截取第一个目标字段
  108. std::string GetContentFromString(std::string& strContent, char ch)
  109. {
  110. std::string strTemp;
  111. int nPos = strContent.find(ch);
  112. if (nPos == std::string::npos)
  113. {
  114. strTemp = strContent;
  115. strContent.clear();
  116. }
  117. else
  118. {
  119. strTemp = strContent.substr(0, nPos);
  120. strContent = strContent.substr(nPos + 1, strContent.length() - nPos - 1);
  121. }
  122. return strTemp;
  123. }
  124. //尝试按16进制解读字符串,并将解读成功的部分转换为10进制返回
  125. //例如str="169acegh12547",则会解读出"169ace",返回 1481422
  126. int String2Hex(std::string str)
  127. {
  128. int base = 16;
  129. char* entptr;
  130. int nRes = strtol(str.c_str(), &entptr, base);
  131. return nRes;
  132. }
  133. //Hex字符转化到Int
  134. int ChartoInt(char uc)
  135. {
  136. int nValue;
  137. if ('0' <= uc && uc <= '9')
  138. {
  139. nValue = uc - '0';
  140. }
  141. else if ('A' <= uc && uc <= 'F')
  142. {
  143. nValue = 10 + uc - 'A';
  144. }
  145. else if ('a' <= uc && uc <= 'f')
  146. {
  147. nValue = 10 + uc - 'a';
  148. }
  149. else
  150. {
  151. nValue = -1;
  152. }
  153. return nValue;
  154. }
  155. //Hex字符转化到Int
  156. int HexUCtoInt(UCHAR uc)
  157. {
  158. int nValue;
  159. if ('0' <= uc && uc <= '9')
  160. {
  161. nValue = uc - '0';
  162. }
  163. else if ('A' <= uc && uc <= 'F')
  164. {
  165. nValue = 10 + uc - 'A';
  166. }
  167. else if ('a' <= uc && uc <= 'f')
  168. {
  169. nValue = 10 + uc - 'a';
  170. }
  171. else
  172. {
  173. nValue = -1;
  174. }
  175. return nValue;
  176. }
  177. //Int转化成Hex字符
  178. char InttoHexUC(int ni)
  179. {
  180. char c;
  181. string str;
  182. if (ni < 0 || ni > 15)
  183. {
  184. c = 0x20;
  185. }
  186. else
  187. {
  188. str = std::format("%X", ni);
  189. c = str.at(0);
  190. }
  191. return c;
  192. }
  193. //串口指令映射表
  194. tFrameMapping::tFrameMapping()
  195. {
  196. m_eOverType = OverType_directly;
  197. m_bLogFlag = false;
  198. m_fFun = NULL;
  199. m_nWaitTime = 0;
  200. m_hAckEvent = NULL;
  201. }
  202. tFrameMapping::tFrameMapping(cmdFun fun, CMDOverType type, bool logFlag, int waitTime)
  203. {
  204. m_bLogFlag = logFlag;
  205. switch (type)
  206. {
  207. case OverType_directly:
  208. {
  209. m_eOverType = OverType_directly;
  210. m_nWaitTime = 0;
  211. m_hAckEvent = NULL;
  212. }
  213. break;
  214. case OverType_WaitTime:
  215. {
  216. m_eOverType = OverType_WaitTime;
  217. m_nWaitTime = waitTime;
  218. m_hAckEvent = NULL;
  219. }
  220. break;
  221. case OverType_WaitACK:
  222. {
  223. m_eOverType = OverType_WaitACK;
  224. m_nWaitTime = 0;
  225. m_hAckEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  226. }
  227. break;
  228. default:
  229. break;
  230. }
  231. m_fFun = fun;
  232. }
  233. tFrameMapping::~tFrameMapping()
  234. {
  235. CloseHandle(m_hAckEvent);
  236. m_fFun = NULL;
  237. }
  238. tFrameMapping& tFrameMapping::operator =(const tFrameMapping& value)
  239. {
  240. m_eOverType = value.m_eOverType;
  241. m_bLogFlag = value.m_bLogFlag;
  242. m_fFun = value.m_fFun;
  243. m_nWaitTime = value.m_nWaitTime;
  244. m_hAckEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  245. return *this;
  246. }
  247. void tFrameMapping::tSetWaitState(const char* CMD)
  248. {
  249. switch (m_eOverType)
  250. {
  251. case OverType_directly:
  252. {
  253. if (m_bLogFlag)
  254. {
  255. if (CMD != NULL)
  256. mLog::FDEBUG("tSetWaitState:[{$}]Exit directly", CMD);
  257. else
  258. mLog::FDEBUG("tSetWaitState:Exit directly");
  259. }
  260. }
  261. break;
  262. case OverType_WaitTime:
  263. {
  264. if (m_bLogFlag)
  265. {
  266. if (CMD != NULL)
  267. mLog::FDEBUG("tSetWaitState:[{$}]wait[{$}]ms", CMD, m_nWaitTime);
  268. else
  269. mLog::FDEBUG("tSetWaitState:wait[{$}]ms", m_nWaitTime);
  270. }
  271. Sleep(m_nWaitTime);
  272. }
  273. break;
  274. case OverType_WaitACK:
  275. {
  276. if (m_bLogFlag)
  277. {
  278. if (CMD != NULL)
  279. mLog::FDEBUG("tSetWaitState:[{$}]wait AckEvent 500ms", CMD);
  280. else
  281. mLog::FDEBUG("tSetWaitState:wait AckEvent 500ms");
  282. }
  283. DWORD reasult = WaitForSingleObject(m_hAckEvent, 500);
  284. if (WAIT_OBJECT_0 == reasult)
  285. {
  286. if (m_bLogFlag)
  287. {
  288. if (CMD != NULL)
  289. mLog::FDEBUG("tSetWaitState:[{$}]wait AckEvent successful", CMD);
  290. else
  291. mLog::FDEBUG("tSetWaitState:wait AckEvent successful");
  292. }
  293. //ResetEvent(m_hAckEvent);
  294. }
  295. else if (WAIT_TIMEOUT == reasult)
  296. {
  297. if (m_bLogFlag)
  298. {
  299. if (CMD != NULL)
  300. mLog::FWARN("tSetWaitState:[{$}]wait AckEvent timeout", CMD);
  301. else
  302. mLog::FWARN("tSetWaitState:wait AckEvent timeout");
  303. }
  304. }
  305. }
  306. break;
  307. default:
  308. break;
  309. }
  310. }
  311. void tFrameMapping::tCheckWaitState(const char* CMD)
  312. {
  313. switch (m_eOverType)
  314. {
  315. case OverType_directly:
  316. {
  317. if (m_bLogFlag)
  318. {
  319. if (CMD != NULL)
  320. mLog::FDEBUG("tCheckWaitState:[{$}]Exit directly", CMD);
  321. else
  322. mLog::FDEBUG("tCheckWaitState:Exit directly");
  323. }
  324. }
  325. break;
  326. case OverType_WaitTime:
  327. {
  328. if (m_bLogFlag)
  329. {
  330. if (CMD != NULL)
  331. mLog::FDEBUG("tCheckWaitState:[{$}]wait ms", CMD);
  332. else
  333. mLog::FDEBUG("tCheckWaitState:wait ms");
  334. }
  335. }
  336. break;
  337. case OverType_WaitACK:
  338. {
  339. if (m_bLogFlag)
  340. {
  341. if (CMD != NULL)
  342. mLog::FDEBUG("tCheckWaitState:[{$}]activate AckEvent", CMD);
  343. else
  344. mLog::FDEBUG("tCheckWaitState:activate AckEvent");
  345. }
  346. //SetEvent(m_hAckEvent);
  347. PulseEvent(m_hAckEvent);
  348. }
  349. break;
  350. default:
  351. break;
  352. }
  353. }
  354. //-----------------------------------------------------------------------------
  355. // DecodeFrame
  356. //-----------------------------------------------------------------------------
  357. std::map <std::string, tFrameMapping> arFrame;
  358. bool DecodeFrame(const char* strFrame, int length)
  359. {
  360. string data(strFrame+1, 3);
  361. auto found = arFrame.find(data);
  362. if (found == arFrame.end())
  363. {
  364. mLog::FERROR("DecodeFrame:not find[{$}]", data.c_str());
  365. return false;
  366. }
  367. //found->second.tCheckWaitState(strFrame);
  368. found->second.m_fFun(strFrame, length-4);//第二个参数 不重要
  369. return true;
  370. }
  371. bool SetWaitAction(const char* strFrame)
  372. {
  373. char data[4] = { 0 };
  374. strncpy_s(data, strFrame+1, 3);
  375. auto found = arFrame.find(data);
  376. if (found == arFrame.end())
  377. {
  378. mLog::FWARN("SetWaitAction:[{$}] not find", strFrame);
  379. return false;
  380. }
  381. found->second.tSetWaitState(strFrame);
  382. return true;
  383. }
  384. bool CheckWaitState(const char* strFrame)
  385. {
  386. char data[4] = { 0 };
  387. strncpy_s(data, strFrame+1, 3);
  388. auto found = arFrame.find(data);
  389. if (found == arFrame.end())
  390. {
  391. mLog::FWARN("CheckWaitState:[{$}] not find", strFrame);
  392. return false;
  393. }
  394. found->second.tCheckWaitState(strFrame);
  395. return true;
  396. }
  397. }