599 lines
17 KiB
C++
599 lines
17 KiB
C++
#include <SmingCore.h>
|
|
#include <Crypto/Sha2.h>
|
|
#include "utils.h"
|
|
#include "main.h"
|
|
#include "FingerPrint.h"
|
|
#include "FingerLogic.h"
|
|
|
|
CFingerLogic::CFingerLogic(CMain *pMain)
|
|
{
|
|
m_pFingerPrint = NULL;
|
|
m_State = STATE_INITIAL;
|
|
m_Finger = false;
|
|
m_Power = false;
|
|
m_pMain = pMain;
|
|
|
|
memset(&m_FingerParams, 0, sizeof(m_FingerParams));
|
|
memset(m_aFingerSlots, 0, sizeof(m_aFingerSlots));
|
|
m_FingerSlotsAdded = 0;
|
|
|
|
m_PowerOffTimer.initializeMs(1000, TimerDelegate(&CFingerLogic::PowerOff, this));
|
|
}
|
|
|
|
void CFingerLogic::Init(CFingerPrint *pFingerPrint)
|
|
{
|
|
m_pFingerPrint = pFingerPrint;
|
|
|
|
InitFinger();
|
|
}
|
|
|
|
void CFingerLogic::SetState(FingerLogicState state)
|
|
{
|
|
m_State = state;
|
|
|
|
if(m_State == STATE_READY || m_State == STATE_ERROR)
|
|
m_PowerOffTimer.start(false);
|
|
else
|
|
{
|
|
m_PowerOffTimer.stop();
|
|
PowerOn();
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::PowerOff()
|
|
{
|
|
if(!m_Power)
|
|
return;
|
|
|
|
debugf("PowerOff()");
|
|
m_Power = false;
|
|
Main().FingerEnable(false);
|
|
wifi_set_sleep_type(LIGHT_SLEEP_T);
|
|
system_soft_wdt_feed();
|
|
}
|
|
|
|
void CFingerLogic::PowerOn()
|
|
{
|
|
if(m_Power)
|
|
return;
|
|
|
|
debugf("PowerOn()");
|
|
m_Power = true;
|
|
Main().FingerEnable(true);
|
|
wifi_set_sleep_type(MODEM_SLEEP_T);
|
|
delayMilliseconds(100);
|
|
}
|
|
|
|
void CFingerLogic::OnFingerInterrupt(bool finger)
|
|
{
|
|
debugf("OnFingerInterrupt: %s", finger ? "DOWN" : "UP");
|
|
m_Finger = finger;
|
|
|
|
if(finger)
|
|
{
|
|
if(m_State == STATE_READY)
|
|
VerifyFinger();
|
|
else if(m_State == STATE_ENROLL_WAITFINGER1 || m_State == STATE_ENROLL_WAITFINGER2)
|
|
EnrollFinger_OnFinger();
|
|
}
|
|
}
|
|
|
|
bool CFingerLogic::FingerSlot(uint16_t index)
|
|
{
|
|
if(index > m_FingerSlotsAdded)
|
|
return false;
|
|
|
|
return m_aFingerSlots[index / 8] & (1 << (index % 8));
|
|
}
|
|
|
|
bool CFingerLogic::FingerSlot(uint16_t index, bool value)
|
|
{
|
|
if(index > m_FingerSlotsAdded)
|
|
return false;
|
|
|
|
if(value)
|
|
m_aFingerSlots[index / 8] |= (1 << (index % 8));
|
|
else
|
|
m_aFingerSlots[index / 8] &= ~(1 << (index % 8));
|
|
return true;
|
|
}
|
|
|
|
int CFingerLogic::FirstFreeFingerSlot()
|
|
{
|
|
for(int i = 0; i < m_FingerSlotsAdded / 8; i++)
|
|
{
|
|
if(m_aFingerSlots[i] != 0xFF)
|
|
{
|
|
uint8_t val = m_aFingerSlots[i];
|
|
for(int j = 0; j < 8; j++)
|
|
{
|
|
if(!(val & (1 << j)))
|
|
return (i * 8) + j;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
void CFingerLogic::InitFinger()
|
|
{
|
|
if(m_State > STATE_INIT_VERIFYPASSWORD)
|
|
return;
|
|
|
|
SetState(STATE_INIT_VERIFYPASSWORD);
|
|
FingerPrint().AsyncVerifyPassword((VerifyPasswordCallback)InitFinger_OnVerifyPassword, this);
|
|
|
|
m_Timer.initializeMs(100, TimerDelegate(&CFingerLogic::InitFinger, this)).start();
|
|
}
|
|
|
|
void CFingerLogic::InitFinger_OnVerifyPassword(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
pThis->m_Timer.stop();
|
|
debugf("InitFinger_OnVerifyPassword: (%d) %s", error, errorStr);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_INIT_READSYSTEMPARAMETERS);
|
|
pThis->FingerPrint().AsyncReadSystemParameters((ReadSystemParametersCallback)InitFinger_OnReadSystemParameters, pThis);
|
|
}
|
|
else
|
|
pThis->SetState(STATE_ERROR);
|
|
}
|
|
|
|
void CFingerLogic::InitFinger_OnReadSystemParameters(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, CFingerSystemParameters *param)
|
|
{
|
|
debugf("InitFinger_OnReadSystemParameters: (%d) %s", error, errorStr);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
memcpy(&pThis->m_FingerParams, param, sizeof(CFingerSystemParameters));
|
|
debugf("statusRegister: %d", param->statusRegister);
|
|
debugf("systemID: %d", param->systemID);
|
|
debugf("storageCapacity: %d", param->storageCapacity);
|
|
debugf("securityLevel: %d", param->securityLevel);
|
|
debugf("deviceAddress: %X", param->deviceAddress);
|
|
debugf("packetLength: %d", param->packetLength);
|
|
debugf("baudRate: %d", param->baudRate);
|
|
|
|
pThis->SetState(STATE_INIT_READTEMPLATEMAP);
|
|
pThis->FingerPrint().AsyncReadTemplateMap((ReadTemplateMapCallback)InitFinger_OnReadTemplateMap, pThis, 0);
|
|
}
|
|
else
|
|
pThis->SetState(STATE_ERROR);
|
|
}
|
|
|
|
void CFingerLogic::InitFinger_OnReadTemplateMap(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, uint8_t *pData, uint16_t dataLen)
|
|
{
|
|
debugf("InitFinger_OnReadTemplateMap: (%d) %s (%p, %d)", error, errorStr, pData, dataLen);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
memcpy(&pThis->m_aFingerSlots[pThis->m_FingerSlotsAdded/8], pData, dataLen);
|
|
pThis->m_FingerSlotsAdded += dataLen * 8;
|
|
|
|
if(pThis->m_FingerSlotsAdded < pThis->m_FingerParams.storageCapacity)
|
|
{
|
|
uint8_t page = pThis->m_FingerSlotsAdded / 8 / dataLen;
|
|
pThis->FingerPrint().AsyncReadTemplateMap((ReadTemplateMapCallback)InitFinger_OnReadTemplateMap, pThis, page);
|
|
}
|
|
else
|
|
{
|
|
pThis->InitFinger_VerifyTemplates();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::InitFinger_VerifyTemplates()
|
|
{
|
|
SetState(STATE_INIT_VERIFYTEMPLATES);
|
|
|
|
HashMap<uint16_t, CSettings::CFingerPrint> &fingerMap = Main().Settings().m_FingerPrints;
|
|
uint16_t fingerCount = fingerMap.count();
|
|
|
|
// Check consistency (1)
|
|
for(uint16_t i = 0; i < fingerCount; i++)
|
|
{
|
|
uint16_t id = fingerMap.keyAt(i);
|
|
if(!FingerSlot(id))
|
|
{
|
|
SetState(STATE_ERROR);
|
|
FingerPrint().EmptyDatabase();
|
|
fingerMap.clear();
|
|
Main().Settings().Save();
|
|
debugf("InitFinger_VerifyTemplates: INCONSITENCY(1) AT SLOT %d !!!", id);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Check consistency (2)
|
|
for(uint16_t id = 0; id < m_FingerSlotsAdded; id++)
|
|
{
|
|
if(FingerSlot(id) && !fingerMap.contains(id))
|
|
{
|
|
SetState(STATE_ERROR);
|
|
FingerPrint().EmptyDatabase();
|
|
fingerMap.clear();
|
|
Main().Settings().Save();
|
|
debugf("InitFinger_VerifyTemplates: INCONSITENCY(2) AT SLOT %d !!!", id);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(!fingerCount)
|
|
{
|
|
SetState(STATE_READY);
|
|
return;
|
|
}
|
|
|
|
m_iBuffer = 0;
|
|
uint16_t position = fingerMap.keyAt(m_iBuffer);
|
|
FingerPrint().AsyncLoadTemplate((LoadTemplateCallback)InitFinger_OnLoadTemplate, this, position, 0x01);
|
|
}
|
|
|
|
void CFingerLogic::InitFinger_OnLoadTemplate(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("InitFinger_OnLoadTemplate: (%d) %s", error, errorStr);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->FingerPrint().AsyncDownloadCharacteristics((DownloadCharacteristicsCallback)InitFinger_OnDownloadCharacteristics, pThis, 0x01);
|
|
}
|
|
else
|
|
pThis->SetState(STATE_ERROR);
|
|
}
|
|
|
|
void CFingerLogic::InitFinger_OnDownloadCharacteristics(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, int8_t *pChar, uint16_t charLen)
|
|
{
|
|
debugf("InitFinger_OnDownloadCharacteristics: (%d) %s (%p, %d)", error, errorStr, pChar, charLen);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
Crypto::Sha256 ctx;
|
|
ctx.update(pChar, charLen);
|
|
uint8_t *digest = ctx.getHash().data();
|
|
|
|
const CSettings::CFingerPrint &finger = pThis->Main().Settings().m_FingerPrints.valueAt(pThis->m_iBuffer);
|
|
|
|
char aHexDigest1[SHA256_SIZE*2+1];
|
|
char aHexDigest2[SHA256_SIZE*2+1];
|
|
bytes2hex(digest, sizeof(digest), aHexDigest1, sizeof(aHexDigest1));
|
|
bytes2hex(finger.m_aDigest, sizeof(finger.m_aDigest), aHexDigest2, sizeof(aHexDigest2));
|
|
|
|
debugf("Index: %d -> Num: %d \"%s\" (%s ?= %s)", pThis->m_iBuffer, finger.m_FingerNum, finger.m_aLabel, aHexDigest1, aHexDigest2);
|
|
|
|
if(memcmp(digest, finger.m_aDigest, SHA256_SIZE) != 0)
|
|
{
|
|
pThis->SetState(STATE_ERROR);
|
|
debugf("InitFinger_VerifyTemplates: DIVERGENT DIGEST AT SLOT %d !!!", pThis->m_iBuffer);
|
|
return;
|
|
}
|
|
|
|
pThis->m_iBuffer++;
|
|
if(pThis->m_iBuffer >= pThis->Main().Settings().m_FingerPrints.count())
|
|
{
|
|
debugf("InitFinger_VerifyTemplates: DONE! Verified %d templates.", pThis->m_iBuffer);
|
|
pThis->SetState(STATE_READY);
|
|
return;
|
|
}
|
|
|
|
uint16_t position = pThis->Main().Settings().m_FingerPrints.keyAt(pThis->m_iBuffer);
|
|
pThis->FingerPrint().AsyncLoadTemplate((LoadTemplateCallback)InitFinger_OnLoadTemplate, pThis, position, 0x01);
|
|
}
|
|
else
|
|
pThis->SetState(STATE_ERROR);
|
|
}
|
|
|
|
|
|
void CFingerLogic::VerifyFinger()
|
|
{
|
|
if(m_State != STATE_READY)
|
|
return;
|
|
|
|
SetState(STATE_VERIFY_READIMAGE);
|
|
FingerPrint().AsyncReadImage((ReadImageCallback)VerifyFinger_OnReadImage, this);
|
|
}
|
|
|
|
void CFingerLogic::VerifyFinger_OnReadImage(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("VerifyFinger_OnReadImage: (%d) %s", error, errorStr);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_VERIFY_CONVERTIMAGE);
|
|
pThis->FingerPrint().AsyncConvertImage((ConvertImageCallback)VerifyFinger_OnConvertImage, pThis, 0x01);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_READY);
|
|
if(pThis->m_Finger)
|
|
pThis->VerifyFinger();
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::VerifyFinger_OnConvertImage(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("VerifyFinger_OnConvertImage: (%d) %s", error, errorStr);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_VERIFY_SEARCHTEMPLATE);
|
|
pThis->FingerPrint().AsyncSearchTemplate((SearchTemplateCallback)VerifyFinger_OnSearchTemplate, pThis, 0x01, 0, pThis->m_FingerParams.storageCapacity);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_READY);
|
|
if(pThis->m_Finger)
|
|
pThis->VerifyFinger();
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::VerifyFinger_OnSearchTemplate(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, int16_t position, int16_t score)
|
|
{
|
|
debugf("VerifyFinger_OnSearchTemplate: (%d) %s (%d, %d)", error, errorStr, position, score);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->m_iBuffer = position;
|
|
pThis->SetState(STATE_VERIFY_LOADTEMPLATE);
|
|
pThis->FingerPrint().AsyncLoadTemplate((LoadTemplateCallback)VerifyFinger_OnLoadTemplate, pThis, position, 0x01);
|
|
}
|
|
else
|
|
pThis->SetState(STATE_READY);
|
|
}
|
|
|
|
void CFingerLogic::VerifyFinger_OnLoadTemplate(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("VerifyFinger_OnLoadTemplate: (%d) %s", error, errorStr);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_VERIFY_DOWNLOADCHARACTERISTICS);
|
|
pThis->FingerPrint().AsyncDownloadCharacteristics((DownloadCharacteristicsCallback)VerifyFinger_OnDownloadCharacteristics, pThis, 0x01);
|
|
}
|
|
else
|
|
pThis->SetState(STATE_READY);
|
|
}
|
|
|
|
void CFingerLogic::VerifyFinger_OnDownloadCharacteristics(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, int8_t *pChar, uint16_t charLen)
|
|
{
|
|
debugf("VerifyFinger_OnDownloadCharacteristics: (%d) %s (%p, %d)", error, errorStr, pChar, charLen);
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
Crypto::Sha256 ctx;
|
|
ctx.update(pChar, charLen);
|
|
uint8_t *digest = ctx.getHash().data();
|
|
|
|
char aHexDigest[SHA256_SIZE*2+1];
|
|
bytes2hex(digest, sizeof(digest), aHexDigest, sizeof(aHexDigest));
|
|
|
|
debugf("Finger hexdigest: %s", aHexDigest);
|
|
|
|
pThis->Main().OnFingerVerified(pThis->m_iBuffer, digest);
|
|
}
|
|
|
|
pThis->SetState(STATE_READY);
|
|
}
|
|
|
|
|
|
bool CFingerLogic::EnrollFinger(bool cancel)
|
|
{
|
|
if(cancel)
|
|
{
|
|
if(m_State < STATE_ENROLL_WAITFINGER1 || m_State > STATE_ENROLL_DOWNLOADCHARACTERISTICS)
|
|
return false;
|
|
|
|
SetState(STATE_READY);
|
|
return true;
|
|
}
|
|
|
|
if(m_State != STATE_READY)
|
|
return false;
|
|
|
|
SetState(STATE_ENROLL_WAITFINGER1);
|
|
if(m_Finger)
|
|
EnrollFinger_OnFinger();
|
|
|
|
return true;
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnFinger()
|
|
{
|
|
if(m_State == STATE_ENROLL_WAITFINGER1)
|
|
{
|
|
SetState(STATE_ENROLL_READIMAGE1);
|
|
FingerPrint().AsyncReadImage((ReadImageCallback)EnrollFinger_OnReadImage1, this);
|
|
}
|
|
else if(m_State == STATE_ENROLL_WAITFINGER2)
|
|
{
|
|
SetState(STATE_ENROLL_READIMAGE2);
|
|
FingerPrint().AsyncReadImage((ReadImageCallback)EnrollFinger_OnReadImage2, this);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnReadImage1(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("EnrollFinger_OnReadImage1: (%d) %s", error, errorStr);
|
|
if(pThis->m_State != STATE_ENROLL_READIMAGE1) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_ENROLL_CONVERTIMAGE1);
|
|
pThis->FingerPrint().AsyncConvertImage((ConvertImageCallback)EnrollFinger_OnConvertImage1, pThis, 0x01);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_ENROLL_WAITFINGER1);
|
|
char aBuf[512];
|
|
m_snprintf(aBuf, sizeof(aBuf), "Error while scanning finger: %s<br>Lift your finger and try again.", errorStr);
|
|
pThis->Main().EnrollMessage(aBuf);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnConvertImage1(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("EnrollFinger_OnConvertImage1: (%d) %s", error, errorStr);
|
|
if(pThis->m_State != STATE_ENROLL_CONVERTIMAGE1) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_ENROLL_SEARCHTEMPLATE);
|
|
pThis->FingerPrint().AsyncSearchTemplate((SearchTemplateCallback)EnrollFinger_OnSearchTemplate, pThis, 0x01, 0, pThis->m_FingerParams.storageCapacity);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_ENROLL_WAITFINGER1);
|
|
char aBuf[512];
|
|
m_snprintf(aBuf, sizeof(aBuf), "Error while analyzing finger: %s<br>Lift your finger and try again.", errorStr);
|
|
pThis->Main().EnrollMessage(aBuf);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnSearchTemplate(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, int16_t position, int16_t score)
|
|
{
|
|
debugf("EnrollFinger_OnSearchTemplate: (%d) %s (%d, %d)", error, errorStr, position, score);
|
|
if(pThis->m_State != STATE_ENROLL_SEARCHTEMPLATE) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_READY);
|
|
pThis->Main().EnrollMessage("Aborting: This finger is already enrolled!", true);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_ENROLL_WAITFINGER2);
|
|
pThis->Main().EnrollMessage("Finger scanned. Lift finger and place it on the sensor again to enroll.");
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnReadImage2(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("EnrollFinger_OnReadImage2: (%d) %s", error, errorStr);
|
|
if(pThis->m_State != STATE_ENROLL_READIMAGE2) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_ENROLL_CONVERTIMAGE2);
|
|
pThis->FingerPrint().AsyncConvertImage((ConvertImageCallback)EnrollFinger_OnConvertImage2, pThis, 0x02);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_ENROLL_WAITFINGER2);
|
|
char aBuf[512];
|
|
m_snprintf(aBuf, sizeof(aBuf), "Error while scanning finger: %s<br>Lift your finger and try again.", errorStr);
|
|
pThis->Main().EnrollMessage(aBuf);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnConvertImage2(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("EnrollFinger_OnConvertImage2: (%d) %s", error, errorStr);
|
|
if(pThis->m_State != STATE_ENROLL_CONVERTIMAGE2) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_ENROLL_COMPARE);
|
|
pThis->FingerPrint().AsyncCompareCharacteristics((CompareCharacteristicsCallback)EnrollFinger_OnCompareCharacteristics, pThis);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_ENROLL_WAITFINGER2);
|
|
char aBuf[512];
|
|
m_snprintf(aBuf, sizeof(aBuf), "Error while analyzing finger: %s<br>Lift your finger and try again.", errorStr);
|
|
pThis->Main().EnrollMessage(aBuf);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnCompareCharacteristics(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, int16_t score)
|
|
{
|
|
debugf("EnrollFinger_OnCompareCharacteristics: (%d) %s (%d)", error, errorStr, score);
|
|
if(pThis->m_State != STATE_ENROLL_COMPARE) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_ENROLL_CREATETEMPLATE);
|
|
pThis->FingerPrint().AsyncCreateTemplate((CreateTemplateCallback)EnrollFinger_OnCreateTemplate, pThis);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_ENROLL_WAITFINGER1);
|
|
char aBuf[512];
|
|
m_snprintf(aBuf, sizeof(aBuf), "Error while comparing fingers: %s<br>Lift your finger and try again.", errorStr);
|
|
pThis->Main().EnrollMessage(aBuf);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnCreateTemplate(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("EnrollFinger_OnCreateTemplate: (%d) %s", error, errorStr);
|
|
if(pThis->m_State != STATE_ENROLL_CREATETEMPLATE) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_ENROLL_STORETEMPLATE);
|
|
pThis->m_iBuffer = pThis->FirstFreeFingerSlot();
|
|
pThis->FingerPrint().AsyncStoreTemplate((StoreTemplateCallback)EnrollFinger_OnStoreTemplate, pThis, pThis->m_iBuffer, 0x01);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_READY);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnStoreTemplate(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, uint16_t positionNumber)
|
|
{
|
|
debugf("EnrollFinger_OnStoreTemplate: (%d) %s (%d)", error, errorStr, positionNumber);
|
|
if(pThis->m_State != STATE_ENROLL_STORETEMPLATE) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->FingerSlot(positionNumber, true);
|
|
pThis->SetState(STATE_ENROLL_LOADTEMPLATE);
|
|
pThis->FingerPrint().AsyncLoadTemplate((LoadTemplateCallback)EnrollFinger_OnLoadTemplate, pThis, positionNumber, 0x01);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_READY);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnLoadTemplate(CFingerLogic *pThis, FingerPrintError error, const char *errorStr)
|
|
{
|
|
debugf("EnrollFinger_OnLoadTemplate: (%d) %s", error, errorStr);
|
|
if(pThis->m_State != STATE_ENROLL_LOADTEMPLATE) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
pThis->SetState(STATE_ENROLL_DOWNLOADCHARACTERISTICS);
|
|
pThis->FingerPrint().AsyncDownloadCharacteristics((DownloadCharacteristicsCallback)EnrollFinger_OnDownloadCharacteristics, pThis, 0x01);
|
|
}
|
|
else
|
|
{
|
|
pThis->SetState(STATE_READY);
|
|
}
|
|
}
|
|
|
|
void CFingerLogic::EnrollFinger_OnDownloadCharacteristics(CFingerLogic *pThis, FingerPrintError error, const char *errorStr, int8_t *pChar, uint16_t charLen)
|
|
{
|
|
debugf("EnrollFinger_OnDownloadCharacteristics: (%d) %s (%p, %d)", error, errorStr, pChar, charLen);
|
|
if(pThis->m_State != STATE_ENROLL_DOWNLOADCHARACTERISTICS) return;
|
|
|
|
if(error == ERROR_OK)
|
|
{
|
|
Crypto::Sha256 ctx;
|
|
ctx.update(pChar, charLen);
|
|
uint8_t *digest = ctx.getHash().data();
|
|
|
|
Serial1.printf("NEW Finger %d hexdigest: ", pThis->m_iBuffer);
|
|
for(uint8_t i = 0; i < sizeof(digest); i++)
|
|
Serial1.printf("%x", digest[i]);
|
|
Serial1.printf("\n");
|
|
|
|
pThis->Main().OnFingerEnrolled(pThis->m_iBuffer, digest);
|
|
}
|
|
|
|
pThis->SetState(STATE_READY);
|
|
}
|