UNPKG

wiegand-control

Version:

Communicate with wiegand door access controller.

211 lines (185 loc) 5.32 kB
import { Socket as UdpSocket } from "dgram"; import { Socket as TcpSocket } from "net"; import { isBuffer, isNumber } from "util"; import { buildBcdDate, ipToHex } from "./utils"; import funcNames from "./funcNames"; const { WGC_HIDE_LOG, WGC_ECHO_1, WGC_ECHO_2, WGC_ECHO_3 } = process.env; const config = { hideLog: !!WGC_HIDE_LOG, echo1: WGC_ECHO_1 ? +WGC_ECHO_1 : 0, echo2: WGC_ECHO_2 ? +WGC_ECHO_2 : 0, echo3: WGC_ECHO_3 ? +WGC_ECHO_3 : 0 }; export default class WgCtl { ip: string; port: number; serial?: number; localSocket?: UdpSocket; remoteSocket?: TcpSocket; serverIp?: string; serverPort?: number; constructor( socket: TcpSocket | UdpSocket, serial?: number, serverIp?: string, serverPort?: number, ip = "", port = 60000 ) { this.ip = ip; this.port = port; this.serial = serial; if (socket instanceof UdpSocket) { this.localSocket = socket; // server ip and port only available for local mode this.serverIp = serverIp; this.serverPort = serverPort; } else { this.remoteSocket = socket; if (this.serverIp || this.serverPort) { throw new Error("Server ip and port only available for local mode."); } } } protected packData(funcCode: number, payload?: string | number | Buffer) { const data = Buffer.alloc(64); data.writeUInt8(0x17, 0); data.writeUInt8(funcCode, 1); if (this.serial) { data.writeUInt32LE(this.serial, 4); } if (payload) { if (isBuffer(payload)) { data.fill(payload, 8, 8 + payload.byteLength); } else if (isNumber(payload)) { data.writeUInt8(payload, 8); } else { data.write(payload.replace(/\s/g, ""), 8, "hex"); } } else { payload = Buffer.alloc(0); } const funcCodeStr = `0x${funcCode.toString(16).toUpperCase()}`; if (!config.hideLog) { console.log( `[WGC] Func ${funcNames[funcCodeStr]}, controller ${this.serial || "all"}, payload to send:`, payload ); } return data; } sendData(funcCode: number, payload?: string | number | Buffer) { const data = this.packData(funcCode, payload); if (this.remoteSocket) { return this.remoteSendData(data); } else { return this.localSendData(data); } } protected remoteSendData(data: Buffer) { if (!this.remoteSocket) return; this.remoteSocket.write(data, err => { if (err) { console.error(err); } }); } protected localSendData(data: Buffer, isEcho = false) { if (!this.localSocket) return; if (!this.ip) { this.localSocket.setBroadcast(true); } if (!WGC_HIDE_LOG) { console.log( `[WGC] Sending local data to ${this.ip || "255.255.255.255"}.` ); } this.localSocket.send( data, 0, data.byteLength, this.port, this.ip || "255.255.255.255", (err, result) => { if (err) { console.error(err); if (!this.ip && this.localSocket) { this.localSocket.setBroadcast(false); } } } ); if (!isEcho && config.echo1) { setTimeout(() => { this.localSendData(data, true); if (config.echo2) { setTimeout(() => { this.localSendData(data, true); if (config.echo3) { setTimeout(() => { this.localSendData(data, true); }, +config.echo3); } }, +config.echo2); } }, +config.echo1); } } search() { this.sendData(0x94); } openDoor(door: number) { this.sendData(0x40, door); } getDate() { this.sendData(0x32); } setDate(date?: Date) { this.sendData(0x30, buildBcdDate(date || new Date())); } setAuth(cardNo: number, door?: number) { const payload = Buffer.alloc(16); payload.writeUInt32LE(cardNo, 0); payload.write("20190101", 4, "hex"); payload.write("20291231", 8, "hex"); payload.writeUInt8(door && door !== 1 ? 0 : 1, 12); payload.writeUInt8(door && door !== 2 ? 0 : 1, 13); payload.writeUInt8(door && door !== 3 ? 0 : 1, 14); payload.writeUInt8(door && door !== 4 ? 0 : 1, 15); this.sendData(0x50, payload); } getAuth(cardNo: number) { const payload = Buffer.alloc(4); payload.writeUInt32LE(cardNo, 0); this.sendData(0x5a, payload); } removeAuth(cardNo: number) { const payload = Buffer.alloc(4); payload.writeUInt32LE(cardNo, 0); this.sendData(0x52, payload); } clearAuth() { const payload = Buffer.from("55aaaa55", "hex"); this.sendData(0x54, payload); } setServerAddress(ip: string, port: number, interval = 0) { const payload = Buffer.alloc(7); payload.write(ipToHex(ip), "hex"); payload.writeUInt16LE(port, 4); payload.writeUInt8(interval, 6); this.sendData(0x90, payload); } setAddress(ip: string, subnet: string, gateway: string) { const payload = Buffer.alloc(16); payload.write(ipToHex(ip), "hex"); payload.write(ipToHex(subnet), 4, "hex"); payload.write(ipToHex(gateway), 8, "hex"); payload.write("55aaaa55", 12, "hex"); this.sendData(0x96, payload); this.ip = ""; } getServerAddress() { this.sendData(0x92); } }