Command.cpp 24 KB

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