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
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)
|
|
// {
|
|
// }
|