|
'use strict';
|
|
const koffi = require('koffi');
|
const { Service } = require('ee-core');
|
const Services = require("ee-core/services");
|
const CoreWindow = require("ee-core/electron/window");
|
const path = require("path");
|
const Ps = require("ee-core/ps");
|
const {ChildJob, ChildPoolJob} = require("ee-core/jobs");
|
const {times} = require("lodash/util");
|
var iconv = require('iconv-lite');
|
|
|
|
const aa = () => {
|
|
}
|
|
const CHANNEL_LIST = {
|
service: 'controller.icrf.service',
|
communication: 'controller.icrf.communication',
|
card: 'controller.icrf.card'
|
}
|
|
//向前端线程发送消息
|
const sendMainContents =(channel,textJson) =>{
|
const win = CoreWindow.getMainWindow();
|
win.webContents.send(channel, textJson);
|
}
|
const ff = {
|
1:'初始化通信端口失败.',
|
2:'关闭通信端口失败.',
|
3:'串口被占用.',
|
4:'不支持的串口波特率.',
|
5:'未扫描到设备.',
|
6:'设备未连接.',
|
7:'无效的句柄.',
|
8:'通讯发生错误.',
|
9:'通讯数据格式错误.',
|
10:'参数错误.',
|
11:'数据长度错误.',
|
12:'地址越界.',
|
13:'缓冲区溢出.',
|
14:'操作超时.',
|
15:'写(卡片)错误.',
|
16:'读(卡片)错误.',
|
17:'BCC 校验和错误.',
|
18:'不支持的卡座编号.',
|
19:'卡片类型错误.',
|
20:'卡座有卡未上电.',
|
21:'未检测到卡片.',
|
22:'非法卡.',
|
23:'装载密码出错.',
|
24:'获取读卡器密码错误.',
|
25:'操作失败,读写器返回未知错误.',
|
26:'请求失败.',
|
27:'防冲突失败.',
|
28:'选卡失败.',
|
29:'认证错误.',
|
30:'非值存储区域.',
|
31:'值溢出错误.',
|
32:'Restore 错误.',
|
33:'Transfer 错误.',
|
34:'增值错误.',
|
35:'减值错误.',
|
36:'Mifare 值操作失败.',
|
37:'磁条卡数据错误.',
|
38:'CPU 卡复位出错.',
|
39:'CPU 卡 APDU 失败.',
|
40:'命令不支持.',
|
41:'系统操作出错.',
|
42:'密码错误.',
|
43:'加载动态库失败.',
|
44:'获取身份证图片信息失败.',
|
45:'指定的标签数据区不存在或标签不支持指定长度的 EPC.',
|
46:'灭活标签失败.',
|
47:'锁定标签数据区失败.',
|
48:'指定的标签数据区被锁定并且/或者是永久锁定,而且锁定状态为不可写或不可读.',
|
49:'标签没有收到足够的能量来读写操作.',
|
50:'NXP 特有错误.',
|
129:'标签处于只读状态.',
|
130:'命令不支持或标签不是任何有效状态 (即检查ndef 失败或以前未被调用).',
|
131:'标签已经是 ndef 格式化状态.',
|
132:'不支持的 NDEF 版本.',
|
133:'标记未按照 ndef 规范配置.',
|
134:'标签不支持 NDEF 格式.',
|
135:'标签处于初始化状态 (即没有 ndef 或空ndef.',
|
136:'标签未 ndef 格式化.',
|
}
|
const getFunErrMsg = (it) => {
|
let absNum = Math.abs(it);
|
let msg = ff[absNum];
|
return msg?msg:'未知错误'
|
}
|
const strCoverZero =(str = "")=>{
|
if (str.length <32){
|
str = str +'0';
|
return strCoverZero(str)
|
}
|
return str
|
}
|
|
/**
|
* 将字符串转换成16进制字符
|
* @param {string} str 要转换的字符串
|
* @returns {string} 转换后的16进制字符
|
*/
|
function strToHexCharCode(str="") {
|
let buffer = iconv.encode(str,"utf-8");
|
let hexString = buffer.toString('hex');
|
// 确保结果为 32 字节(64 个字符)
|
if (hexString.length > 32) {
|
// 截断超出的部分
|
hexString = hexString.slice(0, 32);
|
} else if (hexString.length < 32) {
|
// 补零到 64 个字符
|
hexString = hexString.padStart(32, '0');
|
}
|
return hexString;
|
}
|
|
function hexCharCodeToStr(buffer) {
|
// 截取有效数据的 Buffer
|
let hex = iconv.decode(buffer, 'utf-8');
|
let trimmedHex = hex.replace(/^0+/, '');
|
const buffer2 = Buffer.from(trimmedHex, 'hex');
|
return iconv.decode(buffer2, 'utf-8');
|
}
|
/**
|
* ICRF服务(service层为单例)
|
* @class
|
*/
|
class Icrf extends Service {
|
handle = null;
|
timer = null;
|
constructor(ctx) {
|
super(ctx);
|
const dllPath = path.join(Ps.getExtraResourcesDir(),'dll','hc_icrf64.dll');
|
this.hcicrf =koffi.load(dllPath);
|
}
|
connectDevice(initFunction, ...args) {
|
const hcInit = initFunction(...args);
|
let msg = hcInit > 0 ? '读写器连接成功' : getFunErrMsg(hcInit);
|
|
if (hcInit > 0) {
|
this.handle = hcInit;
|
this.beep();
|
}
|
|
sendMainContents(CHANNEL_LIST.service, { status: hcInit });
|
sendMainContents(CHANNEL_LIST.communication, { msg, handle: hcInit });
|
|
return hcInit;
|
}
|
connectFun(initFun,msgSuc,...args){
|
const code = initFun(...args);
|
let msg = code === 0? msgSuc:getFunErrMsg(code);
|
return {code ,msg}
|
}
|
/**
|
* 连接串口读写器
|
* @param {params.number} port 端口号, 取值 0 ~ 19, 对应端口 COM1 ~ COM20
|
* @param {params.number} baud 波特率, 取值 9600 ~ 115200
|
* @returns {number} 读写器句柄
|
*/
|
connectSerialPort(port,baud) {
|
const hc_init = this.hcicrf.func('int __stdcall hc_init(short port, uint32_t baud)');
|
return this.connectDevice(hc_init, port, baud);
|
};
|
connectUsb(number){
|
const hc_init_usb = this.hcicrf.func('int __stdcall hc_init_usb(int number)');
|
return this.connectDevice(hc_init_usb, number);
|
}
|
connectExit(){
|
const func = this.hcicrf.func('int hc_exit(short iced)');
|
let connectFun = this.connectFun(func,'读写器断开连接成功',this.handle);
|
sendMainContents(CHANNEL_LIST.service, { status: connectFun.code });
|
return connectFun;
|
}
|
getErrMsg(it){
|
|
const err = this.hcicrf.func( 'int16 getErrMsg(int16 st, int32 lg, char* errMsg)');
|
let errMsgBuffer = Buffer.alloc(1024)
|
err(it,1,errMsgBuffer);
|
return errMsgBuffer.toString('utf-8');
|
|
}
|
beep(time = 30){
|
const dv = this.hcicrf.func('int16 dv_beep(short iced,int time)');
|
dv(this.handle,time);
|
}
|
doJobByPool(){
|
if (!this.timer){
|
this.timer = setInterval(()=>{
|
const data = this.connectRfCard();
|
sendMainContents(CHANNEL_LIST.card,data);
|
},2000)
|
}
|
}
|
unJobByPool(){
|
if (this.timer){
|
clearInterval(this.timer);
|
this.timer = null;
|
}
|
}
|
connectRfCard(){
|
const func = this.hcicrf.func('int rf_card(short iced, uint8 _Mode, uint32* _Snr)');
|
const mode = 0x01; // 示例模式值
|
let snrBuffer = Buffer.alloc(4); // 分配一个 4 字节的缓冲区,用于存储 SNR
|
let connectFun = this.connectFun(func,'寻卡成功',this.handle,mode,snrBuffer);
|
return {...connectFun,snr:snrBuffer.readUInt32LE(0)}
|
}
|
connectRfAuthenticationKey(addr){
|
// 定义 func 函数
|
const func = this.hcicrf.func('int16 rf_authentication_key(short iced, uint8 _Mode, uint8 _BlockNr, uint8* _Key)');
|
const key = Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); // 示例 6 字节密码
|
|
return this.connectFun(func,'校验密码成功',this.handle,0x00,addr,key);
|
}
|
|
connectRfRead(addr){
|
const func = this.hcicrf.func('int16 rf_read_hex(short iced, uint8 _Adr, char* _Data)');
|
let dataBuffer = Buffer.alloc(32);
|
|
let conn = this.connectFun(func,'读数据成功',this.handle,addr,dataBuffer);
|
let data ;
|
if (conn.code === 0){
|
data = hexCharCodeToStr(dataBuffer);
|
}
|
return {...conn,data}
|
}
|
connectRfWrite(data,addr){
|
let dataBuffer = strToHexCharCode(data);
|
console.log(dataBuffer,addr)
|
const func = this.hcicrf.func('int16 rf_write_hex(short iced, uint8 _Adr, char* _Data)');
|
return this.connectFun(func,'写数据成功',this.handle,addr,dataBuffer);
|
}
|
connectRfHalt(){
|
const func = this.hcicrf.func('int rf_halt(short iced)');
|
return this.connectFun(func,'终止卡成功',this.handle);
|
}
|
|
|
}
|
|
Icrf.toString = () => '[class IcrfService]';
|
module.exports = Icrf;
|