FingerPrintFSM.cpp 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076
  1. #include "FingerPrintFSM.h"
  2. #include "EventCode.h"
  3. #include "FingerPrint_UserErrorCode.h"
  4. #include "GetDevInfoHelper.h"
  5. #include "path.h"
  6. #include "DevEntityCommBase.hpp"
  7. #include <thread>
  8. #include <chrono>
  9. #include <fstream>
  10. #include <cstdio>
  11. #ifdef RVC_OS_LINUX
  12. #include <sys/stat.h>
  13. #include <unistd.h>
  14. #endif // RVC_OS_LIUNX
  15. void CFingerPrintFSM::s0_on_entry()
  16. {
  17. LOG_FUNCTION();
  18. m_devState = DEVICE_STATUS_NORMAL;
  19. }
  20. void CFingerPrintFSM::s0_on_exit()
  21. {
  22. LOG_FUNCTION();
  23. }
  24. unsigned int CFingerPrintFSM::s0_on_event(FSMEvent* e)
  25. {
  26. LOG_FUNCTION();
  27. Dbg("s0 evt %d", e->iEvt);
  28. switch(e->iEvt)
  29. {
  30. case USER_EVT_ERROR:
  31. {
  32. e->SetHandled();
  33. Dbg("s0 on event error");
  34. break;
  35. }
  36. case USER_EVT_QUIT:
  37. {
  38. e->SetHandled();
  39. Dbg("s0 on event quit");
  40. break;
  41. }
  42. case USER_EVT_SCAN:
  43. {
  44. e->SetHandled();
  45. ScanEvent* pSe = dynamic_cast<ScanEvent*>(e);
  46. ScanTask* pSt = new ScanTask(this);
  47. pSt->ctx = pSe->ctx;
  48. GetEntityBase()->GetFunction()->PostThreadPoolTask(pSt);
  49. break;
  50. }
  51. case USER_EVT_CANCEL_SCAN:
  52. {
  53. e->SetHandled();
  54. Dbg("s0 set cancel flag!");
  55. m_bCancelRegister = true;
  56. break;
  57. }
  58. case USER_EVT_MATCH:
  59. {
  60. e->SetHandled();
  61. MatchEvent* pMe = dynamic_cast<MatchEvent*>(e);
  62. MatchTask* pMt = new MatchTask(this);
  63. pMt->ctx = pMe->ctx;
  64. GetEntityBase()->GetFunction()->PostThreadPoolTask(pMt);
  65. break;
  66. }
  67. default:
  68. break;
  69. }
  70. return 0;
  71. }
  72. void CFingerPrintFSM::s1_on_entry()
  73. {
  74. LOG_FUNCTION();
  75. }
  76. void CFingerPrintFSM::s1_on_exit()
  77. {
  78. LOG_FUNCTION();
  79. }
  80. unsigned int CFingerPrintFSM::s1_on_event(FSMEvent* e)
  81. {
  82. LOG_FUNCTION();
  83. Dbg("s1 evt(%d)", e->iEvt);
  84. int ret = 0;
  85. switch(e->iEvt)
  86. {
  87. case USER_EVT_SCAN_FINISHED:
  88. e->SetHandled();
  89. ret = e->param1;
  90. break;
  91. case USER_EVT_CANCEL_SCAN:
  92. e->SetHandled();
  93. Dbg("Set cancel scan flag");
  94. m_bCancelRegister = true;
  95. break;
  96. case USER_EVT_EXIT:
  97. e->SetHandled();
  98. m_bExit = true;
  99. break;
  100. case USER_EVT_QUIT:
  101. e->SetHandled();
  102. break;
  103. default:
  104. break;
  105. }
  106. return ret;
  107. }
  108. void CFingerPrintFSM::s2_on_entry()
  109. {
  110. LOG_FUNCTION();
  111. Dbg("FingerPrint failed.");
  112. m_devState = DEVICE_STATUS_FAULT;
  113. m_testResult = Error_InvalidState;
  114. }
  115. void CFingerPrintFSM::s2_on_exit()
  116. {
  117. LOG_FUNCTION();
  118. }
  119. unsigned int CFingerPrintFSM::s2_on_event(FSMEvent* e)
  120. {
  121. LOG_FUNCTION();
  122. if (e->iEvt == USER_EVT_QUIT)
  123. {
  124. e->SetHandled();
  125. }
  126. return 0;
  127. }
  128. void CFingerPrintFSM::s3_on_entry()
  129. {
  130. LOG_FUNCTION();
  131. }
  132. void CFingerPrintFSM::s3_on_exit()
  133. {
  134. LOG_FUNCTION();
  135. }
  136. unsigned CFingerPrintFSM::s3_on_event(FSMEvent* e)
  137. {
  138. LOG_FUNCTION();
  139. Dbg("s3 evt %d,%d", e->iEvt, e->param1);
  140. int ret = 0;
  141. switch(e->iEvt)
  142. {
  143. case USER_EVT_MATCH_FINISHED:
  144. {
  145. e->SetHandled();
  146. MatchFinishedEvent* mfe = dynamic_cast<MatchFinishedEvent*>(e);
  147. if (mfe->param1 == 0)
  148. mfe->ctx->Answer(Error_Succeed);
  149. else
  150. mfe->ctx->Answer((ErrorCodeEnum)mfe->param1);
  151. break;
  152. }
  153. case USER_EVT_CANCEL_MATCH:
  154. {
  155. e->SetHandled();
  156. Dbg("Set cancel match flag");
  157. m_bCancelMatch = true;
  158. break;
  159. }
  160. case USER_EVT_EXIT:
  161. {
  162. e->SetHandled();
  163. m_bExit = true;
  164. break;
  165. }
  166. case USER_EVT_QUIT:
  167. {
  168. e->SetHandled();
  169. break;
  170. }
  171. default:
  172. break;
  173. }
  174. return 0;
  175. }
  176. ErrorCodeEnum CFingerPrintFSM::OnInit()
  177. {
  178. CSimpleStringA strLibFullPath;
  179. CDevAdptEntityBase *pEntity = GET_DEV_ENTITY_BASE_POINTER();
  180. ErrorCodeEnum errDev = pEntity->ExtractVendorLibFullPath(strLibFullPath);
  181. Dbg("Extract Vendor lib name: %s", (const char*)strLibFullPath);
  182. if (errDev != Error_Succeed)
  183. {
  184. Dbg("Get vendor libname(%s) failed.", (const char*)strLibFullPath);
  185. LogError(Severity_High, Error_DevLoadFileFailed
  186. , LOG_ERR_FINGERPRINT_GET_DLLNAME_FAILED_ONINIT
  187. , "get dllname failed while init");
  188. return Error_DevLoadFileFailed;
  189. }
  190. CSmartPointer<IConfigInfo> spConfig;
  191. errDev = QueryRootConfigObj(spConfig);
  192. if (Error_Succeed != errDev)
  193. return errDev;
  194. if (strLibFullPath.IsEndWith("FingerPrint.dll")
  195. || strLibFullPath.IsEndWith("libFingerPrint.so"))
  196. {
  197. Dbg("No config in root.ini for FingerPrint.");
  198. GetVendorLibName(spConfig, strLibFullPath);
  199. }
  200. Dbg("vendorlib name: %s", (const char*)strLibFullPath);
  201. if (!IsFileExist(strLibFullPath))
  202. {
  203. Dbg("No vendor fingerprint adapter in dep.");
  204. m_devInit = false;
  205. return Error_Succeed;
  206. }
  207. m_DevAdptLibHelper = new DevAdptLibHelper<FingerPrintClass>();
  208. errDev = m_DevAdptLibHelper->LoadUp(strLibFullPath);
  209. if (Error_Succeed != errDev)
  210. {
  211. Dbg("load vendorlib or create DevAdapterObject failed.");
  212. delete m_DevAdptLibHelper; //TODO: 考虑蓝牙多合一 DevClose()
  213. m_DevAdptLibHelper = nullptr;
  214. return Error_DevLoadFileFailed;
  215. }
  216. m_pFingerPrint = m_DevAdptLibHelper->GetDevPointer();
  217. errDev = DoDevOpen(spConfig);
  218. if (Error_Succeed != errDev)
  219. return errDev;
  220. return DoGetDevInfo();
  221. }
  222. ErrorCodeEnum CFingerPrintFSM::OnExit()
  223. {
  224. if (nullptr != m_DevAdptLibHelper)
  225. {
  226. delete m_DevAdptLibHelper;
  227. m_DevAdptLibHelper = nullptr;
  228. }
  229. return Error_Succeed;
  230. }
  231. void CFingerPrintFSM::SelfTest(EntityTestEnum eTestType
  232. , CSmartPointer<ITransactionContext> pTransactionContext)
  233. {
  234. //LOG_FUNCTION();
  235. pTransactionContext->SendAnswer(m_testResult);
  236. }
  237. int CFingerPrintFSM::GetImageAndFeature(SpReqAnsContext<FingerPrintService_GetImageAndFeature_Req, FingerPrintService_GetImageAndFeature_Ans>::Pointer ctx)
  238. {
  239. LOG_FUNCTION();
  240. ScanParam* pScanParam = new ScanParam();
  241. ErrorCodeEnum errCode = InitParamBeforeScan(pScanParam, ctx->Req.times);
  242. if (errCode != Error_Succeed)
  243. ctx->Answer(errCode);
  244. else {
  245. ScanProcess(pScanParam, ctx);
  246. if (pScanParam != NULL && ctx != NULL)
  247. ProcessAfterScan(pScanParam, ctx);
  248. else
  249. ctx->Answer(Error_Param);
  250. }
  251. return 0;
  252. }
  253. ErrorCodeEnum CFingerPrintFSM::InitParamBeforeScan(ScanParam *initParam, int scanTime)
  254. {
  255. ErrorCodeEnum errCode = Error_Succeed;
  256. errCode = InitCommParam(initParam, RegisterType, scanTime);
  257. if (errCode != Error_Succeed)
  258. return errCode;
  259. switch (scanTime)
  260. {
  261. case 1:
  262. initParam->m_BmpFileName = "finger1.bmp";
  263. m_BmpFileFullPath1 = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  264. , (const char*)initParam->m_DepPath
  265. , (const char*)initParam->m_BmpFileName);
  266. break;
  267. case 2:
  268. initParam->m_BmpFileName = "finger2.bmp";
  269. m_BmpFileFullPath2 = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  270. , (const char*)initParam->m_DepPath
  271. , (const char*)initParam->m_BmpFileName);
  272. break;
  273. case 3:
  274. initParam->m_BmpFileName = "finger3.bmp";
  275. m_BmpFileFullPath3 = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  276. , (const char*)initParam->m_DepPath
  277. , (const char*)initParam->m_BmpFileName);
  278. break;
  279. default:
  280. initParam->m_BmpFileName = "finger.bmp";
  281. break;
  282. }
  283. initParam->m_FullFilePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  284. , (const char*)initParam->m_DepPath
  285. , (const char*)initParam->m_BmpFileName);
  286. Dbg("get imageName success: %s", initParam->m_FullFilePath);
  287. return errCode;
  288. }
  289. void CFingerPrintFSM::ScanProcess(ScanParam* pScanParam, SpReqAnsContext<FingerPrintService_GetImageAndFeature_Req, FingerPrintService_GetImageAndFeature_Ans>::Pointer &ctx)
  290. {
  291. LOG_FUNCTION();
  292. LogEvent(Severity_Middle, LOG_EVT_FINGERPRINT_GREEN_ON, "FingerPrint warning on");
  293. while (pScanParam->m_TimeLeft < FINGERPRINT_SCAN_TIMEOUT
  294. && !m_bCancelRegister && !pScanParam->m_ScanSuc)
  295. {
  296. if (m_bExit)
  297. {
  298. Dbg("Exit");
  299. pScanParam->m_Quit = true;
  300. break;
  301. }
  302. std::this_thread::sleep_for(std::chrono::milliseconds(FINGERPRINT_SCAN_INTERNAL));
  303. pScanParam->m_FeatureLen = MAX_FEATURE_LEN;
  304. ErrorCodeEnum errCode = m_pFingerPrint->Image2Feature(pScanParam->m_BmpFileName
  305. , pScanParam->m_Feature
  306. , pScanParam->m_FeatureLen);
  307. if (errCode == Error_Succeed)
  308. {
  309. Dbg("Invoke routine 'Image2Feature' success.'");
  310. //save image may be delayed some time, not must happen
  311. std::this_thread::sleep_for(std::chrono::milliseconds(200));
  312. std::ifstream bmpImage((const char*)pScanParam->m_FullFilePath, std::ifstream::binary);
  313. if (bmpImage && pScanParam->m_Feature != NULL && pScanParam->m_FeatureLen > 0)
  314. {
  315. Dbg("fingerprint feature length is %d", pScanParam->m_FeatureLen);
  316. ctx->Ans.imageName = pScanParam->m_BmpFileName;
  317. if (ctx->Req.times == 3) {
  318. Dbg("m_strPath1 = %s", m_BmpFileFullPath1.GetData());
  319. Dbg("m_strPath2 = %s", m_BmpFileFullPath2.GetData());
  320. Dbg("m_strPath3 = %s", m_BmpFileFullPath3.GetData());
  321. errCode = m_pFingerPrint->Image2Template(m_BmpFileFullPath1, m_BmpFileFullPath2
  322. , m_BmpFileFullPath3, pScanParam->m_Template
  323. , pScanParam->m_FeatureLen);
  324. if (Error_Succeed == errCode)
  325. {
  326. Dbg("Invoke routine 'Image2Template' success");
  327. if (pScanParam->m_Template != NULL && pScanParam->m_FeatureLen > 0) {
  328. Dbg("template length is %d", pScanParam->m_FeatureLen);
  329. ctx->Ans.feature = (LPCTSTR)pScanParam->m_Template;
  330. }
  331. else {
  332. Dbg("template is NULL");
  333. pScanParam->m_GetTemplateSuc = false;
  334. break;
  335. }
  336. }else {
  337. pScanParam->m_GetTemplateSuc = false;
  338. DevErrorInfo devErrorInfo;
  339. m_pFingerPrint->GetLastErr(devErrorInfo);
  340. Dbg("Invoke routine 'Image2Template' failed which returned %s(%s)"
  341. , SpStrError(errCode), devErrorInfo.szErrMsg);
  342. break;
  343. }
  344. }
  345. pScanParam->m_ScanSuc = true;
  346. break;
  347. }else if (!bmpImage) {
  348. Dbg("Cannot find the fingerprint image %s", pScanParam->m_BmpFileName);
  349. pScanParam->m_NotFindImage = true;
  350. break;
  351. }else {
  352. Dbg("Fingerprint feature is NULL.");
  353. pScanParam->m_FeatureIsNull = true;
  354. break;
  355. }
  356. }else {
  357. DevErrorInfo devErrInfo;
  358. m_pFingerPrint->GetLastErr(devErrInfo);
  359. Dbg("Invoke routine 'Image2Feature' failed which returned %s(%s) while register."
  360. , SpStrError(errCode), devErrInfo.szErrMsg);
  361. }
  362. pScanParam->m_TimeEnd = clock();
  363. pScanParam->m_TimeLeft = pScanParam->m_TimeEnd - pScanParam->m_TimeStart;
  364. }
  365. LogEvent(Severity_Middle, LOG_EVT_FINGERPRINT_GREEN_OFF, "FingerPrint warning on");
  366. m_bExit = false;
  367. }
  368. void CFingerPrintFSM::ProcessAfterScan(ScanParam* pScanParam, SpReqAnsContext<FingerPrintService_GetImageAndFeature_Req, FingerPrintService_GetImageAndFeature_Ans>::Pointer& ctx)
  369. {
  370. if (pScanParam->m_ScanSuc)
  371. {
  372. ctx->Answer(Error_Succeed);
  373. }
  374. else if (pScanParam->m_TimeLeft >= FINGERPRINT_SCAN_TIMEOUT)
  375. {
  376. ctx->Answer(Error_TimeOut);
  377. }
  378. else if (m_bCancelRegister)
  379. {
  380. ctx->Answer(Error_Cancel);
  381. }else {
  382. if (pScanParam->m_NotFindImage)
  383. {
  384. LogError(Severity_High, Error_Hardware
  385. , LOG_ERR_FINGERPRINT_NO_IMAGE_IN_DEP_REGISTER
  386. , "not find fingerprint image in dep while register.");
  387. ctx->Answer(Error_Unexpect, LOG_ERR_FINGERPRINT_NO_IMAGE_IN_DEP_REGISTER);
  388. }
  389. else if (pScanParam->m_FeatureIsNull)
  390. {
  391. LogError(Severity_High, Error_Hardware
  392. , LOG_ERR_FINGERPRINT_GETFEATURE_FAILED_REGISTER
  393. , "fingerprint feature is null while register.");
  394. ctx->Answer(Error_Unexpect, LOG_ERR_FINGERPRINT_GETFEATURE_FAILED_REGISTER);
  395. }else {
  396. if (ctx->Req.times == 3 && !pScanParam->m_GetTemplateSuc)
  397. {
  398. LogError(Severity_High, Error_Hardware
  399. , LOG_ERR_FINGERPRINT_GETTEMPLATE_FAILED
  400. , "Not generate template correctly.");
  401. ctx->Answer(Error_Unexpect, LOG_ERR_FINGERPRINT_GETTEMPLATE_FAILED);
  402. }else if (pScanParam->m_Quit) {
  403. LogWarn(Severity_High, Error_Hardware
  404. , LOG_ERR_FINGERPRINT_REGISTER_FAILED
  405. , "Exit to homepage when register.");
  406. ctx->Answer(Error_Unexpect);
  407. }
  408. }
  409. }
  410. delete[] pScanParam->m_Feature;
  411. pScanParam->m_Feature = NULL;
  412. delete[] pScanParam->m_Template;
  413. pScanParam->m_Template = NULL;
  414. delete pScanParam;
  415. pScanParam = NULL;
  416. }
  417. ErrorCodeEnum CFingerPrintFSM::Match(SpReqAnsContext<FingerPrintService_Match_Req, FingerPrintService_Match_Ans>::Pointer ctx)
  418. {
  419. LOG_FUNCTION();
  420. ScanParam* initParam = new ScanParam();
  421. ErrorCodeEnum errCode = InitParamBeforeMatch(initParam, ctx->Req.templateNum);
  422. if (errCode != Error_Succeed)
  423. return errCode;
  424. ScanBeforeMatch(initParam);
  425. errCode = MatchProcess(initParam, ctx);
  426. return errCode;
  427. }
  428. ErrorCodeEnum CFingerPrintFSM::InitParamBeforeMatch(ScanParam* initParam, int templateNum)
  429. {
  430. ErrorCodeEnum errCode = Error_Succeed;
  431. errCode = InitCommParam(initParam, MatchType, 0, templateNum);
  432. if (errCode != Error_Succeed)
  433. return errCode;
  434. initParam->m_BmpFileName = "finger.bmp";
  435. initParam->m_FullFilePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  436. , (const char*)initParam->m_DepPath
  437. , (const char*)initParam->m_BmpFileName);
  438. Dbg("get imageName success: %s", initParam->m_FullFilePath);
  439. return Error_Succeed;
  440. }
  441. void CFingerPrintFSM::ScanBeforeMatch(ScanParam* initParam)
  442. {
  443. ErrorCodeEnum errCode = Error_Succeed;
  444. LogEvent(Severity_Middle, LOG_EVT_FINGERPRINT_GREEN_ON, "FingerPrint warning on");
  445. while (initParam->m_TimeLeft < FINGERPRINT_MATCH_TIMEOUT
  446. && !m_bCancelMatch && !initParam->m_ScanSuc)
  447. {
  448. if (m_bExit)
  449. {
  450. Dbg("Exit");
  451. initParam->m_Quit = true;
  452. break;
  453. }
  454. std::this_thread::sleep_for(std::chrono::milliseconds(FINGERPRINT_SCAN_INTERNAL));
  455. //Sleep(FINGERPRINT_SCAN_INTERNAL);
  456. initParam->m_FeatureLen = MAX_FEATURE_LEN;
  457. errCode = m_pFingerPrint->Image2Feature(initParam->m_BmpFileName
  458. , initParam->m_Feature
  459. , initParam->m_FeatureLen);
  460. if (errCode == Error_Succeed)
  461. {
  462. //TODO: union test
  463. Dbg("Invoke routine 'Image2Feature' success.");
  464. std::this_thread::sleep_for(std::chrono::milliseconds(200));
  465. //Sleep(200);//save image may be delayed some time, not must happen
  466. std::ifstream bmpImage((const char*)initParam->m_FullFilePath, std::fstream::binary);
  467. if (bmpImage && initParam->m_Feature != NULL && initParam->m_FeatureLen > 0)
  468. {
  469. Dbg("fingerprint feature length is %d", initParam->m_FeatureLen);
  470. initParam->m_ScanSuc = true;
  471. break;
  472. }
  473. else if (!bmpImage)
  474. {
  475. Dbg("Cannot find the fingerprint image finger.bmp");
  476. initParam->m_NotFindImage = true;
  477. break;
  478. }else {
  479. Dbg("Fingerprint feature is NULL.");
  480. initParam->m_FeatureIsNull = true;
  481. break;
  482. }
  483. }else {
  484. DevErrorInfo devErrInfo;
  485. m_pFingerPrint->GetLastErr(devErrInfo);
  486. Dbg("Invoke routine 'Image2Feature' failed which returned %s(%s)"
  487. , SpStrError(errCode), devErrInfo.szErrMsg);
  488. }
  489. initParam->m_TimeEnd = clock();
  490. initParam->m_TimeLeft = initParam->m_TimeEnd - initParam->m_TimeStart;
  491. }
  492. LogEvent(Severity_Middle, LOG_EVT_FINGERPRINT_GREEN_OFF, "FingerPrint warning off");
  493. m_bExit = false;
  494. Dbg("after match, clear bmp file");
  495. DeleteBmp(BmpImage);
  496. }
  497. ErrorCodeEnum CFingerPrintFSM::MatchProcess(ScanParam* initParam, SpReqAnsContext<FingerPrintService_Match_Req, FingerPrintService_Match_Ans>::Pointer& ctx)
  498. {
  499. ErrorCodeEnum errCode = Error_Succeed;
  500. if (initParam->m_ScanSuc)
  501. {
  502. Dbg("templateNum=%d", ctx->Req.templateNum);
  503. int templateNum = ctx->Req.templateNum;
  504. LPBYTE* lpbTemplates = new LPBYTE[templateNum];
  505. int* lpbTemplateLen = new int[templateNum];
  506. for (int i = 0; i < templateNum; ++i)
  507. {
  508. lpbTemplates[i] = new BYTE[MAX_FEATURE_LEN];
  509. memset(lpbTemplates[i], 0, sizeof(lpbTemplates[i]));
  510. strcpy((char*)lpbTemplates[i], ctx->Req.templates[i]);
  511. lpbTemplateLen[i] = ctx->Req.templateLen[i];
  512. }
  513. clock_t startMatch = clock();
  514. errCode = m_pFingerPrint->Match(lpbTemplates, lpbTemplateLen, templateNum,
  515. initParam->m_Feature, initParam->m_FeatureLen);
  516. clock_t endMatch = clock();
  517. int duration = (endMatch - startMatch) * 1000 / CLOCKS_PER_SEC;
  518. LogWarn(Severity_High, Error_Debug, LOG_ERR_FINGERPRINT_MATCH_TIME,
  519. GenerateAlarmJson("FingerPrint", duration).GetData());
  520. if (errCode == Error_Succeed) //always true
  521. {
  522. Dbg("Invoke routine 'Match' success");
  523. ctx->Ans.result.Init(templateNum);
  524. for (int i = 0; i < templateNum; ++i)
  525. ctx->Ans.result[i] = lpbTemplateLen[i];
  526. }else{
  527. DevErrorInfo devErrInfo;
  528. m_pFingerPrint->GetLastErr(devErrInfo);
  529. LogError(Severity_High, Error_Hardware
  530. , LOG_ERR_FINGERPRINT_INVOKE_MATCH_FAILED
  531. , "Invoke routine 'Match' failed.");//no this situation
  532. Dbg("Invoke routine 'Match' failed which returned %s(%s)"
  533. , SpStrError(errCode), devErrInfo.szErrMsg);
  534. errCode = Error_Unexpect;
  535. }
  536. for (int i = 0; i < templateNum; ++i)
  537. {
  538. delete[] lpbTemplates[i];
  539. lpbTemplates[i] = NULL;
  540. }
  541. delete[] lpbTemplateLen;
  542. lpbTemplateLen = NULL;
  543. delete[] lpbTemplates;
  544. lpbTemplates = NULL;
  545. }
  546. else if (initParam->m_TimeLeft >= FINGERPRINT_MATCH_TIMEOUT)
  547. {
  548. Dbg("Match timeout(Invoke vendor failed or not press finger)");
  549. errCode = Error_TimeOut;
  550. }
  551. else if (m_bCancelMatch)
  552. {
  553. errCode = Error_Cancel;
  554. }
  555. else
  556. {
  557. if (initParam->m_NotFindImage)
  558. LogError(Severity_High, Error_Hardware, LOG_ERR_FINGERPRINT_NO_IMAGE_IN_DEP_MATCH, "not find fingerprint image in dep while match.");
  559. else if (initParam->m_FeatureIsNull)
  560. LogError(Severity_High, Error_Hardware, LOG_ERR_FINGERPRINT_GETFEATURE_FAILED_MATCH, "fingerprint feature is null while match.");
  561. else if (initParam->m_Quit)
  562. LogWarn(Severity_High, Error_Hardware, LOG_ERR_FINGERPRINT_MATCH_FAILED, "Exit to homepage when match.");
  563. errCode = Error_Unexpect;
  564. }
  565. delete[] initParam->m_Feature;
  566. initParam->m_Feature = NULL;
  567. delete initParam;
  568. initParam = NULL;
  569. return errCode;
  570. }
  571. ErrorCodeEnum CFingerPrintFSM::InitCommParam(ScanParam* initParam, int operateType, int scanTime, int templateNum)
  572. {
  573. ErrorCodeEnum errCode = Error_Succeed;
  574. if (!initParam)
  575. return Error_Param;
  576. if (!m_devInit)
  577. errCode = Error_NotInit; //maybe no vendor adapter
  578. if ((operateType & RegisterType) == RegisterType)
  579. {
  580. if (m_bCancelRegister) //no cancel button anymore while register
  581. {
  582. m_bCancelRegister = false;
  583. errCode = Error_Cancel;
  584. }
  585. }
  586. if ((operateType & MatchType) == MatchType && templateNum <= 0)
  587. errCode = Error_Param;
  588. if (errCode != Error_Succeed) {
  589. delete initParam;
  590. initParam = NULL;
  591. }
  592. initParam->m_TimeStart = clock();
  593. initParam->m_TimeEnd = clock();
  594. initParam->m_TimeLeft = 0;
  595. initParam->m_Feature = new BYTE[MAX_FEATURE_LEN];
  596. initParam->m_FeatureLen = MAX_FEATURE_LEN;
  597. initParam->m_FullFilePath = "";
  598. initParam->m_ScanSuc = false;
  599. initParam->m_NotFindImage = false;
  600. initParam->m_FeatureIsNull = false;
  601. initParam->m_Quit = false;
  602. if (scanTime == 1)
  603. {
  604. m_BmpFileFullPath1 = "";
  605. m_BmpFileFullPath2 = "";
  606. m_BmpFileFullPath3 = "";
  607. }
  608. Dbg("before scan fingerprint, clear bmp file");
  609. DeleteBmp(BmpImage);
  610. Dbg("before scan fingerprint, finish doing clear job");
  611. if ((operateType & RegisterType) == RegisterType)
  612. {
  613. initParam->m_Template = new BYTE[MAX_FEATURE_LEN];
  614. initParam->m_GetTemplateSuc = true;
  615. m_bCancelRegister = false;
  616. memset(initParam->m_Template, 0, sizeof(initParam->m_Template));
  617. }else
  618. m_bCancelMatch = false;
  619. memset(initParam->m_Feature, 0, sizeof(initParam->m_Feature));
  620. errCode = m_pEntity->GetFunction()->GetPath("Dep", initParam->m_DepPath);
  621. if (errCode != Error_Succeed)
  622. {
  623. delete[] initParam->m_Feature;
  624. initParam->m_Feature = NULL;
  625. if ((operateType & RegisterType) == RegisterType)
  626. {
  627. delete[] initParam->m_Template;
  628. initParam->m_Template = NULL;
  629. Dbg("Get dep path failed while register.");
  630. LogError(Severity_High, Error_DevLoadFileFailed
  631. , LOG_ERR_FINGERPRINT_GET_DEP_PATH_FAILED_REGISTER
  632. , "Get dep path failed while register.");
  633. }
  634. else {
  635. Dbg("Get dep path failed while match.");
  636. LogError(Severity_High, Error_DevLoadFileFailed
  637. , LOG_ERR_FINGERPRINT_GET_DEP_PATH_FAILED_MATCH
  638. , "get dep path failed while match.");
  639. }
  640. delete initParam;
  641. initParam = NULL;
  642. return Error_Param;
  643. }
  644. return Error_Succeed;
  645. }
  646. ErrorCodeEnum CFingerPrintFSM::GetDevCatInfo(DevCategoryInfo& devInfo)
  647. {
  648. Dbg("DevCatgoryInfo len:%d, %d, %d", strlen(m_devCatInfo.szModel), strlen(m_devCatInfo.szType), strlen(m_devCatInfo.szVendor));
  649. #ifdef RVC_OS_WIN
  650. strncpy_s(devInfo.szModel, MAX_DEV_MODEL_LEN, m_devCatInfo.szModel, strlen(m_devCatInfo.szModel));
  651. strncpy_s(devInfo.szType, MAX_DEV_TYPE_LEN, m_devCatInfo.szType, strlen(m_devCatInfo.szType));
  652. strncpy_s(devInfo.szVendor, MAX_DEV_VENDOR_LEN, m_devCatInfo.szVendor, strlen(m_devCatInfo.szVendor));
  653. #else
  654. strncpy(devInfo.szModel, m_devCatInfo.szModel, (MAX_DEV_MODEL_LEN > strlen(m_devCatInfo.szModel)) ? strlen(m_devCatInfo.szModel) : MAX_DEV_MODEL_LEN);
  655. strncpy(devInfo.szType, m_devCatInfo.szType, (MAX_DEV_TYPE_LEN > strlen(m_devCatInfo.szType)) ? strlen(m_devCatInfo.szType) : MAX_DEV_TYPE_LEN);
  656. strncpy(devInfo.szVendor, m_devCatInfo.szVendor, (MAX_DEV_VENDOR_LEN > strlen(m_devCatInfo.szVendor)) ? strlen(m_devCatInfo.szVendor) : MAX_DEV_VENDOR_LEN);
  657. #endif // RVC_OS_WIN
  658. return Error_Succeed;
  659. }
  660. CSimpleString CFingerPrintFSM::GenerateAlarmJson(CSimpleString entityName, int cost)
  661. {
  662. return CSimpleString::Format("[{\"name\":\"%s\",\"cost\":%d}]"
  663. , entityName.GetData(), cost);
  664. }
  665. ErrorCodeEnum CFingerPrintFSM::QueryRootConfigObj(CSmartPointer<IConfigInfo>& spConfig)
  666. {
  667. ErrorCodeEnum errDev = Error_Succeed;
  668. CSmartPointer<IEntityFunction> spEntityFunction = GetEntityBase()->GetFunction();
  669. errDev = spEntityFunction->OpenConfig(Config_Root, spConfig);
  670. if (errDev != Error_Succeed)
  671. {
  672. Dbg("open cfg file failed!");
  673. LogError(Severity_High, Error_DevLoadFileFailed
  674. , LOG_ERR_FINGERPRINT_OPEN_ROOT_FAILED_ONINIT
  675. , "get dllname failed while init");
  676. }
  677. return errDev;
  678. }
  679. ErrorCodeEnum CFingerPrintFSM::DoDevOpen(CSmartPointer<IConfigInfo> spConfig)
  680. {
  681. ErrorCodeEnum errDev = Error_Succeed;
  682. do
  683. {
  684. int tmpPort = 0;
  685. int baudrate = 0;
  686. spConfig->ReadConfigValueInt("Device.FingerPrint", "Port", tmpPort);
  687. spConfig->ReadConfigValueInt("Device.FingerPrint", "Baudrate", baudrate);
  688. Dbg("port: %d, baudrate: %d", tmpPort, baudrate);
  689. if (IsFWBDevice())
  690. {
  691. if (Error_Succeed != CheckCardSwiperStatus())
  692. {
  693. Dbg("this is FWB, device status is not normal now.%d", CheckCardSwiperStatus());
  694. delete m_DevAdptLibHelper;
  695. m_DevAdptLibHelper = nullptr;
  696. return Error_DevCommFailed;
  697. }else {
  698. Dbg("this is FWB, device status is normal now.");
  699. }
  700. }
  701. errDev = m_pFingerPrint->DevOpen(tmpPort, baudrate);
  702. if (errDev != Error_Succeed)
  703. {
  704. WORD devErrCode = errDev;
  705. CSimpleStringA errMsg = "";
  706. GetAndSplitDevErrInfo(errMsg, devErrCode, "DevOpen"); //TODO: devErrCode???
  707. LogError(Severity_High, Error_Hardware, LOG_ERR_FINGERPRINT_OPEN_FAILED, "Fingerprint init(DevOpen) failed.");
  708. delete m_DevAdptLibHelper;
  709. m_DevAdptLibHelper = nullptr;
  710. errDev = Error_DevCommFailed;
  711. }
  712. } while (0);
  713. return errDev;
  714. }
  715. ErrorCodeEnum CFingerPrintFSM::DoGetDevInfo()
  716. {
  717. ErrorCodeEnum errDev = Error_Succeed;
  718. ZeroMemory(m_devCatInfo.szModel, MAX_DEV_MODEL_LEN);
  719. ZeroMemory(m_devCatInfo.szType, MAX_DEV_TYPE_LEN);
  720. ZeroMemory(m_devCatInfo.szVendor, MAX_DEV_VENDOR_LEN);
  721. errDev = m_pFingerPrint->GetDevCategory(m_devCatInfo);
  722. if (errDev == Error_Succeed)
  723. {
  724. Dbg("%d, %d, %d", strlen(m_devCatInfo.szModel), strlen(m_devCatInfo.szType), strlen(m_devCatInfo.szVendor));
  725. if (strlen(m_devCatInfo.szModel) < 256)
  726. Dbg("szMode=%s", m_devCatInfo.szModel);
  727. if (nullptr != m_DevAdptLibHelper && nullptr != m_pFingerPrint)
  728. {
  729. m_devInit = true;
  730. errDev = Error_Succeed;
  731. }
  732. else
  733. errDev = Error_NotInit;
  734. }
  735. else {
  736. Dbg("Invoke vendor routine 'GetDevCategory' failed.");
  737. LogError(Severity_High, Error_Hardware
  738. , LOG_ERR_FINGERPRINT_GETDEVINFO_FAILED
  739. , "Get device info(GetDevCategory) failed.");
  740. delete m_DevAdptLibHelper;
  741. m_DevAdptLibHelper = nullptr;
  742. errDev = Error_DevCommFailed;
  743. }
  744. return errDev;
  745. }
  746. void CFingerPrintFSM::GetVendorLibName(CSmartPointer<IConfigInfo> spConfig
  747. , CSimpleString& dllName)
  748. {
  749. CSimpleString machineVersion(true);
  750. CSimpleString machineType(true);
  751. CSimpleStringA strVendor(true);
  752. CSimpleStringA strVersion(true);
  753. CSimpleStringA strBatch(true);
  754. GetMachineInfo(machineVersion, machineType);
  755. spConfig->ReadConfigValue("Device.PinPad", "Vendor", strVendor);
  756. spConfig->ReadConfigValue("Device.PinPad", "Version", strVersion);
  757. spConfig->ReadConfigValue("Device.PinPad", "Batch", strBatch);
  758. if (strVendor.IsNullOrEmpty() || strVersion.IsNullOrEmpty() || strBatch.IsNullOrEmpty())
  759. {
  760. Dbg("Some related node is not set, cannot continue.");
  761. }else {
  762. strBatch = "1";
  763. if (!strVendor.Compare("Hyosung", true))
  764. {
  765. strVersion = "1";
  766. }else {
  767. if (!machineType.Compare("RVC.Stand2S", true))
  768. {
  769. strVersion = "7";
  770. //TODO: Support new or old edition machine.
  771. }else if (!machineType.Compare("RVC.PAD", true))
  772. {
  773. if (IsFWBDevice())
  774. {
  775. //蓝牙多合一
  776. GetEntityBase()->GetFunction()->GetSysVar("FWBVendor", strVendor);
  777. strVersion = "8";
  778. }else {
  779. strVersion = "1";
  780. }
  781. }
  782. else if (!machineType.Compare("RVC.Desk2S", true))
  783. {
  784. strVersion = "4";
  785. if (machineVersion.Compare("1.0", true))
  786. {
  787. strBatch = "20"; //低柜一体机(贵宾理财2.0&非贵宾理财2.1)
  788. }
  789. }else if (!machineType.Compare("RVC.Desk1S", true) && !machineVersion.Compare("1.0"))
  790. {
  791. strVersion = "4"; //低柜一体机(厅堂自助)
  792. strBatch = "20";
  793. }else {
  794. strVersion = "1"; //eg:CardStore
  795. }
  796. }
  797. CSimpleStringA newFileName(GetEntityBase()->GetEntityName());
  798. newFileName = newFileName + "." + strVendor + "."
  799. + strVersion + "." + strBatch + ".dll";
  800. CSimpleStringA strDepPath;
  801. GetEntityBase()->GetFunction()->GetPath("Dep", strDepPath);
  802. if (strDepPath.IsNullOrEmpty())
  803. {
  804. Dbg("Get Dep path failed!");
  805. }else {
  806. dllName = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  807. , (const char*)strDepPath
  808. , (const char*)newFileName);
  809. }
  810. }
  811. }
  812. ErrorCodeEnum CFingerPrintFSM::GetMachineInfo(CSimpleString& machineVersion
  813. , CSimpleString& machineType)
  814. {
  815. CSystemStaticInfo sysInfo;
  816. GetEntityBase()->GetFunction()->GetSystemStaticInfo(sysInfo);
  817. machineType = sysInfo.strMachineType;
  818. WORD majorVersion = sysInfo.MachineVersion.GetMajor();
  819. WORD minorVersion = sysInfo.MachineVersion.GetMinor();;
  820. machineVersion = CSimpleStringA::Format("%d.%d", majorVersion, minorVersion);
  821. Dbg("MachineType:%s, terminalNo: %s"
  822. , (const char*)machineType
  823. , (const char*)sysInfo.strTerminalID);
  824. return Error_Succeed;
  825. }
  826. bool CFingerPrintFSM::IsFileExist(CSimpleString fileName)
  827. {
  828. std::ifstream bmpImage((const char*)fileName, std::ifstream::binary);
  829. return bmpImage.good();
  830. }
  831. ErrorCodeEnum CFingerPrintFSM::GetDevState(int& state)
  832. {
  833. ErrorCodeEnum errCode;
  834. state = 0;
  835. if (!m_devInit) {
  836. return Error_Succeed;
  837. }
  838. CSimpleStringA fileName = "testFinger.bmp";
  839. LPBYTE lpbFeature = new BYTE[MAX_FEATURE_LEN];
  840. int lpbLength = MAX_FEATURE_LEN;
  841. errCode = m_pFingerPrint->Image2Feature(fileName, lpbFeature, lpbLength);
  842. if (errCode == Error_Succeed)
  843. {
  844. state = 1;
  845. DeleteBmp(TestImage);
  846. }
  847. delete[] lpbFeature;
  848. lpbFeature = NULL;
  849. return Error_Succeed;
  850. }
  851. bool CFingerPrintFSM::IsFWBDevice()
  852. {
  853. CSimpleStringA tmpDevSN("");
  854. bool isFWB = false;
  855. GetEntityBase()->GetFunction()->GetSysVar("FWBDevSN", tmpDevSN);
  856. if (tmpDevSN.GetLength() > 12 && tmpDevSN.IndexOf("FWB") > 2)
  857. {
  858. Dbg("This is fwb device.");
  859. isFWB = true;
  860. }
  861. return isFWB;
  862. }
  863. ErrorCodeEnum CFingerPrintFSM::CheckCardSwiperStatus()
  864. {
  865. ErrorCodeEnum errCode = Error_Unexpect;
  866. CardSwiperService_ClientBase* pCardSwiperClient = new CardSwiperService_ClientBase(this->GetEntityBase());
  867. errCode = pCardSwiperClient->Connect();
  868. if (errCode != Error_Succeed)
  869. {
  870. Dbg("connect CardSwiper fail %s.", SpStrError(errCode));
  871. }else {
  872. CardSwiperService_GetDevInfo_Req req = {};
  873. CardSwiperService_GetDevInfo_Ans ans = {};
  874. errCode = pCardSwiperClient->GetDevInfo(req, ans, 3000);
  875. if (errCode != Error_Succeed)
  876. {
  877. Dbg("CardSwiper::GetDevInfo() fail: 0x%x", errCode);
  878. }else {
  879. Dbg("CardSwiper::GetDevInfo() return state: %d", ans.state);
  880. if (ans.state == DEVICE_STATUS_NOT_READY)
  881. {
  882. std::this_thread::sleep_for(std::chrono::milliseconds(500));
  883. CardSwiperService_GetDevInfo_Req req2 = {};
  884. CardSwiperService_GetDevInfo_Ans ans2 = {};
  885. errCode = pCardSwiperClient->GetDevInfo(req2, ans2, 3000);
  886. if (errCode != Error_Succeed)
  887. {
  888. Dbg("CardSwiper::GetDevInfo() again fail: 0x%x", errCode);
  889. }else {
  890. Dbg("CardSwiper::GetDevInfo() again return state: %d", ans2.state);
  891. if (ans2.state != DEVICE_STATUS_NORMAL)
  892. errCode = Error_DevNotAvailable;
  893. }
  894. }
  895. else if (ans.state != DEVICE_STATUS_NORMAL)
  896. errCode = Error_DevNotAvailable;
  897. }
  898. pCardSwiperClient->GetFunction()->CloseSession();
  899. }
  900. if (pCardSwiperClient != NULL)
  901. {
  902. pCardSwiperClient->SafeDelete();
  903. pCardSwiperClient = NULL;
  904. }
  905. return errCode;
  906. }
  907. void CFingerPrintFSM::DeleteBmp(int type)
  908. {
  909. if ((type & BmpImage) == BmpImage)
  910. {
  911. Dbg("to delete fingerprint images...");
  912. DeleteFileIfExisted("finger.bmp");
  913. DeleteFileIfExisted("finger1.bmp");
  914. DeleteFileIfExisted("finger2.bmp");
  915. DeleteFileIfExisted("finger3.bmp");
  916. }
  917. if ((type & TestImage) == TestImage)
  918. {
  919. DeleteFileIfExisted("testFinger.bmp");
  920. }
  921. }
  922. ErrorCodeEnum CFingerPrintFSM::DeleteFileIfExisted(LPCTSTR fileName)
  923. {
  924. if (strlen(fileName) == 0 || strchr(fileName, (int)'*') != NULL)
  925. {
  926. Dbg("Invalid or empty filename(%s)", fileName);
  927. return Error_Param;
  928. }
  929. CSimpleStringA strPath, strObjPath;
  930. ErrorCodeEnum errCode = m_pEntity->GetFunction()->GetPath("Dep", strPath);
  931. strObjPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", (const char*)strPath, (const char*)fileName);
  932. std::ifstream beDeletedFile((const char*)strObjPath, std::ifstream::binary);
  933. if (beDeletedFile)
  934. {
  935. if (remove((const char*)strObjPath) == 0)
  936. {
  937. Dbg("DeleteFile(%s) success.", (const char*)strObjPath);
  938. return Error_Succeed;
  939. }
  940. else {
  941. Dbg("DeleteFile(%s) failed LastError(%s).", (const char*)strObjPath, GetLastError());
  942. return Error_Unexpect;
  943. }
  944. }
  945. if (GetLastError() == ERROR_FILE_NOT_FOUND)
  946. {
  947. return Error_Succeed;
  948. }
  949. Dbg("DeleteFle(%s) Unexpect GetLastError(%s).", (LPCTSTR)strObjPath, GetLastError());
  950. return Error_Unexpect;
  951. }