UNPKG

@waiting/bankcard-reader-bp8903

Version:
162 lines (142 loc) 4.56 kB
/** * @waiting/bankcard-reader-bp8903 * 南天 BP8903 读银行卡 * * @version 1.1.1 * @author waiting * @license MIT * @link https://github.com/waitingsong/node-bankcard-reader-bp8903#readme */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var win32Def = require('win32-def'); var bankcardReaderBase = require('@waiting/bankcard-reader-base'); var log = require('@waiting/log'); var sharedCore = require('@waiting/shared-core'); var ffi = require('ffi'); var rxjs = require('rxjs'); const dllFuncs = { OpenComPort: [win32Def.DTypes.INT, [win32Def.DTypes.INT, win32Def.DTypes.POINT, win32Def.DTypes.INT, win32Def.DTypes.INT]], CloseComPort: [win32Def.DTypes.INT, []], IsComOpen: [win32Def.DTypes.INT, []], GetCardNumberFromDev: [win32Def.DTypes.INT, [win32Def.DTypes.INT, win32Def.DTypes.POINT, win32Def.DTypes.INT, win32Def.DTypes.POINT]], }; function connectDevice(device, port) { if (device && device.inUse) { device.deviceOpts.debug && log.info('Cautiton: connectDevice() device in use'); return 0 } const openRet = device.apib.OpenComPort(port, Buffer.from(''), 9600, 1); device.deviceOpts.debug && log.info(`open com ret: ${openRet}`); return openRet === 0 ? port : 0 } function disconnectDevice(device) { const ret = device.apib.CloseComPort(); device.deviceOpts.debug && log.info(`disconnectDevice at port: ${device.openPort}, ret: ${ret} `); device.inUse = false; return true } /** 检查端口是否已打开 */ function isDevicePortOpen(device) { const ret = device.apib.IsComOpen(); device.deviceOpts.debug && log.info(`isPortOpen: ${ret}`); return ret === 1 ? true : false } function findDeviceList(deviceOpts, apib) { const arr = []; // 指定了端口 if (deviceOpts.port > 0) { const device = findDevice(deviceOpts.port, deviceOpts, apib); if (device.openPort > 0) { arr.push(device); } } else { // 检测串口. bp8903 为串口接口 for (let i = 1; i <= 16; i++) { const device = findDevice(i, deviceOpts, apib); if (device.openPort > 0) { arr.push(device); } } } return arr } function findDevice(openPort, deviceOpts, apib) { const device = { apib, deviceOpts, inUse: false, openPort: 0, }; const port = connectDevice(device, openPort); if (port > 0 && isDevicePortOpen(device)) { device.inUse = true; device.openPort = port; deviceOpts.debug && log.info(`Found device at serial/usb port: ${port}`); disconnectDevice(device); } return device } /** 读取银行卡 支持 接触、非接触、磁条 */ function readAll(device) { sharedCore.setPathDirectory(sharedCore.dirname(device.deviceOpts.dllTxt)); const buf = Buffer.alloc(64); if (device.deviceOpts.debug) { log.info('starting reading...'); } const ret = { cardno: '', }; const code = device.apib.GetCardNumberFromDev(device.openPort, // Buffer.from('124|A'), Buffer.from(''), 3, buf); if (code === 0) { // 卡号可能重复数字 ...1234557\u0000557 ret.cardno = buf.toString().replace(/\0+.*$/, ''); } if (device.deviceOpts.debug) { log.info(`readDataBase code: ${code}`); log.info(`readDataBase bufLen: ${buf.byteLength}`); log.info('readDataBase buf: '); log.info(buf); log.info(`readDataBase ret: ${ret}`); // info(buf.slice(80)) } return ret } async function init(options) { const deviceOpts = bankcardReaderBase.parseDeviceOpts(options); const { debug } = deviceOpts; if (debug) { log.info(deviceOpts); } await sharedCore.validateDllFile(deviceOpts.dllTxt); const apib = ffi.Library(deviceOpts.dllTxt, dllFuncs); const devices = findDeviceList(deviceOpts, apib); if (devices && devices.length) { return devices } else { throw new Error('未找到读卡设备') } } /** Read card data */ function read(device) { if (device.openPort) { try { disconnectDevice(device); } catch (ex) { throw ex } const ret$ = rxjs.of(readAll(device)); return ret$.toPromise() } else { throw new Error('设备端口未指定') } } exports.initialOpts = bankcardReaderBase.initialOpts; exports.init = init; exports.read = read;