'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/ */