UNPKG

wiegand-daemon

Version:

Local network daemon to connect Wiegand access controller and remote server. 微耕门禁控制板局域网守护进程,用于与远端服务器通讯

206 lines (205 loc) 9.79 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); var dgram_1 = __importDefault(require("dgram")); var net_1 = require("net"); var wiegand_control_1 = __importStar(require("wiegand-control")); var getLocalIp_1 = __importDefault(require("./utils/getLocalIp")); var dotenv_1 = __importDefault(require("dotenv")); dotenv_1.default.config(); var localIp = getLocalIp_1.default(); console.log("[DMN] Local ip address is " + localIp + "."); var localPort = +(process.env.LOCAL_PORT || 6000); var remotePort = +(process.env.REMOTE_PORT || 8000); var remoteHost = process.env.REMOTE_HOST; var storeId = process.env.STORE_ID; var searchTimeout = +(process.env.SEARCH_TIMEOUT || 3000); var searchInterval = +(process.env.SEARCH_INTERVAL || 300000); if (!remoteHost || !storeId) { throw new Error("invalid_config"); } var controllerBySerial = {}; var searchingControllerBySerial = {}; var socket = dgram_1.default.createSocket("udp4"); // local network using udp var client = new net_1.Socket(); // remote network using tcp socket.on("error", function (err) { console.log("[UDP] Error:\n" + err.stack + "."); socket.close(); }); socket.on("message", function (msg, rinfo) { var message = wiegand_control_1.parseData(msg); console.log("[UDP] Got message from " + rinfo.address + ":" + rinfo.port + ".", JSON.stringify(message)); if (message.funcName === "Search") { searchingControllerBySerial[message.serial] = new wiegand_control_1.default(socket, message.serial, localIp, localPort, message.ip); } else { client.write(msg, function (err) { if (err) { console.error(err.message); return; } }); } }); socket.on("listening", function () { return __awaiter(void 0, void 0, void 0, function () { var address; return __generator(this, function (_a) { address = socket.address(); console.log("[UDP] Listening " + address.address + ":" + address.port + "."); console.log("[TCP] Connecting " + remoteHost + ":" + remotePort + "..."); client.connect(remotePort, remoteHost); client.setTimeout(1000); return [2 /*return*/]; }); }); }); socket.bind(localPort); setInterval(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, searchAndReportLocalControllers(socket, client)]; case 1: _a.sent(); return [2 /*return*/]; } }); }); }, searchInterval); client.on("connect", function () { return __awaiter(void 0, void 0, void 0, function () { var address, port; return __generator(this, function (_a) { address = client.remoteAddress; port = client.remotePort; console.log("[TCP] Connected to " + address + ":" + port + "."); client.setTimeout(360000); searchAndReportLocalControllers(socket, client); return [2 /*return*/]; }); }); }); client.on("timeout", function () { console.log("[TCP] Connection timeout."); client.destroy(new Error("timeout")); }); client.on("close", function () { console.log("[TCP] Closed, reconnect in 10 seconds."); setTimeout(function () { client.connect(remotePort, remoteHost); }, 10000); }); client.on("error", function (err) { console.error("[TCP] Error: " + err.message + "."); }); client.on("data", function (data) { return __awaiter(void 0, void 0, void 0, function () { var parsedData, serial, controller; return __generator(this, function (_a) { // console.log(`[TCP] got remote data\n`, data); if (data.length !== 64) { console.log("[TCP] Data:", data.toString()); return [2 /*return*/]; } parsedData = wiegand_control_1.parseData(data); serial = parsedData.serial; if (!serial) { controller = new wiegand_control_1.default(socket); } else if (controllerBySerial[serial]) { controller = controllerBySerial[serial]; } else { console.error("[DMN] Controller " + serial + " not found, trying re-search."); new wiegand_control_1.default(socket).search(); return [2 /*return*/]; } controller.sendData(data.readUInt8(1), Buffer.from(data .slice(8) .toString("hex") .replace(/(00)*$/, ""), "hex")); return [2 /*return*/]; }); }); }); function searchAndReportLocalControllers(socket, client) { return __awaiter(this, void 0, void 0, function () { var searchingSerials, serials; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: socket.setBroadcast(true); searchingControllerBySerial = {}; new wiegand_control_1.default(socket).search(); return [4 /*yield*/, new Promise(function (resolve) { setTimeout(function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { resolve(); return [2 /*return*/]; }); }); }, searchTimeout); })]; case 1: _a.sent(); socket.setBroadcast(false); searchingSerials = Object.keys(searchingControllerBySerial); serials = Object.keys(controllerBySerial); if (!(searchingSerials.length === serials.length && searchingSerials.every(function (serial) { return serials.includes(serial); }))) { console.log("[UDP] Search timeout, controller changed:", Object.keys(searchingControllerBySerial).join(",")); } console.log("[TCP] Reporting searched controllers: " + Object.keys(searchingControllerBySerial).join(",")); if (client.writable) { client.write("store " + JSON.stringify({ storeId: storeId, serials: Object.keys(searchingControllerBySerial).map(function (s) { return +s; }) }) + "\r\n"); } controllerBySerial = searchingControllerBySerial; if (searchingSerials.length < serials.length) { console.warn("[DMN] Some controller is lost, controllers left: " + Object.keys(controllerBySerial).join(",")); } return [2 /*return*/]; } }); }); }