Command.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. #include "StdAfx.h"
  2. #include "Command.h"
  3. #define NoneOptLen 5
  4. #define MINSIZE 128
  5. #define MIDSIZE 4096
  6. #define MAXSIZE 10240
  7. // 宏函数;
  8. #define OPEN_CHECK if (!IsOpen()) return false
  9. byte* TCLCommand::m_pData = NULL;
  10. TCLCommand::TCLCommand(bool bSync):CBaseSerial(bSync ? 0 : FILE_FLAG_OVERLAPPED)
  11. {
  12. m_pData = new byte[MAXSIZE];
  13. }
  14. TCLCommand::~TCLCommand(void)
  15. {
  16. if (m_pData)
  17. delete []m_pData;
  18. m_pData = NULL;
  19. m_vtExternalCMDParams.clear();
  20. m_vtInternalCMDParams.clear();
  21. }
  22. int TCLCommand::pares_time_value(std::string strTime)
  23. {
  24. int nTimes = 0;
  25. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  26. if (strstr(strTime.c_str(), _T("ms")) || strstr(strTime.c_str(), _T("MS")))
  27. {
  28. nTimes = atol(strTime.c_str());
  29. }
  30. else if (strstr(strTime.c_str(), _T("s")) || strstr(strTime.c_str(), _T("S")))
  31. {
  32. nTimes = atol(strTime.c_str()) * 1000;
  33. }
  34. else if (strstr(strTime.c_str(), _T("m")) || strstr(strTime.c_str(), _T("M")))
  35. {
  36. nTimes = atol(strTime.c_str()) * 6000;
  37. }
  38. else
  39. {
  40. // 不带单位或其他的,默认ms;
  41. nTimes = atol(strTime.c_str());
  42. }
  43. #elif _MSC_VER >= 1500
  44. if (_tcsstr(strTime.c_str(), _T("ms")) || _tcsstr(strTime.c_str(), _T("MS")))
  45. {
  46. nTimes = _tstol(strTime.c_str());
  47. }
  48. else if (_tcsstr(strTime.c_str(), _T("s")) || _tcsstr(strTime.c_str(), _T("S")))
  49. {
  50. nTimes = _tstol(strTime.c_str()) * 1000;
  51. }
  52. else if (_tcsstr(strTime.c_str(), _T("m")) || _tcsstr(strTime.c_str(), _T("M")))
  53. {
  54. nTimes = _tstol(strTime.c_str()) * 6000;
  55. }
  56. else
  57. {
  58. // 不带单位或其他的,默认ms;
  59. nTimes = _tstol(strTime.c_str());
  60. }
  61. #endif
  62. return nTimes;
  63. }
  64. bool TCLCommand::parse_pair_key(std::string& RetValue, std::string strLine, TCHAR* lpszText)
  65. {
  66. TCHAR szText[MAX_PATH] = { 0 };
  67. TCHAR szValue[MAX_PATH] = { 0 };
  68. // 去除空格;
  69. #if _MSC_VER > 1900
  70. strLine.erase(std::remove_if(strLine.begin(), strLine.end(), [](unsigned char x) {return std::isspace(x); }), strLine.end()); //C++17
  71. #else
  72. for (std::string::iterator it = strLine.begin(); it != strLine.end();) {
  73. !isspace(*it) ? it++ : it = it = strLine.erase(it);
  74. }
  75. #endif
  76. #if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0
  77. if (2 == sscanf(strLine.c_str(), _T("%[^=]=%s"), szText, MAX_PATH, szValue, MAX_PATH))
  78. #else
  79. if (2 == _stscanf_s(strLine.c_str(), _T("%[^=]=%s"), szText, MAX_PATH, szValue, MAX_PATH))
  80. #endif
  81. {
  82. if (_tcsstr(szText, lpszText)) {
  83. RetValue = szValue;
  84. return true;
  85. }
  86. }
  87. return false;
  88. }
  89. int TCLCommand::parse_cmds_from_file(const TCHAR* file_name, std::vector<CommandParam>& vtCommandParams)
  90. {
  91. TCHAR buf[MAX_PATH] = { 0 };
  92. TCHAR name[MAX_PATH] = { 0 };
  93. TCHAR option[MAX_PATH] = { 0 };
  94. TCHAR head[MAX_PATH] = { 0 };
  95. TCHAR code[MAX_PATH] = { 0 };
  96. TCHAR param[MAX_PATH] = { 0 };
  97. TCHAR multicode[MAX_PATH] = { 0 };
  98. TCHAR cmd_wait_time[MAX_PATH] = { 0 };
  99. TCHAR read_wait_time[MAX_PATH] = { 0 };
  100. int ret = -1;
  101. FILE* fp = NULL;
  102. if (!file_name || file_name[0] == '\0')
  103. return ret;
  104. fp = fopen(file_name, "r");
  105. if (!fp)
  106. goto EXIT;
  107. while ((fgets((char*)buf, MAX_PATH, fp) != NULL)) {
  108. int tmp_len = 0;
  109. tmp_len = _tcslen(buf);
  110. if (tmp_len >= 1) {
  111. if (buf[tmp_len - 1] == '\r' || buf[tmp_len - 1] == '\n')
  112. buf[tmp_len - 1] = 0;
  113. if (tmp_len >= 2) {
  114. if (buf[tmp_len - 2] == '\r' || buf[tmp_len - 2] == '\n')
  115. buf[tmp_len - 2] = 0;
  116. }
  117. }
  118. #if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0
  119. if (sscanf(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, option, head, code, param, multicode, read_wait_time, cmd_wait_time) == 8)
  120. #elif _MSC_VER >= 1500
  121. //if ( _stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8) // 等价下面;
  122. if (_stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%s", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8)
  123. #endif
  124. {
  125. CommandParam cp;
  126. parse_pair_key(cp.name, name, _T("name"));
  127. parse_pair_key(cp.head, head, _T("head"));
  128. parse_pair_key(cp.code, code, _T("cmd"));
  129. parse_pair_key(cp.param, param, _T("param"));
  130. std::string value;
  131. parse_pair_key(value, option, _T("option"));
  132. if (!_tcsicmp(value.c_str(), _T("None")))
  133. cp.nOption = CMDOPT_None;
  134. else if (!_tcsicmp(value.c_str(), _T("Get")))
  135. cp.nOption = CMDOPT_Get;
  136. else if (!_tcsicmp(value.c_str(), _T("Set")))
  137. cp.nOption = CMDOPT_Set;
  138. parse_pair_key(value, multicode, _T("returnParam"));
  139. cp.returnParam = !_tcsicmp(value.c_str(), _T("true")) ? true : false;
  140. parse_pair_key(value, read_wait_time, _T("readWaitTime"));
  141. cp.read_wait_time = pares_time_value(value.c_str());
  142. parse_pair_key(value, cmd_wait_time, _T("cmdWaitTime"));
  143. cp.cmd_wait_time = pares_time_value(value.c_str());
  144. cp.UpdateRtnCode();
  145. vtCommandParams.push_back(cp);
  146. }
  147. }
  148. ret = 0;
  149. EXIT:
  150. if (fp)
  151. fclose(fp);
  152. return ret;
  153. }
  154. void TCLCommand::parse_cmds_from_string(std::string str, std::vector<CommandParam>& vtCommandParams)
  155. {
  156. int nPos(0);
  157. TCHAR buf[MAX_PATH] = { 0 };
  158. TCHAR name[MAX_PATH] = { 0 };
  159. TCHAR option[MAX_PATH] = { 0 };
  160. TCHAR head[MAX_PATH] = { 0 };
  161. TCHAR code[MAX_PATH] = { 0 };
  162. TCHAR param[MAX_PATH] = { 0 };
  163. TCHAR multicode[MAX_PATH] = { 0 };
  164. TCHAR cmd_wait_time[MAX_PATH] = { 0 };
  165. TCHAR read_wait_time[MAX_PATH] = { 0 };
  166. do
  167. {
  168. memset(buf, 0, MAX_PATH);
  169. int nPos1 = str.find_first_of('\r');
  170. int nPos2 = str.find_first_of('\n');
  171. if ( std::string::npos != nPos1 && std::string::npos != nPos2 ) {
  172. nPos = nPos1 > nPos2 ? nPos1 : nPos2;
  173. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  174. sprintf(buf, _T("%s"), str.substr(0, nPos - 1).c_str());
  175. #elif _MSC_VER >= 1500
  176. _stprintf_s(buf, _T("%s"), str.substr(0, nPos - 1).c_str());
  177. #endif
  178. str = str.substr(nPos+1);
  179. }
  180. else if ( std::string::npos != nPos1 ) {
  181. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  182. sprintf(buf, _T("%s"), str.substr(0, nPos1 - 1).c_str());
  183. #elif _MSC_VER >= 1500
  184. _stprintf_s(buf, _T("%s"), str.substr(0, nPos1 - 1).c_str());
  185. #endif
  186. str = str.substr(nPos + 1);
  187. }
  188. else if ( std::string::npos != nPos2 ) {
  189. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  190. sprintf(buf, _T("%s"), str.substr(0, nPos2 - 1).c_str());
  191. #elif _MSC_VER >= 1500
  192. _stprintf_s(buf, _T("%s"), str.substr(0, nPos2 - 1).c_str());
  193. #endif
  194. str = str.substr(nPos + 1);
  195. }
  196. else {
  197. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  198. sprintf(buf, _T("%s"), str.c_str());
  199. #elif _MSC_VER >= 1500
  200. _stprintf_s(buf, _T("%s"), str.c_str());
  201. #endif
  202. str = "";
  203. }
  204. #if _MSC_VER >= 1200 && _MSC_VER < 1500 // VC6.0~8.0
  205. if (sscanf(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, option, head, code, param, multicode, read_wait_time, cmd_wait_time) == 8)
  206. #elif _MSC_VER >= 1500
  207. //if ( _stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;]", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8) // 等价下面;
  208. if (_stscanf_s(buf, "%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%[^;];%s", name, MAX_PATH, option, MAX_PATH, head, MAX_PATH, code, MAX_PATH, param, MAX_PATH, multicode, MAX_PATH, read_wait_time, MAX_PATH, cmd_wait_time, MAX_PATH) == 8)
  209. #endif
  210. {
  211. CommandParam cp;
  212. parse_pair_key(cp.name, name, _T("name"));
  213. parse_pair_key(cp.head, head, _T("head"));
  214. parse_pair_key(cp.code, code, _T("cmd"));
  215. parse_pair_key(cp.param, param, _T("param"));
  216. std::string value;
  217. parse_pair_key(value, option, _T("option"));
  218. if (!_tcsicmp(value.c_str(), _T("None")))
  219. cp.nOption = CMDOPT_None;
  220. else if (!_tcsicmp(value.c_str(), _T("Get")))
  221. cp.nOption = CMDOPT_Get;
  222. else if (!_tcsicmp(value.c_str(), _T("Set")))
  223. cp.nOption = CMDOPT_Set;
  224. parse_pair_key(value, multicode, _T("returnParam"));
  225. cp.returnParam = !_tcsicmp(value.c_str(), _T("true")) ? true : false;
  226. parse_pair_key(value, read_wait_time, _T("readWaitTime"));
  227. cp.read_wait_time = pares_time_value(value.c_str());
  228. parse_pair_key(value, cmd_wait_time, _T("cmdWaitTime"));
  229. cp.cmd_wait_time = pares_time_value(value.c_str());
  230. cp.UpdateRtnCode();
  231. vtCommandParams.push_back(cp);
  232. }
  233. } while (str.size());
  234. }
  235. bool TCLCommand::GetCommandParams(std::string name, CommandParam& cmdPara)
  236. {
  237. bool bget = false;
  238. // 外部优先;
  239. for (std::vector<CommandParam>::iterator it = m_vtExternalCMDParams.begin(); it != m_vtExternalCMDParams.end(); it++ )
  240. {
  241. if ( !_tcsicmp(name.c_str(), it->name.c_str()) ) {
  242. bget = true;
  243. cmdPara = *it;
  244. break;
  245. }
  246. }
  247. if ( !bget )
  248. {
  249. for (std::vector<CommandParam>::iterator it = m_vtInternalCMDParams.begin(); it != m_vtInternalCMDParams.end(); it++ )
  250. {
  251. if ( !_tcsicmp(name.c_str(), it->name.c_str()) ) {
  252. bget = true;
  253. cmdPara = *it;
  254. break;
  255. }
  256. }
  257. }
  258. // 清除状态;
  259. cmdPara.Clean();
  260. return bget;
  261. }
  262. bool TCLCommand::TheFirstPart(CommandParam& cmdPara, std::string data)
  263. {
  264. if (data.size() == NoneOptLen) {
  265. if ((byte)data[0] == cmdPara._rtnCode) {
  266. // 长度;
  267. int nPacketLen = (byte)data[1];
  268. if (nPacketLen != NoneOptLen) {
  269. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  270. cmdPara._rtnError = utils::_dprintf("[%s] 返回数据长度错误:%ld", (byte)data[1]);
  271. #elif _MSC_VER >= 1500
  272. cmdPara._rtnError = utils::_dprintf("[%s] 返回数据长度错误:%ld", __FUNCTION__, (byte)data[1]);
  273. #endif
  274. return false;
  275. }
  276. // 执行状态;
  277. cmdPara._rtnStatus = (byte)data[2];
  278. //utils::_dprintf(_T("[%s] rtnStatus=%02X"), __FUNCTION__, cmdPara._rtnStatus);
  279. // 校验crc;
  280. unsigned short usCRCValue = utils::CRC16Calculate((byte*)data.data(), nPacketLen - 2);
  281. if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPacketLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPacketLen - 1]) {
  282. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  283. cmdPara._rtnError = utils::_dprintf("CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
  284. #elif _MSC_VER >= 1500
  285. cmdPara._rtnError = utils::_dprintf("[%s] CRC校验错误:计算[%02% %02X] != 接收[%02X %02X]", __FUNCTION__, (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
  286. #endif
  287. return false;
  288. }
  289. if ( cmdPara._rtnStatus != 0x0A )
  290. {
  291. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  292. cmdPara._rtnError = utils::_dprintf("执行结果错误:%02X", (byte)cmdPara._rtnStatus);
  293. #elif _MSC_VER >= 1500
  294. cmdPara._rtnError = utils::_dprintf("[%s] 执行结果错误:%02X", __FUNCTION__, (byte)cmdPara._rtnStatus);
  295. #endif
  296. return false;
  297. }
  298. }
  299. else {
  300. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  301. cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
  302. #elif _MSC_VER >= 1500
  303. cmdPara._rtnError = utils::_dprintf("[%s] 返回码错误:%02X", __FUNCTION__, (byte)data[0]);
  304. #endif
  305. return false;
  306. }
  307. }
  308. else {
  309. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  310. cmdPara._rtnError = utils::_dprintf("返回数据长度错误", (byte)data[0]);
  311. #elif _MSC_VER >= 1500
  312. cmdPara._rtnError = utils::_dprintf("[%s] 返回数据长度错误", __FUNCTION__);
  313. #endif
  314. return false;
  315. }
  316. return true;
  317. }
  318. bool TCLCommand::TheSecondPart(CommandParam& cmdPara, std::string data)
  319. {
  320. // 数据起始位;
  321. int nDataPos = 0;
  322. // 数据包长度;
  323. int nPacketLen = 0;
  324. if ((byte)data[0] == cmdPara._rtnCode) {
  325. // 获取长度;
  326. if ((byte)data[1] == 0xFE) {
  327. nDataPos = 4;
  328. nPacketLen = (byte)data[2] << 8 | (byte)data[3];
  329. if (data.size() < 255 && data[2] != 0) {
  330. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  331. cmdPara._rtnError = utils::_dprintf(_T("返回数据长度异常"));
  332. #elif _MSC_VER >= 1500
  333. cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回数据长度异常"), __FUNCTION__);
  334. #endif
  335. return false;
  336. }
  337. }
  338. else
  339. {
  340. nDataPos = 2;
  341. nPacketLen = (byte)data[1];
  342. #if 0 // 如果数据包含有非协议包内的数据,会判断异常;
  343. if (data.size() > 255) {
  344. //nPackageLen = data[1] << 8 | data[2];
  345. cmdPara._rtnError = _dprintf(_T("长度异常"));
  346. return false;
  347. }
  348. #endif
  349. }
  350. #if 1
  351. // 计算出的长度,必等于包长;// 如果包含有其他非包数据,会判断异常;
  352. if (nPacketLen > data.size())
  353. {
  354. cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的数据长度错误, 计算:%d > 实际:%d"), __FUNCTION__, nPacketLen, data.size());
  355. return false;
  356. }
  357. #endif
  358. if (_tcsicmp(cmdPara.code.c_str(), utils::ByteToChars((byte)data[nDataPos] - 1).c_str()) != 0) {
  359. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  360. cmdPara._rtnError = utils::_dprintf(_T("返回的指令码错误, 正确:%02X, 当前:%02X"), utils::TwoHexCharToInteger(cmdPara.code[0],cmdPara.code[1]), (byte)data[nDataPos]);
  361. #elif _MSC_VER >= 1500
  362. cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的指令码错误, 正确:%02X, 当前:%02X"), __FUNCTION__, utils::TwoHexCharToInteger(cmdPara.code[0],cmdPara.code[1]), (byte)data[nDataPos]);
  363. #endif
  364. return false;
  365. }
  366. // 返回的数据;
  367. ++nDataPos;// 返回码占一字节;
  368. if (cmdPara.returnParam) {
  369. // 返回的指令参数
  370. std::string rtnParam = data.substr(nDataPos, cmdPara.param.size()/2);
  371. rtnParam = utils::BytesToHexString((byte*)rtnParam.c_str(), rtnParam.size());
  372. if (_tcsicmp(cmdPara.param.c_str(), rtnParam.c_str()) != 0) {
  373. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  374. cmdPara._rtnError = utils::_dprintf(_T("返回的指令参数错误, %s, %s"), cmdPara.param.c_str(), rtnParam.c_str());
  375. #elif _MSC_VER >= 1500
  376. cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的指令参数错误, %s, %s"), __FUNCTION__, cmdPara.param.c_str(), rtnParam.c_str());
  377. #endif
  378. return false;
  379. }
  380. nDataPos += rtnParam.size()/2;// 指令参数码占一字节;
  381. }
  382. cmdPara._rtnData = data.substr(nDataPos, nPacketLen - nDataPos - 2); //2 = crc;
  383. utils::_dprintf(_T("rtnData=%s"), utils::BytesToHexString((byte*)cmdPara._rtnData.c_str(), cmdPara._rtnData.size(), ' ').c_str());
  384. // 校验crc;
  385. unsigned short usCRCValue = utils::CRC16Calculate((byte*)data.data(), nPacketLen - 2);
  386. if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPacketLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPacketLen - 1])
  387. {
  388. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  389. cmdPara._rtnError = utils::_dprintf("CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
  390. #elif _MSC_VER >= 1500
  391. cmdPara._rtnError = utils::_dprintf("[%s] CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", __FUNCTION__, (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
  392. #endif
  393. return false;
  394. }
  395. if (data.size() > nPacketLen)
  396. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  397. utils::_dprintf(_T("带有脏数据:%s"), data.substr(nPacketLen));
  398. #elif _MSC_VER >= 1500
  399. utils::_dprintf("[%s] 带有脏数据:%s", __FUNCTION__, data.substr(nPacketLen));
  400. #endif
  401. }
  402. else {
  403. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  404. cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
  405. #elif _MSC_VER >= 1500
  406. cmdPara._rtnError = utils::_dprintf("[%s] 返回码错误:%02X", __FUNCTION__, (byte)data[0]);
  407. #endif
  408. return false;
  409. }
  410. return true;
  411. }
  412. void TCLCommand::PackingCommand(CommandParam& cmdPara, LPVOID data, const int& dataLen)
  413. {
  414. // Tag:[命令头][全命令长度][命令码]<命令码参数><附加数据>[crc1][crc2]
  415. std::string command;
  416. // 命令头标识位;
  417. command.append(utils::HexStringToBytes(cmdPara.head, 2).c_str(), cmdPara.head.size() / 2);
  418. // 命令码;
  419. command.append(utils::HexStringToBytes(cmdPara.code, 2).c_str(), cmdPara.code.size() / 2);
  420. // 命令码参数;
  421. if ( cmdPara.param.size()%2 == 0 )
  422. command.append(utils::HexStringToBytes(cmdPara.param, 2).c_str(), cmdPara.param.size() / 2);
  423. // 附加的数据;
  424. if (dataLen > 0 && NULL != data)
  425. command.append((char*)data, dataLen);
  426. int len(0);
  427. // 长度:可能1字节表示,超过255用2字节表示;
  428. byte szlen[2] = { 0 };
  429. //if ((byte)command[1] == 0xFE)
  430. //if ( cmdPara.head.size() >= 4 && cmdPara.head.find("FE", 2, 2) != std::string::npos )
  431. if (_tcsicmp(_T("AAFE"), cmdPara.head.c_str()) == 0)
  432. {// 长度超过255,需要2字节表示;
  433. len = command.size() + 4; // 2位crc + 2位长度;
  434. szlen[0] = (len >> 8) & 0xFF;
  435. szlen[1] = len & 0xFF;
  436. command.insert(2, (char*)szlen, 2);
  437. }
  438. else {
  439. // 2位crc + 1位长度;
  440. len = command.size() + 3;
  441. //if ( _tcsicmp(cmdPara.code.c_str(), "99 00") == 0 )
  442. // len -= 2;
  443. if (len > 255) {// 长度超过255,多一个占位符;
  444. ++len;
  445. szlen[0] = (len >> 8) & 0xFF;
  446. szlen[1] = len & 0xFF;
  447. command.insert(1, (char*)szlen, 2);
  448. }
  449. else {
  450. szlen[0] = len & 0xFF;
  451. command.insert(1, (char*)szlen, 1);
  452. }
  453. }
  454. // crc校验;
  455. byte szcrc[2] = { 0 };
  456. WORD usCRCValue = utils::CRC16Calculate((byte*)command.c_str(), command.size()); // 如果有0断开有危险;
  457. //WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), len - 2);
  458. szcrc[0] = (usCRCValue >> 8) & 0xFF;
  459. szcrc[1] = usCRCValue & 0xFF;
  460. command.append((char*)szcrc, 2);
  461. cmdPara._cmdContext = command;
  462. utils::_dprintf(_T("指令:%s = %s"), cmdPara.name.c_str(), utils::BytesToHexString((byte*)command.c_str(), command.size(), ' ').c_str());
  463. }
  464. bool TCLCommand::ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen)
  465. {
  466. // Tag:[返回头][全数据长度][返回码]<返回码子项><附加数据>[crc16]
  467. if (!TheFirstPart(cmdPara, data.substr(0, 5)))
  468. return false;
  469. if (cmdPara._rtnStatus != 0x0A) {
  470. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  471. utils::_dprintf("执行结果错误:%02X", cmdPara._rtnStatus);
  472. #elif _MSC_VER >= 1500
  473. utils::_dprintf("[%s] 执行结果错误:%02X", __FUNCTION__, cmdPara._rtnStatus);
  474. #endif
  475. return false;
  476. }
  477. if ( data.size() == 5 )
  478. {
  479. return true;
  480. }
  481. switch (cmdPara.nOption)
  482. {
  483. case CMDOPT_None:
  484. break;
  485. case CMDOPT_Get:
  486. case CMDOPT_Set:
  487. return TheSecondPart(cmdPara, data.substr(5));
  488. break;
  489. default:
  490. break;
  491. }
  492. return false;
  493. }
  494. bool TCLCommand::SendCommand(CommandParam& cmdPara)
  495. {
  496. OPEN_CHECK;
  497. memset(m_pData, 0, MAXSIZE);
  498. if (_dwIOMode == FILE_FLAG_OVERLAPPED)
  499. {
  500. if (!Write((void*)cmdPara._cmdContext.c_str(), cmdPara._cmdContext.size()))
  501. return false;
  502. Sleep(cmdPara.read_wait_time);
  503. int nReadCount = Read(m_pData, MAXSIZE);
  504. cmdPara._rtnContext.append((char*)m_pData, nReadCount);
  505. }
  506. else
  507. {
  508. if (!WriteSync((void*)cmdPara._cmdContext.c_str(), cmdPara._cmdContext.size()))
  509. return false;
  510. Sleep(cmdPara.read_wait_time);
  511. int nReadCount = ReadSync(m_pData, MAXSIZE);
  512. cmdPara._rtnContext.append((char*)m_pData, nReadCount);
  513. }
  514. utils::_dprintf("结果:%s = %s", cmdPara.name.c_str(), utils::BytesToHexString((byte*)cmdPara._rtnContext.c_str(), cmdPara._rtnContext.size(), ' ').c_str());
  515. ParseResultString(cmdPara, cmdPara._rtnContext, cmdPara._rtnContext.size());
  516. Sleep(cmdPara.cmd_wait_time);
  517. return cmdPara._rtnStatus == 0x0A ? true : false;
  518. }
  519. bool TCLCommand::SendCommand(std::string name, CommandParam& cmdPara, LPVOID data /* = NULL */, int dataLen /* = 0 */)
  520. {
  521. if ( !GetCommandParams(name, cmdPara) )
  522. return false;
  523. PackingCommand(cmdPara, data, dataLen);
  524. return SendCommand(cmdPara);
  525. }
  526. void TCLCommand::SetInternalCMDParams(DWORD dwResouceID)
  527. {
  528. std::string data;
  529. if ( utils::GetResourceData(dwResouceID, _T("BIN"), data) )
  530. {
  531. parse_cmds_from_string(data, m_vtInternalCMDParams);
  532. }
  533. }
  534. void TCLCommand::SetExternalCMDParams(LPCTSTR lpFileName)
  535. {
  536. parse_cmds_from_file(lpFileName, m_vtExternalCMDParams);
  537. }