Files
2020-06-24 15:36:20 +08:00

515 lines
13 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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)
// {
// }