CustMngrAuthFSM.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533
  1. #include "CustMngrAuthFSM.h"
  2. #include "CustMngrAuth_UserErrorCode.h"
  3. #include "SpHelper.h"
  4. #include "fileutil.h"
  5. #include <fstream>
  6. #include <map>
  7. #include <memory>
  8. #include <thread>
  9. #include <chrono>
  10. #include <string>
  11. #include <ctime>
  12. #include <cstring>
  13. using std::string;
  14. const int UPDATE_INTERNAL = 10 * 60 * 1000; //query data from branch server internal, 10min
  15. const int CONNECT_INTERNAL = 30 * 1000; //connect branch server internal, 30s
  16. const int FINGER_NUM = 8; //suuport max register finger num
  17. const int COLLECT_TIMES = 3; //press finger times
  18. #define RUNINFOFILE "CustMngrAuth.ini"
  19. #define RUNINFOFILE_BAK "CustMngrAuth_bak.ini"
  20. class CCustMngrAuthEntity;
  21. #pragma region event response
  22. void CCustMngrAuthFSM::s0_on_entry()
  23. {
  24. LOG_FUNCTION();
  25. FSMEvent* pEvt = new FSMEvent(USER_EVT_INIT);
  26. PostEventFIFO(pEvt);
  27. }
  28. void CCustMngrAuthFSM::s0_on_exit()
  29. {
  30. LOG_FUNCTION();
  31. }
  32. unsigned int CCustMngrAuthFSM::s0_on_event(FSMEvent* pEvt)
  33. {
  34. LOG_FUNCTION();
  35. Dbg("s0 evt %d", pEvt->iEvt);
  36. switch (pEvt->iEvt)
  37. {
  38. case USER_EVT_INIT:
  39. {
  40. InitTask* task = new InitTask(this);
  41. GetEntityBase()->GetFunction()->PostThreadPoolTask(task);
  42. pEvt->SetHandled();
  43. return 0;
  44. }
  45. break;
  46. default:
  47. break;
  48. }
  49. return 0;
  50. }
  51. void CCustMngrAuthFSM::s1_on_entry()
  52. {
  53. LOG_FUNCTION();
  54. }
  55. void CCustMngrAuthFSM::s1_on_exit()
  56. {
  57. LOG_FUNCTION();
  58. }
  59. unsigned int CCustMngrAuthFSM::s1_on_event(FSMEvent* pEvt)
  60. {
  61. LOG_FUNCTION();
  62. Dbg("s1 evt %d", pEvt->iEvt);
  63. switch (pEvt->iEvt)
  64. {
  65. case USER_EVT_INIT_FINISHED:
  66. pEvt->SetHandled();
  67. return pEvt->param1;
  68. default:
  69. break;
  70. }
  71. return 0;
  72. }
  73. void CCustMngrAuthFSM::s2_on_entry()
  74. {
  75. LOG_FUNCTION();
  76. }
  77. void CCustMngrAuthFSM::s2_on_exit()
  78. {
  79. LOG_FUNCTION();
  80. }
  81. unsigned int CCustMngrAuthFSM::s2_on_event(FSMEvent* pEvt)
  82. {
  83. LOG_FUNCTION();
  84. Dbg("s2 evt(%d)", pEvt->iEvt);
  85. switch (pEvt->iEvt)
  86. {
  87. case USER_EVT_AUTHORIZE_START:
  88. {
  89. pEvt->SetHandled();
  90. AuthorizeStartEvent* authorEvt = dynamic_cast<AuthorizeStartEvent*>(pEvt);
  91. if (authorEvt->ctx->Req.TimeLimit <= 0)
  92. {
  93. AuthorizeFinishedEvent* e = new AuthorizeFinishedEvent();
  94. e->ctx = authorEvt->ctx;
  95. e->param1 = Error_Param;
  96. this->PostEventFIFO(e);
  97. break;
  98. }
  99. //time here should be less than the web
  100. m_TimeLimit = (authorEvt->ctx->Req.TimeLimit - 3) * 1000;
  101. m_bCancelAuthorize = false;
  102. /*ErrorCodeEnum errCode = SwitchUSB(true);
  103. if (errCode != Error_Succeed)
  104. Dbg("open usb failed with eErr(%s)", SpStrError(errCode));
  105. else {
  106. Dbg("open usb successfully.");
  107. m_ctx = authorEvt->ctx;
  108. }*/
  109. MatchFingerPrintTask* matchTask = new MatchFingerPrintTask(this);
  110. matchTask->ctx = authorEvt->ctx;
  111. GetEntityBase()->GetFunction()->PostThreadPoolTask(matchTask);
  112. }
  113. break;
  114. case USER_EVT_COLLECTFINGERPRINT_START:
  115. {
  116. pEvt->SetHandled();
  117. CollectFingerPrintStartEvent* collectEvt = dynamic_cast<CollectFingerPrintStartEvent*>(pEvt);
  118. CollectFingerPrintTask* collectTask = new CollectFingerPrintTask(this);
  119. collectTask->ctx = collectEvt->ctx;
  120. GetEntityBase()->GetFunction()->PostThreadPoolTask(collectTask);
  121. }
  122. break;
  123. case USER_EVT_SAVEFINGERPRINT_START:
  124. {
  125. pEvt->SetHandled();
  126. SaveFingerPrintStartEvent* saveEvtfpe = dynamic_cast<SaveFingerPrintStartEvent*>(pEvt);
  127. SaveFingerPrintTask* saveTask = new SaveFingerPrintTask(this);
  128. saveTask->ctx = saveEvtfpe->ctx;
  129. GetEntityBase()->GetFunction()->PostThreadPoolTask(saveTask);
  130. }
  131. break;
  132. case USER_EVT_CHECKUKEY:
  133. {
  134. pEvt->SetHandled();
  135. //SwitchUSB(true);
  136. }
  137. break;
  138. default:
  139. break;
  140. }
  141. return 0;
  142. }
  143. void CCustMngrAuthFSM::s3_on_entry()
  144. {
  145. LOG_FUNCTION();
  146. ScheduleTimer(1, m_TimeLimit);
  147. Dbg("set timer when match, %dms", m_TimeLimit);
  148. }
  149. void CCustMngrAuthFSM::s3_on_exit()
  150. {
  151. LOG_FUNCTION();
  152. CancelTimer(1);
  153. Dbg("exit match event, timer canceled");
  154. }
  155. unsigned int CCustMngrAuthFSM::s3_on_event(FSMEvent* pEvt)
  156. {
  157. LOG_FUNCTION();
  158. Dbg("s3 evt %d, %d", pEvt->iEvt, pEvt->param1);
  159. switch (pEvt->iEvt)
  160. {
  161. case USER_EVT_HOLDON:
  162. {
  163. pEvt->SetHandled();
  164. CancelTimer(1);
  165. HoldOnEvent* holdEvt = dynamic_cast<HoldOnEvent*>(pEvt);
  166. if (holdEvt->ctx == NULL)
  167. Dbg("HoldOnEvent->ctx is NULL");
  168. Dbg("HoldOn with MoreTime: %d second", holdEvt->ctx->Req.MoreTime);
  169. int moreTime = holdEvt->ctx->Req.MoreTime * 1000;
  170. ScheduleTimer(1, (moreTime > 0) ? moreTime : m_TimeLimit);
  171. }
  172. break;
  173. case EVT_TIMER:
  174. {
  175. pEvt->SetHandled();
  176. Dbg("Hit Timer");
  177. m_bAuthorizeTimeout = true;
  178. m_bCancelAuthorize = true;
  179. CancelAuthorize();
  180. }
  181. break;
  182. case USER_EVT_AUTHORIZE_FINISHED:
  183. {
  184. pEvt->SetHandled();
  185. AuthorizeFinishedEvent* authorEvt = dynamic_cast<AuthorizeFinishedEvent*>(pEvt);
  186. Dbg("Checking m_authCtx and answer ctx");
  187. //SwitchUSB(false);
  188. if (authorEvt->param1 == 0)
  189. {
  190. if (m_authCtx.eAuthByWhich == AuthByUkey)
  191. {
  192. Dbg("m_authCtx.eAuthByWhich == AuthByUkey");
  193. if (m_pFingerPrint != NULL && !m_pFingerPrint->QuerySessionClosed())
  194. {
  195. Dbg("Invoke cancel match.");
  196. m_pFingerPrint->CancelMatch();
  197. }
  198. authorEvt->ctx->Ans.WayofAuth = AuthByUkey;
  199. authorEvt->ctx->Ans.UkeyID = m_authCtx.UkeyID;
  200. authorEvt->ctx->Answer(Error_Succeed);
  201. }
  202. else if (m_authCtx.eAuthByWhich == AuthByFngPrnt)
  203. {
  204. Dbg("m_authCtx.eAuthByWhich == AuthByFngPrnt");
  205. authorEvt->ctx->Ans.WayofAuth = AuthByFngPrnt;
  206. authorEvt->ctx->Ans.CustomerID = m_authCtx.CustomerID;
  207. authorEvt->ctx->Answer(Error_Succeed);
  208. }
  209. }
  210. else
  211. {
  212. Dbg("authorize finished with param1 as %d", authorEvt->param1);
  213. authorEvt->ctx->Answer((ErrorCodeEnum)authorEvt->param1);
  214. }
  215. if (m_pFingerPrint != NULL && !m_pFingerPrint->QuerySessionClosed())
  216. {
  217. m_bCancelAuthorize = true;
  218. m_pFingerPrint->GetFunction()->CloseSession();
  219. m_pFingerPrint = NULL;
  220. }
  221. m_authCtx.eAuthByWhich = AuthByNone;
  222. m_authCtx.CustomerID = "";
  223. m_authCtx.UkeyID = "";
  224. m_ctx = NULL;
  225. }
  226. break;
  227. case USER_EVT_AUTHORIZE_CANCEL:
  228. {
  229. pEvt->SetHandled();
  230. m_bCancelAuthorize = true;
  231. CancelAuthorize();
  232. }
  233. break;
  234. default:
  235. break;
  236. }
  237. return 0;
  238. }
  239. void CCustMngrAuthFSM::s4_on_entry()
  240. {
  241. LOG_FUNCTION();
  242. }
  243. void CCustMngrAuthFSM::s4_on_exit()
  244. {
  245. LOG_FUNCTION();
  246. }
  247. unsigned int CCustMngrAuthFSM::s4_on_event(FSMEvent* pEvt)
  248. {
  249. LOG_FUNCTION();
  250. Dbg("s4 evt %d, %d", pEvt->iEvt, pEvt->param1);
  251. switch (pEvt->iEvt)
  252. {
  253. case USER_EVT_COLLECTFINGERPRINT_FINISHED:
  254. pEvt->SetHandled();
  255. break;
  256. case USER_EVT_COLLECTFINGERPRINT_CANCEL:
  257. {
  258. pEvt->SetHandled();
  259. if (m_pFingerPrint != NULL && !m_pFingerPrint->QuerySessionClosed())
  260. m_pFingerPrint->CancelRegister();
  261. }
  262. break;
  263. case USER_EVT_SAVEFINGERPRINT_FINISHED:
  264. pEvt->SetHandled();
  265. break;
  266. case USER_EVT_CHECKUKEY_FINISHED:
  267. {
  268. pEvt->SetHandled();
  269. //SwitchUSB(false);
  270. }
  271. break;
  272. default:
  273. break;
  274. }
  275. return 0;
  276. }
  277. void CCustMngrAuthFSM::s5_on_entry()
  278. {
  279. LOG_FUNCTION();
  280. }
  281. void CCustMngrAuthFSM::s5_on_exit()
  282. {
  283. LOG_FUNCTION();
  284. }
  285. unsigned int CCustMngrAuthFSM::s5_on_event(FSMEvent* pEvt)
  286. {
  287. LOG_FUNCTION();
  288. Dbg("s5 evt %d, %d", pEvt->iEvt, pEvt->param1);
  289. return 0;
  290. }
  291. ErrorCodeEnum CCustMngrAuthFSM::WaitForUkey(ErrorCodeEnum eErr)
  292. {
  293. int status = (eErr == Error_NoTarget) ? 4 : 3;//4: no data in local, 3:enitty exception
  294. BroadcastGetFinger(status);
  295. while (1)
  296. {
  297. SLEEP(300);
  298. if (m_bCancelAuthorize)
  299. {
  300. m_bCancelAuthorize = false;
  301. if (m_bAuthorizeTimeout)
  302. {
  303. m_bAuthorizeTimeout = false;
  304. return Error_TimeOut;
  305. }
  306. else
  307. return Error_Cancel;
  308. }
  309. }
  310. }
  311. void CCustMngrAuthFSM::CancelAuthorize()
  312. {
  313. Dbg("Invoke m_pFingerPrint->CancelMatch()");
  314. if (m_pFingerPrint != NULL && !m_pFingerPrint->QuerySessionClosed())
  315. m_pFingerPrint->CancelMatch();
  316. }
  317. ErrorCodeEnum CCustMngrAuthFSM::SwitchUSB(bool bOpen)
  318. {
  319. LOG_FUNCTION();
  320. Dbg("connecting DeviceControl");
  321. ErrorCodeEnum errCode;
  322. m_pDeviceControl = new DeviceControlService_ClientBase(GetEntityBase());
  323. if (m_pDeviceControl != NULL)
  324. {
  325. errCode = m_pDeviceControl->Connect();
  326. if (errCode != Error_Succeed)
  327. {
  328. Dbg("m_pDeviceControl connect failed with errCode(%s)", SpStrError(errCode));
  329. m_pDeviceControl->SafeDelete();
  330. }else {
  331. if (bOpen)
  332. Dbg("Open USB");
  333. else
  334. Dbg("Close USB");
  335. DeviceControlService_USB_Req usbReq;
  336. DeviceControlService_USB_Ans usbAns;
  337. usbReq.open = bOpen;//open or close usb
  338. errCode = m_pDeviceControl->USB(usbReq, usbAns, 2000);
  339. if (errCode != Error_Succeed)
  340. Dbg("Open/Close usb failed.");
  341. else
  342. Dbg("Open/Close usb success.");
  343. m_pDeviceControl->GetFunction()->CloseSession();
  344. }
  345. m_pDeviceControl = NULL;
  346. return errCode;
  347. }
  348. else {
  349. Dbg("DeviceControl is null.");
  350. return Error_Unexpect;
  351. }
  352. }
  353. #pragma endregion
  354. #pragma region entity init
  355. ErrorCodeEnum CCustMngrAuthFSM::OnInit()
  356. {
  357. LOG_FUNCTION();
  358. CSystemStaticInfo staticInfo;
  359. m_pEntity->GetFunction()->GetSystemStaticInfo(staticInfo);
  360. m_TerminalID = staticInfo.strTerminalID;
  361. m_csMachineType = staticInfo.strMachineType;
  362. m_authCtx.eAuthByWhich = AuthByNone;
  363. m_FingerSection = "FingerInfo";
  364. return Error_Succeed;
  365. }
  366. int CCustMngrAuthFSM::Initial()
  367. {
  368. ErrorCodeEnum errCode = OpenRunInfoFile();
  369. if (errCode != Error_Succeed)
  370. return 1;
  371. FeatureUpdateTask* pTask = new FeatureUpdateTask(this);
  372. GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask);
  373. return 0;
  374. }
  375. ErrorCodeEnum CCustMngrAuthFSM::OpenRunInfoFile()
  376. {
  377. ErrorCodeEnum errCode;
  378. errCode = GetEntityBase()->GetFunction()->GetPath("RunInfo", m_RunInfoPath);
  379. if (errCode != Error_Succeed)
  380. {
  381. LogError(Severity_High, Error_DevLoadFileFailed
  382. , LOG_ERR_CUSTMNGRAUTH_GET_RUNINFO_PATH_FAILED_Init
  383. , "get runinfo path failed while init");
  384. errCode = Error_Unexpect;
  385. }
  386. Dbg("runinfo path: %s", m_RunInfoPath.GetData());
  387. return errCode;
  388. }
  389. #pragma endregion
  390. #pragma region entity exit
  391. ErrorCodeEnum CCustMngrAuthFSM::OnExit()
  392. {
  393. LOG_FUNCTION();
  394. FSMImpl<CCustMngrAuthFSM>::OnExit();
  395. return Error_Succeed;
  396. }
  397. #pragma endregion
  398. #pragma region update feature process
  399. void CCustMngrAuthFSM::FeatureUpdate()
  400. {
  401. LOG_FUNCTION();
  402. InitBeforeUpdateData();
  403. int waitInternal = UPDATE_INTERNAL;
  404. while (true)
  405. {
  406. do
  407. {
  408. int connectFailedTimes = 0;
  409. m_pConnection = new FeatureUpdateConn(m_pEntity, this);
  410. if (m_pConnection->ConnectFromCentralSetting() && m_pConnection->IsConnectionOK())
  411. {
  412. connectFailedTimes = 0;
  413. waitInternal = UPDATE_INTERNAL;
  414. ErrorCodeEnum errCode;
  415. CSmartPointer<IConfigInfo> spConfig;
  416. CAutoArray<CSimpleStringA> transArray;
  417. RunInfoParams runInfoParam;
  418. memset(&runInfoParam, 0, sizeof(runInfoParam));
  419. errCode = InitBeforeQueryData(runInfoParam, spConfig);
  420. if (errCode != Error_Succeed)
  421. break;
  422. errCode = ReceiveDataFromServer(transArray, runInfoParam);
  423. if (errCode != Error_Succeed)
  424. break;
  425. errCode = BackupBeforeWriteData(runInfoParam, spConfig);
  426. if (errCode != Error_Succeed)
  427. break;
  428. errCode = WriteData(runInfoParam, transArray, spConfig);
  429. if (errCode != Error_Succeed)
  430. break;
  431. }else {
  432. connectFailedTimes++;
  433. Dbg("connect branchserver failed for %d times, try again in %d ms."
  434. , connectFailedTimes, CONNECT_INTERNAL);
  435. if (connectFailedTimes >= 60)
  436. {
  437. //30min give a warn
  438. LogWarn(Severity_Middle, Error_Unexpect
  439. , LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_CONNECT_FAILED
  440. , "Connect branch server failed.");
  441. connectFailedTimes = 0;
  442. }
  443. waitInternal = CONNECT_INTERNAL;
  444. }
  445. } while (false);
  446. if (m_pConnection)
  447. {
  448. m_pConnection->Close();
  449. m_pConnection->DecRefCount();
  450. m_pConnection = NULL;
  451. }
  452. Dbg("Feature-update processed, wait until next");
  453. //wait for next query
  454. if (WaitForSingleObject(hStopUpdate, waitInternal) == WAIT_OBJECT_0)
  455. break;
  456. }
  457. }
  458. /// <summary>
  459. /// Init memory data
  460. /// </summary>
  461. void CCustMngrAuthFSM::InitBeforeUpdateData()
  462. {
  463. bool bHasData = false;
  464. bool bReadResult = ReadDataIntoMemory(bHasData);
  465. if (bReadResult && bHasData)
  466. {
  467. Dbg("Read feature data into memory success.");
  468. }
  469. else if (bReadResult && !bHasData) {
  470. Dbg("Has no data in local file.");
  471. }
  472. else {
  473. Dbg("Read feature data into memory failed, wait next read.");
  474. }
  475. }
  476. /// <summary>
  477. /// read fingerprint feature data into memory from local file
  478. /// </summary>
  479. /// <param name="bHasData">output param</param>
  480. /// <returns></returns>
  481. bool CCustMngrAuthFSM::ReadDataIntoMemory(bool& bHasData)
  482. {
  483. LOG_FUNCTION();
  484. CSimpleStringA runInfoFile(true);
  485. runInfoFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR RUNINFOFILE
  486. , m_RunInfoPath.GetData());
  487. std::ifstream inFile(runInfoFile.GetData());
  488. string line;
  489. int customerNum = 0;
  490. ULLINT startReadFile = RVCGetTickCount();
  491. ULLINT endReadFile = RVCGetTickCount();
  492. while (getline(inFile, line))
  493. {
  494. if (line.length() <= 0)
  495. continue;
  496. string tempLine = ClearStringSpaceHeadTail(line);
  497. if (!tempLine.compare("[UpdateTime]") || string::npos != tempLine.find("UpdateTime")
  498. || !tempLine.compare("[LatestTime]") || string::npos != tempLine.find("LatestTime")
  499. || !tempLine.compare("[FingerInfo]") || !tempLine.compare("[FaceInfo]")
  500. || string::npos != tempLine.find("FaceInfo1") || string::npos != tempLine.find("FaceInfo2"))
  501. {
  502. continue;
  503. }
  504. string::size_type pos = tempLine.find("=");
  505. if (pos != 16)
  506. continue;
  507. string keys = tempLine.substr(0, pos);
  508. string values = tempLine.substr(pos + 1);
  509. Json::Reader reader;
  510. Json::Value root;
  511. if (reader.parse((const char*)values.c_str(), root))
  512. {
  513. customerNum++;
  514. FeatureData* fd = new FeatureData();
  515. fd->FingerIDArray.Init(FINGER_NUM);
  516. fd->FingerIDLenArray.Init(FINGER_NUM);
  517. char index[20];
  518. for (int i = 0; i < FINGER_NUM; ++i)
  519. {
  520. memset(index, 0, sizeof(index));
  521. #ifdef RVC_OS_WIN
  522. _snprintf_s(index, 10, "FingerID%d", i + 1);
  523. #else
  524. snprintf(index, 10, "FingerID%d", i + 1);
  525. #endif // RVC_OS_WIN
  526. fd->FingerIDArray[i] = root.isMember(index) ? CSimpleStringA(root[index].asCString()) : "";
  527. fd->FingerIDLenArray[i] = root.isMember(index) ? fd->FingerIDArray[i].GetLength() : 0;
  528. }
  529. m_featureData[CSimpleStringA(keys.c_str())] = fd;
  530. }
  531. else {
  532. Dbg("Error: parse jsonFingerInfo failed.");
  533. LogWarn(Severity_Middle, Error_Unexpect
  534. , LOG_ERR_CUSTMNGRAUTH_AUTHORIZATION_READFEAT_FAILED
  535. , "Read fingerprint feature json failed.");
  536. return false;
  537. }
  538. }
  539. Dbg("Total CustomerNum:%d in local file.", customerNum);
  540. endReadFile = RVCGetTickCount();
  541. ULLINT duration = endReadFile - startReadFile;
  542. LogWarn(Severity_Middle, Error_Debug
  543. , LOG_ERR_CUSTMNGRAUTH_READ_INTO_MEMORY_TIME
  544. , GenerateAlarmJson("CustMngrAuth", duration).GetData());
  545. bHasData = true;
  546. return true;
  547. }
  548. CSimpleString CCustMngrAuthFSM::GenerateAlarmJson(CSimpleString entityName, int cost)
  549. {
  550. return CSimpleString::Format("[{\"name\":\"%s\",\"cost\":%d}]"
  551. , entityName.GetData(), cost);
  552. }
  553. string CCustMngrAuthFSM::ClearStringSpaceHeadTail(string& line)
  554. {
  555. if (line.empty())
  556. return line;
  557. line.erase(0, line.find_first_not_of(" "));
  558. line.erase(line.find_last_not_of(" ") + 1);
  559. return line;
  560. }
  561. /// <summary>
  562. /// init runinfo pointer and some time parameters
  563. /// </summary>
  564. /// <param name="runInfoParam">out param</param>
  565. /// <param name="spConfig">out param</param>
  566. /// <returns></returns>
  567. ErrorCodeEnum CCustMngrAuthFSM::InitBeforeQueryData(RunInfoParams& runInfoParam, CSmartPointer<IConfigInfo>& spConfig)
  568. {
  569. ErrorCodeEnum errCode = Error_Succeed;
  570. EnterCriticalSection(&m_cs);//临时锁一下运行时,防止在写入
  571. errCode = LoadRunConfig(spConfig);
  572. if (Error_Succeed != errCode)
  573. {
  574. LeaveCriticalSection(&m_cs);
  575. return errCode;
  576. }
  577. InitTimeParams(runInfoParam, spConfig);
  578. LeaveCriticalSection(&m_cs);
  579. return errCode;
  580. }
  581. ErrorCodeEnum CCustMngrAuthFSM::LoadRunConfig(CSmartPointer<IConfigInfo>& spConfig)
  582. {
  583. ErrorCodeEnum errCode = Error_Succeed;
  584. errCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
  585. if (errCode != Error_Succeed)
  586. {
  587. Dbg("Open runcfg file failed before query data.");
  588. LogError(Severity_High, Error_Unexpect
  589. , LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO_FAILED_UPDATE
  590. , "open runcfg failed before query data.");
  591. }
  592. return errCode;
  593. }
  594. void CCustMngrAuthFSM::InitTimeParams(RunInfoParams& runInfoParam, CSmartPointer<IConfigInfo>& spConfig)
  595. {
  596. ErrorCodeEnum errCode = Error_Succeed;
  597. runInfoParam.LatestTime = "";
  598. runInfoParam.UpdateTime = "";
  599. CSimpleStringA latestTime(""), updateTime("");
  600. spConfig->ReadConfigValue("LatestTime", "LatestTime", latestTime);
  601. spConfig->ReadConfigValue("UpdateTime", "UpdateTime", updateTime);
  602. //query current time
  603. CSimpleStringA newTime = GetCurrentDate();
  604. runInfoParam.UpdateTime = newTime;
  605. runInfoParam.LatestTime = latestTime;
  606. //当前日期大于文件中日期时,需要做全量更新
  607. if (updateTime.GetLength() <= 0
  608. || (updateTime.GetLength() > 0 && CompareTime(newTime, updateTime) > 0)
  609. || latestTime.GetLength() <= 0)
  610. {
  611. runInfoParam.IsFirstTimeQueryData = true;
  612. }
  613. }
  614. CSimpleStringA CCustMngrAuthFSM::GetCurrentDate()
  615. {
  616. time_t curTime = time(NULL);
  617. tm* p = localtime(&curTime);
  618. char cTime[100] = { 0 };
  619. #ifdef RVC_OS_WIN
  620. _snprintf_s(cTime, 100, "%d%02d%02d", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday);
  621. #else
  622. snprintf(cTime, 100, "%d%02d%02d", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday);
  623. #endif // RVC_OS_WIN
  624. CSimpleStringA curDate(cTime);
  625. return curDate;
  626. }
  627. int CCustMngrAuthFSM::CompareTime(CSimpleStringA time1, CSimpleStringA time2)
  628. {
  629. if (time1.GetLength() > 0 && time2.GetLength() > 0)
  630. {
  631. int year1 = atoi((const char*)time1.SubString(0, 4));
  632. int month1 = atoi((const char*)time1.SubString(4, 2));
  633. int day1 = atoi((const char*)time1.SubString(6, 2));
  634. int year2 = atoi((const char*)time2.SubString(0, 4));
  635. int month2 = atoi((const char*)time2.SubString(4, 2));
  636. int day2 = atoi((const char*)time2.SubString(6, 2));
  637. int temp1 = year1 * 10000 + month1 * 100 + day1;
  638. int temp2 = year2 * 10000 + month2 * 100 + day2;
  639. if (temp1 > temp2)
  640. return 1;
  641. else if (temp1 < temp2)
  642. return -1;
  643. else
  644. return 0;
  645. }
  646. return 0;
  647. }
  648. /// <summary>
  649. /// receive fingerprint feature from branch server
  650. /// </summary>
  651. /// <param name="dataArray">out param</param>
  652. /// <param name="runInfoParam">in param</param>
  653. /// <returns></returns>
  654. ErrorCodeEnum CCustMngrAuthFSM::ReceiveDataFromServer(CAutoArray<CSimpleStringA>& dataArray, RunInfoParams runInfoParam)
  655. {
  656. LOG_FUNCTION();
  657. char currAgent[16];
  658. char branchID[16];
  659. memset(currAgent, 0, sizeof(currAgent));
  660. memset(branchID, 0, sizeof(currAgent));
  661. bool bResumeTrans = true;
  662. ErrorCodeEnum errCode = Error_Unexpect;
  663. while (bResumeTrans)
  664. {
  665. if (runInfoParam.IsFirstTimeQueryData)
  666. m_pConnection->SendFeatReq(currAgent, branchID);
  667. else
  668. m_pConnection->SendFeatReq(currAgent, branchID, runInfoParam.LatestTime.GetData());
  669. ResetEvent(m_pConnection->m_hPkgAnswer);
  670. DWORD dw = WaitForSingleObject(m_pConnection->m_hPkgAnswer, 20000); //10->20 20200430@liuwentao
  671. switch (dw)
  672. {
  673. case WAIT_FAILED:
  674. Dbg("WAIT_FAILED!");
  675. break;
  676. case WAIT_TIMEOUT:
  677. Dbg("WAIT_TIMEOUT");
  678. case WAIT_OBJECT_0:
  679. Dbg("WAIT_OBJECT_0");
  680. break;
  681. }
  682. ResetEvent(m_pConnection->m_hPkgAnswer);
  683. if (m_pConnection->m_reply == NULL)
  684. {
  685. Dbg("m_reply still null after m_hPkgAnswer handled");
  686. break;
  687. }
  688. if (m_pConnection->m_GetErrMsg)
  689. {
  690. Dbg("get error message, check dbg log");
  691. break;
  692. }
  693. if (m_pConnection->m_reply->ResultCode == 2)
  694. {
  695. Dbg("remote server uninitialized yet, unable to excute query");
  696. break;
  697. }
  698. else {
  699. if (m_pConnection->m_reply->ResultCode == 0)
  700. {
  701. Dbg("All package downloaded from branch server.");
  702. bResumeTrans = false;
  703. errCode = Error_Succeed;
  704. }
  705. memcpy(currAgent, m_pConnection->m_reply->CurrentAgent, 16);
  706. memcpy(branchID, m_pConnection->m_reply->BranchID, 16);
  707. CSimpleStringA jbuf(m_pConnection->m_reply->Data, m_pConnection->m_jsonLen);
  708. dataArray.Append(&jbuf, 0, 1);
  709. }
  710. }
  711. if (bResumeTrans)
  712. Dbg("some errors happened, check the related log");
  713. if (dataArray.GetCount() <= 0)
  714. Dbg("query no data from branchServer.");
  715. return errCode;
  716. }
  717. /// <summary>
  718. /// backup runinfo file, in case some error occurs when process data
  719. /// </summary>
  720. /// <param name="runInfoParam">input/output param</param>
  721. /// <param name="spConfig">input param</param>
  722. /// <returns></returns>
  723. ErrorCodeEnum CCustMngrAuthFSM::BackupBeforeWriteData(RunInfoParams& runInfoParam, CSmartPointer<IConfigInfo>& spConfig)
  724. {
  725. LOG_FUNCTION();
  726. ErrorCodeEnum errCode = Error_Succeed;
  727. runInfoParam.SrcFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR RUNINFOFILE
  728. , m_RunInfoPath.GetData());
  729. runInfoParam.BackupFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR RUNINFOFILE_BAK
  730. , m_RunInfoPath.GetData());
  731. EnterCriticalSection(&m_cs);
  732. if (!BackupFile(runInfoParam.SrcFile, runInfoParam.BackupFile))
  733. Dbg("Backup runinfo file failed.");
  734. if (runInfoParam.IsFirstTimeQueryData)
  735. {
  736. //首次更新,需清除数据,全量写入,并更新时间
  737. ofstream fileOut((const char*)runInfoParam.SrcFile, ios::trunc);
  738. fileOut.close();
  739. }
  740. errCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
  741. if (errCode != Error_Succeed)
  742. {
  743. Dbg("error: open runcfg failed with errCode(%s)", SpStrError(errCode));
  744. BackupFile(runInfoParam.BackupFile, runInfoParam.SrcFile);// if backup fail, recover
  745. LeaveCriticalSection(&m_cs);
  746. }
  747. spConfig->WriteConfigValue("UpdateTime", "UpdateTime", runInfoParam.UpdateTime.GetData());
  748. if (runInfoParam.IsFirstTimeQueryData)
  749. {
  750. spConfig->WriteConfigValue("LatestTime", "LatestTime", "");
  751. }
  752. return errCode;
  753. }
  754. bool CCustMngrAuthFSM::BackupFile(CSimpleStringA srcFile, CSimpleStringA dstFile)
  755. {
  756. if (!ExistsFile(srcFile.GetData()))
  757. return true;
  758. int result = fileutil_copy_file(dstFile.GetData(), srcFile.GetData());
  759. return (result == 0) ? true : false;
  760. }
  761. /// <summary>
  762. /// write data into local file and memory
  763. /// </summary>
  764. /// <param name="runInfoParam">input/output param</param>
  765. /// <param name="dataArray">input param</param>
  766. /// <param name="spConfig">input param</param>
  767. /// <returns></returns>
  768. ErrorCodeEnum CCustMngrAuthFSM::WriteData(RunInfoParams& runInfoParam
  769. , CAutoArray<CSimpleStringA> dataArray
  770. , CSmartPointer<IConfigInfo>& spConfig)
  771. {
  772. ErrorCodeEnum errCode = Error_Unexpect;
  773. TempFeatureData tmpFeatureData;
  774. tmpFeatureData.MaxUpdateTime = runInfoParam.LatestTime;
  775. bool bExitLoop = false;
  776. for (int transTime = 0; transTime < dataArray.GetCount(); ++transTime)
  777. {
  778. Json::Value root;
  779. Json::Reader reader;
  780. //only 3-4 data, cause the limit of transfer amount
  781. CSimpleStringA transBuffer = dataArray[transTime];
  782. if (reader.parse(transBuffer.GetData(), root))
  783. {
  784. for (int i = 0; i < (int)root.size(); ++i)
  785. {
  786. JsonParams jsonParam;
  787. jsonParam.Root = root;
  788. jsonParam.Index = i;
  789. errCode = ProcessFeatureData(jsonParam, tmpFeatureData, runInfoParam, spConfig);
  790. if (Error_Succeed != errCode)
  791. {
  792. bExitLoop = true;
  793. break;
  794. }
  795. }
  796. if (bExitLoop)
  797. break;
  798. }else {
  799. Dbg("fail to parse transArray[%d]!", transTime);
  800. LeaveCriticalSection(&m_cs);
  801. bExitLoop = true;
  802. break;
  803. }
  804. }
  805. if (bExitLoop)
  806. return Error_Unexpect;
  807. if (tmpFeatureData.MaxUpdateTime.GetLength() > 0)
  808. {
  809. spConfig->WriteConfigValue("LatestTime", "LatestTime"
  810. , tmpFeatureData.MaxUpdateTime.GetData());
  811. }
  812. Dbg("updateNum=%d", tmpFeatureData.tmpFeatureMap.size());
  813. UpdateDataIntoMemory(tmpFeatureData.tmpFeatureMap, runInfoParam.IsFirstTimeQueryData);
  814. LeaveCriticalSection(&m_cs);
  815. return Error_Succeed;
  816. }
  817. /// <summary>
  818. /// process feature data
  819. /// </summary>
  820. /// <param name="jsonParam"></param>
  821. /// <param name="tmpFeatureData"></param>
  822. /// <param name="runinfoParam"></param>
  823. /// <param name="spConfig"></param>
  824. /// <returns></returns>
  825. ErrorCodeEnum CCustMngrAuthFSM::ProcessFeatureData(JsonParams& jsonParam, TempFeatureData& tmpFeatureData
  826. , RunInfoParams runinfoParam, CSmartPointer<IConfigInfo>& spConfig)
  827. {
  828. ErrorCodeEnum errCode = Error_Succeed;
  829. FeatureData* fd = new FeatureData();
  830. fd->FingerIDArray.Init(FINGER_NUM);
  831. fd->FingerIDLenArray.Init(FINGER_NUM);
  832. char FingerID[20];//runinfo file is named "FingerID"
  833. char fingerId[20];//branchserver is named "fingerId" , history bug
  834. for (int fingerIndex = 0; fingerIndex < FINGER_NUM; ++fingerIndex)
  835. {
  836. ZeroMemory(FingerID, sizeof(FingerID));
  837. ZeroMemory(fingerId, sizeof(fingerId));
  838. #ifdef RVC_OS_WIN
  839. _snprintf_s(FingerID, 10, "FingerID%d", fingerIndex + 1);
  840. _snprintf_s(fingerId, 10, "fingerId%d", fingerIndex + 1);
  841. #else
  842. snprintf(FingerID, 10, "FingerID%d", fingerIndex + 1);
  843. snprintf(fingerId, 10, "fingerId%d", fingerIndex + 1);
  844. #endif // RVC_OS_WIN
  845. jsonParam.FingerInfo[FingerID] = jsonParam.Root[jsonParam.Index][fingerId].asCString();
  846. fd->FingerIDArray[fingerIndex] = CSimpleStringA(jsonParam.Root[jsonParam.Index][fingerId].asCString());
  847. fd->FingerIDLenArray[fingerIndex] = fd->FingerIDArray[fingerIndex].GetLength();
  848. }
  849. CSimpleStringA customerID = CSimpleStringA(jsonParam.Root[jsonParam.Index]["customerID"].asCString());
  850. if (tmpFeatureData.tmpFeatureMap.find(customerID) == tmpFeatureData.tmpFeatureMap.end())
  851. {
  852. // if not exist , insert directly
  853. tmpFeatureData.tmpFeatureMap[customerID] = fd;
  854. }else {
  855. auto tempFD = tmpFeatureData.tmpFeatureMap[customerID];
  856. tmpFeatureData.tmpFeatureMap[customerID] = fd;
  857. if (tempFD)
  858. {
  859. delete tempFD;
  860. tempFD = NULL;
  861. }
  862. }
  863. CSimpleStringA tempMaxUpdateTime = CSimpleStringA(jsonParam.Root[jsonParam.Index]["updateTime"].asCString());
  864. tmpFeatureData.MaxUpdateTime = GetMaxTime(tmpFeatureData.MaxUpdateTime, tempMaxUpdateTime);
  865. int fingerDataState = jsonParam.Root[jsonParam.Index]["state"].asCString()[0] - '0';
  866. if (fingerDataState == 0)
  867. {
  868. Json::FastWriter writer;
  869. CSimpleStringA jsonFingerStr(writer.write(jsonParam.FingerInfo).c_str());
  870. int jlen = jsonFingerStr.GetLength() - 1;
  871. char* jstr = new char[jlen + 1];
  872. memcpy(jstr, jsonFingerStr.GetData(), jlen);
  873. jstr[jlen] = '\0'; //in case no \n in the end
  874. errCode = spConfig->WriteConfigValue(m_FingerSection.GetData(), customerID.GetData(), jstr);
  875. delete[] jstr;
  876. if (errCode != Error_Succeed)
  877. {
  878. BackupFile(runinfoParam.BackupFile, runinfoParam.SrcFile);
  879. LeaveCriticalSection(&m_cs);
  880. errCode = Error_Unexpect;
  881. }
  882. }else if (fingerDataState == 2)
  883. {
  884. Dbg("state(2): customer %s is currently unavailable.", customerID.GetData());
  885. spConfig->WriteConfigValue((const char*)m_FingerSection, customerID.GetData(), "");
  886. }else {
  887. Dbg("unexpected customer(%s)'s state is either 0 or 2", customerID.GetData());
  888. }
  889. return errCode;
  890. }
  891. CSimpleStringA CCustMngrAuthFSM::GetMaxTime(CSimpleStringA maxTime, CSimpleStringA tempTime)
  892. {
  893. if (tempTime.GetLength() <= 0)
  894. return maxTime;
  895. if (maxTime.GetLength() <= 0)
  896. {
  897. maxTime = tempTime;
  898. }
  899. else {
  900. int compareResult = CompareUpdateTime((const char*)maxTime, (const char*)tempTime);
  901. if (compareResult == 0)
  902. {
  903. maxTime = tempTime;
  904. }
  905. }
  906. return maxTime;
  907. }
  908. int CCustMngrAuthFSM::CompareUpdateTime(const char* time1, const char* time2)
  909. {
  910. int year1, month1, day1, hour1, minute1, second1;
  911. int year2, month2, day2, hour2, minute2, second2;
  912. sscanf(time1, "%d-%d-%d %d:%d:%d", &year1, &month1, &day1, &hour1, &minute1, &second1);
  913. sscanf(time2, "%d-%d-%d %d:%d:%d", &year2, &month2, &day2, &hour2, &minute2, &second2);
  914. int tm1 = year1 * 10000 + month1 * 100 + day1;
  915. int tm2 = year2 * 10000 + month2 * 100 + day2;
  916. if (tm1 != tm2)
  917. return (tm1 > tm2) ? 1 : 0;
  918. tm1 = hour1 * 3600 + minute1 * 60 + second1;
  919. tm2 = hour2 * 3600 + minute2 * 60 + second2;
  920. if (tm1 != tm2)
  921. return (tm1 > tm2) ? 1 : 0;
  922. return 2;
  923. }
  924. /// <summary>
  925. /// write data into memory when update fingerprint feature
  926. /// </summary>
  927. /// <param name="tempFeature"></param>
  928. /// <param name="bIsFirstTimeQueryData"></param>
  929. void CCustMngrAuthFSM::UpdateDataIntoMemory(map<CSimpleStringA, FeatureData*> tempFeature, bool bIsFirstTimeQueryData)
  930. {
  931. if (!bIsFirstTimeQueryData)
  932. {
  933. for (auto it = tempFeature.begin(); it != tempFeature.end(); ++it) {
  934. if (m_featureData.find(it->first) == m_featureData.end()) {//if not exist,insert immediately
  935. m_featureData[it->first] = it->second;
  936. }
  937. else {//if exist already, release memory first, then insert
  938. auto tempFD = m_featureData[it->first];
  939. m_featureData[it->first] = it->second;
  940. if (tempFD != NULL) {
  941. delete tempFD;
  942. tempFD = NULL;
  943. }
  944. }
  945. }
  946. }else {
  947. for (auto iter = m_featureData.begin(); iter != m_featureData.end();) {
  948. auto fd = iter->second;
  949. if (fd) {
  950. delete fd;
  951. fd = NULL;
  952. m_featureData.erase(iter++);
  953. }
  954. }
  955. m_featureData.insert(tempFeature.begin(), tempFeature.end());
  956. }
  957. }
  958. #pragma endregion
  959. #pragma region Registe process
  960. ErrorCodeEnum CCustMngrAuthFSM::CollectFingerPrint(SpReqAnsContext<CustMngrAuthService_CollectFingerPrint_Req, CustMngrAuthService_CollectFingerPrint_Ans>::Pointer ctx, DWORD& dwUserErrCode)
  961. {
  962. LOG_FUNCTION();
  963. ErrorCodeEnum errCode = ConnectFingerPrintEntity();
  964. if (errCode != Error_Succeed)
  965. return errCode;
  966. errCode = CollectProcess(ctx, dwUserErrCode);
  967. if (errCode == Error_Succeed)
  968. {
  969. Dbg("Register FingerPrint successfully.");
  970. return Error_Succeed;
  971. }
  972. else {
  973. Dbg("Register FingerPrint failed!");
  974. return errCode;
  975. }
  976. }
  977. ErrorCodeEnum CCustMngrAuthFSM::CollectProcess(SpReqAnsContext<CustMngrAuthService_CollectFingerPrint_Req, CustMngrAuthService_CollectFingerPrint_Ans>::Pointer& ctx, DWORD& dwUserErrCode)
  978. {
  979. ErrorCodeEnum errCode = Error_Succeed;
  980. vector<CSimpleStringA> imgPaths;
  981. CSimpleStringA depPath(true);
  982. m_pEntity->GetFunction()->GetPath("Dep", depPath);
  983. ctx->Ans.FingerImgs.Init(COLLECT_TIMES);
  984. for (int i = 0; i < COLLECT_TIMES; ++i)
  985. {
  986. if (i) SLEEP(2000);
  987. if (m_pFingerPrint == NULL || m_pFingerPrint->QuerySessionClosed())
  988. {
  989. Dbg("m_pFingerPrint is NULL or connection closed.");
  990. return Error_NoTarget;
  991. }
  992. BroadcastPressFinger(i + 1, true);//press finger
  993. FingerPrintService_GetImageAndFeature_Req collecetReq;
  994. FingerPrintService_GetImageAndFeature_Ans collecetAns;
  995. collecetReq.times = i + 1;//the num from 1 start , 1/2/3
  996. errCode = m_pFingerPrint->GetImageAndFeature(collecetReq, collecetAns, 16000, dwUserErrCode);//fingerprint entity loop duration is 15s
  997. if (errCode == Error_Succeed)
  998. {
  999. BroadcastPressFinger(i + 1, false);//lift finger
  1000. CBlob data;
  1001. CSimpleStringA imgFullPath(true);
  1002. imgFullPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  1003. , depPath.GetData(), collecetAns.imageName.GetData());
  1004. errCode = GetImgBlob(data, imgFullPath);
  1005. imgPaths.push_back(imgFullPath);
  1006. if (errCode != Error_Succeed)
  1007. {
  1008. Dbg("Failed to load finger image, %s", imgFullPath.GetData());
  1009. errCode = Error_Unexpect;
  1010. break;
  1011. }
  1012. switch (i)
  1013. {
  1014. case 0:
  1015. ctx->Ans.FingerImg1 = data;
  1016. break;
  1017. case 1:
  1018. ctx->Ans.FingerImg2 = data;
  1019. break;
  1020. case 2:
  1021. ctx->Ans.FingerImg3 = data;
  1022. break;
  1023. }
  1024. ctx->Ans.FingerImgs[i] = data;
  1025. if (i == (COLLECT_TIMES - 1)) {
  1026. ctx->Ans.feature = collecetAns.feature;
  1027. Dbg("feature = %s", ctx->Ans.feature.GetData());
  1028. }
  1029. }
  1030. else {
  1031. Dbg("invoke GetImageAndFeature failed in %dth time, errCode(%s)", i + 1, SpStrError(errCode));
  1032. break;
  1033. }
  1034. }
  1035. for (size_t i = 0; i < imgPaths.size(); ++i)
  1036. {
  1037. if (ExistsFileA(imgPaths[i]))
  1038. RemoveFileA(imgPaths[i]);
  1039. }
  1040. return errCode;
  1041. }
  1042. void CCustMngrAuthFSM::BroadcastPressFinger(int times, bool bPressFinger)
  1043. {
  1044. if (bPressFinger)
  1045. {
  1046. PressFinger pfEvt;//
  1047. pfEvt.FingerNo = 1;//maybe no use,control by @zhuyi
  1048. pfEvt.Times = times;
  1049. SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(PressFinger)
  1050. , SP_MSG_SIG_OF(PressFinger), pfEvt);
  1051. }
  1052. else {
  1053. LiftFinger lfEvt;
  1054. lfEvt.FingerNo = 1;
  1055. lfEvt.Times = times;
  1056. SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(LiftFinger)
  1057. , SP_MSG_SIG_OF(LiftFinger), lfEvt);
  1058. }
  1059. }
  1060. ErrorCodeEnum CCustMngrAuthFSM::GetImgBlob(CBlob& data, CSimpleStringA imgPath)
  1061. {
  1062. Dbg("image full path: %s", imgPath.GetData());
  1063. FILE* fp = fopen(imgPath, "rb");
  1064. if (fp)
  1065. {
  1066. Dbg("fopen succeed.");
  1067. fseek(fp, 0, SEEK_END);
  1068. long flen = ftell(fp);
  1069. fseek(fp, 0, SEEK_SET);
  1070. data.Alloc(flen);
  1071. fread(data.m_pData, 1, flen, fp);
  1072. fclose(fp);
  1073. return Error_Succeed;
  1074. }
  1075. else {
  1076. Dbg("fopen %s failed!", imgPath.GetData());
  1077. return Error_IO;
  1078. }
  1079. }
  1080. #pragma endregion
  1081. #pragma region Save fingerprint process
  1082. ErrorCodeEnum CCustMngrAuthFSM::SaveFingerPrint(SpReqAnsContext<CustMngrAuthService_SaveFingerPrint_Req, CustMngrAuthService_SaveFingerPrint_Ans>::Pointer ctx)
  1083. {
  1084. LOG_FUNCTION();
  1085. EnterCriticalSection(&m_cs);
  1086. CSmartPointer<IConfigInfo> spConfig;
  1087. Json::FastWriter writer;
  1088. ErrorCodeEnum errCode;
  1089. errCode = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
  1090. if (errCode != Error_Succeed) {
  1091. LogError(Severity_High, Error_DevLoadFileFailed
  1092. , LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO_FAILED_SAVEFINGERPRINT
  1093. , "open runinfo file failed while save data to local.");
  1094. LeaveCriticalSection(&m_cs);
  1095. return Error_Unexpect;
  1096. }
  1097. if (ctx->Req.FPFeatureList == nullptr)
  1098. return Error_Param;
  1099. int fingerIDNum = ctx->Req.FingerIdList.GetCount();
  1100. Dbg("FingerIDNum=%d", fingerIDNum);
  1101. FeatureData* fd = new FeatureData();
  1102. fd->FingerIDArray.Init(fingerIDNum);
  1103. fd->FingerIDLenArray.Init(fingerIDNum);
  1104. char fingerID[20];
  1105. Json::Value fingerInfo;
  1106. for (int i = 0; i < fingerIDNum; ++i)
  1107. {
  1108. memset(fingerID, 0, sizeof(fingerID));
  1109. #ifdef RVC_OS_WIN
  1110. _snprintf_s(fingerID, 10, "FingerID%d", ctx->Req.FingerIdList[i]);
  1111. #else
  1112. snprintf(fingerID, 10, "FingerID%d", ctx->Req.FingerIdList[i]);
  1113. #endif // RVC_OS_WIN
  1114. Dbg("writing %s", fingerID);
  1115. fingerInfo[fingerID] = ctx->Req.FPFeatureList[i].GetData();
  1116. fd->FingerIDArray[i] = ctx->Req.FPFeatureList[i];
  1117. fd->FingerIDLenArray[i] = fd->FingerIDArray[i].GetLength();
  1118. }
  1119. if (m_featureData.find(ctx->Req.CustomerID) == m_featureData.end())
  1120. {
  1121. //not exist, insert directly
  1122. m_featureData[ctx->Req.CustomerID] = fd;
  1123. }
  1124. else {
  1125. auto tempFD = m_featureData[ctx->Req.CustomerID];
  1126. m_featureData[ctx->Req.CustomerID] = fd;
  1127. if (tempFD) { delete tempFD; tempFD = NULL; }
  1128. }
  1129. errCode = spConfig->WriteConfigValue(m_FingerSection.GetData()
  1130. , ctx->Req.CustomerID.GetData()
  1131. , writer.write(fingerInfo).c_str());
  1132. if (errCode != Error_Succeed)
  1133. {
  1134. LogError(Severity_High, Error_DevLoadFileFailed
  1135. , LOG_ERR_CUSTMNGRAUTH_REGISTER_WRITE_RUNINFO_FAILED
  1136. , "write data into runinfo failed when commit.");
  1137. LeaveCriticalSection(&m_cs);
  1138. return Error_Unexpect;
  1139. }
  1140. Dbg("write data into runinfo success when commit.");
  1141. LeaveCriticalSection(&m_cs);
  1142. return errCode;
  1143. }
  1144. #pragma endregion
  1145. #pragma region authorize process
  1146. ErrorCodeEnum CCustMngrAuthFSM::MatchFingerPrint(SpReqAnsContext<CustMngrAuthService_StartAuthorize_Req, CustMngrAuthService_StartAuthorize_Ans>::Pointer ctx, bool& bStopAuthorize)
  1147. {
  1148. LOG_FUNCTION();
  1149. ErrorCodeEnum errCode = ConnectFingerPrintEntity();
  1150. if (errCode != Error_Succeed)
  1151. return errCode;
  1152. MatchParams* matchParam = new MatchParams();
  1153. matchParam->sTotalNumOfTemplate = 0;
  1154. errCode = PrepareDataBeforeMatch(matchParam);
  1155. if (errCode != Error_Succeed)
  1156. return errCode;
  1157. errCode = MatchProcess(matchParam, bStopAuthorize);
  1158. return errCode;
  1159. }
  1160. ErrorCodeEnum CCustMngrAuthFSM::ConnectFingerPrintEntity()
  1161. {
  1162. ErrorCodeEnum errCode = Error_Succeed;
  1163. m_pFingerPrint = new FingerPrintService_ClientBase(m_pEntity);
  1164. errCode = m_pFingerPrint->Connect();
  1165. if (errCode != Error_Succeed)
  1166. {
  1167. Dbg("ERROR: connect to fingerprint entity failed!");
  1168. m_pFingerPrint->SafeDelete();
  1169. errCode = Error_NoTarget; //TODO::give one other errCode
  1170. }
  1171. return errCode;
  1172. }
  1173. ErrorCodeEnum CCustMngrAuthFSM::PrepareDataBeforeMatch(MatchParams* matchParam)
  1174. {
  1175. EnterCriticalSection(&m_cs);
  1176. CAutoArray<CSimpleStringA> tempFeatureArray;
  1177. CAutoArray<int> tempFeatureLenArray;
  1178. int totalCustomerID = m_featureData.size();
  1179. int totalTemplate = totalCustomerID * FINGER_NUM;
  1180. tempFeatureArray.Init(totalTemplate);
  1181. tempFeatureLenArray.Init(totalTemplate);
  1182. if (totalCustomerID <= 0)
  1183. {
  1184. Dbg("No FingerPrint data in local file or read local file failed.");
  1185. LeaveCriticalSection(&m_cs);
  1186. if (matchParam != NULL)
  1187. delete matchParam;
  1188. return Error_NoTarget;
  1189. }
  1190. Dbg("begin copy feature to reqParams");
  1191. for (auto it = m_featureData.begin(); it != m_featureData.end(); ++it)
  1192. {
  1193. TemplateInfo ti;
  1194. memset(&ti, 0, sizeof(ti));
  1195. ti.CustomerID = it->first;
  1196. ti.TemplateNum = 0;
  1197. for (int index = 0; index < FINGER_NUM; ++index)
  1198. {
  1199. if (index >= it->second->FingerIDArray.GetCount()) //旧版本可能只有2个
  1200. break;
  1201. if (it->second->FingerIDArray[index].GetLength() <= 0)
  1202. continue;
  1203. tempFeatureArray[matchParam->sTotalNumOfTemplate] = it->second->FingerIDArray[index];
  1204. tempFeatureLenArray[matchParam->sTotalNumOfTemplate] = it->second->FingerIDLenArray[index];
  1205. ti.TemplateNum = ti.TemplateNum + 1;
  1206. ++matchParam->sTotalNumOfTemplate;
  1207. }
  1208. if (ti.TemplateNum > 0)
  1209. matchParam->sFingerCount.push_back(ti);
  1210. }
  1211. LeaveCriticalSection(&m_cs);
  1212. Dbg("num of template not empty:%d", matchParam->sTotalNumOfTemplate);
  1213. matchParam->sMatchReq.templateNum = matchParam->sTotalNumOfTemplate;
  1214. matchParam->sMatchReq.templates.Init(matchParam->sTotalNumOfTemplate);
  1215. matchParam->sMatchReq.templateLen.Init(matchParam->sTotalNumOfTemplate);
  1216. for (int i = 0; i < matchParam->sTotalNumOfTemplate; ++i)
  1217. {
  1218. matchParam->sMatchReq.templates[i] = tempFeatureArray[i];
  1219. matchParam->sMatchReq.templateLen[i] = tempFeatureLenArray[i];
  1220. }
  1221. Dbg("end copy feature to reqParams");
  1222. Dbg("templateNum: %d", matchParam->sMatchReq.templateNum);
  1223. return Error_Succeed;
  1224. }
  1225. ErrorCodeEnum CCustMngrAuthFSM::MatchProcess(MatchParams* matchParam, bool& bStopAuthorize)
  1226. {
  1227. ErrorCodeEnum errCode = Error_Succeed;
  1228. while (true)
  1229. {
  1230. if (m_pFingerPrint == NULL || m_pFingerPrint->QuerySessionClosed())
  1231. {
  1232. Dbg("m_pFingerPrint is NULL or connection closed.");
  1233. return Error_Unexpect;
  1234. }
  1235. //fingerprint entity may not return immediately
  1236. SLEEP(100);
  1237. Dbg("begin next invoke match.");
  1238. errCode = m_pFingerPrint->Match(matchParam->sMatchReq, matchParam->sMatchAns, 20000);
  1239. if (m_bCancelAuthorize || errCode == Error_Cancel)
  1240. {
  1241. Dbg("cancel authorize task.");
  1242. bStopAuthorize = true;
  1243. m_bCancelAuthorize = false;
  1244. if (m_bAuthorizeTimeout)
  1245. {
  1246. m_bAuthorizeTimeout = false;
  1247. return Error_TimeOut;
  1248. }
  1249. return Error_Cancel;
  1250. }
  1251. else if (errCode == Error_Unexpect || errCode == Error_TimeOut)
  1252. {
  1253. Dbg("invoke match error with errCode(%s)", SpStrError(errCode));
  1254. BroadcastGetFinger(2);
  1255. }
  1256. else if (errCode == Error_Succeed)
  1257. {
  1258. Dbg("invoke match success, start analyze result.");
  1259. errCode = AnalyzeMatchResult(matchParam, bStopAuthorize);
  1260. if (errCode == Error_Succeed)
  1261. return Error_Succeed; //continue if other errCode
  1262. }
  1263. else {
  1264. Dbg("invole match error(%s), stop authorize", SpStrError(errCode));
  1265. return Error_Unexpect;
  1266. }
  1267. }
  1268. }
  1269. void CCustMngrAuthFSM::BroadcastGetFinger(int status)
  1270. {
  1271. GetFinger evt;
  1272. evt.Status = status;
  1273. SpSendBroadcast(GetEntityBase()->GetFunction()
  1274. , SP_MSG_OF(GetFinger), SP_MSG_SIG_OF(GetFinger)
  1275. , evt);
  1276. }
  1277. ErrorCodeEnum CCustMngrAuthFSM::AnalyzeMatchResult(MatchParams* matchParam, bool& bStopAuthorize)
  1278. {
  1279. int resTemplateNum = matchParam->sMatchAns.result.GetCount();
  1280. if (resTemplateNum != matchParam->sTotalNumOfTemplate)
  1281. {
  1282. Dbg("result templateNum(%d) is not equale to the Req's(%d)."
  1283. , resTemplateNum, matchParam->sTotalNumOfTemplate);
  1284. return Error_Unexpect;
  1285. }
  1286. std::vector<TemplateInfo>tmpFingerCountInfo(matchParam->sFingerCount);
  1287. int matchIndex = -1; //matched CustomerID's index in array
  1288. int matchCount = 0; //num of matched
  1289. int fingerCountIndex = 0; //index of fingerCountInfo
  1290. int FINGER_NUM = tmpFingerCountInfo[fingerCountIndex].TemplateNum;
  1291. for (int i = 0; i < resTemplateNum; i += FINGER_NUM)
  1292. {
  1293. int oneCustMatchResult = 0;
  1294. FINGER_NUM = tmpFingerCountInfo[fingerCountIndex].TemplateNum;
  1295. for (int j = 0; j < FINGER_NUM; ++j)
  1296. {
  1297. oneCustMatchResult += matchParam->sMatchAns.result[i + j];
  1298. }
  1299. if (oneCustMatchResult > 0) //one customer has more than one match, just as one
  1300. {
  1301. matchCount++;
  1302. matchIndex = fingerCountIndex;
  1303. }
  1304. if (matchCount > 1) //more than one customer's finger matched
  1305. break;
  1306. fingerCountIndex++;
  1307. }
  1308. int matchResult = matchCount;//0:no match; 1:just one match; 2: muti match
  1309. switch (matchResult)
  1310. {
  1311. case 0:
  1312. {
  1313. Dbg("MatchResult: 0| no match");
  1314. BroadcastGetFinger(0);
  1315. }
  1316. break;
  1317. case 1:
  1318. {
  1319. Dbg("MatchResult: 1| one and only one match, authorize done.");
  1320. Dbg("Match Finger(CustomerID=%s)", (const char*)tmpFingerCountInfo[matchIndex].CustomerID);
  1321. m_authCtx.eAuthByWhich = AuthByFngPrnt;
  1322. m_authCtx.CustomerID = tmpFingerCountInfo[matchIndex].CustomerID;
  1323. bStopAuthorize = true;
  1324. return Error_Succeed;
  1325. }
  1326. break;
  1327. case 2:
  1328. {
  1329. Dbg("MatchResult: 2 | two and more matches. be alerted");
  1330. BroadcastGetFinger(1);
  1331. }
  1332. break;
  1333. default:break;
  1334. }
  1335. return Error_Unexpect;
  1336. }
  1337. #pragma endregion