Command.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  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. {
  404. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  405. cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
  406. #elif _MSC_VER >= 1500
  407. cmdPara._rtnError = utils::_dprintf("[%s] 返回码错误:%02X", __FUNCTION__, (byte)data[0]);
  408. #endif
  409. return false;
  410. }
  411. return true;
  412. }
  413. bool TCLCommand::TheSecondPartForFC(CommandParam& cmdPara, std::string data)
  414. {
  415. // 数据起始位;
  416. int nDataPos = 0;
  417. // 数据包长度;
  418. int nPacketLen = 0;
  419. if ((byte)data[0] == cmdPara._rtnCode) {
  420. // 获取长度;
  421. if ((byte)data[1] == 0xFE) {
  422. nDataPos = 4;
  423. nPacketLen = (byte)data[2] << 8 | (byte)data[3];
  424. if (data.size() < 255 && data[2] != 0) {
  425. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  426. cmdPara._rtnError = utils::_dprintf(_T("返回数据长度异常"));
  427. #elif _MSC_VER >= 1500
  428. cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回数据长度异常"), __FUNCTION__);
  429. #endif
  430. return false;
  431. }
  432. }
  433. else
  434. {
  435. nDataPos = 2;
  436. nPacketLen = (byte)data[1];
  437. #if 0 // 如果数据包含有非协议包内的数据,会判断异常;
  438. if (data.size() > 255) {
  439. //nPackageLen = data[1] << 8 | data[2];
  440. cmdPara._rtnError = _dprintf(_T("长度异常"));
  441. return false;
  442. }
  443. #endif
  444. }
  445. #if 1
  446. // 计算出的长度,必等于包长;// 如果包含有其他非包数据,会判断异常;
  447. if (nPacketLen > data.size())
  448. {
  449. cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的数据长度错误, 计算:%d > 实际:%d"), __FUNCTION__, nPacketLen, data.size());
  450. return false;
  451. }
  452. #endif
  453. // FireTV的Code是与Write时一样;
  454. if (_tcsicmp(cmdPara.code.c_str(), utils::ByteToChars((byte)data[nDataPos]).c_str()) != 0) {
  455. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  456. cmdPara._rtnError = utils::_dprintf(_T("返回的指令码错误, 正确:%02X, 当前:%02X"), utils::TwoHexCharToInteger(cmdPara.code[0],cmdPara.code[1]), (byte)data[nDataPos]);
  457. #elif _MSC_VER >= 1500
  458. cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的指令码错误, 正确:%02X, 当前:%02X"), __FUNCTION__, utils::TwoHexCharToInteger(cmdPara.code[0],cmdPara.code[1]), (byte)data[nDataPos]);
  459. #endif
  460. return false;
  461. }
  462. // 返回的数据;
  463. ++nDataPos;// 返回码占一字节;
  464. #if 0 // FireTV的返回的指令参数与code没有规律对应;returnParam要外部根据协议来判断;
  465. if (cmdPara.returnParam) {
  466. // 返回的指令参数
  467. std::string rtnParam = data.substr(nDataPos, cmdPara.param.size()/2);
  468. rtnParam = utils::BytesToHexString((byte*)rtnParam.c_str(), rtnParam.size());
  469. if (_tcsicmp(cmdPara.param.c_str(), rtnParam.c_str()) != 0) {
  470. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  471. cmdPara._rtnError = utils::_dprintf(_T("返回的指令参数错误, %s, %s"), cmdPara.param.c_str(), rtnParam.c_str());
  472. #elif _MSC_VER >= 1500
  473. cmdPara._rtnError = utils::_dprintf(_T("[%s] 返回的指令参数错误, %s, %s"), __FUNCTION__, cmdPara.param.c_str(), rtnParam.c_str());
  474. #endif
  475. return false;
  476. }
  477. nDataPos += rtnParam.size()/2;// 指令参数码占一字节;
  478. }
  479. #endif
  480. cmdPara._rtnData = data.substr(nDataPos, nPacketLen - nDataPos - 2); //2 = crc;
  481. utils::_dprintf(_T("rtnData=%s"), utils::BytesToHexString((byte*)cmdPara._rtnData.c_str(), cmdPara._rtnData.size(), ' ').c_str());
  482. // 校验crc;
  483. unsigned short usCRCValue = utils::CRC16Calculate((byte*)data.data(), nPacketLen - 2);
  484. if (((usCRCValue >> 8) & 0xFF) != (byte)data[nPacketLen - 2] || (usCRCValue & 0xFF) != (byte)data[nPacketLen - 1])
  485. {
  486. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  487. cmdPara._rtnError = utils::_dprintf("CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
  488. #elif _MSC_VER >= 1500
  489. cmdPara._rtnError = utils::_dprintf("[%s] CRC校验错误:计算[%02X %02X] != 接收[%02X %02X]", __FUNCTION__, (usCRCValue >> 8) & 0xFF, usCRCValue & 0xFF, (byte)data[nPacketLen - 2], (byte)data[nPacketLen - 1]);
  490. #endif
  491. return false;
  492. }
  493. if (data.size() > nPacketLen)
  494. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  495. utils::_dprintf(_T("带有脏数据:%s"), data.substr(nPacketLen));
  496. #elif _MSC_VER >= 1500
  497. utils::_dprintf("[%s] 带有脏数据:%s", __FUNCTION__, data.substr(nPacketLen));
  498. #endif
  499. }
  500. else
  501. {
  502. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  503. cmdPara._rtnError = utils::_dprintf("返回码错误:%02X", (byte)data[0]);
  504. #elif _MSC_VER >= 1500
  505. cmdPara._rtnError = utils::_dprintf("[%s] 返回码错误:%02X", __FUNCTION__, (byte)data[0]);
  506. #endif
  507. return false;
  508. }
  509. return true;
  510. }
  511. void TCLCommand::PackingCommand(CommandParam& cmdPara, LPVOID data, const int& dataLen)
  512. {
  513. // Tag:[命令头][全命令长度][命令码]<命令码参数><附加数据>[crc1][crc2]
  514. std::string command;
  515. // 命令头标识位;
  516. command.append(utils::HexStringToBytes(cmdPara.head, 2).c_str(), cmdPara.head.size() / 2);
  517. // 命令码;
  518. command.append(utils::HexStringToBytes(cmdPara.code, 2).c_str(), cmdPara.code.size() / 2);
  519. // 命令码参数;
  520. if ( cmdPara.param.size()%2 == 0 )
  521. command.append(utils::HexStringToBytes(cmdPara.param, 2).c_str(), cmdPara.param.size() / 2);
  522. // 附加的数据;
  523. if (dataLen > 0 && NULL != data)
  524. command.append((char*)data, dataLen);
  525. int len(0);
  526. // 长度:可能1字节表示,超过255用2字节表示;
  527. byte szlen[2] = { 0 };
  528. //if ((byte)command[1] == 0xFE)
  529. //if ( cmdPara.head.size() >= 4 && cmdPara.head.find("FE", 2, 2) != std::string::npos )
  530. if (_tcsicmp(_T("AAFE"), cmdPara.head.c_str()) == 0)
  531. {// 长度超过255,需要2字节表示;
  532. len = command.size() + 4; // 2位crc + 2位长度;
  533. szlen[0] = (len >> 8) & 0xFF;
  534. szlen[1] = len & 0xFF;
  535. command.insert(2, (char*)szlen, 2);
  536. }
  537. else {
  538. // 2位crc + 1位长度;
  539. len = command.size() + 3;
  540. //if ( _tcsicmp(cmdPara.code.c_str(), "99 00") == 0 )
  541. // len -= 2;
  542. if (len > 255) {// 长度超过255,多一个占位符;
  543. ++len;
  544. szlen[0] = (len >> 8) & 0xFF;
  545. szlen[1] = len & 0xFF;
  546. command.insert(1, (char*)szlen, 2);
  547. }
  548. else {
  549. szlen[0] = len & 0xFF;
  550. command.insert(1, (char*)szlen, 1);
  551. }
  552. }
  553. // crc校验;
  554. byte szcrc[2] = { 0 };
  555. WORD usCRCValue = utils::CRC16Calculate((byte*)command.c_str(), command.size()); // 如果有0断开有危险;
  556. //WORD usCRCValue = CRC16Calculate((byte *)command.c_str(), len - 2);
  557. szcrc[0] = (usCRCValue >> 8) & 0xFF;
  558. szcrc[1] = usCRCValue & 0xFF;
  559. command.append((char*)szcrc, 2);
  560. cmdPara._cmdContext = command;
  561. utils::_dprintf(_T("指令:%s = %s"), cmdPara.name.c_str(), utils::BytesToHexString((byte*)command.c_str(), command.size(), ' ').c_str());
  562. }
  563. bool TCLCommand::ParseResultString(CommandParam& cmdPara, std::string data, const int& dataLen)
  564. {
  565. // Tag:[返回头][全数据长度][返回码]<返回码子项><附加数据>[crc16]
  566. if (!TheFirstPart(cmdPara, data.substr(0, 5)))
  567. return false;
  568. if (cmdPara._rtnStatus != 0x0A) {
  569. #if _MSC_VER >= 1200 && _MSC_VER < 1500
  570. utils::_dprintf("执行结果错误:%02X", cmdPara._rtnStatus);
  571. #elif _MSC_VER >= 1500
  572. utils::_dprintf("[%s] 执行结果错误:%02X", __FUNCTION__, cmdPara._rtnStatus);
  573. #endif
  574. return false;
  575. }
  576. if ( data.size() == 5 )
  577. {
  578. return true;
  579. }
  580. switch (cmdPara.nOption)
  581. {
  582. case CMDOPT_None:
  583. break;
  584. case CMDOPT_Get:
  585. case CMDOPT_Set:
  586. return TheSecondPart(cmdPara, data.substr(5));
  587. break;
  588. default:
  589. break;
  590. }
  591. return false;
  592. }
  593. bool TCLCommand::SendCommand(CommandParam& cmdPara)
  594. {
  595. OPEN_CHECK;
  596. memset(m_pData, 0, MAXSIZE);
  597. if (_dwIOMode == FILE_FLAG_OVERLAPPED)
  598. {
  599. if (!Write((void*)cmdPara._cmdContext.c_str(), cmdPara._cmdContext.size()))
  600. return false;
  601. Sleep(cmdPara.read_wait_time);
  602. int nReadCount = Read(m_pData, MAXSIZE);
  603. cmdPara._rtnContext.append((char*)m_pData, nReadCount);
  604. }
  605. else
  606. {
  607. if (!WriteSync((void*)cmdPara._cmdContext.c_str(), cmdPara._cmdContext.size()))
  608. return false;
  609. Sleep(cmdPara.read_wait_time);
  610. int nReadCount = ReadSync(m_pData, MAXSIZE);
  611. cmdPara._rtnContext.append((char*)m_pData, nReadCount);
  612. }
  613. utils::_dprintf("结果:%s = %s", cmdPara.name.c_str(), utils::BytesToHexString((byte*)cmdPara._rtnContext.c_str(), cmdPara._rtnContext.size(), ' ').c_str());
  614. ParseResultString(cmdPara, cmdPara._rtnContext, cmdPara._rtnContext.size());
  615. Sleep(cmdPara.cmd_wait_time);
  616. return cmdPara._rtnStatus == 0x0A ? true : false;
  617. }
  618. bool TCLCommand::SendCommand(std::string name, CommandParam& cmdPara, LPVOID data /* = NULL */, int dataLen /* = 0 */)
  619. {
  620. if ( !GetCommandParams(name, cmdPara) )
  621. return false;
  622. PackingCommand(cmdPara, data, dataLen);
  623. return SendCommand(cmdPara);
  624. }
  625. void TCLCommand::SetInternalCMDParams(DWORD dwResouceID)
  626. {
  627. std::string data;
  628. if ( utils::GetResourceData(dwResouceID, _T("BIN"), data) )
  629. {
  630. parse_cmds_from_string(data, m_vtInternalCMDParams);
  631. }
  632. }
  633. void TCLCommand::SetExternalCMDParams(LPCTSTR lpFileName)
  634. {
  635. m_vtExternalCMDParams.clear();
  636. parse_cmds_from_file(lpFileName, m_vtExternalCMDParams);
  637. }