CustMngrAuthFSM.cpp 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308
  1. //#include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpHelper.h"
  4. #include "CustMngrAuth_UserErrorCode.h"
  5. #include "CustMngrAuthFSM.h"
  6. #include <iostream>
  7. #include <fstream>
  8. #include <map>
  9. #include <iomanip>
  10. #include <random>
  11. #include <stdint.h>
  12. #include <sstream>
  13. #include <thread>
  14. #include <chrono>
  15. #include <time.h>
  16. #include "path.h"
  17. using namespace std;
  18. #define _ATL_NO_AUTOMATIC_NAMESPACE
  19. //#include <atltime.h>
  20. const int UPDATEINTERNAL = 10*60*1000; //query data from branch server internal, 10min
  21. const int CONNECTINTERNAL = 30*1000; //connect branch server internal, 30s
  22. const int FINGERNUM = 8; //suuport max register finger num
  23. class CCustMngrAuthEntity;
  24. //Init
  25. void CCustMngrAuthFSM::s0_on_entry()
  26. {
  27. LOG_FUNCTION();
  28. FSMEvent *pEvt = new FSMEvent(USER_EVT_INIT);
  29. PostEventFIFO(pEvt);
  30. }
  31. void CCustMngrAuthFSM::s0_on_exit()
  32. {
  33. LOG_FUNCTION();
  34. }
  35. unsigned int CCustMngrAuthFSM::s0_on_event(FSMEvent* pEvt)
  36. {
  37. LOG_FUNCTION();
  38. Dbg("s0 evt %d", pEvt->iEvt);
  39. switch (pEvt->iEvt)
  40. {
  41. case USER_EVT_INIT:
  42. {
  43. InitTask* task = new InitTask(this);
  44. GetEntityBase()->GetFunction()->PostThreadPoolTask(task);
  45. pEvt->SetHandled();
  46. return 0;
  47. }
  48. break;
  49. default:
  50. break;
  51. }
  52. return 0;
  53. }
  54. //Initializing
  55. void CCustMngrAuthFSM::s1_on_entry()
  56. {
  57. LOG_FUNCTION();
  58. }
  59. void CCustMngrAuthFSM::s1_on_exit()
  60. {
  61. LOG_FUNCTION();
  62. }
  63. unsigned int CCustMngrAuthFSM::s1_on_event(FSMEvent* pEvt)
  64. {
  65. LOG_FUNCTION();
  66. Dbg("s1 evt %d", pEvt->iEvt);
  67. switch (pEvt->iEvt)
  68. {
  69. case USER_EVT_INIT_FINISHED:
  70. pEvt->SetHandled();
  71. return pEvt->param1;
  72. default:
  73. break;
  74. }
  75. return 0;
  76. }
  77. //Idle
  78. void CCustMngrAuthFSM::s2_on_entry()
  79. {
  80. LOG_FUNCTION();
  81. }
  82. void CCustMngrAuthFSM::s2_on_exit()
  83. {
  84. LOG_FUNCTION();
  85. }
  86. unsigned int CCustMngrAuthFSM::s2_on_event(FSMEvent* pEvt)
  87. {
  88. Dbg("s2 evt(%d)", pEvt->iEvt);
  89. int ret = 0;
  90. switch (pEvt->iEvt)
  91. {
  92. case USER_EVT_AUTHORIZE_START:
  93. {
  94. pEvt->SetHandled();
  95. Dbg("start to authorize");
  96. AuthorizeStartEvent *ase = dynamic_cast<AuthorizeStartEvent*>(pEvt);
  97. if (ase->ctx->Req.TimeLimit <= 0)
  98. {
  99. LOG_TRACE("ERROR: receive timelimit lessequal than zero. ctx->Answer(error_Param)");
  100. AuthorizeFinishedEvent *e = new AuthorizeFinishedEvent();
  101. e->ctx = ase->ctx;
  102. e->param1 = Error_Param;
  103. this->PostEventFIFO(e);
  104. break;
  105. }
  106. m_TimeLimit = (ase->ctx->Req.TimeLimit - 3) * 1000; //状态机流程会耗一些时间,这里要比前端传过来的时间小一些,及时返回给前端
  107. ErrorCodeEnum eErr;
  108. m_bCancelAuthorize = false;
  109. //打开USB
  110. eErr = SwitchUSB(true);
  111. if (eErr != Error_Succeed)
  112. Dbg("open usb failed with eErr(0x%x)", eErr);
  113. else{
  114. Dbg("open usb successfully.");
  115. m_ctx = ase->ctx;
  116. }
  117. //起指纹匹配线程
  118. MatchFingerPrintTask *mTask = new MatchFingerPrintTask(this);
  119. mTask->ctx = ase->ctx;
  120. GetEntityBase()->GetFunction()->PostThreadPoolTask(mTask);
  121. }
  122. break;
  123. case USER_EVT_COLLECTFINGERPRINT_START:
  124. {
  125. CollectFingerPrintStartEvent *cfpe = dynamic_cast<CollectFingerPrintStartEvent*>(pEvt);
  126. CollectFingerPrintTask *ftask = new CollectFingerPrintTask(this);
  127. ftask->ctx = cfpe->ctx;
  128. GetEntityBase()->GetFunction()->PostThreadPoolTask(ftask);
  129. Dbg("collect_finger_print task posted");
  130. pEvt->SetHandled();
  131. }
  132. break;
  133. case USER_EVT_SAVEFINGERPRINT_START:
  134. {
  135. pEvt->SetHandled();
  136. SaveFingerPrintStartEvent *sfpe = dynamic_cast<SaveFingerPrintStartEvent*>(pEvt);
  137. SaveFingerPrintTask *sTask = new SaveFingerPrintTask(this);
  138. sTask->ctx = sfpe->ctx;
  139. GetEntityBase()->GetFunction()->PostThreadPoolTask(sTask);
  140. Dbg("save_finger_print task posted");
  141. }
  142. break;
  143. case USER_EVT_CHECKUKEY:
  144. {
  145. pEvt->SetHandled();
  146. SwitchUSB(true);
  147. }
  148. break;
  149. default:
  150. break;
  151. }
  152. return 0;
  153. }
  154. void CCustMngrAuthFSM::s3_on_entry()
  155. {
  156. LOG_FUNCTION();
  157. ScheduleTimer(1, m_TimeLimit);
  158. Dbg("Timer Set %dms", m_TimeLimit);
  159. }
  160. void CCustMngrAuthFSM::s3_on_exit()
  161. {
  162. LOG_FUNCTION();
  163. CancelTimer(1);
  164. Dbg("Timer Canceled");
  165. }
  166. unsigned int CCustMngrAuthFSM::s3_on_event(FSMEvent* pEvt)
  167. {
  168. Dbg("s3 evt %d, %d", pEvt->iEvt, pEvt->param1);
  169. switch (pEvt->iEvt)
  170. {
  171. case USER_EVT_HOLDON:
  172. {
  173. HoldOnEvent *hoe = dynamic_cast<HoldOnEvent*>(pEvt);
  174. Dbg(" Cancel old timer(1) and rescheduling timer(1)");
  175. CancelTimer(1);
  176. Dbg("Timer1 canceled");
  177. if (hoe->ctx == NULL)
  178. Dbg("HoldOnEvent->ctx is NULL");
  179. Dbg("HoldOn with MoreTime: %d second", hoe->ctx->Req.MoreTime);
  180. int moreTime = hoe->ctx->Req.MoreTime * 1000;
  181. Dbg("Adding more time: %d", moreTime);
  182. ScheduleTimer(1, (moreTime > 0) ? moreTime : m_TimeLimit);
  183. pEvt->SetHandled();
  184. }
  185. break;
  186. case EVT_TIMER:
  187. {
  188. Dbg("Hit Timer");
  189. pEvt->SetHandled();
  190. m_bAuthorizeTimeout = true;
  191. m_bCancelAuthorize = true;
  192. CancelAuthorize();
  193. //SwitchUSB(false);
  194. }
  195. break;
  196. case USER_EVT_AUTHORIZE_FINISHED:
  197. {
  198. pEvt->SetHandled();
  199. ErrorCodeEnum eErr;
  200. AuthorizeFinishedEvent *afe = dynamic_cast<AuthorizeFinishedEvent*>(pEvt);
  201. Dbg("Checking m_authCtx and answer ctx");
  202. if(m_csMachineType.Compare("RVC.PAD", true))
  203. {
  204. //非PAD才去关闭U口
  205. SwitchUSB(false);
  206. }
  207. if (afe->param1 == 0)
  208. {
  209. Dbg("authorize finished with param1 as 0");
  210. if (m_authCtx.eAuthByWhich == AuthByUkey)
  211. {
  212. Dbg("m_authCtx.eAuthByWhich == AuthByUkey");
  213. if (m_pFingerPrint != NULL && !m_pFingerPrint->QuerySessionClosed())
  214. {
  215. Dbg("Invoke cancel match.");
  216. m_pFingerPrint->CancelMatch();
  217. }
  218. afe->ctx->Ans.WayofAuth = AuthByUkey;
  219. afe->ctx->Ans.UkeyID = m_authCtx.UkeyID;
  220. afe->ctx->Answer(Error_Succeed);
  221. }
  222. else if (m_authCtx.eAuthByWhich == AuthByFngPrnt)
  223. {
  224. Dbg("m_authCtx.eAuthByWhich == AuthByFngPrnt");
  225. afe->ctx->Ans.WayofAuth = AuthByFngPrnt;
  226. afe->ctx->Ans.CustomerID = m_authCtx.CustomerID;
  227. afe->ctx->Answer(Error_Succeed);
  228. }
  229. }
  230. else
  231. {
  232. Dbg("authorize finished with param1 as %d", afe->param1);
  233. afe->ctx->Answer((ErrorCodeEnum)afe->param1);
  234. }
  235. if (m_pFingerPrint != NULL && !m_pFingerPrint->QuerySessionClosed())
  236. {
  237. m_bCancelAuthorize = true;
  238. //m_pFingerPrint->CancelMatch();
  239. m_pFingerPrint->GetFunction()->CloseSession();
  240. m_pFingerPrint->SafeDelete();
  241. m_pFingerPrint=NULL;
  242. Dbg("M_pFingerPrint disconnected.");
  243. }
  244. m_authCtx.eAuthByWhich = AuthByNone;
  245. m_authCtx.CustomerID = "";
  246. m_authCtx.UkeyID = "";
  247. m_ctx = NULL;
  248. }
  249. break;
  250. case USER_EVT_AUTHORIZE_CANCEL:
  251. {
  252. pEvt->SetHandled();
  253. m_bCancelAuthorize = true;
  254. CancelAuthorize();
  255. }
  256. break;
  257. default:
  258. break;
  259. }
  260. return 0;
  261. }
  262. void CCustMngrAuthFSM::s4_on_entry()
  263. {
  264. LOG_FUNCTION();
  265. }
  266. void CCustMngrAuthFSM::s4_on_exit()
  267. {
  268. LOG_FUNCTION();
  269. }
  270. unsigned int CCustMngrAuthFSM::s4_on_event(FSMEvent* pEvt)
  271. {
  272. Dbg("s4 evt %d, %d", pEvt->iEvt, pEvt->param1);
  273. int ret = 0;
  274. switch (pEvt->iEvt)
  275. {
  276. case USER_EVT_COLLECTFINGERPRINT_FINISHED:
  277. pEvt->SetHandled();
  278. break;
  279. case USER_EVT_COLLECTFINGERPRINT_CANCEL:
  280. {
  281. pEvt->SetHandled();
  282. if (m_pFingerPrint != NULL && !m_pFingerPrint->QuerySessionClosed())
  283. m_pFingerPrint->CancelRegister();
  284. }
  285. break;
  286. case USER_EVT_SAVEFINGERPRINT_FINISHED:
  287. pEvt->SetHandled();
  288. break;
  289. case USER_EVT_CHECKUKEY_FINISHED:
  290. {
  291. pEvt->SetHandled();
  292. if (m_csMachineType.Compare("RVC.PAD", true))
  293. {
  294. SwitchUSB(false);
  295. }
  296. }
  297. break;
  298. default:
  299. break;
  300. }
  301. return 0;
  302. }
  303. void CCustMngrAuthFSM::s5_on_entry()
  304. {
  305. LOG_FUNCTION();
  306. }
  307. void CCustMngrAuthFSM::s5_on_exit()
  308. {
  309. LOG_FUNCTION();
  310. }
  311. unsigned int CCustMngrAuthFSM::s5_on_event(FSMEvent* pEvt)
  312. {
  313. Dbg("s5 evt %d, %d", pEvt->iEvt, pEvt->param1);
  314. return 0;
  315. }
  316. ErrorCodeEnum CCustMngrAuthFSM::OnInit()
  317. {
  318. LOG_FUNCTION();
  319. m_authCtx.eAuthByWhich = AuthByNone;
  320. CSystemStaticInfo staticInfo;
  321. m_pEntity->GetFunction()->GetSystemStaticInfo(staticInfo);
  322. m_TerminalID = staticInfo.strTerminalID;
  323. m_csMachineType = staticInfo.strMachineType;
  324. return Error_Succeed;
  325. }
  326. ErrorCodeEnum CCustMngrAuthFSM::OnExit()
  327. {
  328. LOG_FUNCTION();
  329. FSMImpl<CCustMngrAuthFSM>::OnExit();
  330. return Error_Succeed;
  331. }
  332. int CCustMngrAuthFSM::Initial()
  333. {
  334. STR_FINGERINFO = "FingerInfo";
  335. ErrorCodeEnum eErr = GetEntityBase()->GetFunction()->GetPath("RunInfo", m_runInfoPath);
  336. if(eErr != Error_Succeed){
  337. Dbg("get runinfo path failed.");
  338. LogError(Severity_High, Error_DevLoadFileFailed, LOG_ERR_CUSTMNGRAUTH_GET_RUNINFO_PATH_FAILED_Init, "get runinfo path failed while init");
  339. return 1;
  340. }
  341. FeatureUpdateTask *pTask = new FeatureUpdateTask(this);
  342. GetEntityBase()->GetFunction()->PostThreadPoolTask(pTask);
  343. return 0;
  344. }
  345. string CCustMngrAuthFSM::ClearStringSpaceHeadTail(string& line)
  346. {
  347. if(line.empty()){
  348. return line;
  349. }
  350. line.erase(0, line.find_first_not_of(" "));
  351. line.erase(line.find_last_not_of(" ") + 1);
  352. return line;
  353. }
  354. bool CCustMngrAuthFSM::ReadDataIntoMemory(bool& bHasData)
  355. {
  356. LOG_FUNCTION();
  357. CSmartPointer<IConfigInfo> spConfig;
  358. ErrorCodeEnum eErr;
  359. CSimpleStringA strPath;
  360. CSimpleStringA runInfoFile;
  361. runInfoFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR "CustMngrAuth.ini"
  362. , (const char*)m_runInfoPath);
  363. ifstream inFile(runInfoFile);
  364. string line;
  365. int customerNum = 0;
  366. Dbg("read data timer start...");
  367. SYSTEMTIME urlStartTime, urlEndTime;
  368. GetLocalTime(&urlStartTime);
  369. DWORD dwStart = GetTickCount();
  370. while(getline(inFile, line)){
  371. if(line.length() <= 0){
  372. continue;
  373. }
  374. string tempLine = ClearStringSpaceHeadTail(line);
  375. if(!tempLine.compare("[UpdateTime]") || string::npos != tempLine.find("UpdateTime")
  376. || !tempLine.compare("[LatestTime]") || string::npos != tempLine.find("LatestTime")
  377. || !tempLine.compare("[FingerInfo]") || !tempLine.compare("[FaceInfo]")
  378. || string::npos != tempLine.find("FaceInfo1") || string::npos != tempLine.find("FaceInfo2")){
  379. continue;
  380. }
  381. string::size_type pos = tempLine.find("=");
  382. if(pos != 16){
  383. continue;
  384. }
  385. string keys = tempLine.substr(0, pos);
  386. string values = tempLine.substr(pos+1);
  387. Json::Reader reader;
  388. Json::Value root;
  389. if (reader.parse((const char*)values.c_str(), root)){
  390. customerNum++;
  391. FeatureData *fd = new FeatureData();
  392. fd->FingerIDArray.Init(FINGERNUM);
  393. fd->FingerIDLenArray.Init(FINGERNUM);
  394. for (int i = 0; i < FINGERNUM; ++i){
  395. char index[20];
  396. _snprintf_s(index, 10, "FingerID%d", i+1);
  397. fd->FingerIDArray[i] = root.isMember(index) ? CSimpleStringA(root[index].asCString()) : "";
  398. fd->FingerIDLenArray[i] = root.isMember(index) ? fd->FingerIDArray[i].GetLength() : 0;
  399. }
  400. //首次读取到内存,m_featureData为空,不用考虑其中已存在该key值
  401. m_featureData[CSimpleStringA(keys.c_str())] = fd;
  402. //Dbg("CustomerID=%s success.", keys.c_str());
  403. }else{
  404. Dbg("Error: parse jsonFingerInfo failed.");
  405. LogWarn(Severity_High, Error_Unexpect, LOG_ERR_CUSTMNGRAUTH_AUTHORIZATION_READFEAT_FAILED, "Read fingerprint feature json failed.");
  406. return false;
  407. }
  408. }
  409. Dbg("Total CustomerNum:%d in local file.", customerNum);
  410. DWORD dwEnd = GetTickCount();
  411. GetLocalTime(&urlEndTime);
  412. auto urlDuration = getDuration(urlStartTime, urlEndTime);
  413. LogWarn(Severity_High, Error_Debug, LOG_ERR_CUSTMNGRAUTH_READ_INTO_MEMORY_TIME,
  414. generateAlarmJson("CustMngrAuth", formatTime(urlStartTime).c_str(), urlDuration).GetData());
  415. Dbg("read data timer end...");
  416. Dbg("cost time:%dms", (dwEnd - dwStart)) ;
  417. bHasData = true;
  418. return true;
  419. }
  420. void CCustMngrAuthFSM::TransDataFromServer(CAutoArray<CSimpleStringA> &dataArray, CSimpleStringA latestTime, bool& bResumeTrans, bool bIsFirstTimeQueryData)
  421. {
  422. LOG_FUNCTION();
  423. int transTime = 0;
  424. char currAgent[16]="";
  425. char branchID[16]="";
  426. while(bResumeTrans){
  427. transTime++;
  428. if (bIsFirstTimeQueryData)
  429. m_pConnection->SendFeatReq(currAgent, branchID);
  430. else
  431. m_pConnection->SendFeatReq(currAgent, branchID, (const char*)latestTime);
  432. ResetEvent(m_pConnection->hPkgAnswer);
  433. DWORD dw = WaitForSingleObject(m_pConnection->hPkgAnswer, 20000); //10->20 20200430@liuwentao
  434. switch(dw)
  435. {
  436. case WAIT_FAILED:
  437. Dbg("WAIT_FAILED!");
  438. break;
  439. case WAIT_TIMEOUT:
  440. Dbg("WAIT_TIMEOUT");
  441. case WAIT_OBJECT_0:
  442. Dbg("WAIT_OBJECT_0");
  443. break;
  444. }
  445. ResetEvent(m_pConnection->hPkgAnswer);
  446. if (m_pConnection->m_reply == NULL){
  447. Dbg("m_reply still null after hPkgAnswer handled");
  448. break;
  449. }else{
  450. if (m_pConnection->getErrMsg){
  451. Dbg("get error message, check dbg log");
  452. break;
  453. }
  454. if (m_pConnection->m_reply->ResultCode == 2){
  455. Dbg("remote server uninitialized yet, unable to excute query");
  456. break;
  457. }else{
  458. if (m_pConnection->m_reply->ResultCode == 0){
  459. Dbg("All package downloaded from branch server.");
  460. bResumeTrans = false;
  461. }
  462. memcpy(currAgent, m_pConnection->m_reply->CurrentAgent, 16);
  463. memcpy(branchID, m_pConnection->m_reply->BranchID, 16);
  464. CSimpleStringA jbuf(m_pConnection->m_reply->Data, m_pConnection->m_jsonLen);
  465. dataArray.Append(&jbuf,0,1);
  466. }
  467. }
  468. }
  469. }
  470. bool CCustMngrAuthFSM::BackupFile(CSimpleStringA srcFile, CSimpleStringA dstFile)
  471. {
  472. bool backupResult = true;
  473. fstream fileExist;
  474. ifstream inFile;
  475. ofstream outFile;
  476. fileExist.open((const char*)srcFile, ios::in);
  477. if(!fileExist){
  478. fileExist.close();
  479. return true;
  480. }
  481. fileExist.close();
  482. inFile.open((const char*)srcFile);
  483. if (inFile.fail()){
  484. Dbg("Open CustMngrAuth.ini failed");
  485. inFile.close();
  486. return false;
  487. }
  488. outFile.open((const char*)dstFile);
  489. if (outFile.fail()){
  490. Dbg("Open CustMngrAuth_bak.ini failed.");
  491. backupResult = false;
  492. }else{
  493. outFile << inFile.rdbuf();
  494. }
  495. inFile.close();
  496. outFile.close();
  497. return backupResult;
  498. }
  499. void CCustMngrAuthFSM::FeatureUpdate()
  500. {
  501. LOG_FUNCTION();
  502. //when start entity, read data into memory
  503. bool bHasData = false;
  504. bool bReadResult = ReadDataIntoMemory(bHasData);
  505. if (bReadResult && bHasData)
  506. {
  507. Dbg("Read feature data into memory success.");
  508. }else if (bReadResult && !bHasData) {
  509. Dbg("Has no data in local file.");
  510. }else{
  511. Dbg("Read feature data into memory failed, wait next read.");
  512. }
  513. int tWait = UPDATEINTERNAL;
  514. int connectFailedTimes = 0;
  515. ErrorCodeEnum eErr;
  516. while(1){
  517. CSmartPointer<IConfigInfo> spConfig;
  518. CAutoArray<CSimpleStringA> transArray;
  519. m_pConnection = new FeatureUpdateConn(m_pEntity, this);
  520. //connect branch server
  521. if (m_pConnection->ConnectFromCentralSetting() && m_pConnection->IsConnectionOK()){
  522. connectFailedTimes = 0;
  523. tWait = UPDATEINTERNAL;
  524. bool resumeTrans = true;
  525. bool isFirstTimeQueryData = false;
  526. EnterCriticalSection(&m_cs);//临时锁一下运行时,防止在写入
  527. eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
  528. if (eErr != Error_Succeed){
  529. Dbg("Open runcfg file failed before query data.");
  530. LogError(Severity_High, Error_Unexpect, LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO_FAILED_UPDATE, "open runcfg failed before query data.");
  531. LeaveCriticalSection(&m_cs);
  532. goto Err;
  533. }
  534. CSimpleStringA latestTime(""), updateTime("");//latestTime表示最上一次传来的最新时间,updateTime表示更新日期(是否要做全量清除更新)
  535. spConfig->ReadConfigValue("LatestTime", "LatestTime", latestTime);
  536. spConfig->ReadConfigValue("UpdateTime", "UpdateTime", updateTime);
  537. LeaveCriticalSection(&m_cs);
  538. //query current time
  539. CSimpleStringA newTime = GetCurrentDate();
  540. //当前日期大于文件中日期时,需要做全量更新
  541. if (updateTime.GetLength() <= 0 || (updateTime.GetLength() > 0 && CompareTime(newTime, updateTime) > 0) || latestTime.GetLength() <= 0){
  542. isFirstTimeQueryData = true;
  543. }
  544. //多次续传从分行服务获取数据(增量更新时,大于latestTime的才传下来)
  545. TransDataFromServer(transArray, latestTime, resumeTrans, isFirstTimeQueryData);
  546. if(resumeTrans){
  547. Dbg("ERROR: The last update of feature ended with resumetrans as true, might be timeout or some errors happened");
  548. //存在有时因分行服务升级导致连接断开,更新数据失败,暂时对业务无影响
  549. //LogError(Severity_High, Error_Unexpect, LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_DOWNLOAD_FAILED, "Transmission of fingerprint feature failed.");
  550. goto Err;
  551. }
  552. if (transArray.GetCount() <= 0){
  553. Dbg("query no data from branchServer.(exact no data or the sql was deleted)");
  554. //LogWarn(Severity_High, Error_Unexpect, LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_DOWNLOAD_FAILED, "query no data from branchServer.");
  555. goto Err;
  556. }
  557. //续传成功结束,解析jbuf数组并写入本地
  558. Dbg("Transmission finished successfully. Ready to decode json data and write into runcfg");
  559. //写入文件前,先判断是否已存在CustMngrAuth.ini文件,若不存在则直接写入,若存在,则先备份该文件
  560. CSimpleStringA srcFile(true);
  561. CSimpleStringA backupFile(true);
  562. srcFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR "CustMngrAuth.ini"
  563. , (const char*)m_runInfoPath);
  564. backupFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "runcfg" SPLIT_SLASH_STR "CustMngrAuth_bak.ini"
  565. , (const char*)m_runInfoPath);
  566. EnterCriticalSection(&m_cs);
  567. if(!BackupFile(srcFile, backupFile)){
  568. Dbg("Backup runinfo file failed.");
  569. }
  570. if (isFirstTimeQueryData){
  571. //首次更新,需清除数据,全量写入,并更新时间
  572. ofstream fileOut((const char*)srcFile, ios::trunc);
  573. fileOut.close();
  574. }
  575. eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
  576. if (eErr != Error_Succeed){
  577. RecoverFile(srcFile, backupFile);//有失败情况,恢复原文件
  578. //LogError(Severity_High, Error_DevLoadFileFailed, LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO__FAILED, "Open runinfo file failed.");
  579. Dbg("ERROR: Open runcfg failed with %d", eErr);
  580. LeaveCriticalSection(&m_cs);
  581. goto Err;
  582. }
  583. spConfig->WriteConfigValue("UpdateTime", "UpdateTime", (const char*)newTime);
  584. if (isFirstTimeQueryData){
  585. //首次全量更新或存量无LatestTime字段
  586. spConfig->WriteConfigValue("LatestTime", "LatestTime", "");
  587. }
  588. map<CSimpleStringA, FeatureData*> tempFeature;//如果是全量更新,需要更新后全量传给m_featureData
  589. CSimpleStringA maxUpdateTime = latestTime;
  590. for(int transTime = 0; transTime < transArray.GetCount(); ++transTime){
  591. Json::Value root;
  592. Json::Reader reader;
  593. Json::FastWriter writer;
  594. CSimpleStringA transBuffer = transArray[transTime];//一次传输受大小限制,只能有3~4条
  595. //Dbg("transBuffer=%s", transBuffer.GetData());
  596. if (reader.parse((const char*)transBuffer, root)){
  597. for (int i = 0; i < (int)root.size(); ++i){
  598. Json::Value jsonFingerInfo;
  599. FeatureData *fd = new FeatureData();
  600. fd->FingerIDArray.Init(FINGERNUM);
  601. fd->FingerIDLenArray.Init(FINGERNUM);
  602. for(int fingerIndex = 0; fingerIndex < FINGERNUM; ++fingerIndex){
  603. char FingerID[20];//运行时文件是"FingerID"
  604. char fingerId[20];//分行服务是"fingerId" 二者不一致,历史遗留
  605. _snprintf_s(FingerID, 10, "FingerID%d", fingerIndex+1);
  606. _snprintf_s(fingerId, 10, "fingerId%d", fingerIndex+1);
  607. jsonFingerInfo[FingerID] = root[i][fingerId].asCString();
  608. fd->FingerIDArray[fingerIndex] = CSimpleStringA(root[i][fingerId].asCString());
  609. fd->FingerIDLenArray[fingerIndex] = fd->FingerIDArray[fingerIndex].GetLength();
  610. }
  611. //插入临时map
  612. if(tempFeature.find(CSimpleStringA(root[i]["customerID"].asCString())) == tempFeature.end()){//不存在,直接插入
  613. tempFeature[CSimpleStringA(root[i]["customerID"].asCString())] = fd;
  614. }else{//已存在,需要释放原有内存
  615. auto tempFD = tempFeature[CSimpleStringA(root[i]["customerID"].asCString())];
  616. tempFeature[CSimpleStringA(root[i]["customerID"].asCString())] = fd;
  617. if(tempFD){
  618. delete tempFD;
  619. tempFD = NULL;
  620. }
  621. }
  622. CSimpleStringA tempMaxUpdateTime = CSimpleStringA(root[i]["updateTime"].asCString());
  623. maxUpdateTime = GetMaxTime(maxUpdateTime, tempMaxUpdateTime);
  624. int fingerDataState = root[i]["state"].asCString()[0] - '0';
  625. if (fingerDataState == 0){
  626. CSimpleStringA jsonFingerStr(writer.write(jsonFingerInfo).c_str());
  627. int jlen = jsonFingerStr.GetLength()-1;
  628. char *jstr = new char[jlen+1];
  629. memcpy(jstr, jsonFingerStr.GetData(), jlen);
  630. jstr[jlen]= '\0';
  631. //不做这步处理的话runcfg里faceinfo节不同customerID间没有换行,fingerinfo节本来有,但以防万一也做同样处理。
  632. eErr = spConfig->WriteConfigValue(STR_FINGERINFO, root[i]["customerID"].asCString(), jstr);
  633. delete []jstr;
  634. if (eErr != Error_Succeed){
  635. //如果写入失败,则将原文件恢复
  636. RecoverFile(srcFile, backupFile);
  637. LeaveCriticalSection(&m_cs);
  638. goto Err;
  639. }
  640. }else if (fingerDataState == 2){
  641. Dbg("state(2): customer %s is currently unavailable.", root[i]["customerID"].asCString());
  642. spConfig->WriteConfigValue(STR_FINGERINFO, root[i]["customerID"].asCString(), "");
  643. }else{
  644. Dbg("ERROR: unexpectedly customer(%s)'s state is either 0 or 2", root[i]["customerID"].asCString());
  645. }
  646. }
  647. }else{
  648. Dbg("ERROR: fail to parse transArray[%d]!", transTime);
  649. //LogError(Severity_High, Error_Unexpect, LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_WRITE_FAILED, "Failed to write fingerprint feature into runcfg.");
  650. LeaveCriticalSection(&m_cs);
  651. goto Err;
  652. }
  653. }
  654. //数据写完,将最新时间更新到本地
  655. if (maxUpdateTime.GetLength() > 0){
  656. spConfig->WriteConfigValue("LatestTime", "LatestTime", (const char*)maxUpdateTime);
  657. }
  658. Dbg("updateNum=%d", tempFeature.size());
  659. //更新数据到内存
  660. UpdateDataIntoMemory(tempFeature, isFirstTimeQueryData);
  661. LeaveCriticalSection(&m_cs);
  662. }else{
  663. Dbg("ERROR: Fail to connect remote server! Try again in %d mm.", CONNECTINTERNAL);
  664. connectFailedTimes++;
  665. Dbg("connect time = %d", connectFailedTimes);
  666. if(connectFailedTimes >= 60){//如果一直连不上,则30分钟抛一次告警
  667. LogWarn(Severity_High, Error_Unexpect, LOG_ERR_CUSTMNGRAUTH_FEATUPDATE_CONNECT_FAILED, "Connect branch server failed.");
  668. connectFailedTimes = 0;
  669. }
  670. tWait = CONNECTINTERNAL;
  671. }
  672. Err:
  673. if(m_pConnection){
  674. m_pConnection->Close();
  675. m_pConnection->DecRefCount();
  676. m_pConnection = NULL;
  677. }
  678. Dbg("Feature-update processed, wait until next");
  679. //等待tWait时间后,进行下一次请求更新
  680. if (WaitForSingleObject(hStopUpdate, tWait) == WAIT_OBJECT_0)
  681. break;
  682. }
  683. }
  684. void CCustMngrAuthFSM::UpdateDataIntoMemory(map<CSimpleStringA, FeatureData*> tempFeature, bool bIsFirstTimeQueryData)
  685. {
  686. //如果不是第一次更新,则只覆盖新增/修改数据
  687. if(!bIsFirstTimeQueryData){
  688. for(auto it = tempFeature.begin(); it != tempFeature.end(); ++it){
  689. if(m_featureData.find(it->first) == m_featureData.end()){//没有这个key,直接插入
  690. m_featureData[it->first] = it->second;
  691. }else{//已存在该key,释放旧有的内存
  692. auto tempFD = m_featureData[it->first];
  693. m_featureData[it->first] = it->second;
  694. if(tempFD != NULL){
  695. delete tempFD;
  696. tempFD = NULL;
  697. }
  698. }
  699. }
  700. }else{//如果是全量更新,需要先将内存数据清理掉,内存中有可能存在已离职人员
  701. DWORD dwStart = GetTickCount();
  702. for(auto iter = m_featureData.begin(); iter != m_featureData.end();){
  703. auto fd = iter->second;
  704. if(fd){
  705. delete fd;
  706. fd = NULL;
  707. m_featureData.erase(iter++);
  708. }
  709. }
  710. m_featureData.insert(tempFeature.begin(), tempFeature.end());
  711. DWORD dwEnd = GetTickCount();
  712. Dbg("copy data to memory time:%dms", dwEnd - dwStart);
  713. }
  714. }
  715. ErrorCodeEnum CCustMngrAuthFSM::MatchFingerPrint(SpReqAnsContext<CustMngrAuthService_StartAuthorize_Req, CustMngrAuthService_StartAuthorize_Ans>::Pointer ctx, bool& bStopAuthorize)
  716. {
  717. //只有取消、超时、成功匹配、侦听到ukey插入触发这里的取消这些情况下才会终止授权,否则就算遇到异常退出本方法,也要继续等待直到超时或ukey或取消。
  718. LOG_FUNCTION();
  719. ErrorCodeEnum eErr;
  720. m_pFingerPrint = new FingerPrintService_ClientBase(m_pEntity);
  721. eErr = m_pFingerPrint->Connect();
  722. if (eErr != Error_Succeed){
  723. Dbg("ERROR: connect to fingerprint entity failed!");
  724. m_pFingerPrint->SafeDelete();
  725. m_pFingerPrint=NULL;
  726. return Error_Unexpect; //TODO::give one other errCode
  727. }
  728. EnterCriticalSection(&m_cs);
  729. //loop invoke match, only when have one match,stop;otherwise, continue loop
  730. FingerPrintService_Match_Req matchReq;
  731. FingerPrintService_Match_Ans matchAns;
  732. CAutoArray<CSimpleStringA> tempFeatureArray; //临时存放指纹数据,用于给入参赋值
  733. CAutoArray<int> tempFeatureLenArray;
  734. int totalCustomerID = m_featureData.size();
  735. int totalTemplate = totalCustomerID * FINGERNUM;
  736. if (totalCustomerID <= 0){
  737. Dbg("No FingerPrint data in local file or read local file failed.");
  738. LeaveCriticalSection(&m_cs);
  739. return Error_NoTarget;
  740. }
  741. tempFeatureArray.Init(totalTemplate);
  742. tempFeatureLenArray.Init(totalTemplate);
  743. vector<TemplateInfo> fingerCount;//存放CustomerID及其对应指纹个数(非空指纹)
  744. Dbg("begin copy feature to reqParams");
  745. int i = 0, j = 0;
  746. DWORD dwStart = GetTickCount();
  747. int count = 0; //实际不为空的指纹模板总个数
  748. for (auto it = m_featureData.begin(); it != m_featureData.end(); ++it){
  749. int countPerCust = 0;//统计每个CustomerID不为空指纹个数
  750. TemplateInfo ti;
  751. memset(&ti, 0, sizeof(ti));
  752. ti.CustomerID = it->first;
  753. ti.TemplateNum = 0;
  754. for(int index = 0; index < FINGERNUM; ++index){//
  755. if(index >= it->second->FingerIDArray.GetCount()){//旧版本可能只有2个
  756. break;
  757. }
  758. if(it->second->FingerIDArray[index].GetLength() <= 0){
  759. continue;
  760. }
  761. tempFeatureArray[count] = it->second->FingerIDArray[index];
  762. tempFeatureLenArray[count] = it->second->FingerIDLenArray[index];
  763. ti.TemplateNum = ti.TemplateNum + 1;
  764. ++count;
  765. }
  766. if(ti.TemplateNum > 0){
  767. fingerCount.push_back(ti);
  768. }
  769. }
  770. LeaveCriticalSection(&m_cs);
  771. Dbg("num of template not empty:%d", count);
  772. matchReq.templateNum = count;
  773. matchReq.templates.Init(count);
  774. matchReq.templateLen.Init(count);
  775. for(int i = 0; i < count; ++i){
  776. matchReq.templates[i] = tempFeatureArray[i];
  777. matchReq.templateLen[i] = tempFeatureLenArray[i];
  778. }
  779. DWORD dwEnd = GetTickCount();
  780. Dbg("copy data to match req, cost time:%dms", dwEnd - dwStart);
  781. Dbg("end copy feature to reqParams");
  782. Dbg("templateNum: %d", matchReq.templateNum);
  783. while (true){
  784. if (m_pFingerPrint == NULL || m_pFingerPrint->QuerySessionClosed()){
  785. Dbg("m_pFingerPrint is NULL or connection closed.");
  786. return Error_Unexpect;
  787. }
  788. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  789. //Sleep(100);//如果指纹仪返回及时,这里可以考虑去掉
  790. DWORD startMatch, endMatch;
  791. startMatch = GetTickCount();
  792. Dbg("begin next invoke match.");
  793. eErr = m_pFingerPrint->Match(matchReq, matchAns, 20000);
  794. endMatch = GetTickCount();
  795. Dbg("MatchTime:%d", endMatch - startMatch);
  796. if (m_bCancelAuthorize || eErr == Error_Cancel){
  797. bStopAuthorize = true;
  798. Dbg("m_bCancelAuthorize=true or m_pFingerPrint->Match return Error_Cancel, closing authorization task and setting m_bCancelAuthorize=false");
  799. m_bCancelAuthorize = false;
  800. if (m_bAuthorizeTimeout){
  801. m_bAuthorizeTimeout = false;
  802. return Error_TimeOut;
  803. }
  804. return Error_Cancel;
  805. }else if (eErr == Error_Unexpect || eErr == Error_TimeOut){//调用指纹仪接口失败,但可以立即进行下一次授权
  806. Dbg("#################### Invoke Match Error %d ######################", eErr);
  807. BroadcastGetFinger(2);//调用match出错
  808. }else if (eErr == Error_Succeed){//指纹仪成功返回匹配结果数组
  809. Dbg("#################### Match Result Received And Analyzing ######################");
  810. int resTemplateNum = matchAns.result.GetCount();
  811. if (resTemplateNum != count){
  812. Dbg("Ans match result template num is not equale to the Req's ");
  813. continue;
  814. }
  815. int matchIndex = -1;//匹配的CustomerID对应的下标
  816. int matchCount = 0;//匹配的CustomerID个数
  817. int m = 0;
  818. int fingerNum = fingerCount[m].TemplateNum;
  819. for(int i = 0; i < resTemplateNum; i += fingerNum){
  820. //单人有多指纹匹配不报错(可能多个指纹都用同一个手指注册的)
  821. //Dbg("i=%d", i);
  822. int oneCustMatchResult = 0;
  823. fingerNum = fingerCount[m].TemplateNum;
  824. for(int j = 0; j < fingerNum; ++j){
  825. oneCustMatchResult += matchAns.result[i+j];
  826. }
  827. //Dbg("oneCustMatcnResult=%d", oneCustMatchResult);
  828. if(oneCustMatchResult > 0){//同一个CustomerID的指纹如果有多个匹配,算作一个
  829. matchCount++;
  830. matchIndex = m;
  831. }
  832. if(matchCount > 1){//有多个CustomerID的指纹都匹配上,则是多匹配
  833. break;
  834. }
  835. m++;
  836. }
  837. int matchResult = matchCount;//0:no match; 1:just one match; 2: muti match
  838. if (m_bCancelAuthorize){
  839. bStopAuthorize = true;
  840. Dbg("m_bCancelAuthorize=true, closing authorization task and setting m_bCancelAuthorize=false");
  841. m_bCancelAuthorize = false;
  842. if (m_bAuthorizeTimeout){
  843. m_bAuthorizeTimeout = false;
  844. return Error_TimeOut;
  845. }else
  846. return Error_Cancel;
  847. }
  848. //根据返回匹配结果数组,判断发送指纹授权失败提示广播还是授权结果广播
  849. switch (matchResult)
  850. {
  851. case 0:
  852. {
  853. Dbg("MatchResult: 0| no match");
  854. BroadcastGetFinger(0);
  855. }
  856. break;
  857. case 1:
  858. {
  859. Dbg("MatchResult: 1| one and only one match, authorize done.");
  860. Dbg("Match Finger(CustomerID=%s)", (const char*)fingerCount[matchIndex].CustomerID);
  861. m_authCtx.eAuthByWhich = AuthByFngPrnt;
  862. m_authCtx.CustomerID = fingerCount[matchIndex].CustomerID;
  863. bStopAuthorize = true;
  864. return Error_Succeed;
  865. }
  866. break;
  867. case 2:
  868. {
  869. Dbg("MatchResult: 2| two and more matches. be alerted");
  870. BroadcastGetFinger(1);
  871. }
  872. break;
  873. default:break;
  874. }
  875. }else{//指纹仪match返回其他错误(eg:Error_NotInit,Error_Param),不再调用指纹仪实体的match
  876. Dbg("Invoke Match Error %d, Stopping FingerPrint-Authorization", eErr);
  877. return Error_Unexpect;
  878. }
  879. }
  880. }
  881. ErrorCodeEnum CCustMngrAuthFSM::WaitForUkey(ErrorCodeEnum eErr)
  882. {
  883. int status = (eErr == Error_NoTarget) ? 4: 3;//与朱毅约定,4表示本地无指纹数据,3表示指纹仪实体异常,前端给予提示
  884. BroadcastGetFinger(status);
  885. while(1){
  886. std::this_thread::sleep_for(std::chrono::milliseconds(300));
  887. //Sleep(300);
  888. if (m_bCancelAuthorize){
  889. m_bCancelAuthorize = false;
  890. if (m_bAuthorizeTimeout){
  891. m_bAuthorizeTimeout = false;
  892. return Error_TimeOut;
  893. }else
  894. return Error_Cancel;
  895. }
  896. }
  897. }
  898. void CCustMngrAuthFSM::CancelAuthorize()
  899. {
  900. Dbg("Invoke m_pFingerPrint->CancelMatch()");
  901. if (m_pFingerPrint != NULL && !m_pFingerPrint->QuerySessionClosed())
  902. m_pFingerPrint->CancelMatch();
  903. }
  904. void CCustMngrAuthFSM::BroadcastPressFinger(int times, bool bPressFinger)
  905. {
  906. if(bPressFinger){
  907. PressFinger pfEvt;//
  908. pfEvt.FingerNo = 1;//maybe no use,control by @zhuyi
  909. pfEvt.Times = times;
  910. SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(PressFinger), SP_MSG_SIG_OF(PressFinger), pfEvt);
  911. }else{
  912. LiftFinger lfEvt;
  913. lfEvt.FingerNo = 1;
  914. lfEvt.Times = times;
  915. SpSendBroadcast(m_pEntity->GetFunction(), SP_MSG_OF(LiftFinger), SP_MSG_SIG_OF(LiftFinger), lfEvt);
  916. }
  917. }
  918. void CCustMngrAuthFSM::BroadcastGetFinger(int status)
  919. {
  920. GetFinger evt;
  921. evt.Status = status;
  922. SpSendBroadcast(GetEntityBase()->GetFunction(), SP_MSG_OF(GetFinger),SP_MSG_SIG_OF(GetFinger),evt);
  923. }
  924. ErrorCodeEnum CCustMngrAuthFSM::CollectFingerPrint(SpReqAnsContext<CustMngrAuthService_CollectFingerPrint_Req, CustMngrAuthService_CollectFingerPrint_Ans>::Pointer ctx, DWORD& dwUserErrCode)
  925. {
  926. LOG_FUNCTION();
  927. ErrorCodeEnum eErr;
  928. m_pFingerPrint = new FingerPrintService_ClientBase(GetEntityBase());
  929. eErr = m_pFingerPrint->Connect();
  930. if (eErr!= Error_Succeed)
  931. {
  932. m_pFingerPrint->SafeDelete();
  933. m_pFingerPrint = NULL;
  934. return Error_NoTarget;
  935. }
  936. //need to collect for 3 times
  937. const int NUM_COLLECT = 3;
  938. ctx->Ans.FingerImgs.Init(NUM_COLLECT);
  939. CAutoArray<CSimpleStringA> imgPaths;
  940. CSimpleStringA strPath;
  941. imgPaths.Init(NUM_COLLECT);
  942. m_pEntity->GetFunction()->GetPath("Dep", strPath);
  943. int getImgNum = 0;
  944. for(int i = 0; i < NUM_COLLECT; ++i){
  945. if (i) {
  946. std::this_thread::sleep_for(std::chrono::milliseconds(2000));
  947. //Sleep(2 * 1000);//internal for 2s between two times(actually finger entity cannot detect finger lift or not)
  948. }
  949. BroadcastPressFinger(i+1, true);//press finger
  950. FingerPrintService_GetImageAndFeature_Req gifReq;
  951. FingerPrintService_GetImageAndFeature_Ans gifAns;
  952. gifReq.times = i+1;//the num from 1 start , 1/2/3
  953. if (m_pFingerPrint == NULL || m_pFingerPrint->QuerySessionClosed()){
  954. Dbg("m_pFingerPrint is NULL or connection closed.");
  955. return Error_NoTarget;
  956. }
  957. eErr = m_pFingerPrint->GetImageAndFeature(gifReq, gifAns, 16000, dwUserErrCode);//fingerprint entity loop duration is 15s
  958. if (eErr == Error_Succeed){
  959. getImgNum += 1;
  960. BroadcastPressFinger(i+1, false);//lift finger
  961. CBlob data;
  962. CSimpleStringA tempFullPath;
  963. tempFullPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  964. , (const char*)strPath, (const char*)gifAns.imageName);
  965. eErr = GetImgBlob(data, tempFullPath);
  966. if (eErr != Error_Succeed){
  967. Dbg("Failed to load finger image.");
  968. break;
  969. }
  970. switch(i)
  971. {
  972. case 0:
  973. ctx->Ans.FingerImg1 = data;
  974. break;
  975. case 1:
  976. ctx->Ans.FingerImg2 = data;
  977. break;
  978. case 2:
  979. ctx->Ans.FingerImg3 = data;
  980. break;
  981. }
  982. ctx->Ans.FingerImgs[i] = data;
  983. imgPaths[i] = gifAns.imageName;
  984. }
  985. else
  986. {
  987. Dbg("failed to collect fingerprint %th times, also failed to generate template failed.");
  988. break;
  989. }
  990. //third times, get th template success
  991. if (i == (NUM_COLLECT-1)){
  992. ctx->Ans.feature = gifAns.feature;
  993. }
  994. }
  995. //delete bmp files in dep
  996. for (int j = 0; j < getImgNum; ++j)
  997. {
  998. CSimpleStringA tempFullPath(true);
  999. tempFullPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s"
  1000. , (const char*)strPath, (const char*)imgPaths[j]);
  1001. if(remove((const char*)tempFullPath) == 0)
  1002. Dbg("finger image %s deleted!", (const char*)tempFullPath);
  1003. else
  1004. Dbg("fail to delete image %s!", (const char*)tempFullPath);
  1005. }
  1006. if (eErr == Error_Succeed){
  1007. Dbg("Register FingerPrint successfully.");
  1008. return Error_Succeed;
  1009. }else{
  1010. Dbg("Register FingerPrint failed!");
  1011. return Error_Unexpect;
  1012. }
  1013. }
  1014. ErrorCodeEnum CCustMngrAuthFSM::SaveFingerPrint(SpReqAnsContext<CustMngrAuthService_SaveFingerPrint_Req, CustMngrAuthService_SaveFingerPrint_Ans>::Pointer ctx)
  1015. {
  1016. LOG_FUNCTION();
  1017. EnterCriticalSection(&m_cs);
  1018. CSmartPointer<IConfigInfo> spConfig;
  1019. Json::FastWriter writer;
  1020. ErrorCodeEnum eErr;
  1021. eErr = GetEntityBase()->GetFunction()->OpenConfig(Config_Run, spConfig);
  1022. if (eErr != Error_Succeed){
  1023. Dbg("ERROR: open config failed! eErr: %d", eErr);
  1024. LogError(Severity_High, Error_DevLoadFileFailed, LOG_ERR_CUSTMNGRAUTH_OPEN_RUNINFO_FAILED_SAVEFINGERPRINT, "open runinfo file failed while save data to local.");
  1025. LeaveCriticalSection(&m_cs);
  1026. return Error_Unexpect;
  1027. }
  1028. Dbg("open Config_Run succeed, prepare to write feature data.");
  1029. Json::Value fingerInfo;
  1030. int fingerIDNum = ctx->Req.FingerIdList.GetCount();
  1031. FeatureData *fd = new FeatureData();
  1032. Dbg("FingerIDNum=%d", fingerIDNum);
  1033. fd->FingerIDArray.Init(fingerIDNum);
  1034. fd->FingerIDLenArray.Init(fingerIDNum);
  1035. for (int i = 0; i < fingerIDNum; ++i){
  1036. char a[20]={0};
  1037. _snprintf_s(a, 10,"FingerID%d", ctx->Req.FingerIdList[i]);
  1038. Dbg("writing %s",a);
  1039. fingerInfo[a] = (const char*)ctx->Req.FPFeatureList[i];
  1040. fd->FingerIDArray[i] = ctx->Req.FPFeatureList[i];
  1041. fd->FingerIDLenArray[i] = fd->FingerIDArray[i].GetLength();
  1042. }
  1043. if(m_featureData.find(ctx->Req.CustomerID) == m_featureData.end()){//不存在,直接插入
  1044. m_featureData[ctx->Req.CustomerID] = fd;
  1045. }else{
  1046. auto tempFD = m_featureData[ctx->Req.CustomerID];
  1047. m_featureData[ctx->Req.CustomerID] = fd;
  1048. if(tempFD){
  1049. delete tempFD;
  1050. tempFD = NULL;
  1051. }
  1052. }
  1053. Dbg("jsonvalue for fingerinfo created, writing config value......");
  1054. eErr = spConfig->WriteConfigValue(STR_FINGERINFO, (const char*)ctx->Req.CustomerID, writer.write(fingerInfo).c_str());
  1055. Dbg("spConfig->WriteConfigValue done");
  1056. if (eErr != Error_Succeed){
  1057. Dbg("write data into runinfo failed when commit.");
  1058. LogError(Severity_High, Error_DevLoadFileFailed, LOG_ERR_CUSTMNGRAUTH_REGISTER_WRITE_RUNINFO_FAILED, "write data into runinfo failed when commit.");
  1059. LeaveCriticalSection(&m_cs);
  1060. return Error_Unexpect;
  1061. }
  1062. Dbg("write data into runinfo success when commit.");
  1063. LeaveCriticalSection(&m_cs);
  1064. return eErr;
  1065. }
  1066. ErrorCodeEnum CCustMngrAuthFSM::SwitchUSB(bool bOpen)
  1067. {
  1068. LOG_FUNCTION();
  1069. ErrorCodeEnum eErr;
  1070. //connect devicecontrol and open usb
  1071. Dbg("connecting DeviceControl");
  1072. m_pDeviceControl = new DeviceControlService_ClientBase(GetEntityBase());
  1073. if(m_pDeviceControl != NULL){
  1074. eErr = m_pDeviceControl->Connect();
  1075. if (eErr != Error_Succeed){
  1076. Dbg("m_pDeviceControl connect failed with eErr %x0x", eErr);
  1077. }else{
  1078. if(bOpen)
  1079. Dbg("Open USB");
  1080. else
  1081. Dbg("Close USB");
  1082. DeviceControlService_USB_Req usbReq;
  1083. DeviceControlService_USB_Ans usbAns;
  1084. usbReq.open = bOpen;//open or close usb
  1085. eErr = m_pDeviceControl->USB(usbReq, usbAns, 2000);
  1086. if (eErr != Error_Succeed)
  1087. Dbg("Open/Close usb failed.");
  1088. else
  1089. Dbg("Open/Close usb success.");
  1090. m_pDeviceControl->GetFunction()->CloseSession();
  1091. }
  1092. m_pDeviceControl->SafeDelete();
  1093. m_pDeviceControl = NULL;
  1094. return eErr;
  1095. }else{
  1096. Dbg("DeviceControl is null.");
  1097. return Error_Unexpect;
  1098. }
  1099. }
  1100. ErrorCodeEnum CCustMngrAuthFSM::GetImgBlob(CBlob &data, CSimpleStringA imgPath)
  1101. {
  1102. Dbg("########Openning imgpath: %s", (const char*)imgPath);
  1103. ErrorCodeEnum eErr;
  1104. FILE *fp = fopen(imgPath, "rb");
  1105. if (fp) {
  1106. Dbg("fopen succeed.");
  1107. fseek(fp, 0, SEEK_END);
  1108. long flen = ftell(fp);
  1109. fseek(fp, 0, SEEK_SET);
  1110. data.Alloc(flen);
  1111. fread(data.m_pData, 1, flen, fp);
  1112. fclose(fp);
  1113. eErr = Error_Succeed;
  1114. }else{
  1115. Dbg("fopen %s failed!", (LPCSTR)imgPath);
  1116. eErr = Error_IO;
  1117. }
  1118. return eErr;
  1119. }
  1120. int CCustMngrAuthFSM::CompareTime(CSimpleStringA time1, CSimpleStringA time2)
  1121. {
  1122. //这里只比较是否是同一天
  1123. if (time1.GetLength() > 0 && time2.GetLength() > 0)
  1124. {
  1125. int year1 = atoi((const char*)time1.SubString(0, 4));
  1126. int month1 = atoi((const char*)time1.SubString(4, 2));
  1127. int day1 = atoi((const char*)time1.SubString(6, 2));
  1128. int year2 = atoi((const char*)time2.SubString(0, 4));
  1129. int month2 = atoi((const char*)time2.SubString(4, 2));
  1130. int day2 = atoi((const char*)time2.SubString(6, 2));
  1131. int temp1 = year1 * 10000 + month1 * 100 + day1;
  1132. int temp2 = year2 * 10000 + month2 * 100 + day2;
  1133. if (temp1 > temp2)
  1134. {
  1135. return 1;
  1136. }
  1137. else if(temp1 < temp2)
  1138. {
  1139. return -1;
  1140. }
  1141. else
  1142. {
  1143. return 0;
  1144. }
  1145. }
  1146. return 0;
  1147. }
  1148. int CCustMngrAuthFSM::RecoverFile(CSimpleStringA nowFileName, CSimpleStringA backupFileName)
  1149. {
  1150. ofstream fileOut((const char*)nowFileName, ios::trunc);
  1151. ifstream fileIn((const char*)backupFileName);
  1152. if (!(fileOut.fail() || fileIn.fail()))
  1153. {
  1154. fileOut << fileIn.rdbuf();
  1155. fileOut.close();
  1156. fileIn.close();
  1157. return 0;
  1158. }
  1159. fileOut.close();
  1160. fileIn.close();
  1161. return -1;
  1162. }
  1163. CSimpleStringA CCustMngrAuthFSM::GetCurrentDate()
  1164. {
  1165. time_t curTime = time(NULL);
  1166. tm* p = localtime(&curTime);
  1167. char cTime[100];
  1168. sprintf(cTime, "%d%02d%02d", p->tm_year+1900, p->tm_mon+1, p->tm_mday);
  1169. CSimpleStringA curDate(cTime);
  1170. return curDate;
  1171. }
  1172. CSimpleStringA CCustMngrAuthFSM::GetMaxTime(CSimpleStringA maxTime, CSimpleStringA tempTime)
  1173. {
  1174. if (tempTime.GetLength() > 0){
  1175. if (maxTime.GetLength() <= 0){
  1176. maxTime = tempTime;
  1177. }else{
  1178. int compareResult = CompareUpdateTime((const char*)maxTime, (const char*)tempTime);
  1179. if (compareResult == 0){
  1180. maxTime = tempTime;
  1181. }
  1182. }
  1183. }
  1184. return maxTime;
  1185. }
  1186. int CCustMngrAuthFSM::CompareUpdateTime(const char* time1, const char* time2)
  1187. {
  1188. int year1, month1, day1, hour1, minute1, second1;
  1189. int year2, month2, day2, hour2, minute2, second2;
  1190. sscanf(time1, "%d-%d-%d %d:%d:%d", &year1, &month1, &day1, &hour1, &minute1, &second1);
  1191. sscanf(time2, "%d-%d-%d %d:%d:%d", &year2, &month2, &day2, &hour2, &minute2, &second2);
  1192. int tm1 = year1 * 10000 + month1 * 100 + day1;
  1193. int tm2 = year2 * 10000 + month2 * 100 + day2;
  1194. if(tm1 != tm2)
  1195. return (tm1 > tm2) ? 1 : 0;
  1196. tm1 = hour1 * 3600 + minute1 * 60 + second1;
  1197. tm2 = hour2 * 3600 + minute2 * 60 + second2;
  1198. if(tm1 != tm2)
  1199. return (tm1 > tm2) ? 1 : 0;
  1200. return 2;
  1201. }
  1202. int CCustMngrAuthFSM::getDuration(SYSTEMTIME time1, SYSTEMTIME time2)
  1203. {
  1204. ULARGE_INTEGER fTime1;/*FILETIME*/
  1205. ULARGE_INTEGER fTime2;/*FILETIME*/
  1206. SystemTimeToFileTime(&time1, (FILETIME*)&fTime1);
  1207. SystemTimeToFileTime(&time2, (FILETIME*)&fTime2);
  1208. unsigned __int64 dft = fTime2.QuadPart - fTime1.QuadPart;
  1209. return dft / 10000;
  1210. }
  1211. std::string CCustMngrAuthFSM::formatTime(SYSTEMTIME time)
  1212. {
  1213. char tBuf[1024] = "";
  1214. sprintf(tBuf, "%04u-%02u-%02u %02u:%02u:%02u:%03u", time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);
  1215. return tBuf;
  1216. }
  1217. CSimpleString CCustMngrAuthFSM::generateAlarmJson(CSimpleString entityName, CSimpleString startTime, int cost)
  1218. {
  1219. return CSimpleString::Format("[{\"name\":\"%s\",\"time\":\"%s\",\"cost\":%d}]", entityName.GetData(), startTime.GetData(), cost);
  1220. }