You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

515 lines
13 KiB

#include "fingerprint.h"
/*起始帧*/
#define GR_PACK_HEAD 0XEF01
/* 包标识*/
#define GR_PACK_COMMAND_FLAG 0X01
//当为2时,表示后续还有包
#define GR_PACK_DATA_FALG 0X02
#define GR_PACK_ACK_FALG 0X07
#define GR_PACK_END_FALG 0X08
// 包长度 = 数据到校验和之间的长度
// 校验和 = 包标识 ~ 校验和之间的和 ,超两个字节对高位进行忽略
Fingerprint::Fingerprint(Stream *UART, uint32_t ADDRRESS)
{
_uart = UART;
_addr = ADDRRESS;
_headBuffer[0] = 0xEF;
_headBuffer[1] = 0x01;
memcpy(&_headBuffer[2], &_addr, sizeof(_addr));
};
Fingerprint::~Fingerprint(void)
{
};
/*********************
* 0 1 2 3 4 5 6 7 8 9 10 11
* ef 01 ff ff ff ff flag len_h len_l code sum_h sum_l
* *******************/
bool Fingerprint::validSum(uint8_t *resp, uint8_t len)
{
uint16_t sum = 0;
for (int i = 6; i < len - 2; i++) {
sum += resp[i];
}
// Serial.printf("sum:%x -2:%x -1:%x \n", sum, resp[len - 2], resp[len - 1]);
// Serial.printf("merge: %x \n", (resp[len - 2] << 8 | resp[len - 1]));
return sum == (resp[len - 2] << 8 | resp[len - 1]);
}
bool Fingerprint::waitForAck(uint8_t *reqs, uint8_t len)
{
uint32_t i = 0, timerStart = millis();
while (1) {
if (_uart->available()) {
reqs[i++] = _uart->read();
Serial.print(reqs[i - 1], HEX);
Serial.print(" ");
if (i >= len) {
Serial.println();
break;
}
}
if (millis() - timerStart > 1000) {
Serial.printf("time out\n");
return false;
}
}
return true;
}
int Fingerprint::waitForResp(uint8_t respSize, uint32_t timeout)
{
int i = 0;
uint32_t timerStart = millis();
uint8_t response[respSize];
while (1) {
if (_uart->available()) {
response[i++] = _uart->read();
if (i >= sizeof(response))
break;
}
if (millis() - timerStart > 1000 * timeout) {
return -1;
}
}
if (validSum(response, sizeof(response))) {
return response[9];
}
return -1;
}
void Fingerprint::__sendCom(uint8_t command, uint16_t len)
{
uint16_t sum = 0;
uint8_t commandBuffer[6];
commandBuffer[0] = GR_PACK_COMMAND_FLAG;
commandBuffer[1] = (len & 0xFF00) >> 8;
commandBuffer[2] = len & 0xFF;
commandBuffer[3] = command;
for (int i = 0; i < sizeof(commandBuffer) - 2; i++) {
sum += commandBuffer[i];
}
commandBuffer[4] = (sum & 0xFF00) >> 8;
commandBuffer[5] = sum & 0xFF;
_uart->write(_headBuffer, sizeof(_headBuffer));
_uart->write(commandBuffer, sizeof(commandBuffer));
}
/**
* @brief 录入指纹到ImageBuffer
* @note 标准应答格式 12Bytes
* @retval 0H ~ 03H
*/
bool Fingerprint::entryFinger(void)
{
int ret = GR_OK;
__sendCom(GR_GET_IMAGE, 0x03);
ret = waitForResp(12, 15);
if (ret != GR_OK) {
getErrorReason(ret);
}
return ret == GR_OK;
}
void Fingerprint::getErrorReason(int err)
{
// Serial.printf("Error :[%d]\n", err);
switch (err) {
case 0:
break;
}
}
/**
* @brief 生成特征标识
* @note 标准应答格式 12Bytes
* @param id: 01H ~ 02H
* @retval
*/
bool Fingerprint::generateFeature(GR_BufID_t id)
{
int ret = GR_OK;
uint8_t commandBuffer[7];
_uart->write(_headBuffer, 6);
commandBuffer[0] = GR_PACK_COMMAND_FLAG;
commandBuffer[1] = 0x00;
commandBuffer[2] = 0x04;
commandBuffer[3] = GR_GET_CHAR;
commandBuffer[4] = id;
commandBuffer[5] = 0x00;
commandBuffer[6] = 0x07 + id;
_uart->write(commandBuffer, sizeof(commandBuffer));
ret = waitForResp(12, 1);
if (ret != GR_OK) {
getErrorReason(ret);
}
return ret == GR_OK;
}
/**
* @brief 精确比对两枚指纹特征
* @note //! 非标准应答格式 14Bytes
* @retval 0x00 0x01 0x08
*/
bool Fingerprint::matchFingerprint(void)
{
int ret = GR_OK;
__sendCom(GR_MATCH, 0x03);
ret = waitForResp(14, 1);
if (ret != GR_OK) {
getErrorReason(ret);
}
return ret == GR_OK;
}
/**
* @brief 搜索指纹
* @note //! 非标准应答格式 16Bytes
* @retval 确认字,页码(相配指纹模板)
*/
bool Fingerprint::searchFingerprint(GR_BufID_t id, uint16_t sPage, uint16_t pNum)
{
int ret = GR_OK;
uint32_t sum = 0;
uint8_t commandBuffer[11];
_uart->write(_headBuffer, 6);
commandBuffer[0] = GR_PACK_COMMAND_FLAG;
commandBuffer[1] = 0x00;
commandBuffer[2] = 0x08;
commandBuffer[3] = GR_SEARCH;
commandBuffer[4] = id;
commandBuffer[5] = (sPage & 0xFF00) >> 8;
commandBuffer[6] = sPage & 0xFF;
commandBuffer[7] = (pNum & 0xFF00) >> 8;
commandBuffer[8] = pNum & 0xFF;
for (int i = 0; i < sizeof(commandBuffer) - 2; i++) {
sum += commandBuffer[i];
}
commandBuffer[9] = (sum & 0x00FF00) >> 8;
commandBuffer[10] = sum & 0xFF;
_uart->write(commandBuffer, sizeof(commandBuffer));
ret = waitForResp(16, 1);
if (ret != GR_OK) {
getErrorReason(ret);
}
return ret == GR_OK;
}
/**
* @brief 合并特征(生成模板)
* @note 标准应答格式 12Bytes
* @retval 0x00 0x01 0x0A
*/
bool Fingerprint::mergeFeature(void)
{
int ret = GR_OK;
uint8_t commandBuffer[6];
_uart->write(_headBuffer, 6);
commandBuffer[0] = GR_PACK_COMMAND_FLAG;
commandBuffer[1] = 0x00;
commandBuffer[2] = 0x03;
commandBuffer[3] = GR_REG_MODEL;
commandBuffer[4] = 0x00;
commandBuffer[5] = 0x09;
_uart->write(commandBuffer, sizeof(commandBuffer));
ret = waitForResp(12, 1);
if (ret != GR_OK) {
getErrorReason(ret);
}
return ret == GR_OK;
}
/**
* @brief 储存模板
* @note 标准应答格式 12Bytes
* @retval
*/
bool Fingerprint::storeFeature(GR_BufID_t id, uint16_t posNum)
{
int ret = GR_OK;
uint32_t sum = 0;
uint8_t commandBuffer[9];
_uart->write(_headBuffer, 6);
commandBuffer[0] = GR_PACK_COMMAND_FLAG;
commandBuffer[1] = 0x00;
commandBuffer[2] = 0x06;
commandBuffer[3] = GR_STORE_CHAR;
commandBuffer[4] = id;
commandBuffer[5] = (posNum & 0xFF00) >> 8;
commandBuffer[6] = posNum & 0xFF;
for (int i = 0; i < sizeof(commandBuffer) - 2; i++) {
sum += commandBuffer[i];
}
commandBuffer[7] = (sum & 0x00FF00) >> 8;
commandBuffer[8] = sum & 0xFF;
_uart->write(commandBuffer, sizeof(commandBuffer));
ret = waitForResp(12, 1);
if (ret != GR_OK) {
getErrorReason(ret);
}
return ret == GR_OK;
}
/**
* @brief 读出模板
* @note 标准应答格式 12Bytes,将flash数据库中指定ID号的指纹模板读入到模板缓冲区CharBuffer1或CharBuffer2
* @retval
*/
bool Fingerprint::loadFeature(GR_BufID_t id, uint16_t pNum)
{
int ret = GR_OK;
uint32_t sum = 0;
uint8_t commandBuffer[9];
_uart->write(_headBuffer, 6);
commandBuffer[0] = GR_PACK_COMMAND_FLAG;
commandBuffer[1] = 0x00;
commandBuffer[2] = 0x06;
commandBuffer[3] = GR_LOAD_CHAR;
commandBuffer[4] = id;
commandBuffer[5] = (pNum & 0xFF00) >> 8;
commandBuffer[6] = pNum & 0xFF;
for (int i = 0; i < sizeof(commandBuffer) - 2; i++) {
sum += commandBuffer[i];
}
commandBuffer[7] = (sum & 0x00FF00) >> 8;
commandBuffer[8] = sum & 0xFF;
_uart->write(commandBuffer, sizeof(commandBuffer));
ret = waitForResp(12, 1);
if (ret != GR_OK) {
getErrorReason(ret);
}
return ret == GR_OK;
}
/**
* @brief 上传特征或模板
* @note 标准应答格式 12Bytes
* @retval
*/
bool Fingerprint::uplaodFeature(GR_BufID_t id)
{
int ret = GR_OK;
uint32_t sum = 0;
uint8_t commandBuffer[7];
_uart->write(_headBuffer, 6);
commandBuffer[0] = GR_PACK_COMMAND_FLAG;
commandBuffer[1] = 0x00;
commandBuffer[2] = 0x04;
commandBuffer[3] = GR_UP_CHAR;
commandBuffer[4] = id;
for (int i = 0; i < sizeof(commandBuffer) - 2; i++) {
sum += commandBuffer[i];
}
commandBuffer[5] = (sum & 0x00FF00) >> 8;
commandBuffer[6] = sum & 0xFF;
_uart->write(commandBuffer, sizeof(commandBuffer));
ret = waitForResp(12, 1);
if (ret != GR_OK) {
getErrorReason(ret);
}
return ret == GR_OK;
}
/**
* @brief 下载特征或模板
* @note 标准应答格式 12Bytes
* @retval
*/
bool Fingerprint::downloadFeature(GR_BufID_t id)
{
return true;
}
// /**
// * @brief 上传原始图像
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::uploadImage(void)
// {
// }
// /**
// * @brief 下载原始图像
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::downloadImage(void)
// {
// }
// /**
// * @brief 删除模板
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::uploadImage(void)
// {
// }
// /**
// * @brief 清空指纹库
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::deleteLibarry(void)
// {
// }
// /**
// * @brief 写系统寄存器
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::writeSysReg(void)
// {
// }
/**
* @brief 读系统基本参数
* @note //! 非标准应答格式 28Bytes
* @retval
*/
bool Fingerprint::readSysParams(SysParams_t *params)
{
uint8_t response[28];
const uint8_t order[] = {0x01, 0x00, 0x03, 0x0F, 0x00, 0x13};
_uart->write(_headBuffer, sizeof(_headBuffer));
_uart->write(order, sizeof(order));
if (waitForAck(response, sizeof(response))) {
if (validSum(response, sizeof(response)) && response[9] == GR_OK) {
Serial.printf("\nvalid pass\n\n");
params->statusReg = (response[10] << 8) | response[11];
params->code = response[12] << 8 | response[13];
params->libSize = response[14] << 8 | response[15];
params->level = response[16] << 8 | response[17];
params->address = response[18] << 24 | response[19] << 16 | response[20] << 8 | response[21];
params->packSize = response[22] << 8 | response[23];
params->bps = response[24] << 8 | response[25];
return true;
}
}
return false;
}
bool Fingerprint::readINFpage()
{
uint8_t response[255];
const uint8_t order[] = {0x01, 0x00, 0x03, 0x16, 0x00, 0x19};
_uart->write(_headBuffer, sizeof(_headBuffer));
_uart->write(order, sizeof(order));
if (waitForAck(response, sizeof(response))) {
if (validSum(response, sizeof(response)) && response[9] == GR_OK) {
Serial.printf("\nvalid pass\n\n");
return true;
}
}
return false;
}
// /**
// * @brief 设置口令
// * @note //! 非标准应答格式 11Bytes
// * @retval
// */
// bool Fingerprint::setPassWord(void)
// {
// }
// /**
// * @brief 验证口令
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::setPassWord(void)
// {
// }
// /**
// * @brief 采样随机数
// * @note //! 非标准应答格式 16Bytes
// * @retval
// */
// bool Fingerprint::getRandom(void)
// {
// }
// /**
// * @brief 设置模块地址
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::setAddress(void)
// {
// }
// /**
// * @brief 端口控制
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::setAddress(void)
// {
// }
// /**
// * @brief 写记事本
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::writeNotepad(void)
// {
// }
// /**
// * @brief 读记事本
// * @note //! 非标准应答格式 44Bytes
// * @retval
// */
// bool Fingerprint::readNotepad(void)
// {
// }
// /**
// * @brief 生成细化指纹图像
// * @note 标准应答格式 12Bytes
// * @retval
// */
// bool Fingerprint::generateBinImage(void)
// {
// }
// /**
// * @brief 读有效模板个数
// * @note //! 标准应答格式 14Bytes
// * @retval
// */
// bool Fingerprint::generateBinImage(void)
// {
// }
// /**
// * @brief 读索引表
// * @note //! 非标准应答格式 44Bytes
// * @retval
// */
// bool Fingerprint::readNotepad(void)
// {
// }