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)", SpStrError(errCode), devErrorInfo.szErrMsg);
  341. break;
  342. }
  343. }
  344. pScanParam->m_ScanSuc = true;
  345. break;
  346. }else if (!bmpImage) {
  347. Dbg("Cannot find the fingerprint image %s", pScanParam->m_BmpFileName);
  348. pScanParam->m_NotFindImage = true;
  349. break;
  350. }else {
  351. Dbg("Fingerprint feature is NULL.");
  352. pScanParam->m_FeatureIsNull = true;
  353. break;
  354. }
  355. }else {
  356. DevErrorInfo devErrInfo;
  357. m_pFingerPrint->GetLastErr(devErrInfo);
  358. Dbg("Invoke routine 'Image2Feature' failed which returned %s(%s) while register."
  359. , SpStrError(errCode), devErrInfo.szErrMsg);
  360. }
  361. pScanParam->m_TimeEnd = clock();
  362. pScanParam->m_TimeLeft = pScanParam->m_TimeEnd - pScanParam->m_TimeStart;
  363. }
  364. LogEvent(Severity_Middle, LOG_EVT_FINGERPRINT_GREEN_OFF, "FingerPrint warning on");
  365. m_bExit = false;
  366. }
  367. void CFingerPrintFSM::ProcessAfterScan(ScanParam* pScanParam, SpReqAnsContext<FingerPrintService_GetImageAndFeature_Req, FingerPrintService_GetImageAndFeature_Ans>::Pointer& ctx)
  368. {
  369. if (pScanParam->m_ScanSuc)
  370. {
  371. ctx->Answer(Error_Succeed);
  372. }
  373. else if (pScanParam->m_TimeLeft >= FINGERPRINT_SCAN_TIMEOUT)
  374. {
  375. ctx->Answer(Error_TimeOut);
  376. }
  377. else if (m_bCancelRegister)
  378. {
  379. ctx->Answer(Error_Cancel);
  380. }else {
  381. if (pScanParam->m_NotFindImage)
  382. {
  383. LogError(Severity_High, Error_Hardware
  384. , LOG_ERR_FINGERPRINT_NO_IMAGE_IN_DEP_REGISTER
  385. , "not find fingerprint image in dep while register.");
  386. ctx->Answer(Error_Unexpect, LOG_ERR_FINGERPRINT_NO_IMAGE_IN_DEP_REGISTER);
  387. }
  388. else if (pScanParam->m_FeatureIsNull)
  389. {
  390. LogError(Severity_High, Error_Hardware
  391. , LOG_ERR_FINGERPRINT_GETFEATURE_FAILED_REGISTER
  392. , "fingerprint feature is null while register.");
  393. ctx->Answer(Error_Unexpect, LOG_ERR_FINGERPRINT_GETFEATURE_FAILED_REGISTER);
  394. }else {
  395. if (ctx->Req.times == 3 && !pScanParam->m_GetTemplateSuc)
  396. {
  397. LogError(Severity_High, Error_Hardware
  398. , LOG_ERR_FINGERPRINT_GETTEMPLATE_FAILED
  399. , "Not generate template correctly.");
  400. ctx->Answer(Error_Unexpect, LOG_ERR_FINGERPRINT_GETTEMPLATE_FAILED);
  401. }else if (pScanParam->m_Quit) {
  402. LogWarn(Severity_High, Error_Hardware
  403. , LOG_ERR_FINGERPRINT_REGISTER_FAILED
  404. , "Exit to homepage when register.");
  405. ctx->Answer(Error_Unexpect);
  406. }
  407. }
  408. }
  409. delete[] pScanParam->m_Feature;
  410. pScanParam->m_Feature = NULL;
  411. delete[] pScanParam->m_Template;
  412. pScanParam->m_Template = NULL;
  413. delete pScanParam;
  414. pScanParam = NULL;
  415. }
  416. ErrorCodeEnum CFingerPrintFSM::Match(SpReqAnsContext<FingerPrintService_Match_Req, FingerPrintService_Match_Ans>::Pointer ctx)
  417. {
  418. LOG_FUNCTION();
  419. ScanParam* initParam = new ScanParam();
  420. ErrorCodeEnum errCode = InitParamBeforeMatch(initParam, ctx->Req.templateNum);
  421. if (errCode != Error_Succeed)
  422. return errCode;
  423. ScanBeforeMatch(initParam);
  424. errCode = MatchProcess(initParam, ctx);
  425. return errCode;
  426. }
  427. ErrorCodeEnum CFingerPrintFSM::InitParamBeforeMatch(ScanParam* initParam, int templateNum)
  428. {
  429. ErrorCodeEnum errCode = Error_Succeed;
  430. errCode = InitCommParam(initParam, MatchType, 0, templateNum);
  431. if (errCode != Error_Succeed)
  432. return errCode;
  433. initParam->m_BmpFileName = "finger.bmp";
  434. initParam->m_FullFilePath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  435. , (const char*)initParam->m_DepPath
  436. , (const char*)initParam->m_BmpFileName);
  437. Dbg("get imageName success: %s", initParam->m_FullFilePath);
  438. return Error_Succeed;
  439. }
  440. void CFingerPrintFSM::ScanBeforeMatch(ScanParam* initParam)
  441. {
  442. ErrorCodeEnum errCode = Error_Succeed;
  443. LogEvent(Severity_Middle, LOG_EVT_FINGERPRINT_GREEN_ON, "FingerPrint warning on");
  444. while (initParam->m_TimeLeft < FINGERPRINT_MATCH_TIMEOUT
  445. && !m_bCancelMatch && !initParam->m_ScanSuc)
  446. {
  447. if (m_bExit)
  448. {
  449. Dbg("Exit");
  450. initParam->m_Quit = true;
  451. break;
  452. }
  453. std::this_thread::sleep_for(std::chrono::milliseconds(FINGERPRINT_SCAN_INTERNAL));
  454. //Sleep(FINGERPRINT_SCAN_INTERNAL);
  455. initParam->m_FeatureLen = MAX_FEATURE_LEN;
  456. errCode = m_pFingerPrint->Image2Feature(initParam->m_BmpFileName
  457. , initParam->m_Feature
  458. , initParam->m_FeatureLen);
  459. if (errCode == Error_Succeed)
  460. {
  461. //TODO: union test
  462. Dbg("Invoke routine 'Image2Feature' success.");
  463. std::this_thread::sleep_for(std::chrono::milliseconds(200));
  464. //Sleep(200);//save image may be delayed some time, not must happen
  465. std::ifstream bmpImage((const char*)initParam->m_FullFilePath, std::fstream::binary);
  466. if (bmpImage && initParam->m_Feature != NULL && initParam->m_FeatureLen > 0)
  467. {
  468. Dbg("fingerprint feature length is %d", initParam->m_FeatureLen);
  469. initParam->m_ScanSuc = true;
  470. break;
  471. }
  472. else if (!bmpImage)
  473. {
  474. Dbg("Cannot find the fingerprint image finger.bmp");
  475. initParam->m_NotFindImage = true;
  476. break;
  477. }else {
  478. Dbg("Fingerprint feature is NULL.");
  479. initParam->m_FeatureIsNull = true;
  480. break;
  481. }
  482. }else {
  483. DevErrorInfo devErrInfo;
  484. m_pFingerPrint->GetLastErr(devErrInfo);
  485. Dbg("Invoke routine 'Image2Feature' failed which returned %s(%s)"
  486. , SpStrError(errCode), devErrInfo.szErrMsg);
  487. }
  488. initParam->m_TimeEnd = clock();
  489. initParam->m_TimeLeft = initParam->m_TimeEnd - initParam->m_TimeStart;
  490. }
  491. LogEvent(Severity_Middle, LOG_EVT_FINGERPRINT_GREEN_OFF, "FingerPrint warning off");
  492. m_bExit = false;
  493. Dbg("after match, clear bmp file");
  494. DeleteBmp(BmpImage);
  495. }
  496. ErrorCodeEnum CFingerPrintFSM::MatchProcess(ScanParam* initParam, SpReqAnsContext<FingerPrintService_Match_Req, FingerPrintService_Match_Ans>::Pointer& ctx)
  497. {
  498. ErrorCodeEnum errCode = Error_Succeed;
  499. if (initParam->m_ScanSuc)
  500. {
  501. Dbg("templateNum=%d", ctx->Req.templateNum);
  502. int templateNum = ctx->Req.templateNum;
  503. LPBYTE* lpbTemplates = new LPBYTE[templateNum];
  504. int* lpbTemplateLen = new int[templateNum];
  505. for (int i = 0; i < templateNum; ++i)
  506. {
  507. lpbTemplates[i] = new BYTE[MAX_FEATURE_LEN];
  508. memset(lpbTemplates[i], 0, sizeof(lpbTemplates[i]));
  509. strcpy((char*)lpbTemplates[i], ctx->Req.templates[i]);
  510. lpbTemplateLen[i] = ctx->Req.templateLen[i];
  511. }
  512. clock_t startMatch = clock();
  513. errCode = m_pFingerPrint->Match(lpbTemplates, lpbTemplateLen, templateNum,
  514. initParam->m_Feature, initParam->m_FeatureLen);
  515. clock_t endMatch = clock();
  516. int duration = (endMatch - startMatch) * 1000 / CLOCKS_PER_SEC;
  517. LogWarn(Severity_High, Error_Debug, LOG_ERR_FINGERPRINT_MATCH_TIME,
  518. GenerateAlarmJson("FingerPrint", duration).GetData());
  519. if (errCode == Error_Succeed) //always true
  520. {
  521. Dbg("Invoke routine 'Match' success");
  522. ctx->Ans.result.Init(templateNum);
  523. for (int i = 0; i < templateNum; ++i)
  524. ctx->Ans.result[i] = lpbTemplateLen[i];
  525. }else{
  526. DevErrorInfo devErrInfo;
  527. m_pFingerPrint->GetLastErr(devErrInfo);
  528. LogError(Severity_High, Error_Hardware
  529. , LOG_ERR_FINGERPRINT_INVOKE_MATCH_FAILED
  530. , "Invoke routine 'Match' failed.");//no this situation
  531. Dbg("Invoke routine 'Match' failed which returned %s(%s)"
  532. , SpStrError(errCode), devErrInfo.szErrMsg);
  533. errCode = Error_Unexpect;
  534. }
  535. for (int i = 0; i < templateNum; ++i)
  536. {
  537. delete[] lpbTemplates[i];
  538. lpbTemplates[i] = NULL;
  539. }
  540. delete[] lpbTemplateLen;
  541. lpbTemplateLen = NULL;
  542. delete[] lpbTemplates;
  543. lpbTemplates = NULL;
  544. }
  545. else if (initParam->m_TimeLeft >= FINGERPRINT_MATCH_TIMEOUT)
  546. {
  547. Dbg("Match timeout(Invoke vendor failed or not press finger)");
  548. errCode = Error_TimeOut;
  549. }
  550. else if (m_bCancelMatch)
  551. {
  552. errCode = Error_Cancel;
  553. }
  554. else
  555. {
  556. if (initParam->m_NotFindImage)
  557. LogError(Severity_High, Error_Hardware, LOG_ERR_FINGERPRINT_NO_IMAGE_IN_DEP_MATCH, "not find fingerprint image in dep while match.");
  558. else if (initParam->m_FeatureIsNull)
  559. LogError(Severity_High, Error_Hardware, LOG_ERR_FINGERPRINT_GETFEATURE_FAILED_MATCH, "fingerprint feature is null while match.");
  560. else if (initParam->m_Quit)
  561. LogWarn(Severity_High, Error_Hardware, LOG_ERR_FINGERPRINT_MATCH_FAILED, "Exit to homepage when match.");
  562. errCode = Error_Unexpect;
  563. }
  564. delete[] initParam->m_Feature;
  565. initParam->m_Feature = NULL;
  566. delete initParam;
  567. initParam = NULL;
  568. return errCode;
  569. }
  570. ErrorCodeEnum CFingerPrintFSM::InitCommParam(ScanParam* initParam, int operateType, int scanTime, int templateNum)
  571. {
  572. ErrorCodeEnum errCode = Error_Succeed;
  573. if (!initParam)
  574. return Error_Param;
  575. if (!m_devInit)
  576. errCode = Error_NotInit; //maybe no vendor adapter
  577. if ((operateType & RegisterType) == RegisterType)
  578. {
  579. if (m_bCancelRegister) //no cancel button anymore while register
  580. {
  581. m_bCancelRegister = false;
  582. errCode = Error_Cancel;
  583. }
  584. }
  585. if ((operateType & MatchType) == MatchType && templateNum <= 0)
  586. errCode = Error_Param;
  587. if (errCode != Error_Succeed) {
  588. delete initParam;
  589. initParam = NULL;
  590. }
  591. initParam->m_TimeStart = clock();
  592. initParam->m_TimeEnd = clock();
  593. initParam->m_TimeLeft = 0;
  594. initParam->m_Feature = new BYTE[MAX_FEATURE_LEN];
  595. initParam->m_FeatureLen = MAX_FEATURE_LEN;
  596. initParam->m_FullFilePath = "";
  597. initParam->m_ScanSuc = false;
  598. initParam->m_NotFindImage = false;
  599. initParam->m_FeatureIsNull = false;
  600. initParam->m_Quit = false;
  601. if (scanTime == 1)
  602. {
  603. m_BmpFileFullPath1 = "";
  604. m_BmpFileFullPath2 = "";
  605. m_BmpFileFullPath3 = "";
  606. }
  607. Dbg("before scan fingerprint, clear bmp file");
  608. DeleteBmp(BmpImage);
  609. Dbg("before scan fingerprint, finish doing clear job");
  610. if ((operateType & RegisterType) == RegisterType)
  611. {
  612. initParam->m_Template = new BYTE[MAX_FEATURE_LEN];
  613. initParam->m_GetTemplateSuc = true;
  614. m_bCancelRegister = false;
  615. memset(initParam->m_Template, 0, sizeof(initParam->m_Template));
  616. }else
  617. m_bCancelMatch = false;
  618. memset(initParam->m_Feature, 0, sizeof(initParam->m_Feature));
  619. errCode = m_pEntity->GetFunction()->GetPath("Dep", initParam->m_DepPath);
  620. if (errCode != Error_Succeed)
  621. {
  622. delete[] initParam->m_Feature;
  623. initParam->m_Feature = NULL;
  624. if ((operateType & RegisterType) == RegisterType)
  625. {
  626. delete[] initParam->m_Template;
  627. initParam->m_Template = NULL;
  628. Dbg("Get dep path failed while register.");
  629. LogError(Severity_High, Error_DevLoadFileFailed
  630. , LOG_ERR_FINGERPRINT_GET_DEP_PATH_FAILED_REGISTER
  631. , "Get dep path failed while register.");
  632. }
  633. else {
  634. Dbg("Get dep path failed while match.");
  635. LogError(Severity_High, Error_DevLoadFileFailed
  636. , LOG_ERR_FINGERPRINT_GET_DEP_PATH_FAILED_MATCH
  637. , "get dep path failed while match.");
  638. }
  639. delete initParam;
  640. initParam = NULL;
  641. return Error_Param;
  642. }
  643. return Error_Succeed;
  644. }
  645. ErrorCodeEnum CFingerPrintFSM::GetDevCatInfo(DevCategoryInfo& devInfo)
  646. {
  647. Dbg("DevCatgoryInfo len:%d, %d, %d", strlen(m_devCatInfo.szModel), strlen(m_devCatInfo.szType), strlen(m_devCatInfo.szVendor));
  648. #ifdef RVC_OS_WIN
  649. strncpy_s(devInfo.szModel, MAX_DEV_MODEL_LEN, m_devCatInfo.szModel, strlen(m_devCatInfo.szModel));
  650. strncpy_s(devInfo.szType, MAX_DEV_TYPE_LEN, m_devCatInfo.szType, strlen(m_devCatInfo.szType));
  651. strncpy_s(devInfo.szVendor, MAX_DEV_VENDOR_LEN, m_devCatInfo.szVendor, strlen(m_devCatInfo.szVendor));
  652. #else
  653. strncpy(devInfo.szModel, m_devCatInfo.szModel, (MAX_DEV_MODEL_LEN > strlen(m_devCatInfo.szModel)) ? strlen(m_devCatInfo.szModel) : MAX_DEV_MODEL_LEN);
  654. strncpy(devInfo.szType, m_devCatInfo.szType, (MAX_DEV_TYPE_LEN > strlen(m_devCatInfo.szType)) ? strlen(m_devCatInfo.szType) : MAX_DEV_TYPE_LEN);
  655. strncpy(devInfo.szVendor, m_devCatInfo.szVendor, (MAX_DEV_VENDOR_LEN > strlen(m_devCatInfo.szVendor)) ? strlen(m_devCatInfo.szVendor) : MAX_DEV_VENDOR_LEN);
  656. #endif // RVC_OS_WIN
  657. return Error_Succeed;
  658. }
  659. CSimpleString CFingerPrintFSM::GenerateAlarmJson(CSimpleString entityName, int cost)
  660. {
  661. return CSimpleString::Format("[{\"name\":\"%s\",\"cost\":%d}]"
  662. , entityName.GetData(), cost);
  663. }
  664. ErrorCodeEnum CFingerPrintFSM::QueryRootConfigObj(CSmartPointer<IConfigInfo>& spConfig)
  665. {
  666. ErrorCodeEnum errDev = Error_Succeed;
  667. CSmartPointer<IEntityFunction> spEntityFunction = GetEntityBase()->GetFunction();
  668. errDev = spEntityFunction->OpenConfig(Config_Root, spConfig);
  669. if (errDev != Error_Succeed)
  670. {
  671. Dbg("open cfg file failed!");
  672. LogError(Severity_High, Error_DevLoadFileFailed
  673. , LOG_ERR_FINGERPRINT_OPEN_ROOT_FAILED_ONINIT
  674. , "get dllname failed while init");
  675. }
  676. return errDev;
  677. }
  678. ErrorCodeEnum CFingerPrintFSM::DoDevOpen(CSmartPointer<IConfigInfo> spConfig)
  679. {
  680. ErrorCodeEnum errDev = Error_Succeed;
  681. do
  682. {
  683. int tmpPort = 0;
  684. int baudrate = 0;
  685. spConfig->ReadConfigValueInt("Device.FingerPrint", "Port", tmpPort);
  686. spConfig->ReadConfigValueInt("Device.FingerPrint", "Baudrate", baudrate);
  687. Dbg("port: %d, baudrate: %d", tmpPort, baudrate);
  688. if (IsFWBDevice())
  689. {
  690. if (Error_Succeed != CheckCardSwiperStatus())
  691. {
  692. Dbg("this is FWB, device status is not normal now.%d", CheckCardSwiperStatus());
  693. delete m_DevAdptLibHelper;
  694. m_DevAdptLibHelper = nullptr;
  695. return Error_DevCommFailed;
  696. }else {
  697. Dbg("this is FWB, device status is normal now.");
  698. }
  699. }
  700. errDev = m_pFingerPrint->DevOpen(tmpPort, baudrate);
  701. if (errDev != Error_Succeed)
  702. {
  703. WORD devErrCode = errDev;
  704. CSimpleStringA errMsg = "";
  705. GetAndSplitDevErrInfo(errMsg, devErrCode, "DevOpen"); //TODO: devErrCode???
  706. LogError(Severity_High, Error_Hardware, LOG_ERR_FINGERPRINT_OPEN_FAILED, "Fingerprint init(DevOpen) failed.");
  707. delete m_DevAdptLibHelper;
  708. m_DevAdptLibHelper = nullptr;
  709. errDev = Error_DevCommFailed;
  710. }
  711. } while (0);
  712. return errDev;
  713. }
  714. ErrorCodeEnum CFingerPrintFSM::DoGetDevInfo()
  715. {
  716. ErrorCodeEnum errDev = Error_Succeed;
  717. ZeroMemory(m_devCatInfo.szModel, MAX_DEV_MODEL_LEN);
  718. ZeroMemory(m_devCatInfo.szType, MAX_DEV_TYPE_LEN);
  719. ZeroMemory(m_devCatInfo.szVendor, MAX_DEV_VENDOR_LEN);
  720. errDev = m_pFingerPrint->GetDevCategory(m_devCatInfo);
  721. if (errDev == Error_Succeed)
  722. {
  723. Dbg("%d, %d, %d", strlen(m_devCatInfo.szModel), strlen(m_devCatInfo.szType), strlen(m_devCatInfo.szVendor));
  724. if (strlen(m_devCatInfo.szModel) < 256)
  725. Dbg("szMode=%s", m_devCatInfo.szModel);
  726. if (nullptr != m_DevAdptLibHelper && nullptr != m_pFingerPrint)
  727. {
  728. m_devInit = true;
  729. errDev = Error_Succeed;
  730. }
  731. else
  732. errDev = Error_NotInit;
  733. }
  734. else {
  735. Dbg("Invoke vendor routine 'GetDevCategory' failed.");
  736. LogError(Severity_High, Error_Hardware
  737. , LOG_ERR_FINGERPRINT_GETDEVINFO_FAILED
  738. , "Get device info(GetDevCategory) failed.");
  739. delete m_DevAdptLibHelper;
  740. m_DevAdptLibHelper = nullptr;
  741. errDev = Error_DevCommFailed;
  742. }
  743. return errDev;
  744. }
  745. void CFingerPrintFSM::GetVendorLibName(CSmartPointer<IConfigInfo> spConfig, CSimpleString& dllName)
  746. {
  747. CSimpleString machineVersion(true);
  748. CSimpleString machineType(true);
  749. CSimpleStringA strVendor(true);
  750. CSimpleStringA strVersion(true);
  751. CSimpleStringA strBatch(true);
  752. GetMachineInfo(machineVersion, machineType);
  753. spConfig->ReadConfigValue("Device.PinPad", "Vendor", strVendor);
  754. spConfig->ReadConfigValue("Device.PinPad", "Version", strVersion);
  755. spConfig->ReadConfigValue("Device.PinPad", "Batch", strBatch);
  756. if (strVendor.IsNullOrEmpty() || strVersion.IsNullOrEmpty() || strBatch.IsNullOrEmpty())
  757. {
  758. Dbg("Some related node is not set, cannot continue.");
  759. }else {
  760. strBatch = "1";
  761. if (!strVendor.Compare("Hyosung", true))
  762. {
  763. strVersion = "1";
  764. }else {
  765. if (!machineType.Compare("RVC.Stand2S", true))
  766. {
  767. strVersion = "7";
  768. //TODO: Support new or old edition machine.
  769. }else if (!machineType.Compare("RVC.PAD", true))
  770. {
  771. if (IsFWBDevice())
  772. {
  773. //蓝牙多合一
  774. GetEntityBase()->GetFunction()->GetSysVar("FWBVendor", strVendor);
  775. strVersion = "8";
  776. }else {
  777. strVersion = "1";
  778. }
  779. }
  780. else if (!machineType.Compare("RVC.Desk2S", true))
  781. {
  782. strVersion = "4";
  783. if (machineVersion.Compare("1.0", true))
  784. {
  785. strBatch = "20"; //低柜一体机(贵宾理财2.0&非贵宾理财2.1)
  786. }
  787. }else if (!machineType.Compare("RVC.Desk1S", true) && !machineVersion.Compare("1.0"))
  788. {
  789. strVersion = "4"; //低柜一体机(厅堂自助)
  790. strBatch = "20";
  791. }else {
  792. strVersion = "1"; //eg:CardStore
  793. }
  794. }
  795. CSimpleStringA newFileName(GetEntityBase()->GetEntityName());
  796. newFileName = newFileName + "." + strVendor + "."
  797. + strVersion + "." + strBatch + ".dll";
  798. CSimpleStringA strDepPath;
  799. GetEntityBase()->GetFunction()->GetPath("Dep", strDepPath);
  800. if (strDepPath.IsNullOrEmpty())
  801. {
  802. Dbg("Get Dep path failed!");
  803. }else {
  804. dllName = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  805. , (const char*)strDepPath
  806. , (const char*)newFileName);
  807. }
  808. }
  809. }
  810. ErrorCodeEnum CFingerPrintFSM::GetMachineInfo(CSimpleString& machineVersion, CSimpleString& machineType)
  811. {
  812. CSystemStaticInfo sysInfo;
  813. GetEntityBase()->GetFunction()->GetSystemStaticInfo(sysInfo);
  814. machineType = sysInfo.strMachineType;
  815. WORD majorVersion = sysInfo.MachineVersion.GetMajor();
  816. WORD minorVersion = sysInfo.MachineVersion.GetMinor();;
  817. machineVersion = CSimpleStringA::Format("%d.%d", majorVersion, minorVersion);
  818. Dbg("MachineType:%s, terminalNo: %s"
  819. , (const char*)machineType
  820. , (const char*)sysInfo.strTerminalID);
  821. return Error_Succeed;
  822. }
  823. bool CFingerPrintFSM::IsFileExist(CSimpleString fileName)
  824. {
  825. std::ifstream bmpImage((const char*)fileName, std::ifstream::binary);
  826. return bmpImage.good();
  827. }
  828. ErrorCodeEnum CFingerPrintFSM::GetDevState(int& state)
  829. {
  830. ErrorCodeEnum errCode;
  831. state = 0;
  832. if (!m_devInit) {
  833. return Error_Succeed;
  834. }
  835. CSimpleStringA fileName = "testFinger.bmp";
  836. LPBYTE lpbFeature = new BYTE[MAX_FEATURE_LEN];
  837. int lpbLength = MAX_FEATURE_LEN;
  838. errCode = m_pFingerPrint->Image2Feature(fileName, lpbFeature, lpbLength);
  839. if (errCode == Error_Succeed)
  840. {
  841. state = 1;
  842. DeleteBmp(TestImage);
  843. }
  844. delete[] lpbFeature;
  845. lpbFeature = NULL;
  846. return Error_Succeed;
  847. }
  848. bool CFingerPrintFSM::IsFWBDevice()
  849. {
  850. CSimpleStringA tmpDevSN("");
  851. bool isFWB = false;
  852. GetEntityBase()->GetFunction()->GetSysVar("FWBDevSN", tmpDevSN);
  853. if (tmpDevSN.GetLength() > 12 && tmpDevSN.IndexOf("FWB") > 2)
  854. {
  855. Dbg("This is fwb device.");
  856. isFWB = true;
  857. }
  858. return isFWB;
  859. }
  860. ErrorCodeEnum CFingerPrintFSM::CheckCardSwiperStatus()
  861. {
  862. ErrorCodeEnum errCode = Error_Unexpect;
  863. CardSwiperService_ClientBase* pCardSwiperClient = new CardSwiperService_ClientBase(this->GetEntityBase());
  864. errCode = pCardSwiperClient->Connect();
  865. if (errCode != Error_Succeed)
  866. {
  867. Dbg("connect CardSwiper fail 0x%x(%d).", errCode, errCode);
  868. }
  869. else {
  870. CardSwiperService_GetDevInfo_Req req = {};
  871. CardSwiperService_GetDevInfo_Ans ans = {};
  872. errCode = pCardSwiperClient->GetDevInfo(req, ans, 3000);
  873. if (errCode != Error_Succeed)
  874. {
  875. Dbg("CardSwiper::GetDevInfo() fail: 0x%x", errCode);
  876. }
  877. else {
  878. Dbg("CardSwiper::GetDevInfo() return state: %d", ans.state);
  879. if (ans.state == DEVICE_STATUS_NOT_READY)
  880. {
  881. std::this_thread::sleep_for(std::chrono::milliseconds(500));
  882. CardSwiperService_GetDevInfo_Req req2 = {};
  883. CardSwiperService_GetDevInfo_Ans ans2 = {};
  884. errCode = pCardSwiperClient->GetDevInfo(req2, ans2, 3000);
  885. if (errCode != Error_Succeed)
  886. {
  887. Dbg("CardSwiper::GetDevInfo() again fail: 0x%x", errCode);
  888. }
  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. }