DevFSMCommBase.hpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  1. #ifndef _COMM_DEVICE_FSM_BASE_HPP_
  2. #define _COMM_DEVICE_FSM_BASE_HPP_
  3. #include "DevEntityCommBase.hpp"
  4. #include "CommEntityUtil.hpp"
  5. #include "SpFSM.h"
  6. #include "RVCComm.h"
  7. #include "DevErrorCode.h"
  8. #include "DeviceBaseClass.h"
  9. #include "publicFunExport.h"
  10. #include <winpr/file.h>
  11. #include <winpr/sysinfo.h>
  12. #include <map>
  13. #include <string>
  14. #include "fileutil.h"
  15. #if defined(_MSC_VER)
  16. #pragma comment(lib, "Version.lib")
  17. typedef ErrorCodeEnum(*DevAdaptObjCreateFunc)(DeviceBaseClass*& baseObj);
  18. typedef ErrorCodeEnum(*DevAdaptObjReleaseFunc)(DeviceBaseClass*& pBaseObj);
  19. typedef void(*GetPrefixErrMsgFunc)(char* szErrMsg, DWORD* pMsgLen);
  20. #else //C/C++ Compiler
  21. using DevAdaptObjCreateFunc = ErrorCodeEnum(*)(DeviceBaseClass*& pOutDevAptObj);
  22. using DevAdaptObjReleaseFunc = ErrorCodeEnum(*)(DeviceBaseClass*& pInDevAptObj);
  23. using GetPrefixErrMsgFunc = void(*)(char* szErrMsg, DWORD* pMsgLen);
  24. #endif //_MSC_VER
  25. typedef ErrorCodeEnum(*GetDevAdapterVersionFunc)(DevSoftVersion& retVersion);
  26. #define HARDWARE_ENTITY_RESET_ENTITYID(ent, entityID) \
  27. do{\
  28. memset(&ent, 0, sizeof(ent)); \
  29. ent.dwEntityId = entityID; \
  30. } while (false)
  31. #define HARDWARE_ENTITY_SET_DEVCODE(ent, ec, reserved) \
  32. do {\
  33. ent.dwVendorErroCode = ec; \
  34. ent.dwReserved = reserved; \
  35. } while (false)
  36. #define HARDWARE_ENTITY_MAKE_ERRORCODE(ec) \
  37. MAKE_SLV_ERRORCODE(ec.dwEntityId, (ec.dwVendorId), ec.dwVendorErroCode)
  38. #define HARDWARE_ENTITY_MAKE_ERRORCODE_TO_BUSINESS(ec) \
  39. MAKE_SLV_ERRORCODE_TO_BUSINESS(ec.dwEntityId, ec.dwVendorErroCode, ec.dwReserved)
  40. enum PageType
  41. {
  42. PageType_Init,
  43. PageType_MainPage,
  44. PageType_UserDesktop,
  45. PageType_Other,
  46. };
  47. template <typename TSubAdpt>
  48. struct DevAdptLibHelper
  49. {
  50. private:
  51. bool CheckAndGetMapAdatperName(const CSimpleStringA& strPath, CSimpleStringA& replaceAdapterName)
  52. {
  53. bool result = false;
  54. CSimpleStringA strTest = m_strAdapterName.IsNullOrEmpty() ? strPath.GetData() : m_strAdapterName.GetData();
  55. for (int i = 0; i < strTest.GetLength(); ++i) {
  56. if (strTest[i] >= 'A' && strTest[i] <= 'Z') strTest[i] = strTest[i] + ('a' - 'A');
  57. }
  58. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("strTest:%s", strPath.GetData());
  59. if (strTest.IndexOf("pinpad") != -1) {
  60. replaceAdapterName = "PinPad.self.1.1.dll";
  61. result = true;
  62. } else if (strTest.IndexOf("cardissuer") != -1) {
  63. replaceAdapterName = "CardIssuer.self.1.1.dll";
  64. result = true;
  65. } else if (strTest.IndexOf("contactlesscard") != -1) {
  66. replaceAdapterName = "ContactlessCard.self.1.1.dll";
  67. result = true;
  68. } else if (strTest.IndexOf("fingerprint") != -1) {
  69. replaceAdapterName = "FingerPrint.self.1.1.dll";
  70. result = true;
  71. } else if (strTest.IndexOf("gpio") != -1) {
  72. replaceAdapterName = "GPIO.self.1.1.dll";
  73. result = true;
  74. } else if (strTest.IndexOf("idcertificate") != -1) {
  75. replaceAdapterName = "IDCertificate.self.1.1.dll";
  76. result = true;
  77. } else if (strTest.IndexOf("hspscanner") != -1) {
  78. replaceAdapterName = "HSPSCanner.self.1.1.dll";
  79. result = true;
  80. }
  81. return result;
  82. }
  83. bool PreLoadLib(CSimpleStringA& strFullLibPath)
  84. {
  85. bool result(false);
  86. ///*TODO: Test (80374374@1/23/2024)*/
  87. DWORD d1;
  88. DWORD d2;
  89. DWORD d3;
  90. DWORD d4;
  91. if (!ExistsFileA(strFullLibPath)) {
  92. return result;
  93. }
  94. #ifndef DEVOPS_ON_PRD
  95. GetDllVersionInfo(strFullLibPath, d1, d2, d3, d4);
  96. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("dll %s version: %d.%d.%d.%d", strFullLibPath.GetData(), d1, d2, d3, d4);
  97. //VC16.0 [1920,1929] VS2019 142
  98. if (d4 >= 1920 && d4 <= 1929 && d3 == 142) {
  99. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("detect it built with VS2019, skip latter procedure, version: %d.%d.%d.%d", d1, d2, d3, d4);
  100. return result;
  101. }
  102. #endif
  103. CSimpleStringA strTest = strFullLibPath.GetData();
  104. CSimpleStringA strSelf(true);
  105. if (CheckAndGetMapAdatperName(strTest, strSelf)) {
  106. int index = -1;
  107. for (int i = 0; i < strTest.GetLength(); ++i)
  108. if (strTest[i] == '\\' || strTest[i] == '/') index = i;
  109. if (index != -1) {
  110. toolkit_setenv("INVOKE_VENDOR_ADAPTER_NAME", strFullLibPath.GetData());
  111. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("env:%s", strFullLibPath.GetData());
  112. CSimpleStringA strAdapterName = strTest.SubString(index + 1);
  113. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("adapter name:%s", strAdapterName.GetData());
  114. strTest[index + 1] = '\0'; //!!!!
  115. strFullLibPath = strTest.SubString(0, index + 1);
  116. strFullLibPath += strSelf;
  117. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("new adapter path:%s", strFullLibPath.GetData());
  118. result = true;
  119. }
  120. }
  121. return result;
  122. }
  123. public:
  124. void SetAdapterName(const CSimpleStringA& strEntityName) { m_strAdapterName = strEntityName; }
  125. ErrorCodeEnum LoadLibAddress(const CSimpleStringA& strFullLibPath)
  126. {
  127. ErrorCodeEnum erroCode = Error_Succeed;
  128. CSimpleStringA strTemp = strFullLibPath.GetData();
  129. #if defined(_MSC_VER)
  130. m_VS2010BridgeMode = PreLoadLib(strTemp);
  131. #endif //_MSC_VER
  132. do {
  133. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to load lib: %s", strTemp.GetData());
  134. if (!ExistsFileA(strTemp)) {
  135. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("the lib file %s is not existed!", strTemp.GetData());
  136. erroCode = Error_NotExist;
  137. break;
  138. }
  139. int res = toolkit_dlopen(strTemp, &m_lib);
  140. if (res != 0) {
  141. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("toolkit_dlopen[%s] failed with error %s.", strTemp.GetData(), toolkit_dlerror(&m_lib));
  142. erroCode = Error_DevLoadFileFailed;
  143. break;
  144. }
  145. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get CreateDevComponent pointer address...");
  146. if ((res = toolkit_dlsym(&m_lib, "CreateDevComponent", (void**)&pFuncCreateAdapt)) != 0)
  147. {
  148. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Get 'CreateDevComponent' Func address failed with error: %s", toolkit_dlerror(&m_lib));
  149. erroCode = Error_DevLoadFileFailed;
  150. break;
  151. }
  152. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get ReleaseDevComponent pointer address...");
  153. if ((res = toolkit_dlsym(&m_lib, "ReleaseDevComponent", (void**)&pFuncReleaseAdapt)) != 0)
  154. {
  155. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Get 'ReleaseDevComponent' Func address failed with error: %s", toolkit_dlerror(&m_lib));
  156. erroCode = Error_DevLoadFileFailed;
  157. break;
  158. }
  159. #if defined(RVC_OS_WIN)
  160. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get GetMoreErrorDetail pointer address...");
  161. if ((res = toolkit_dlsym(&m_lib, "GetMoreErrorDetail", (void**)&pFuncGetPrefixErr)) != 0)
  162. {
  163. pFuncGetPrefixErr = nullptr;
  164. }
  165. else {
  166. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Get 'GetMoreErrorDetail' Func address succ");
  167. }
  168. #endif //RVC_OS_WIN
  169. } while (false);
  170. if (IS_FAILURED(erroCode))
  171. {
  172. TearDown();
  173. }
  174. return erroCode;
  175. }
  176. ErrorCodeEnum CreateDevAdptObject()
  177. {
  178. if (m_AdptObjPtr != nullptr) {
  179. return Error_AlreadyExist;
  180. }
  181. if (pFuncCreateAdapt == nullptr || pFuncReleaseAdapt == nullptr) {
  182. return Error_NotInit;
  183. }
  184. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get Adapter object...");
  185. ErrorCodeEnum erroCode = pFuncCreateAdapt((DeviceBaseClass*&)m_AdptObjPtr);
  186. if (IS_FAILURED(erroCode)) {
  187. if (pFuncGetPrefixErr != nullptr) {
  188. char szErrMsg[MAX_DEV_ERROR_MSG_LEN];
  189. memset(szErrMsg, '\0', sizeof(szErrMsg));
  190. DWORD dwLen = MAX_DEV_ERROR_MSG_LEN;
  191. pFuncGetPrefixErr(szErrMsg, &dwLen);
  192. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Create device adapter object failed! EC=%s, Msg:[%s]"
  193. , SpStrError(erroCode), szErrMsg);
  194. }
  195. else {
  196. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("Create device adapter object failed! EC=%s", SpStrError(erroCode));
  197. }
  198. return erroCode;
  199. }
  200. LOG_ASSERT(m_AdptObjPtr != nullptr);
  201. return Error_Succeed;
  202. }
  203. /** Integrate function LoadLibAddress and CreateDevAdptObject, please use LoadUpAdapterLibrary replace with it*/
  204. ErrorCodeEnum LoadUp(const CSimpleStringA& strFullLibPath)
  205. {
  206. ErrorCodeEnum erroCode = LoadLibAddress(strFullLibPath);
  207. if (IS_SUCCEED(erroCode)) {
  208. erroCode = CreateDevAdptObject();
  209. if (!IS_SUCCEED(erroCode)) {
  210. TearDown();
  211. }
  212. }
  213. return erroCode;
  214. }
  215. void TearDown()
  216. {
  217. LOG_FUNCTION();
  218. if (m_AdptObjPtr != nullptr)
  219. {
  220. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("To DevClose...");
  221. ErrorCodeEnum result = m_AdptObjPtr->DevClose();
  222. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("DevClose returned %s", SpStrError(result));
  223. if (nullptr != pFuncReleaseAdapt)
  224. {
  225. DeviceBaseClass* devBasePtr = static_cast<DeviceBaseClass*>(m_AdptObjPtr);
  226. if (devBasePtr != nullptr) {
  227. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("To Release DevAdapter Object...");
  228. pFuncReleaseAdapt(devBasePtr);
  229. m_AdptObjPtr = nullptr;
  230. } else {
  231. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("static cast base dev class failed!");
  232. }
  233. }
  234. }
  235. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to dlclose DevAdapter libs...");
  236. toolkit_dlclose(&m_lib);
  237. pFuncReleaseAdapt = pFuncCreateAdapt = nullptr;
  238. pFuncGetPrefixErr = nullptr;
  239. }
  240. #if defined(RVC_OS_WIN)
  241. ErrorCodeEnum GetDllVersionInfo(LPCTSTR lpcszFilePath, DWORD& dwMajor, DWORD& dwMinor, DWORD& dwBuild, DWORD& dwRevision)
  242. {
  243. char* buf = NULL;
  244. dwMajor = dwMinor = dwBuild = dwRevision = (DWORD)(-1);
  245. DWORD dwHnd;
  246. DWORD dwVerInfoSize;
  247. if (0 >= (dwVerInfoSize = GetFileVersionInfoSizeA(lpcszFilePath, &dwHnd))) {
  248. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("GetFileVersionInfoSizeA failed: %u", GetLastError());
  249. return Error_Unexpect;
  250. }
  251. buf = new char[dwVerInfoSize];
  252. if (NULL == buf) {
  253. return Error_Resource;
  254. }
  255. // get file version info
  256. if (!GetFileVersionInfo(lpcszFilePath, dwHnd, dwVerInfoSize, buf)) {
  257. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("GetFileVersionInfo failed: %u", GetLastError());
  258. delete[] buf;
  259. return Error_Unexpect;
  260. }
  261. // get FileVersion string from resource
  262. VS_FIXEDFILEINFO* ptrVersion;
  263. unsigned int versionLen = 0;
  264. if (!VerQueryValue(buf, "\\", (void**)&ptrVersion, &versionLen)) {
  265. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("VS_FIXEDFILEINFO failed: %u", GetLastError());
  266. delete[] buf;
  267. return Error_Unexpect;
  268. }
  269. dwMajor = (ptrVersion->dwFileVersionMS >> 16) & 0x0000FFFF;
  270. dwMinor = ptrVersion->dwFileVersionMS & 0x0000FFFF;
  271. dwBuild = (ptrVersion->dwFileVersionLS >> 16) & 0x0000FFFF;
  272. dwRevision = ptrVersion->dwFileVersionLS & 0x0000FFFF;
  273. delete[] buf;
  274. return Error_Succeed;
  275. }
  276. #else
  277. ErrorCodeEnum GetDllVersionInfo(LPCTSTR lpcszFilePath, DWORD& dwMajor, DWORD& dwMinor, DWORD& dwBuild, DWORD& dwRevision)
  278. {
  279. dwMajor = dwMinor = dwBuild = dwRevision = 0;
  280. return Error_NotSupport;
  281. }
  282. #endif //RVC_OS_WIN
  283. #if defined(_MSC_VER)
  284. operator bool() const { return (m_AdptObjPtr != nullptr); }
  285. #else
  286. /** Linux 下不加此会影响 编译 Gifur@2023329]*/
  287. explicit operator bool() const { return (m_AdptObjPtr != nullptr); }
  288. #endif //_MSC_VER
  289. operator DeviceBaseClass* () { return m_AdptObjPtr; }
  290. TSubAdpt* GetDevPointer() { return m_AdptObjPtr; }
  291. TSubAdpt* operator->()
  292. {
  293. if (m_AdptObjPtr == nullptr) {
  294. throw std::runtime_error("the dev class pointer is nullptr!!");
  295. }
  296. return m_AdptObjPtr;
  297. }
  298. bool operator !=(TSubAdpt* rhs)
  299. {
  300. return !(m_AdptObjPtr == rhs);
  301. }
  302. bool operator !=(const DevAdptLibHelper& rhs)
  303. {
  304. return !(m_AdptObjPtr == rhs.operator->());
  305. }
  306. DevAdptLibHelper()
  307. : pFuncCreateAdapt(nullptr), pFuncReleaseAdapt(nullptr), pFuncGetPrefixErr(nullptr)
  308. , m_AdptObjPtr(nullptr), m_VS2010BridgeMode(false), m_strAdapterName(true)
  309. {
  310. memset(&m_lib, 0, sizeof(toolkit_lib_t));
  311. }
  312. ~DevAdptLibHelper()
  313. {
  314. TearDown();
  315. }
  316. #if defined(RVC_OS_LINUX)
  317. DevAdptLibHelper(const DevAdptLibHelper&) = delete;
  318. DevAdptLibHelper& operator=(const DevAdptLibHelper&) = delete;
  319. #endif //RVC_OS_LINUX
  320. private:
  321. toolkit_lib_t m_lib;
  322. DevAdaptObjCreateFunc pFuncCreateAdapt;
  323. DevAdaptObjReleaseFunc pFuncReleaseAdapt;
  324. GetDevAdapterVersionFunc pFuncGetDevAdapterVer;
  325. GetPrefixErrMsgFunc pFuncGetPrefixErr;
  326. TSubAdpt* m_AdptObjPtr;
  327. bool m_VS2010BridgeMode;
  328. CSimpleStringA m_strAdapterName;
  329. };
  330. struct AdaptorInfo
  331. {
  332. public:
  333. CSimpleStringA strVendor;
  334. CSimpleStringA strVersion;
  335. CSimpleStringA strBatch;
  336. CSimpleStringA strPort;
  337. CSimpleStringA strBaudrate;
  338. CSimpleStringA strPortNum;
  339. CSimpleStringA strCheckdata;
  340. CSimpleStringA strKeysn;
  341. CSimpleStringA strPureAdapterName;
  342. AdaptorInfo() :strVendor(true), strVersion(true), strBatch(true)
  343. , strPort(true), strBaudrate(true)
  344. , strPortNum(true)
  345. , strCheckdata(true), strKeysn(true), strPureAdapterName(true)
  346. {
  347. }
  348. int GetVersionInt() const
  349. {
  350. int result = 0;
  351. if (!strVersion.IsNullOrEmpty()) {
  352. result = atoi(strVersion.GetData());
  353. }
  354. return result;
  355. }
  356. int GetBatchInt() const
  357. {
  358. int result = 0;
  359. if (!strBatch.IsNullOrEmpty()) {
  360. result = atoi(strBatch.GetData());
  361. }
  362. return result;
  363. }
  364. int GetPortInt() const
  365. {
  366. int result = 0;
  367. if (!strPort.IsNullOrEmpty()) {
  368. result = atoi(strPort.GetData());
  369. }
  370. return result;
  371. }
  372. int GetBaudrateInt() const
  373. {
  374. int result = 0;
  375. if (!strBaudrate.IsNullOrEmpty()) {
  376. result = atoi(strBaudrate.GetData());
  377. }
  378. return result;
  379. }
  380. int GetPortNumInt() const
  381. {
  382. int result = 0;
  383. if (!strPortNum.IsNullOrEmpty()) {
  384. result = atoi(strPortNum.GetData());
  385. }
  386. return result;
  387. }
  388. };
  389. struct AdapterInfo : public AdaptorInfo
  390. {
  391. CSimpleStringA adapterFilePath;
  392. CSimpleStringA adapterFileName;
  393. DevCategoryInfo devCatInfo;
  394. AdapterInfo() :adapterFilePath(true), adapterFileName(true)
  395. {
  396. ZeroMemory(devCatInfo.szModel, sizeof(devCatInfo.szModel));
  397. ZeroMemory(devCatInfo.szType, sizeof(devCatInfo.szType));
  398. ZeroMemory(devCatInfo.szVendor, sizeof(devCatInfo.szVendor));
  399. }
  400. void FulfillCategoryInfo(const DevCategoryInfo& rhs)
  401. {
  402. devCatInfo.eState = rhs.eState;
  403. devCatInfo.version.wMajor = rhs.version.wMajor;
  404. devCatInfo.version.wMinor = rhs.version.wMinor;
  405. devCatInfo.version.wRevision = rhs.version.wRevision;
  406. devCatInfo.version.wBuild = rhs.version.wBuild;
  407. strcpy(devCatInfo.szType, rhs.szType);
  408. strcpy(devCatInfo.szModel, rhs.szModel);
  409. strcpy(devCatInfo.szVendor, rhs.szVendor);
  410. CSimpleStringA strCatVersion = CSimpleStringA::Format("%d.%d.%d.%d", devCatInfo.version.wMajor, devCatInfo.version.wMinor, devCatInfo.version.wRevision, devCatInfo.version.wBuild);
  411. if (strlen(devCatInfo.szType) >= MAX_DEV_TYPE_LEN) {
  412. devCatInfo.szType[MAX_DEV_TYPE_LEN - 1] = '\0';
  413. }
  414. if (strlen(devCatInfo.szModel) >= MAX_DEV_MODEL_LEN) {
  415. devCatInfo.szModel[MAX_DEV_MODEL_LEN - 1] = '\0';
  416. }
  417. if (strlen(devCatInfo.szVendor) >= MAX_DEV_VENDOR_LEN) {
  418. devCatInfo.szVendor[MAX_DEV_VENDOR_LEN - 1] = '\0';
  419. }
  420. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetDevCategory")("{\"szVendor\":\"%s\",\"szType\":\"%s\",\"szModel\":\"%s\",\"szVersion\":\"%s\"}", devCatInfo.szVendor, devCatInfo.szType, devCatInfo.szModel, strCatVersion.GetData());
  421. CheckCategoryInfoFormat();
  422. }
  423. void CheckCategoryInfoFormat()
  424. {
  425. const int DEV_CATINFO_SUM = 3;
  426. char* devInfo[DEV_CATINFO_SUM] = { "szModel", "szVendor", "szType" };
  427. for (int devSn = 0; devSn < DEV_CATINFO_SUM; devSn++)
  428. {
  429. CSimpleStringA strCatInfo;
  430. if (devSn == 0)
  431. strCatInfo = devCatInfo.szModel;
  432. else if (devSn == 1)
  433. strCatInfo = devCatInfo.szVendor;
  434. else if (devSn == 2)
  435. strCatInfo = devCatInfo.szType;
  436. if (!strCatInfo.IsNullOrEmpty())
  437. {
  438. auto arr = strCatInfo.Split('#');
  439. if (arr.GetCount() > 0)
  440. {
  441. for (int sec = 0; sec < arr.GetCount(); sec++)
  442. {
  443. auto arr2 = arr[sec].Split('=');
  444. if (arr2.GetCount() != 2)
  445. {
  446. if (devSn != 1)//szVendor 没有要求符合"key=value#"的格式
  447. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong section of %s:%s", devInfo[devSn], arr[sec].GetData());
  448. continue;
  449. }
  450. if ((strnicmp((LPCTSTR)arr2[0], "MID", strlen("MID")) == 0 && arr2[1].Compare("1.0") != 0)
  451. || (strnicmp((LPCTSTR)arr2[0], "CODE", strlen("CODE")) == 0 && arr2[1].Compare("UCS2") != 0))
  452. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData());
  453. else if (strnicmp((LPCTSTR)arr2[0], "PID", strlen("PID")) == 0 || strnicmp((LPCTSTR)arr2[0], "FWID", strlen("FWID")) == 0)
  454. {
  455. string strData = arr2[1].GetData();
  456. regex pattern(".{8,16}");
  457. smatch sm;
  458. if (!regex_match(strData, sm, pattern))
  459. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData());
  460. }
  461. else if (strnicmp((LPCTSTR)arr2[0], "STYLE", strlen("STYLE")) == 0)
  462. {
  463. string strData = arr2[1].GetData();
  464. regex pattern("CL|IG");
  465. smatch sm;
  466. if (!regex_match(strData, sm, pattern))
  467. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData());
  468. }
  469. else if (strnicmp((LPCTSTR)arr2[0], "RF", strlen("RF")) == 0)
  470. {
  471. string strData = arr2[1].GetData();
  472. regex pattern("Y|N");
  473. smatch sm;
  474. if (!regex_match(strData, sm, pattern))
  475. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData());
  476. }
  477. else if (strnicmp((LPCTSTR)arr2[0], "FUNCTION", strlen("FUNCTION")) == 0)
  478. {
  479. string strData = arr2[1].GetData();
  480. //regex pattern("^(I|T|F|Y|IT|TI|IF|FI|TF|FT|IY|TY|FY|ITF|IFT|FIT|FTI|FIT|FTI)$");//stupid,how to write the right... composite of 'I'/'T'/'F'/'Y'
  481. regex pattern("^[ITFY]{1,4}$");
  482. smatch sm;
  483. if (!regex_match(strData, sm, pattern))
  484. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData());
  485. }
  486. }
  487. }
  488. else
  489. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, can't split from %s:%s", devInfo[devSn], strCatInfo.GetData());
  490. }
  491. else
  492. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, %s is empty.", devInfo[devSn]);
  493. }
  494. }
  495. };
  496. struct ErrorPackageEx {
  497. ErrorCodeEnum errCode;
  498. DWORD apiUserCode;
  499. CSimpleStringA devApi;
  500. bool bInBusiness;
  501. int costTime;
  502. CSimpleStringA funPath;
  503. ErrorPackageEx() :errCode(Error_Succeed), apiUserCode(0), devApi(true), bInBusiness(false), costTime(0), funPath(true) {}
  504. };
  505. struct DevEntityErrorCode {
  506. DWORD dwEntityId;
  507. DWORD dwVendorId;
  508. DWORD dwVendorErroCode;
  509. DWORD dwReserved;
  510. DevEntityErrorCode() :dwEntityId(0), dwVendorId(0), dwVendorErroCode(0), dwReserved(0) {}
  511. void ResetWithEntityID(WORD wEntityID)
  512. {
  513. dwEntityId = dwVendorId = dwVendorErroCode = dwReserved = 0;
  514. dwEntityId = wEntityID;
  515. }
  516. void SetDevCode(DWORD devErrorCode, DWORD dwReservedCode)
  517. {
  518. dwVendorErroCode = devErrorCode;
  519. dwReserved = dwReservedCode;
  520. }
  521. DWORD GetCompleteErrorCode() const
  522. {
  523. return MAKE_SLV_ERRORCODE(dwEntityId, dwVendorId, dwVendorErroCode);
  524. }
  525. };
  526. template<class TFSM, class TDevClass>
  527. class CCommDevFSM : public FSMImpl<TFSM>
  528. {
  529. public:
  530. CCommDevFSM() :m_FirstStart(TRUE), m_iInWhatPage(PageType_Init),m_bOpened(false), m_bOpening(true), m_eDevState(DEVICE_STATUS_NOT_READY),m_contiErrTimes(0)
  531. {
  532. m_WarnCodeMap.insert(std::make_pair<std::string, DWORD>("CardIssuerStand", 0x2030021f));
  533. m_WarnCodeMap.insert(std::make_pair<std::string, DWORD>("CardIssuerStore", 0x2200021f));
  534. m_WarnCodeMap.insert(std::make_pair<std::string, DWORD>("ContactlessCard", 0x21300203));
  535. m_WarnCodeMap.insert(std::make_pair<std::string, DWORD>("FingerPrint", 0x20400211));
  536. m_WarnCodeMap.insert(std::make_pair<std::string, DWORD>("IDCertificate", 0x20100202));
  537. m_WarnCodeMap.insert(std::make_pair<std::string, DWORD>("PinPad", 0x20600207));
  538. m_WarnCodeMap.insert(std::make_pair<std::string, DWORD>("Gpio", 0x20900201));
  539. m_WarnCodeMap.insert(std::make_pair<std::string, DWORD>("HSPScanner", 0x21700207));
  540. m_RootIniCodeMap.insert(std::make_pair<std::string, DWORD>("CardIssuerStand", 0x20300299));
  541. m_RootIniCodeMap.insert(std::make_pair<std::string, DWORD>("CardIssuerStore", 0x22000299));
  542. m_RootIniCodeMap.insert(std::make_pair<std::string, DWORD>("ContactlessCard", 0x21300224));
  543. m_RootIniCodeMap.insert(std::make_pair<std::string, DWORD>("FingerPrint", 0x20400229));
  544. m_RootIniCodeMap.insert(std::make_pair<std::string, DWORD>("IDCertificate", 0x2010021f));
  545. m_RootIniCodeMap.insert(std::make_pair<std::string, DWORD>("PinPad", 0x2060021f));
  546. m_RootIniCodeMap.insert(std::make_pair<std::string, DWORD>("Gpio", 0x20900203));
  547. m_RootIniCodeMap.insert(std::make_pair<std::string, DWORD>("HSPScanner", 0x2170020f));
  548. }
  549. ErrorCodeEnum GetAndSplitDevErrInfo(
  550. CSimpleStringA& csErrMsg, WORD& wdDevErrCode, LPCTSTR lpszFuncNameForDisplay = "");
  551. DWORD SetErrorAndLog(ErrorCodeEnum errCode, DWORD userCode, CSimpleStringA devApi, CSimpleStringA funPath, bool bInBusiness = false, int costTime = 0, CSimpleStringA logCode = "", CSimpleStringA context = "")
  552. {
  553. //set error info
  554. m_errPkgEx.errCode = errCode;
  555. m_errPkgEx.apiUserCode = userCode;
  556. m_errPkgEx.devApi = devApi;
  557. m_errPkgEx.bInBusiness = bInBusiness;
  558. m_errPkgEx.costTime = costTime;
  559. m_errPkgEx.funPath = funPath;
  560. //get DevAdapter vendor errmsg and log info
  561. WORD wdErrCode = 0;
  562. CSimpleStringA csErrMsg(true);
  563. ErrorCodeEnum ec = GetAndSplitDevErrInfo(csErrMsg, wdErrCode, "");
  564. if (ec == Error_Succeed && wdErrCode != 0) {
  565. //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly
  566. if ((m_errPkgEx.apiUserCode >> 20) == m_entCode.dwEntityId)
  567. UpdateDEC(m_errPkgEx.apiUserCode);
  568. else
  569. UpdateDEC(wdErrCode);
  570. }
  571. else if (m_errPkgEx.apiUserCode != 0) {
  572. UpdateDEC(m_errPkgEx.apiUserCode);
  573. }
  574. //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly
  575. const DWORD dwCode = GetAlarmDEC();
  576. const CSimpleStringA alarmMsg = CSimpleStringA::Format("{\"Function\":\"%s\", \"DevApi\":\"%s\", \"ReturnCode\":\"%s\", \"Msg\":\"%s\", \"Context\":\"%s\"}"
  577. , funPath.GetData(), devApi.GetData(), SpStrError(m_errPkgEx.errCode), csErrMsg.GetData(), context.GetData());
  578. std::map<std::string, std::string> msgInfo;
  579. msgInfo["ReturnCode"] = SpStrError(errCode);
  580. msgInfo["ErrMsg"] = csErrMsg.GetData();
  581. msgInfo["Context"] = context.GetData();
  582. std::pair<bool, std::string> strResult;
  583. strResult = generateJsonStr(msgInfo);
  584. CSimpleStringA csErrMsgWithReturnCode = strResult.second.c_str();
  585. CSimpleStringA tmpRTA(true), tmpDesc(true);
  586. this->GetEntityBase()->GetFunction()->GetVTMErrMsg(dwCode, tmpDesc, tmpRTA);
  587. if (bInBusiness) {
  588. LogError(Severity_High, m_errPkgEx.errCode, dwCode, alarmMsg.GetData());
  589. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(logCode).setAPI(devApi).setResultCode(tmpRTA.GetData()).setCostTime(costTime)(csErrMsgWithReturnCode.GetData());
  590. }
  591. else {
  592. LogWarn(Severity_High, m_errPkgEx.errCode, dwCode, alarmMsg.GetData());
  593. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(logCode).setAPI(devApi).setResultCode(tmpRTA.GetData()).setCostTime(costTime)(csErrMsgWithReturnCode.GetData());
  594. }
  595. return dwCode;
  596. }
  597. //在旧dep路径下找到文件时告警
  598. void UpdateAndWarnFileFindInDepBak(CSimpleStringA& newDepPath, const char* filename, DWORD userCode)
  599. {
  600. CSimpleStringA strOldPath;
  601. if (!ExistsFileA(newDepPath.GetData()))
  602. {
  603. ErrorCodeEnum eErrOld = this->GetEntityBase()->GetFunction()->GetPath("DepBak", strOldPath);
  604. if (eErrOld != Error_Succeed)
  605. {
  606. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Get [DepBak] Path failed! errcode:%s.", SpStrError(eErrOld));
  607. }
  608. strOldPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strOldPath.GetData(), filename);
  609. if (ExistsFileA(strOldPath.GetData()))
  610. {
  611. newDepPath = strOldPath;
  612. CSimpleStringA warnMsg = CSimpleStringA::Format("Find %s in OLD dep path!", strOldPath.GetData());
  613. LogWarn(Severity_Middle, Error_Unexpect, userCode, warnMsg.GetData());
  614. }
  615. }
  616. }
  617. ErrorCodeEnum LoadUpAdapterLibrary(const CSimpleStringA& customDllPath = "")
  618. {
  619. m_hDevHelper.SetAdapterName(this->GetEntityBase()->GetEntityName());
  620. ErrorCodeEnum rc = m_hDevHelper.LoadUp(customDllPath.IsNullOrEmpty() ? m_adapterInfo.adapterFilePath : customDllPath);
  621. return rc;
  622. }
  623. /*fulfill adapter elem, open param and adapter file name&absolute path */
  624. void FulfillAdapterInfoFrom(const VendorLibInfo& vendorLib)
  625. {
  626. m_adapterInfo.strVendor = vendorLib.strVendor;
  627. m_adapterInfo.strVersion = vendorLib.strVersion;
  628. m_adapterInfo.strBatch = vendorLib.strBatch;
  629. m_adapterInfo.strPureAdapterName = vendorLib.strFileValue;
  630. CSmartPointer<IConfigInfo> spConfigRoot;
  631. this->GetEntityBase()->GetFunction()->OpenConfig(Config_Root, spConfigRoot);
  632. CSimpleStringA entityName(this->GetEntityBase()->GetEntityName());
  633. if (entityName.Compare("CardIssuerStore", true) == 0 || entityName.Compare("CardIssuerStand", true) == 0) {
  634. entityName = "CardIssuer";
  635. }
  636. CSimpleStringA sectionName = CSimpleStringA::Format("Device.%s", entityName.GetData());
  637. CSimpleStringA csPort(true), csBaudrate(true);
  638. spConfigRoot->ReadConfigValue(sectionName.GetData(), "Port", csPort);
  639. spConfigRoot->ReadConfigValue(sectionName.GetData(), "Baudrate", csBaudrate);
  640. m_adapterInfo.strPort = csPort;
  641. m_adapterInfo.strBaudrate = csBaudrate;
  642. CSimpleStringA csPortNum(true), csCheckData(true), csKeySN(true), csInOutDir(true);
  643. if (!entityName.Compare("Gpio")) {
  644. spConfigRoot->ReadConfigValue(sectionName.GetData(), "PortNum", csPortNum);
  645. m_adapterInfo.strPortNum = csPortNum;
  646. } else if (!entityName.Compare("PinPad")) {
  647. spConfigRoot->ReadConfigValue(sectionName.GetData(), "Checkdata", csCheckData);
  648. spConfigRoot->ReadConfigValue(sectionName.GetData(), "Keysn", csKeySN);
  649. m_adapterInfo.strCheckdata = csCheckData;
  650. m_adapterInfo.strKeysn = csKeySN;
  651. }
  652. m_adapterInfo.adapterFileName = vendorLib.toLibNameString();
  653. CSimpleStringA strDepPath(true);
  654. this->GetEntityBase()->GetFunction()->GetPath("Dep", strDepPath);
  655. m_adapterInfo.adapterFilePath = CSimpleStringA::Format(
  656. "%s" SPLIT_SLASH_STR "%s", (LPCTSTR)strDepPath, (LPCTSTR)m_adapterInfo.adapterFileName);
  657. }
  658. ErrorCodeEnum FulfillAdapterDevCategory()
  659. {
  660. if (!!m_hDevHelper) {
  661. ErrorCodeEnum result(Error_Succeed);
  662. DevCategoryInfo devCat;
  663. ZeroMemory(devCat.szModel, sizeof(devCat.szModel));
  664. ZeroMemory(devCat.szType, sizeof(devCat.szType));
  665. ZeroMemory(devCat.szVendor, sizeof(devCat.szVendor));
  666. result = m_hDevHelper->GetDevCategory(devCat);
  667. if (IS_SUCCEED(result)) {
  668. m_adapterInfo.FulfillCategoryInfo(devCat);
  669. }
  670. return result;
  671. }
  672. return Error_InvalidState;
  673. }
  674. #if defined(_MSC_VER)
  675. const char* LPCSTRSmartPrintString(const CSimpleStringA& str)
  676. {
  677. return str.IsNullOrEmpty() ? "" : str.GetData();
  678. }
  679. CSimpleStringA GenerateJson(AdaptorInfo adaptorInfo, const CSimpleStringA& devDeviceName)
  680. {
  681. CSimpleStringA result(true);
  682. if (0 == devDeviceName.Compare("Gpio", true)) {
  683. result = CSimpleStringA::Format("{\"Vendor\":\"%s\", \"Version\":\"%s\", \"Batch\":\"%s\", \"Port\":\"%s\", \"Baudrate\":\"%s\", \"PortNum\":\"%s\"}",
  684. LPCSTRSmartPrintString(adaptorInfo.strVendor), LPCSTRSmartPrintString(adaptorInfo.strVersion),
  685. LPCSTRSmartPrintString(adaptorInfo.strBatch), LPCSTRSmartPrintString(adaptorInfo.strPort), LPCSTRSmartPrintString(adaptorInfo.strBaudrate),
  686. LPCSTRSmartPrintString(adaptorInfo.strPortNum));
  687. } else if (0 == devDeviceName.Compare("PinPad", true)) {
  688. result = CSimpleStringA::Format("{\"Vendor\":\"%s\", \"Version\":\"%s\", \"Batch\":\"%s\", \"Port\":\"%s\", \"Baudrate\":\"%s\", \"Checkdata\":\"%s\", \"Keysn\":\"%s\"}",
  689. LPCSTRSmartPrintString(adaptorInfo.strVendor), LPCSTRSmartPrintString(adaptorInfo.strVersion),
  690. LPCSTRSmartPrintString(adaptorInfo.strBatch), LPCSTRSmartPrintString(adaptorInfo.strPort), LPCSTRSmartPrintString(adaptorInfo.strBaudrate),
  691. LPCSTRSmartPrintString(adaptorInfo.strCheckdata), LPCSTRSmartPrintString(adaptorInfo.strKeysn));
  692. } else {
  693. result = CSimpleStringA::Format("{\"Vendor\":\"%s\", \"Version\":\"%s\", \"Batch\":\"%s\", \"Port\":\"%s\", \"Baudrate\":\"%s\"}",
  694. LPCSTRSmartPrintString(adaptorInfo.strVendor), LPCSTRSmartPrintString(adaptorInfo.strVersion),
  695. LPCSTRSmartPrintString(adaptorInfo.strBatch), LPCSTRSmartPrintString(adaptorInfo.strPort), LPCSTRSmartPrintString(adaptorInfo.strBaudrate));
  696. }
  697. return result;
  698. }
  699. #endif //_MSC_VER
  700. void ToLogRootINIInfoOnce()
  701. {
  702. CSmartPointer<IConfigInfo> spConfig;
  703. this->GetEntityBase()->GetFunction()->OpenConfig(Config_Cache, spConfig);
  704. CSimpleStringA entityName(this->GetEntityBase()->GetEntityName());
  705. int nUploadTime(0);
  706. spConfig->ReadConfigValueInt("RootUploadFlag", entityName, nUploadTime);
  707. SYSTEMTIME stNow = CSmallDateTime::GetNow().ToSystemTime();
  708. SYSTEMTIME lastUploadTime = CSmallDateTime(nUploadTime).ToSystemTime();
  709. if (lastUploadTime.wYear != stNow.wYear || lastUploadTime.wMonth != stNow.wMonth || lastUploadTime.wDay != stNow.wDay) {
  710. ToLogRootINIInfo();
  711. spConfig->WriteConfigValue("RootUploadFlag", entityName, CSimpleStringA::Format("0x%08X", (DWORD)CSmallDateTime::GetNow()));
  712. }
  713. }
  714. void ToLogRootINIInfo()
  715. {
  716. CSimpleStringA entityName(this->GetEntityBase()->GetEntityName());
  717. std::map<std::string, std::string> rootInfo;
  718. rootInfo["File"] = m_adapterInfo.strPureAdapterName.GetData();
  719. rootInfo["Vendor"] = m_adapterInfo.strVendor.GetData();
  720. rootInfo["Version"] = m_adapterInfo.strVersion.GetData();
  721. rootInfo["Batch"] = m_adapterInfo.strBatch.GetData();
  722. rootInfo["Port"] = m_adapterInfo.strPort.GetData();
  723. rootInfo["Baudrate"] = m_adapterInfo.strBaudrate.GetData();
  724. if (!entityName.Compare("Gpio")) {
  725. rootInfo["PortNum"] = m_adapterInfo.strPortNum.GetData();
  726. } else if (!entityName.Compare("PinPad")) {
  727. rootInfo["Checkdata"] = m_adapterInfo.strCheckdata.GetData();
  728. rootInfo["Keysn"] = m_adapterInfo.strKeysn.GetData();
  729. }
  730. std::pair<bool, std::string> strResult;
  731. strResult = generateJsonStr(rootInfo);
  732. if (!entityName.IsNullOrEmpty()) {
  733. LogWarn(Severity_Low, Error_Debug, m_RootIniCodeMap[entityName.GetData()], strResult.second.c_str());
  734. } else {
  735. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Entity Name is empty, please check!!!");
  736. }
  737. return;
  738. }
  739. /** upload adapter file's hash value and open param as well as dev category information, return if information has uploaded this time*/
  740. bool ToLogWarnInfoAboutTerm()
  741. {
  742. std::map<std::string, std::string> emptys;
  743. return ToLogWarnInfoAboutTermExtend(emptys);
  744. }
  745. /** upload adapter file's hash value and open param as well as dev category information, return if information has uploaded this time
  746. extend from ToLogWarnInfoAboutTerm
  747. */
  748. bool ToLogWarnInfoAboutTermExtend(std::map<std::string, std::string> additionalParams)
  749. {
  750. bool bUpload(false);
  751. int fileSize = 0;
  752. //calculate file hash value
  753. std::map<std::string, std::string> termInfo;
  754. char* strFileHash = new char[128];
  755. if (ExistsFileA(m_adapterInfo.adapterFilePath)) {
  756. BYTE fileHash[32];
  757. SM3File(const_cast<char*>(m_adapterInfo.adapterFilePath.GetData()), fileHash);
  758. ZeroMemory(strFileHash, 128);
  759. SP::Module::Util::HexBuf2StrBuf(fileHash, &strFileHash, 32);
  760. #if defined(_MSC_VER)
  761. HANDLE hFile;
  762. hFile = CreateFile(m_adapterInfo.adapterFilePath.GetData(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  763. if (hFile == INVALID_HANDLE_VALUE) {
  764. fileSize = 0;
  765. } else {
  766. fileSize = GetFileSize(hFile, NULL);
  767. CloseHandle(hFile);
  768. }
  769. #else
  770. //calculate file size
  771. struct stat statbuf;
  772. ZeroMemory(&statbuf, sizeof(statbuf));
  773. stat(m_adapterInfo.adapterFilePath.GetData(), &statbuf);
  774. fileSize = statbuf.st_size;
  775. #endif //_MSC_VER
  776. } else {
  777. memset(strFileHash, '\0', sizeof(char) * 128);
  778. }
  779. //necessary elements about adapter
  780. CSimpleStringA csPortNum(true), csCheckData(true), csKeySN(true), csInOutDir(true);
  781. termInfo["VendorDllName"] = m_adapterInfo.adapterFilePath.GetData();
  782. termInfo["VendorDllFileHash"] = strFileHash;
  783. ZeroMemory(strFileHash, 128);
  784. termInfo["VendorDllFileSize"] = _itoa(fileSize, strFileHash, 10);
  785. termInfo["szModel"] = m_adapterInfo.devCatInfo.szModel;
  786. termInfo["szType"] = m_adapterInfo.devCatInfo.szType;
  787. termInfo["Port"] = m_adapterInfo.strPort.GetData();
  788. termInfo["Baudrate"] = m_adapterInfo.strBaudrate.GetData();
  789. if (strFileHash != nullptr) {
  790. delete[] strFileHash;
  791. strFileHash = nullptr;
  792. }
  793. CSimpleStringA entityName(this->GetEntityBase()->GetEntityName());
  794. if (!entityName.Compare("Gpio")) {
  795. termInfo["PortNum"] = m_adapterInfo.strPortNum.GetData();
  796. }
  797. else if (!entityName.Compare("PinPad")) {
  798. termInfo["CheckData"] = m_adapterInfo.strCheckdata.GetData();
  799. termInfo["Keysn"] = m_adapterInfo.strKeysn.GetData();
  800. }
  801. if (!additionalParams.empty()) {
  802. for (auto it = additionalParams.cbegin(); it != additionalParams.cend(); ++it) {
  803. termInfo[it->first.c_str()] = it->second;
  804. }
  805. }
  806. std::pair<bool, std::string> strResult;
  807. strResult = generateJsonStr(termInfo);
  808. CSmartPointer<IConfigInfo> spConfigRun;
  809. CSimpleStringA csWarnMsg;
  810. this->GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfigRun);
  811. spConfigRun->ReadConfigValue("Run", "WarnMsg", csWarnMsg);
  812. SYSTEMTIME localTime;
  813. GetLocalTime(&localTime);
  814. if (csWarnMsg.IsNullOrEmpty() || csWarnMsg.Compare(strResult.second.c_str()) != 0) {
  815. spConfigRun->WriteConfigValueInt("Run", "WarnDay", localTime.wDay);
  816. spConfigRun->WriteConfigValue("Run", "WarnMsg", strResult.second.c_str());
  817. if (!entityName.IsNullOrEmpty()) {
  818. LogWarn(Severity_Low, Error_Unexpect, m_WarnCodeMap[entityName.GetData()], strResult.second.c_str());
  819. bUpload = true;
  820. } else {
  821. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Entity Name is empty, please check!!!");
  822. }
  823. } else {
  824. int wDay = 99;
  825. spConfigRun->ReadConfigValueInt("Run", "WarnDay", wDay);
  826. if (wDay != localTime.wDay) {
  827. spConfigRun->WriteConfigValueInt("Run", "WarnDay", localTime.wDay);
  828. if (!entityName.IsNullOrEmpty()) {
  829. LogWarn(Severity_Low, Error_Unexpect, m_WarnCodeMap[entityName.GetData()], strResult.second.c_str());
  830. bUpload = true;
  831. } else {
  832. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Entity Name is empty, please check!!!");
  833. }
  834. }
  835. }
  836. return bUpload;
  837. }
  838. void ResetRepeatErrTimes()
  839. {
  840. m_contiErrTimes = 0;
  841. }
  842. /** TODO等待废弃,不建议再继续使用 [Gifur@2025114]*/
  843. ErrorCodeEnum TransECWithRepeat(const ErrorCodeEnum& ec)
  844. {
  845. ErrorCodeEnum result(ec);
  846. if (ec != Error_Succeed) {
  847. if (!m_bOpened) {
  848. result = Error_DevNotAvailable;
  849. } else if (0 < CountDevError(this->GetEntityBase())) {
  850. result = Error_DevFailAddUp;
  851. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER)("exceed max allow repeat error times! 0x%x -> 0x%x", ec, result);
  852. }
  853. }
  854. return result;
  855. }
  856. virtual ErrorCodeEnum PreOpenDevice() { return Error_Succeed; }
  857. virtual ErrorCodeEnum ToOpenDevice() { return Error_NotImpl; }
  858. virtual ErrorCodeEnum PostOpenDevice() { return Error_Succeed; }
  859. //暂时未使用
  860. ErrorCodeEnum OpenDevice()
  861. {
  862. if (m_bOpening) {
  863. return Error_Pending;
  864. }
  865. if (m_bOpened) {
  866. return Error_DevAlreadyConnected;
  867. }
  868. m_bOpening = true;
  869. ErrorCodeEnum result = PreOpenDevice();
  870. if (IS_SUCCEED(result)) {
  871. result = ToOpenDevice();
  872. if (IS_SUCCEED(result)) {
  873. m_bOpened = true;
  874. result = PostOpenDevice();
  875. }
  876. }
  877. m_bOpening = false;
  878. return result;
  879. }
  880. virtual void SetDevInitFlag(bool val = true) {
  881. m_bOpened = val;
  882. }
  883. bool GetDevInitFlag() const {
  884. return m_bOpened;
  885. }
  886. virtual void SetDevInitingFlag(bool val = true) {
  887. m_bOpening = val;
  888. }
  889. bool GetDevInitingFlag() const {
  890. return m_bOpening;
  891. }
  892. virtual void SetInWhatPage(int iPageType) {
  893. m_iInWhatPage = iPageType;
  894. }
  895. void OnUIState4SetWhatPage(const char* pcszValue) {
  896. if (pcszValue != NULL && strlen(pcszValue) > 0) {
  897. //增加页面位置判断
  898. if (_strnicmp(pcszValue, "M", strlen("M")) == 0) {
  899. SetInWhatPage(PageType_MainPage);
  900. }
  901. else if (_strnicmp(pcszValue, "U", strlen("U")) == 0) {
  902. SetInWhatPage(PageType_UserDesktop);
  903. }
  904. else {
  905. SetInWhatPage(PageType_Other);
  906. }
  907. }
  908. }
  909. virtual DevStateEnum GetDevState() const {
  910. return m_eDevState;
  911. }
  912. void SetDevState(DevStateEnum val) {
  913. m_eDevState = val;
  914. }
  915. public:
  916. bool m_bOpened;
  917. bool m_bOpening;
  918. protected:
  919. DevAdptLibHelper<TDevClass> m_hDevHelper;
  920. DevEntityErrorCode m_entCode;
  921. BOOL m_FirstStart;
  922. int m_iInWhatPage/*在哪个页面,区分首页,用户桌面,其他页*/;
  923. ErrorPackageEx m_errPkgEx;
  924. unsigned int m_contiErrTimes;
  925. AdapterInfo m_adapterInfo;
  926. DevStateEnum m_eDevState;
  927. void UpdateEntityIDIfZero()
  928. {
  929. if (m_entCode.dwEntityId == 0) {
  930. UpdateEntityID();
  931. }
  932. }
  933. void UpdateEntityID()
  934. {
  935. CEntityStaticInfo esi = { 0 };
  936. ErrorCodeEnum ec = this->GetEntityBase()->GetFunction()->GetEntityStaticInfo(this->GetEntityBase()->GetEntityName(), esi);
  937. if (ec == Error_Succeed) {
  938. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("wEntityDevelopID: 0x%X", esi.wEntityDevelopID);
  939. m_entCode.ResetWithEntityID(esi.wEntityDevelopID);
  940. }
  941. }
  942. DWORD GetEntityID()
  943. {
  944. UpdateEntityIDIfZero();
  945. return m_entCode.dwEntityId;
  946. }
  947. DWORD UpdateDEC(DWORD dwVal = 0)
  948. {
  949. UpdateEntityIDIfZero();
  950. /** 14 is for entity define, FC(6bit) is reserved*/
  951. int reserved = (dwVal & 0xFC000) >> 14;
  952. m_entCode.SetDevCode(dwVal, reserved);
  953. return GetDEC();
  954. }
  955. DWORD GetDEC() const
  956. {
  957. return m_entCode.GetCompleteErrorCode();
  958. }
  959. DWORD GetAlarmDEC(DWORD dwValue = 0)
  960. {
  961. if (dwValue > 0)
  962. UpdateDEC(dwValue);
  963. //if have been set ErrorCode of entity defined (not device),use it directly
  964. DWORD dwCode = 0;
  965. //if ((m_entCode.dwVendorErroCode >> 20) == m_entCode.dwEntityId)
  966. if(IsEntityIDSettle(m_entCode.dwVendorErroCode))
  967. dwCode = m_entCode.dwVendorErroCode;
  968. else
  969. dwCode = HARDWARE_ENTITY_MAKE_ERRORCODE_TO_BUSINESS(m_entCode);
  970. return dwCode;
  971. }
  972. void ClearRelatedDEC()
  973. {
  974. UpdateDEC();
  975. }
  976. bool IsEntityIDSettle(const DWORD& dwVal) const
  977. {
  978. return ((dwVal >> 20) == m_entCode.dwEntityId);
  979. }
  980. static void GetFileSizeAndCalcHashValue(const char* fileName, int& fileSize, BYTE fileHash[32])
  981. {
  982. HANDLE hFile;
  983. hFile = CreateFile(fileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  984. if (hFile == INVALID_HANDLE_VALUE) {
  985. fileSize = 0;
  986. return;
  987. }
  988. fileSize = GetFileSize(hFile, NULL);
  989. CloseHandle(hFile);
  990. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to calc vendor dll hash");
  991. SM3File(const_cast<char*>(fileName), fileHash);
  992. return;
  993. }
  994. int CountDevError(CEntityBase *pEntityBase);
  995. virtual bool IsInBusiness() const {
  996. return (m_iInWhatPage == PageType_Other);
  997. }
  998. virtual void OnHardwareShakeHand(CSmartPointer<ITransactionContext> pTransactionContext);
  999. private:
  1000. std::map<std::string, DWORD> m_WarnCodeMap;
  1001. std::map<std::string, DWORD> m_RootIniCodeMap;
  1002. };
  1003. template<class TFSM, class TDevClass>
  1004. inline ErrorCodeEnum CCommDevFSM<TFSM, TDevClass>::GetAndSplitDevErrInfo(
  1005. CSimpleStringA& csErrMsg, WORD& wdDevErrCode, LPCTSTR lpszFuncNameForDisplay)
  1006. {
  1007. csErrMsg = "";
  1008. wdDevErrCode = 0;
  1009. BOOL bDisplayFunName = TRUE;
  1010. if (lpszFuncNameForDisplay == NULL || strlen(lpszFuncNameForDisplay) == 0) {
  1011. bDisplayFunName = FALSE;
  1012. }
  1013. if (!m_hDevHelper) {
  1014. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("inst occurs nullptr !!!");
  1015. return Error_Param;
  1016. }
  1017. DevErrorInfo devErrInfo;
  1018. ZeroMemory(&devErrInfo, sizeof(DevErrorInfo));
  1019. ErrorCodeEnum erroCode = m_hDevHelper->GetLastErr(devErrInfo);
  1020. if (erroCode == Error_Succeed) {
  1021. if (strlen(devErrInfo.szErrMsg) > 0) {
  1022. csErrMsg = devErrInfo.szErrMsg;
  1023. }
  1024. if (devErrInfo.dwErrMsgLen > MAX_DEV_ERROR_MSG_LEN) {
  1025. wdDevErrCode = (WORD)((devErrInfo.dwErrMsgLen >> 16) & 0x0000FFFF);
  1026. }
  1027. if (bDisplayFunName) {
  1028. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(lpszFuncNameForDisplay)("Invoke <%s> failed, Dev_GLE: DevErrCode[%d], ErrMsg[%s]",
  1029. lpszFuncNameForDisplay, wdDevErrCode, (LPCTSTR)csErrMsg);
  1030. } else {
  1031. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Dev_GLE: DevErrCode[%d], ErrMsg[%s]", wdDevErrCode, (LPCTSTR)csErrMsg);
  1032. }
  1033. } else {
  1034. if (bDisplayFunName) {
  1035. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("DevAdapter::GetLastErr")("Invoke <%s> failed, and unfortunately Dev_GLE failed returned EC: %s",
  1036. lpszFuncNameForDisplay, SpStrError(erroCode));
  1037. csErrMsg = CSimpleStringA::Format("Invoke <%s> failed", lpszFuncNameForDisplay);
  1038. } else {
  1039. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI("DevAdapter::GetLastErr")("Dev_GLE failed returned EC: %s", SpStrError(erroCode));
  1040. }
  1041. }
  1042. /** reset vendor device error code to stop reporting to alarm [12/11/2020 Gifur] */
  1043. wdDevErrCode = 0;
  1044. return erroCode;
  1045. }
  1046. //1:报错累计到上限,需要返回错误码给业务
  1047. //0:报错累计未到上限,或者不需要计数
  1048. //-1:出现错误
  1049. template<class TFSM, class TDevClass>
  1050. int CCommDevFSM<TFSM, TDevClass>::CountDevError(CEntityBase* pEntityBase)
  1051. {
  1052. static int iErrNumLimit = -1;
  1053. if (iErrNumLimit == -1) {
  1054. CSmartPointer<IConfigInfo> spCenterConfig;
  1055. ErrorCodeEnum eErrDev = pEntityBase->GetFunction()->OpenConfig(Config_CenterSetting, spCenterConfig);
  1056. if (eErrDev != Error_Succeed) {
  1057. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("open centersetting file failed!");
  1058. return -1;
  1059. } else {
  1060. int value(0);
  1061. spCenterConfig->ReadConfigValueInt("Common", "ErrUpperLimit", value);
  1062. if (0 == value) {
  1063. iErrNumLimit = 5;
  1064. } else if (0 > value) {
  1065. iErrNumLimit = 0;
  1066. } else {
  1067. iErrNumLimit = value;
  1068. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("iErrNumLimit=%d", iErrNumLimit);
  1069. }
  1070. }
  1071. }
  1072. m_contiErrTimes++;
  1073. if (iErrNumLimit > 0 && m_contiErrTimes >= iErrNumLimit) {
  1074. return 1;
  1075. } else {
  1076. return 0;
  1077. }
  1078. }
  1079. template<class TFSM, class TDevClass>
  1080. void CCommDevFSM<TFSM, TDevClass>::OnHardwareShakeHand(CSmartPointer<ITransactionContext> pTransactionContext)
  1081. {
  1082. if (m_eDevState == DEVICE_STATUS_NORMAL)
  1083. pTransactionContext->SendAnswer(Error_Succeed);
  1084. else
  1085. {
  1086. if (m_bOpening)
  1087. pTransactionContext->SendAnswer(Error_Succeed);
  1088. else if (!m_bOpened)
  1089. pTransactionContext->SendAnswer(Error_DevNotAvailable);
  1090. else
  1091. pTransactionContext->SendAnswer(Error_InvalidState);
  1092. }
  1093. }
  1094. #endif /*_COMM_DEVICE_FSM_BASE_HPP_*/