DevFSMCommBase.hpp 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  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. #include "RVCEventCode.h"
  16. #if defined(_MSC_VER)
  17. #pragma comment(lib, "Version.lib")
  18. #endif //_MSC_VER
  19. using DevAdaptObjCreateFunc = ErrorCodeEnum(*)(DeviceBaseClass*& pOutDevAptObj);
  20. using DevAdaptObjReleaseFunc = ErrorCodeEnum(*)(DeviceBaseClass*& pInDevAptObj);
  21. using GetPrefixErrMsgFunc = void(*)(char* szErrMsg, DWORD* pMsgLen);
  22. typedef ErrorCodeEnum(*GetDevAdapterVersionFunc)(DevSoftVersion& retVersion);
  23. #define HARDWARE_ENTITY_RESET_ENTITYID(ent, entityID) \
  24. do{\
  25. memset(&ent, 0, sizeof(ent)); \
  26. ent.dwEntityId = entityID; \
  27. } while (false)
  28. #define HARDWARE_ENTITY_MAKE_ERRORCODE_TO_BUSINESS(ec) \
  29. MAKE_SLV_ERRORCODE_TO_BUSINESS(ec.dwEntityId, ec.dwVendorErroCode, ec.dwReserved)
  30. enum PageType
  31. {
  32. PageType_Init,
  33. PageType_MainPage,
  34. PageType_UserDesktop,
  35. PageType_Other,
  36. };
  37. template <typename TSubAdpt>
  38. struct DevAdptLibHelper
  39. {
  40. private:
  41. bool CheckAndGetMapAdatperName(const CSimpleStringA& strPath, CSimpleStringA& replaceAdapterName)
  42. {
  43. bool result = false;
  44. CSimpleStringA strTest = m_strAdapterName.IsNullOrEmpty() ? strPath.GetData() : m_strAdapterName.GetData();
  45. for (int i = 0; i < strTest.GetLength(); ++i) {
  46. if (strTest[i] >= 'A' && strTest[i] <= 'Z') strTest[i] = strTest[i] + ('a' - 'A');
  47. }
  48. if (strTest.IndexOf("pinpad") != -1) {
  49. replaceAdapterName = "PinPad.self.1.1.dll";
  50. result = true;
  51. } else if (strTest.IndexOf("cardissuer") != -1) {
  52. replaceAdapterName = "CardIssuer.self.1.1.dll";
  53. result = true;
  54. } else if (strTest.IndexOf("contactlesscard") != -1) {
  55. replaceAdapterName = "ContactlessCard.self.1.1.dll";
  56. result = true;
  57. } else if (strTest.IndexOf("fingerprint") != -1) {
  58. replaceAdapterName = "FingerPrint.self.1.1.dll";
  59. result = true;
  60. } else if (strTest.IndexOf("gpio") != -1) {
  61. replaceAdapterName = "GPIO.self.1.1.dll";
  62. result = true;
  63. } else if (strTest.IndexOf("idcertificate") != -1) {
  64. replaceAdapterName = "IDCertificate.self.1.1.dll";
  65. result = true;
  66. } else if (strTest.IndexOf("hspscanner") != -1) {
  67. replaceAdapterName = "HSPSCanner.self.1.1.dll";
  68. result = true;
  69. }
  70. return result;
  71. }
  72. bool PreLoadLib(CSimpleStringA& strFullLibPath)
  73. {
  74. bool result(false);
  75. ///*TODO: Test (80374374@1/23/2024)*/
  76. DWORD d1;
  77. DWORD d2;
  78. DWORD d3;
  79. DWORD d4;
  80. if (!ExistsFileA(strFullLibPath)) {
  81. return result;
  82. }
  83. #ifndef DEVOPS_ON_PRD
  84. GetDllVersionInfo(strFullLibPath, d1, d2, d3, d4);
  85. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("dll %s version: %d.%d.%d.%d", strFullLibPath.GetData(), d1, d2, d3, d4);
  86. //VC16.0 [1920,1929] VS2019 142
  87. if (d4 >= 1920 && d4 <= 1929 && d3 == 142) {
  88. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("detect it built with VS2019, skip latter procedure, version: %d.%d.%d.%d", d1, d2, d3, d4);
  89. return result;
  90. }
  91. #endif
  92. CSimpleStringA strTest = strFullLibPath.GetData();
  93. CSimpleStringA strSelf(true);
  94. if (CheckAndGetMapAdatperName(strTest, strSelf)) {
  95. int index = -1;
  96. for (int i = 0; i < strTest.GetLength(); ++i)
  97. if (strTest[i] == '\\' || strTest[i] == '/') index = i;
  98. if (index != -1) {
  99. toolkit_setenv("INVOKE_VENDOR_ADAPTER_NAME", strFullLibPath.GetData());
  100. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("env:%s", strFullLibPath.GetData());
  101. CSimpleStringA strAdapterName = strTest.SubString(index + 1);
  102. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("adapter name:%s", strAdapterName.GetData());
  103. strTest[index + 1] = '\0'; //!!!!
  104. strFullLibPath = strTest.SubString(0, index + 1);
  105. strFullLibPath += strSelf;
  106. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("new adapter path:%s", strFullLibPath.GetData());
  107. result = true;
  108. }
  109. }
  110. return result;
  111. }
  112. public:
  113. void SetAdapterName(const CSimpleStringA& strEntityName) { m_strAdapterName = strEntityName; }
  114. ErrorCodeEnum LoadLibAddress(const CSimpleStringA& strFullLibPath)
  115. {
  116. ErrorCodeEnum erroCode = Error_Succeed;
  117. CSimpleStringA strTemp = strFullLibPath.GetData();
  118. #if defined(_MSC_VER)
  119. m_VS2010BridgeMode = PreLoadLib(strTemp);
  120. #endif //_MSC_VER
  121. do {
  122. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to load lib: %s", strTemp.GetData());
  123. if (!ExistsFileA(strTemp)) {
  124. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("the lib file %s is not existed!", strTemp.GetData());
  125. erroCode = Error_NotExist;
  126. break;
  127. }
  128. int res = toolkit_dlopen(strTemp, &m_lib);
  129. if (res != 0) {
  130. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setResultCode(DEVICE_FSM_LOADADDR_DLOPEN_FAILED)("toolkit_dlopen[%s] failed with error %s.", strTemp.GetData(), toolkit_dlerror(&m_lib));
  131. erroCode = Error_DevLoadFileFailed;
  132. break;
  133. }
  134. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get CreateDevComponent pointer address...");
  135. if ((res = toolkit_dlsym(&m_lib, "CreateDevComponent", (void**)&pFuncCreateAdapt)) != 0)
  136. {
  137. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setResultCode(DEVICE_FSM_LOADADDR_CREATEOJ_FAILED)("Get 'CreateDevComponent' Func address failed with error: %s", toolkit_dlerror(&m_lib));
  138. erroCode = Error_DevLoadFileFailed;
  139. break;
  140. }
  141. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get ReleaseDevComponent pointer address...");
  142. if ((res = toolkit_dlsym(&m_lib, "ReleaseDevComponent", (void**)&pFuncReleaseAdapt)) != 0)
  143. {
  144. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setResultCode(DEVICE_FSM_LOADADDR_RELOJ_FAILED)("Get 'ReleaseDevComponent' Func address failed with error: %s", toolkit_dlerror(&m_lib));
  145. erroCode = Error_DevLoadFileFailed;
  146. break;
  147. }
  148. #if defined(RVC_OS_WIN)
  149. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get GetMoreErrorDetail pointer address...");
  150. if ((res = toolkit_dlsym(&m_lib, "GetMoreErrorDetail", (void**)&pFuncGetPrefixErr)) != 0)
  151. {//该接口是后面加到桥接层适配器的,所以报错不作强制性阻碍
  152. pFuncGetPrefixErr = nullptr;
  153. }
  154. else {
  155. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("Get 'GetMoreErrorDetail' Func address succ");
  156. }
  157. #endif //RVC_OS_WIN
  158. } while (false);
  159. if (IS_FAILURED(erroCode))
  160. {
  161. TearDown();
  162. }
  163. return erroCode;
  164. }
  165. ErrorCodeEnum CreateDevAdptObject()
  166. {
  167. if (m_AdptObjPtr != nullptr) {
  168. return Error_AlreadyExist;
  169. }
  170. if (pFuncCreateAdapt == nullptr || pFuncReleaseAdapt == nullptr) {
  171. return Error_NotInit;
  172. }
  173. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to get Adapter object...");
  174. ErrorCodeEnum erroCode = pFuncCreateAdapt((DeviceBaseClass*&)m_AdptObjPtr);
  175. if (IS_FAILURED(erroCode)) {
  176. if (pFuncGetPrefixErr != nullptr) {
  177. char szErrMsg[MAX_DEV_ERROR_MSG_LEN];
  178. memset(szErrMsg, '\0', sizeof(szErrMsg));
  179. DWORD dwLen = MAX_DEV_ERROR_MSG_LEN;
  180. pFuncGetPrefixErr(szErrMsg, &dwLen);
  181. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setResultCode(DEVICE_FSM_CREATE_DEVOBJ_FAILED)("Create device adapter object failed! EC=%s, Msg:[%s]"
  182. , SpStrError(erroCode), szErrMsg);
  183. }
  184. else {
  185. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setResultCode(DEVICE_FSM_CREATE_DEVOBJ_FAILED)("Create device adapter object failed! EC=%s", SpStrError(erroCode));
  186. }
  187. return erroCode;
  188. }
  189. LOG_ASSERT(m_AdptObjPtr != nullptr);
  190. return Error_Succeed;
  191. }
  192. /** Integrate function LoadLibAddress and CreateDevAdptObject, please use LoadUpAdapterLibrary replace with it*/
  193. ErrorCodeEnum LoadUp(const CSimpleStringA& strFullLibPath)
  194. {
  195. ErrorCodeEnum erroCode = LoadLibAddress(strFullLibPath);
  196. if (IS_SUCCEED(erroCode)) {
  197. erroCode = CreateDevAdptObject();
  198. if (!IS_SUCCEED(erroCode)) {
  199. TearDown();
  200. }
  201. }
  202. return erroCode;
  203. }
  204. void TearDown()
  205. {
  206. if (m_AdptObjPtr != nullptr)
  207. {
  208. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("To DevClose...");
  209. ULONGLONG ullStart = SP::Module::Comm::RVCGetTickCount();
  210. ErrorCodeEnum result = m_AdptObjPtr->DevClose();
  211. ULONGLONG ullEnd = SP::Module::Comm::RVCGetTickCount();
  212. if (IS_FAILURED(result)) {
  213. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode(DEVICE_FSM_DEVCLOSE_FAILED)/*.setAPI("DevAdapter::DevClose") 不纳入适配器消费,因为不好分配RTA,只做调研*/
  214. .setCostTime(ullEnd - ullStart)("DevClose returned %s", SpStrError(result));
  215. }
  216. if (nullptr != pFuncReleaseAdapt)
  217. {
  218. DeviceBaseClass* devBasePtr = static_cast<DeviceBaseClass*>(m_AdptObjPtr);
  219. if (devBasePtr != nullptr) {
  220. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("To Release DevAdapter Object...");
  221. pFuncReleaseAdapt(devBasePtr);
  222. m_AdptObjPtr = nullptr;
  223. }
  224. }
  225. }
  226. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to dlclose DevAdapter libs...");
  227. toolkit_dlclose(&m_lib);
  228. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("dlclose DevAdapter libs succ");
  229. pFuncReleaseAdapt = pFuncCreateAdapt = nullptr;
  230. pFuncGetPrefixErr = nullptr;
  231. }
  232. #if defined(RVC_OS_WIN)
  233. ErrorCodeEnum GetDllVersionInfo(LPCTSTR lpcszFilePath, DWORD& dwMajor, DWORD& dwMinor, DWORD& dwBuild, DWORD& dwRevision)
  234. {
  235. char* buf = NULL;
  236. dwMajor = dwMinor = dwBuild = dwRevision = (DWORD)(-1);
  237. DWORD dwHnd;
  238. DWORD dwVerInfoSize;
  239. if (0 >= (dwVerInfoSize = GetFileVersionInfoSizeA(lpcszFilePath, &dwHnd))) {
  240. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("GetFileVersionInfoSizeA failed: %u", GetLastError());
  241. return Error_Unexpect;
  242. }
  243. buf = new char[dwVerInfoSize];
  244. if (NULL == buf) {
  245. return Error_Resource;
  246. }
  247. // get file version info
  248. if (!GetFileVersionInfo(lpcszFilePath, dwHnd, dwVerInfoSize, buf)) {
  249. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("GetFileVersionInfo failed: %u", GetLastError());
  250. delete[] buf;
  251. return Error_Unexpect;
  252. }
  253. // get FileVersion string from resource
  254. VS_FIXEDFILEINFO* ptrVersion;
  255. unsigned int versionLen = 0;
  256. if (!VerQueryValue(buf, "\\", (void**)&ptrVersion, &versionLen)) {
  257. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("VS_FIXEDFILEINFO failed: %u", GetLastError());
  258. delete[] buf;
  259. return Error_Unexpect;
  260. }
  261. dwMajor = (ptrVersion->dwFileVersionMS >> 16) & 0x0000FFFF;
  262. dwMinor = ptrVersion->dwFileVersionMS & 0x0000FFFF;
  263. dwBuild = (ptrVersion->dwFileVersionLS >> 16) & 0x0000FFFF;
  264. dwRevision = ptrVersion->dwFileVersionLS & 0x0000FFFF;
  265. delete[] buf;
  266. return Error_Succeed;
  267. }
  268. #else
  269. ErrorCodeEnum GetDllVersionInfo(LPCTSTR lpcszFilePath, DWORD& dwMajor, DWORD& dwMinor, DWORD& dwBuild, DWORD& dwRevision)
  270. {
  271. dwMajor = dwMinor = dwBuild = dwRevision = 0;
  272. return Error_NotSupport;
  273. }
  274. #endif //RVC_OS_WIN
  275. #if defined(_MSC_VER)
  276. operator bool() const { return (m_AdptObjPtr != nullptr); }
  277. #else
  278. /** Linux 下不加此会影响 编译 Gifur@2023329]*/
  279. explicit operator bool() const { return (m_AdptObjPtr != nullptr); }
  280. #endif //_MSC_VER
  281. operator DeviceBaseClass* () { return m_AdptObjPtr; }
  282. TSubAdpt* GetDevPointer() { return m_AdptObjPtr; }
  283. TSubAdpt* operator->()
  284. {
  285. if (m_AdptObjPtr == nullptr) {
  286. throw std::runtime_error("the dev class pointer is nullptr!!");
  287. }
  288. return m_AdptObjPtr;
  289. }
  290. bool operator !=(TSubAdpt* rhs)
  291. {
  292. return !(m_AdptObjPtr == rhs);
  293. }
  294. bool operator !=(const DevAdptLibHelper& rhs)
  295. {
  296. return !(m_AdptObjPtr == rhs.operator->());
  297. }
  298. DevAdptLibHelper()
  299. : pFuncCreateAdapt(nullptr), pFuncReleaseAdapt(nullptr), pFuncGetPrefixErr(nullptr)
  300. , m_AdptObjPtr(nullptr), m_VS2010BridgeMode(false), m_strAdapterName(true)
  301. {
  302. memset(&m_lib, 0, sizeof(toolkit_lib_t));
  303. }
  304. ~DevAdptLibHelper()
  305. {
  306. TearDown();
  307. }
  308. #if defined(RVC_OS_LINUX)
  309. DevAdptLibHelper(const DevAdptLibHelper&) = delete;
  310. DevAdptLibHelper& operator=(const DevAdptLibHelper&) = delete;
  311. #endif //RVC_OS_LINUX
  312. private:
  313. toolkit_lib_t m_lib;
  314. DevAdaptObjCreateFunc pFuncCreateAdapt;
  315. DevAdaptObjReleaseFunc pFuncReleaseAdapt;
  316. GetDevAdapterVersionFunc pFuncGetDevAdapterVer;
  317. GetPrefixErrMsgFunc pFuncGetPrefixErr;
  318. TSubAdpt* m_AdptObjPtr;
  319. bool m_VS2010BridgeMode;
  320. CSimpleStringA m_strAdapterName;
  321. };
  322. struct AdaptorInfo
  323. {
  324. public:
  325. CSimpleStringA strVendor;
  326. CSimpleStringA strVersion;
  327. CSimpleStringA strBatch;
  328. CSimpleStringA strPort;
  329. CSimpleStringA strBaudrate;
  330. CSimpleStringA strPortNum;
  331. CSimpleStringA strPureAdapterName;
  332. AdaptorInfo() :strVendor(true), strVersion(true), strBatch(true)
  333. , strPort(true), strBaudrate(true)
  334. , strPortNum(true)
  335. , strPureAdapterName(true)
  336. {
  337. }
  338. int GetVersionInt() const
  339. {
  340. int result = 0;
  341. if (!strVersion.IsNullOrEmpty()) {
  342. result = atoi(strVersion.GetData());
  343. }
  344. return result;
  345. }
  346. int GetBatchInt() const
  347. {
  348. int result = 0;
  349. if (!strBatch.IsNullOrEmpty()) {
  350. result = atoi(strBatch.GetData());
  351. }
  352. return result;
  353. }
  354. int GetPortInt() const
  355. {
  356. int result = 0;
  357. if (!strPort.IsNullOrEmpty()) {
  358. result = atoi(strPort.GetData());
  359. }
  360. return result;
  361. }
  362. int GetBaudrateInt() const
  363. {
  364. int result = 0;
  365. if (!strBaudrate.IsNullOrEmpty()) {
  366. result = atoi(strBaudrate.GetData());
  367. }
  368. return result;
  369. }
  370. int GetPortNumInt() const
  371. {
  372. int result = 0;
  373. if (!strPortNum.IsNullOrEmpty()) {
  374. result = atoi(strPortNum.GetData());
  375. }
  376. return result;
  377. }
  378. };
  379. struct AdapterInfo : public AdaptorInfo
  380. {
  381. CSimpleStringA adapterFilePath;
  382. CSimpleStringA adapterFileName;
  383. DevCategoryInfo devCatInfo;
  384. AdapterInfo() :adapterFilePath(true), adapterFileName(true)
  385. {
  386. ZeroMemory(devCatInfo.szModel, sizeof(devCatInfo.szModel));
  387. ZeroMemory(devCatInfo.szType, sizeof(devCatInfo.szType));
  388. ZeroMemory(devCatInfo.szVendor, sizeof(devCatInfo.szVendor));
  389. }
  390. void FulfillCategoryInfo(const DevCategoryInfo& rhs)
  391. {
  392. devCatInfo.eState = rhs.eState;
  393. devCatInfo.version.wMajor = rhs.version.wMajor;
  394. devCatInfo.version.wMinor = rhs.version.wMinor;
  395. devCatInfo.version.wRevision = rhs.version.wRevision;
  396. devCatInfo.version.wBuild = rhs.version.wBuild;
  397. strcpy(devCatInfo.szType, rhs.szType);
  398. strcpy(devCatInfo.szModel, rhs.szModel);
  399. strcpy(devCatInfo.szVendor, rhs.szVendor);
  400. CSimpleStringA strCatVersion = CSimpleStringA::Format("%d.%d.%d.%d", devCatInfo.version.wMajor, devCatInfo.version.wMinor, devCatInfo.version.wRevision, devCatInfo.version.wBuild);
  401. if (strlen(devCatInfo.szType) >= MAX_DEV_TYPE_LEN) {
  402. devCatInfo.szType[MAX_DEV_TYPE_LEN - 1] = '\0';
  403. }
  404. if (strlen(devCatInfo.szModel) >= MAX_DEV_MODEL_LEN) {
  405. devCatInfo.szModel[MAX_DEV_MODEL_LEN - 1] = '\0';
  406. }
  407. if (strlen(devCatInfo.szVendor) >= MAX_DEV_VENDOR_LEN) {
  408. devCatInfo.szVendor[MAX_DEV_VENDOR_LEN - 1] = '\0';
  409. }
  410. 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());
  411. //oilyang@20250220 as device adapter have been decoupled from us, no need to check anymore
  412. //CheckCategoryInfoFormat();
  413. }
  414. /*
  415. void CheckCategoryInfoFormat()
  416. {
  417. const int DEV_CATINFO_SUM = 3;
  418. char* devInfo[DEV_CATINFO_SUM] = { "szModel", "szVendor", "szType" };
  419. for (int devSn = 0; devSn < DEV_CATINFO_SUM; devSn++)
  420. {
  421. CSimpleStringA strCatInfo;
  422. if (devSn == 0)
  423. strCatInfo = devCatInfo.szModel;
  424. else if (devSn == 1)
  425. strCatInfo = devCatInfo.szVendor;
  426. else if (devSn == 2)
  427. strCatInfo = devCatInfo.szType;
  428. if (!strCatInfo.IsNullOrEmpty())
  429. {
  430. auto arr = strCatInfo.Split('#');
  431. if (arr.GetCount() > 0)
  432. {
  433. for (int sec = 0; sec < arr.GetCount(); sec++)
  434. {
  435. auto arr2 = arr[sec].Split('=');
  436. if (arr2.GetCount() != 2)
  437. {
  438. if (devSn != 1)//szVendor 没有要求符合"key=value#"的格式
  439. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong section of %s:%s", devInfo[devSn], arr[sec].GetData());
  440. continue;
  441. }
  442. if ((strnicmp((LPCTSTR)arr2[0], "MID", strlen("MID")) == 0 && arr2[1].Compare("1.0") != 0)
  443. || (strnicmp((LPCTSTR)arr2[0], "CODE", strlen("CODE")) == 0 && arr2[1].Compare("UCS2") != 0))
  444. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData());
  445. else if (strnicmp((LPCTSTR)arr2[0], "PID", strlen("PID")) == 0 || strnicmp((LPCTSTR)arr2[0], "FWID", strlen("FWID")) == 0)
  446. {
  447. string strData = arr2[1].GetData();
  448. regex pattern(".{8,16}");
  449. smatch sm;
  450. if (!regex_match(strData, sm, pattern))
  451. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData());
  452. }
  453. else if (strnicmp((LPCTSTR)arr2[0], "STYLE", strlen("STYLE")) == 0)
  454. {
  455. string strData = arr2[1].GetData();
  456. regex pattern("CL|IG");
  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], "RF", strlen("RF")) == 0)
  462. {
  463. string strData = arr2[1].GetData();
  464. regex pattern("Y|N");
  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], "FUNCTION", strlen("FUNCTION")) == 0)
  470. {
  471. string strData = arr2[1].GetData();
  472. //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'
  473. regex pattern("^[ITFY]{1,4}$");
  474. smatch sm;
  475. if (!regex_match(strData, sm, pattern))
  476. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, Wrong format of %s:%s", arr2[0].GetData(), arr2[1].GetData());
  477. }
  478. }
  479. }
  480. else
  481. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, can't split from %s:%s", devInfo[devSn], strCatInfo.GetData());
  482. }
  483. else
  484. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("CheckDevInfoFormat, %s is empty.", devInfo[devSn]);
  485. }
  486. }
  487. */
  488. };
  489. struct ErrorPackageEx {
  490. ErrorCodeEnum errCode;
  491. DWORD apiUserCode;
  492. CSimpleStringA devApi;
  493. bool bInBusiness;
  494. int costTime;
  495. CSimpleStringA funPath;
  496. ErrorPackageEx() :errCode(Error_Succeed), apiUserCode(0), devApi(true), bInBusiness(false), costTime(0), funPath(true) {}
  497. };
  498. struct DevEntityErrorCode {
  499. DWORD dwEntityId;
  500. DWORD dwVendorId;
  501. DWORD dwVendorErroCode;
  502. DWORD dwReserved;
  503. DevEntityErrorCode() :dwEntityId(0), dwVendorId(0), dwVendorErroCode(0), dwReserved(0) {}
  504. void ResetWithEntityID(WORD wEntityID)
  505. {
  506. dwEntityId = dwVendorId = dwVendorErroCode = dwReserved = 0;
  507. dwEntityId = wEntityID;
  508. }
  509. void SetDevCode(DWORD devErrorCode, DWORD dwReservedCode)
  510. {
  511. dwVendorErroCode = devErrorCode;
  512. dwReserved = dwReservedCode;
  513. }
  514. DWORD GetCompleteErrorCode() const
  515. {
  516. return MAKE_SLV_ERRORCODE(dwEntityId, dwVendorId, dwVendorErroCode);
  517. }
  518. };
  519. template<class TFSM, class TDevClass>
  520. class CCommDevFSM : public FSMImpl<TFSM>
  521. {
  522. public:
  523. CCommDevFSM() : m_iInWhatPage(PageType_Init),m_bOpened(false), m_bOpening(true), m_eDevState(DEVICE_STATUS_NOT_READY), m_preUIState('X')
  524. {
  525. }
  526. ErrorCodeEnum GetAndSplitDevErrInfo(
  527. CSimpleStringA& csErrMsg, WORD& wdDevErrCode, LPCTSTR lpszFuncNameForDisplay = "");
  528. DWORD SetErrorAndLog(ErrorCodeEnum errCode, DWORD userCode, CSimpleStringA devApi, CSimpleStringA funPath, bool bInBusiness = false, int costTime = 0, CSimpleStringA logCode = "", CSimpleStringA context = "")
  529. {
  530. //set error info
  531. m_errPkgEx.errCode = errCode;
  532. m_errPkgEx.apiUserCode = userCode;
  533. m_errPkgEx.devApi = devApi;
  534. m_errPkgEx.bInBusiness = bInBusiness;
  535. m_errPkgEx.costTime = costTime;
  536. m_errPkgEx.funPath = funPath;
  537. //get DevAdapter vendor errmsg and log info
  538. WORD wdErrCode = 0;
  539. CSimpleStringA csErrMsg(true);
  540. ErrorCodeEnum ec = GetAndSplitDevErrInfo(csErrMsg, wdErrCode, "");
  541. if (ec == Error_Succeed && wdErrCode != 0) {
  542. //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly
  543. if ((m_errPkgEx.apiUserCode >> 20) == m_entCode.dwEntityId)
  544. UpdateDEC(m_errPkgEx.apiUserCode);
  545. else
  546. UpdateDEC(wdErrCode);
  547. }
  548. else if (m_errPkgEx.apiUserCode != 0) {
  549. UpdateDEC(m_errPkgEx.apiUserCode);
  550. }
  551. //oilyang@20200525 if have been set ErrorCode of entity defined (not device),use it directly
  552. const DWORD dwCode = GetAlarmDEC();
  553. const CSimpleStringA alarmMsg = CSimpleStringA::Format("{\"Function\":\"%s\", \"DevApi\":\"%s\", \"ReturnCode\":\"%s\", \"Msg\":\"%s\", \"Context\":\"%s\"}"
  554. , funPath.GetData(), devApi.GetData(), SpStrError(m_errPkgEx.errCode), csErrMsg.GetData(), context.GetData());
  555. std::map<std::string, std::string> msgInfo;
  556. msgInfo["ReturnCode"] = SpStrError(errCode);
  557. msgInfo["ErrMsg"] = csErrMsg.GetData();
  558. msgInfo["Context"] = context.GetData();
  559. std::pair<bool, std::string> strResult;
  560. strResult = generateJsonStr(msgInfo);
  561. CSimpleStringA csErrMsgWithReturnCode = strResult.second.c_str();
  562. CSimpleStringA tmpRTA(true), tmpDesc(true);
  563. this->GetEntityBase()->GetFunction()->GetVTMErrMsg(dwCode, tmpDesc, tmpRTA);
  564. if (bInBusiness) {
  565. LogError(Severity_High, m_errPkgEx.errCode, dwCode, alarmMsg.GetData());
  566. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_USER).setLogCode(logCode).setAPI(devApi).setResultCode(tmpRTA.GetData()).setCostTime(costTime)(csErrMsgWithReturnCode.GetData());
  567. }
  568. else {
  569. LogWarn(Severity_High, m_errPkgEx.errCode, dwCode, alarmMsg.GetData());
  570. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER).setLogCode(logCode).setAPI(devApi).setResultCode(tmpRTA.GetData()).setCostTime(costTime)(csErrMsgWithReturnCode.GetData());
  571. }
  572. return dwCode;
  573. }
  574. //在旧dep路径下找到文件时告警
  575. void UpdateAndWarnFileFindInDepBak(CSimpleStringA& newDepPath, const char* filename, DWORD userCode)
  576. {
  577. CSimpleStringA strOldPath;
  578. if (!ExistsFileA(newDepPath.GetData()))
  579. {
  580. ErrorCodeEnum eErrOld = this->GetEntityBase()->GetFunction()->GetPath("DepBak", strOldPath);
  581. if (eErrOld != Error_Succeed)
  582. {
  583. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode(RTAERR_GETPATH_FAILED)("Get [DepBak] Path failed! errcode:%s.", SpStrError(eErrOld));
  584. }
  585. strOldPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", strOldPath.GetData(), filename);
  586. if (ExistsFileA(strOldPath.GetData()))
  587. {
  588. newDepPath = strOldPath;
  589. CSimpleStringA warnMsg = CSimpleStringA::Format("Find %s in OLD dep path!", strOldPath.GetData());
  590. LogWarn(Severity_Middle, Error_Unexpect, userCode, warnMsg.GetData());
  591. }
  592. }
  593. }
  594. ErrorCodeEnum LoadUpAdapterLibrary(const CSimpleStringA& customDllPath = "")
  595. {
  596. m_hDevHelper.SetAdapterName(this->GetEntityBase()->GetEntityName());
  597. ErrorCodeEnum rc = m_hDevHelper.LoadUp(customDllPath.IsNullOrEmpty() ? m_adapterInfo.adapterFilePath : customDllPath);
  598. return rc;
  599. }
  600. /*fulfill adapter elem, open param and adapter file name&absolute path */
  601. void FulfillAdapterInfoFrom(const VendorLibInfo& vendorLib)
  602. {
  603. m_adapterInfo.strVendor = vendorLib.strVendor;
  604. m_adapterInfo.strVersion = vendorLib.strVersion;
  605. m_adapterInfo.strBatch = vendorLib.strBatch;
  606. m_adapterInfo.strPureAdapterName = vendorLib.strFileValue;
  607. CSmartPointer<IConfigInfo> spConfigRoot;
  608. ErrorCodeEnum ec = this->GetEntityBase()->GetFunction()->OpenConfig(Config_Root, spConfigRoot);
  609. if (ec != Error_Succeed) {
  610. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode(RTAERR_CONFIG_OPEN_FAILED)("Open Config_Root failed: %s.", SpStrError(ec));
  611. return;
  612. }
  613. CSimpleStringA entityName(this->GetEntityBase()->GetEntityName());
  614. if (entityName.Compare("CardIssuerStore", true) == 0 || entityName.Compare("CardIssuerStand", true) == 0) {
  615. entityName = "CardIssuer";
  616. }
  617. CSimpleStringA sectionName = CSimpleStringA::Format("Device.%s", entityName.GetData());
  618. CSimpleStringA csPort(true), csBaudrate(true);
  619. spConfigRoot->ReadConfigValue(sectionName.GetData(), "Port", csPort);
  620. spConfigRoot->ReadConfigValue(sectionName.GetData(), "Baudrate", csBaudrate);
  621. m_adapterInfo.strPort = csPort;
  622. m_adapterInfo.strBaudrate = csBaudrate;
  623. CSimpleStringA csPortNum(true);
  624. if (!entityName.Compare("Gpio")) {
  625. spConfigRoot->ReadConfigValue(sectionName.GetData(), "PortNum", csPortNum);
  626. m_adapterInfo.strPortNum = csPortNum;
  627. }
  628. m_adapterInfo.adapterFileName = vendorLib.toLibNameString();
  629. CSimpleStringA strDepPath(true);
  630. ec = this->GetEntityBase()->GetFunction()->GetPath("Dep", strDepPath);
  631. if (IS_FAILURED(ec)) {
  632. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode(RTAERR_GETPATH_FAILED)("GetPath for Dep failed: %s.", SpStrError(ec));
  633. }
  634. m_adapterInfo.adapterFilePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (LPCTSTR)strDepPath, (LPCTSTR)m_adapterInfo.adapterFileName);
  635. }
  636. ErrorCodeEnum FulfillAdapterDevCategory()
  637. {
  638. if (!!m_hDevHelper) {
  639. ErrorCodeEnum result(Error_Succeed);
  640. DevCategoryInfo devCat;
  641. ZeroMemory(devCat.szModel, sizeof(devCat.szModel));
  642. ZeroMemory(devCat.szType, sizeof(devCat.szType));
  643. ZeroMemory(devCat.szVendor, sizeof(devCat.szVendor));
  644. result = m_hDevHelper->GetDevCategory(devCat); /** 这里不加错误的判断,让硬件实体调用方去兜 [Gifur@2025714]*/
  645. if (IS_SUCCEED(result)) {
  646. m_adapterInfo.FulfillCategoryInfo(devCat);
  647. }
  648. return result;
  649. }
  650. return Error_InvalidState;
  651. }
  652. virtual ErrorCodeEnum PreOpenDevice() { return Error_Succeed; }
  653. virtual ErrorCodeEnum ToOpenDevice() { return Error_NotImpl; }
  654. virtual ErrorCodeEnum PostOpenDevice() { return Error_Succeed; }
  655. //暂时未使用
  656. ErrorCodeEnum OpenDevice()
  657. {
  658. if (m_bOpening) {
  659. return Error_Pending;
  660. }
  661. if (m_bOpened) {
  662. return Error_DevAlreadyConnected;
  663. }
  664. m_bOpening = true;
  665. ErrorCodeEnum result = PreOpenDevice();
  666. if (IS_SUCCEED(result)) {
  667. result = ToOpenDevice();
  668. if (IS_SUCCEED(result)) {
  669. m_bOpened = true;
  670. result = PostOpenDevice();
  671. }
  672. }
  673. m_bOpening = false;
  674. return result;
  675. }
  676. virtual void SetDevInitFlag(bool val = true) {
  677. m_bOpened = val;
  678. }
  679. bool GetDevInitFlag() const {
  680. return m_bOpened;
  681. }
  682. virtual void SetDevInitingFlag(bool val = true) {
  683. m_bOpening = val;
  684. }
  685. bool GetDevInitingFlag() const {
  686. return m_bOpening;
  687. }
  688. virtual void SetInWhatPage(int iPageType) {
  689. m_iInWhatPage = iPageType;
  690. }
  691. void OnUIState4SetWhatPage(const char* pcszValue) {
  692. if (pcszValue != NULL && strlen(pcszValue) > 0) {
  693. bool trigger(false);
  694. UiState2WhatPage(pcszValue);
  695. if (m_preUIState != pcszValue[0]) {
  696. if (pcszValue[0] == 'M') {
  697. trigger = true;
  698. }
  699. m_preUIState = pcszValue[0];
  700. }
  701. if (trigger) {
  702. this->PostEventFIFO(new FSMEvent(EVT_MAINPAGE_DISPLAY));
  703. }
  704. }
  705. }
  706. virtual DevStateEnum GetDevState() const {
  707. return m_eDevState;
  708. }
  709. void SetDevState(DevStateEnum val = DEVICE_STATUS_NORMAL) {
  710. m_eDevState = val;
  711. }
  712. public:
  713. bool m_bOpened;
  714. bool m_bOpening;
  715. protected:
  716. DevAdptLibHelper<TDevClass> m_hDevHelper;
  717. DevEntityErrorCode m_entCode;
  718. int m_iInWhatPage/*在哪个页面,区分首页,用户桌面,其他页*/;
  719. ErrorPackageEx m_errPkgEx;
  720. AdapterInfo m_adapterInfo;
  721. DevStateEnum m_eDevState;
  722. void __PostInit() override
  723. {
  724. if (this->GetEntityBase() != NULL) {
  725. CSimpleStringA uiState(true);
  726. auto err = this->GetEntityBase()->GetFunction()->GetSysVar("UIState", uiState);
  727. if (err == Error_Succeed && !uiState.IsNullOrEmpty()) {
  728. UiState2WhatPage(uiState);
  729. } else if (err != Error_Succeed) {
  730. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setResultCode(RTAERR_SYSVAR_GET_FAILED)("Get sysVar for UIState failed:%s", SpStrError(err));
  731. }
  732. }
  733. }
  734. void UpdateEntityIDIfZero()
  735. {
  736. if (m_entCode.dwEntityId == 0) {
  737. UpdateEntityID();
  738. }
  739. }
  740. void UpdateEntityID()
  741. {
  742. CEntityStaticInfo esi = { 0 };
  743. ErrorCodeEnum ec = this->GetEntityBase()->GetFunction()->GetEntityStaticInfo(this->GetEntityBase()->GetEntityName(), esi);
  744. if (ec == Error_Succeed) {
  745. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("wEntityDevelopID: 0x%X", esi.wEntityDevelopID);
  746. m_entCode.ResetWithEntityID(esi.wEntityDevelopID);
  747. }
  748. }
  749. DWORD GetEntityID()
  750. {
  751. UpdateEntityIDIfZero();
  752. return m_entCode.dwEntityId;
  753. }
  754. DWORD UpdateDEC(DWORD dwVal = 0)
  755. {
  756. UpdateEntityIDIfZero();
  757. /** 14 is for entity define, FC(6bit) is reserved*/
  758. int reserved = (dwVal & 0xFC000) >> 14;
  759. m_entCode.SetDevCode(dwVal, reserved);
  760. return GetDEC();
  761. }
  762. DWORD GetDEC() const
  763. {
  764. return m_entCode.GetCompleteErrorCode();
  765. }
  766. DWORD GetAlarmDEC(DWORD dwValue = 0)
  767. {
  768. if (dwValue > 0)
  769. UpdateDEC(dwValue);
  770. //if have been set ErrorCode of entity defined (not device),use it directly
  771. DWORD dwCode = 0;
  772. //if ((m_entCode.dwVendorErroCode >> 20) == m_entCode.dwEntityId)
  773. if(IsEntityIDSettle(m_entCode.dwVendorErroCode))
  774. dwCode = m_entCode.dwVendorErroCode;
  775. else
  776. dwCode = HARDWARE_ENTITY_MAKE_ERRORCODE_TO_BUSINESS(m_entCode);
  777. return dwCode;
  778. }
  779. void ClearRelatedDEC()
  780. {
  781. UpdateDEC();
  782. }
  783. bool IsEntityIDSettle(const DWORD& dwVal) const
  784. {
  785. return ((dwVal >> 20) == m_entCode.dwEntityId);
  786. }
  787. /** 目前没有调用方,暂时注释 [Gifur@2025711]*/
  788. /*
  789. static void GetFileSizeAndCalcHashValue(const char* fileName, int& fileSize, BYTE fileHash[32])
  790. {
  791. HANDLE hFile;
  792. hFile = CreateFile(fileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  793. if (hFile == INVALID_HANDLE_VALUE) {
  794. fileSize = 0;
  795. return;
  796. }
  797. fileSize = GetFileSize(hFile, NULL);
  798. CloseHandle(hFile);
  799. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("to calc vendor dll hash");
  800. SM3File(const_cast<char*>(fileName), fileHash);
  801. return;
  802. }*/
  803. virtual bool IsInBusiness() const {
  804. return (m_iInWhatPage == PageType_Other);
  805. }
  806. virtual void OnHardwareShakeHand(CSmartPointer<ITransactionContext> pTransactionContext);
  807. private:
  808. void UiState2WhatPage(const char* pcszValue)
  809. {
  810. //增加页面位置判断
  811. if (_strnicmp(pcszValue, "M", strlen("M")) == 0) {
  812. SetInWhatPage(PageType_MainPage);
  813. }
  814. else if (_strnicmp(pcszValue, "U", strlen("U")) == 0) {
  815. SetInWhatPage(PageType_UserDesktop);
  816. }
  817. else if (_strnicmp(pcszValue, "X", strlen("X")) != 0) {
  818. SetInWhatPage(PageType_Other);
  819. }
  820. }
  821. private:
  822. char m_preUIState;
  823. };
  824. template<class TFSM, class TDevClass>
  825. inline ErrorCodeEnum CCommDevFSM<TFSM, TDevClass>::GetAndSplitDevErrInfo(
  826. CSimpleStringA& csErrMsg, WORD& wdDevErrCode, LPCTSTR lpszFuncNameForDisplay)
  827. {
  828. csErrMsg = "";
  829. wdDevErrCode = 0;
  830. BOOL bDisplayFunName = TRUE;
  831. if (lpszFuncNameForDisplay == NULL || strlen(lpszFuncNameForDisplay) == 0) {
  832. bDisplayFunName = FALSE;
  833. }
  834. if (!m_hDevHelper) {
  835. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__).setResultCode(DEVICE_FSM_DEVOBJ_NULLPTR)("inst occurs nullptr !!!");
  836. return Error_Param;
  837. }
  838. DevErrorInfo devErrInfo;
  839. ZeroMemory(&devErrInfo, sizeof(DevErrorInfo));
  840. ErrorCodeEnum erroCode = m_hDevHelper->GetLastErr(devErrInfo);
  841. if (erroCode == Error_Succeed) {
  842. if (strlen(devErrInfo.szErrMsg) > 0) {
  843. csErrMsg = devErrInfo.szErrMsg;
  844. }
  845. if (devErrInfo.dwErrMsgLen > MAX_DEV_ERROR_MSG_LEN) {
  846. wdDevErrCode = (WORD)((devErrInfo.dwErrMsgLen >> 16) & 0x0000FFFF);
  847. }
  848. } else {
  849. if (bDisplayFunName) {
  850. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)/*.setAPI("DevAdapter::GetLastErr")不纳入适配器消费,因为不好分配RTA,只做调研*/
  851. .setResultCode(DEVICE_FSM_DEVGETLE_FAILED)("GetLastErr after %s failed returned: %s",lpszFuncNameForDisplay, SpStrError(erroCode));
  852. csErrMsg = CSimpleStringA::Format("Invoke <%s> failed", lpszFuncNameForDisplay);
  853. } else {
  854. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)/*.setAPI("DevAdapter::GetLastErr")不纳入适配器消费,因为不好分配RTA,只做调研*/
  855. .setResultCode(DEVICE_FSM_DEVGETLE_FAILED)("GetLastErr failed returned: %s", SpStrError(erroCode));
  856. }
  857. }
  858. /** reset vendor device error code to stop reporting to alarm [12/11/2020 Gifur] */
  859. wdDevErrCode = 0;
  860. return erroCode;
  861. }
  862. template<class TFSM, class TDevClass>
  863. void CCommDevFSM<TFSM, TDevClass>::OnHardwareShakeHand(CSmartPointer<ITransactionContext> pTransactionContext)
  864. {
  865. if (m_eDevState == DEVICE_STATUS_NORMAL)
  866. pTransactionContext->SendAnswer(Error_Succeed);
  867. else
  868. {
  869. if (m_bOpening)
  870. pTransactionContext->SendAnswer(Error_Succeed);
  871. else if (!m_bOpened)
  872. pTransactionContext->SendAnswer(Error_DevNotAvailable);
  873. else
  874. pTransactionContext->SendAnswer(Error_InvalidState);
  875. }
  876. }
  877. #endif /*_COMM_DEVICE_FSM_BASE_HPP_*/