mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-22 15:49:48 +00:00
165 lines
5.2 KiB
JavaScript
165 lines
5.2 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
// Private constance
|
||
|
|
||
|
const err_msg = 'Serial port already opened. Please close old connection to use new one.';
|
||
|
|
||
|
const SFM_SERIAL_TIMEOUT = 8000 // serial timeout (ms)
|
||
|
const SFM_DEFAULT_USERROLE = 0x03 // Default user role for register
|
||
|
|
||
|
const SFM_ACK_SUCCESS = 0x00 // Command successful
|
||
|
const SFM_ACK_FAIL = 0x01 // Command failed
|
||
|
const SFM_ACK_FULL = 0x04 // Database full
|
||
|
const SFM_ACK_NOUSER = 0x05 // User does not exist
|
||
|
const SFM_ACK_USER_EXIST = 0x07 // User exists
|
||
|
const SFM_ACK_TIMEOUT = 0x08 // Image collection timeout
|
||
|
const SFM_ACK_HWERROR = 0x0A // Hardware error
|
||
|
const SFM_ACK_IMGERROR = 0x10 // Image error
|
||
|
const SFM_ACK_BREAK = 0x18 // Stop current cmd
|
||
|
const SFM_ACK_ALGORITHMFAIL = 0x11 // Film/Mask attack detected
|
||
|
const SFM_ACK_HOMOLOGYFAIL = 0x12 // Homology check fail
|
||
|
const SFM_ACK_SERIALTIMEOUT = 0x13 // Serial receive time exceeds SFM_SERIAL_TIMEOUT
|
||
|
const SFM_ACK_IDLE = 0x14 // Module idle
|
||
|
|
||
|
// Public constance
|
||
|
|
||
|
exports.SFM_RING_OFF = 0x07 // Ring LED Off
|
||
|
exports.SFM_RING_RED = 0x03 // Ring Color Red
|
||
|
exports.SFM_RING_GREEN = 0x05 // Ring Color Green
|
||
|
exports.SFM_RING_BLUE = 0x06 // Ring Color Blue
|
||
|
exports.SFM_RING_YELLOW = 0x01 // Ring Color Yellow
|
||
|
exports.SFM_RING_PURPLE = 0x02 // Ring Color Purple
|
||
|
exports.SFM_RING_CYAN = 0x04 // Ring Color Cyan
|
||
|
|
||
|
// Public variables
|
||
|
|
||
|
exports.last_status = 0;
|
||
|
|
||
|
// Private variables
|
||
|
|
||
|
let rg;
|
||
|
let ser_hand = -1;
|
||
|
|
||
|
// Private Functions
|
||
|
|
||
|
// Delay usec
|
||
|
const delay = microsec =>
|
||
|
new Promise(r => setTimeout(r, microsec));
|
||
|
|
||
|
// Calculate checksum
|
||
|
const getCheckSum = buffer => {
|
||
|
let result = 0;
|
||
|
for (let i = 1; i <= 5; i++) {
|
||
|
result ^= buffer[i];
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
// Send command to uart and retruns responce tuple
|
||
|
const sendCmd = async (cmdType, p1, p2, p3) => {
|
||
|
while (await rg.serial_data_available(ser_hand)) rg.serial_read(ser_hand);
|
||
|
let cmdBuffer = [0xF5, cmdType, p1, p2, p3, 0, 0, 0xF5];
|
||
|
cmdBuffer[6] = getCheckSum(cmdBuffer);
|
||
|
await rg.serial_write(ser_hand, cmdBuffer);
|
||
|
|
||
|
let ackBuffer = Buffer.from([]);
|
||
|
let timer = SFM_SERIAL_TIMEOUT;
|
||
|
while (timer--) {
|
||
|
if (await rg.serial_data_available(ser_hand)) {
|
||
|
ackBuffer = Buffer.concat([ackBuffer, await rg.serial_read(ser_hand, 0, true)]);
|
||
|
}
|
||
|
else if (ackBuffer.length >= 8) {
|
||
|
// console.log(ackBuffer);
|
||
|
if (ackBuffer[6] == getCheckSum(ackBuffer))
|
||
|
return [ackBuffer[4], ackBuffer[1], ackBuffer[2], ackBuffer[3]];
|
||
|
else
|
||
|
return [SFM_ACK_FAIL];
|
||
|
}
|
||
|
await delay(1);
|
||
|
}
|
||
|
return [SFM_ACK_SERIALTIMEOUT];
|
||
|
}
|
||
|
|
||
|
// Rapping sendCmd... Returns tuple
|
||
|
const getCmdReturn = async (cmdType, p1 = 0, p2 = 0, p3 = 0) => {
|
||
|
let [q3, ackType, q1, q2] = await sendCmd(cmdType, p1, p2, p3);
|
||
|
this.last_status = q3; // コマンド実行結果ステータスを保存
|
||
|
if (ackType == cmdType) return [q3, ackType, q1, q2];
|
||
|
else return [SFM_ACK_FAIL, 0, 0, 0];
|
||
|
}
|
||
|
|
||
|
// Initialize module... just connect uart
|
||
|
exports.init = async (_rg, serial_port, baud = 115200) => {
|
||
|
rg = _rg;
|
||
|
if (ser_hand >= 0) { throw new Error(err_msg); return; }
|
||
|
ser_hand = await rg.serial_open(serial_port, baud);
|
||
|
return ser_hand;
|
||
|
}
|
||
|
|
||
|
// LED ring
|
||
|
exports.setRingColor = async (start_color, end_color = -1, period = 500) => {
|
||
|
period /= 10;
|
||
|
if (period < 30) period = 30;
|
||
|
else if (period > 200) period = 200;
|
||
|
if (end_color == -1) end_color = start_color;
|
||
|
let [q3, ackType, q1, q2] = await getCmdReturn(0xC3, start_color, end_color, period);
|
||
|
return q3;
|
||
|
}
|
||
|
|
||
|
// Count users
|
||
|
exports.getUserCount = async () => {
|
||
|
let [q3, ackType, q1, q2] = await getCmdReturn(0x09, 0x00, 0x00, 0x00);
|
||
|
let userCount = -1;
|
||
|
if (q3 != SFM_ACK_FAIL) userCount = (q1 << 8) | q2;
|
||
|
// else userCount = -1;
|
||
|
return userCount;
|
||
|
}
|
||
|
|
||
|
// Recognize fingerprint... returns userID / 0: not found / -1: error
|
||
|
exports.recognition_1vN = async () => {
|
||
|
let [q3, ackType, q1, q2] = await getCmdReturn(0x0C, 0x00, 0x00, 0x00);
|
||
|
let uid = (q1 << 8) | q2;
|
||
|
if (uid == 0 && q3 != SFM_ACK_SUCCESS) return -1;
|
||
|
else return uid;
|
||
|
}
|
||
|
|
||
|
// Registration :
|
||
|
// step 1... returns success: 0 / fail: -1
|
||
|
// step 2... returns success: 0 / fail: -1
|
||
|
// step 3... returns new userID / fail: -1
|
||
|
exports.register_3c3r = async (step, uid = 0) => {
|
||
|
let q3, ackType, q1, q2;
|
||
|
if (step == 1) {
|
||
|
[q3, ackType, q1, q2] = await getCmdReturn(0x01, (uid >> 8) & 0xFF, uid & 0xFF, SFM_DEFAULT_USERROLE);
|
||
|
if (q3 == SFM_ACK_SUCCESS) return 0;
|
||
|
else return -1;
|
||
|
} else if (step == 2) {
|
||
|
[q3, ackType, q1, q2] = await getCmdReturn(0x02);
|
||
|
if (q3 == SFM_ACK_SUCCESS) return 0;
|
||
|
else return -1;
|
||
|
} else if (step == 3) {
|
||
|
[q3, ackType, q1, q2] = await getCmdReturn(0x03, 0x00, 0x00, 0x00);
|
||
|
let uid = -1;
|
||
|
if (q3 == SFM_ACK_SUCCESS) uid = (q1 << 8) | q2;
|
||
|
return uid;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Delete all users
|
||
|
exports.deleteAllUser = async () => {
|
||
|
let [q3, ackType, q1, q2] = await getCmdReturn(0x05);
|
||
|
if (q3 == SFM_ACK_SUCCESS) return 0;
|
||
|
else return -1;
|
||
|
}
|
||
|
|
||
|
// Disconnect from uart
|
||
|
exports.stop = async () => {
|
||
|
if (ser_hand >= 0) {
|
||
|
await rg.serial_close(ser_hand);
|
||
|
ser_hand = -1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This library is forked from https://github.com/Matrixchung/SFM-V1.7/
|
||
|
*/
|