From 7b2522f7128fa67c413f1545b934d99cdb5ee701 Mon Sep 17 00:00:00 2001 From: Viet Dzung Date: Wed, 26 Jun 2019 00:38:36 +0700 Subject: [PATCH] Support whitelist devices feature #1643 (#1654) * Support whitelist devices feature #1643 * Control via MQTT * Log --- lib/extension/bridgeConfig.js | 11 +++++++++++ lib/util/settings.js | 13 +++++++++++++ lib/zigbee.js | 36 ++++++++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/lib/extension/bridgeConfig.js b/lib/extension/bridgeConfig.js index 4a798b7fa..7d12e4995 100644 --- a/lib/extension/bridgeConfig.js +++ b/lib/extension/bridgeConfig.js @@ -27,6 +27,7 @@ class BridgeConfig { this.deviceOptions = this.deviceOptions.bind(this); this.addGroup = this.addGroup.bind(this); this.removeGroup = this.removeGroup.bind(this); + this.whitelist= this.whitelist.bind(this); // Set supported options this.supportedOptions = { @@ -44,9 +45,19 @@ class BridgeConfig { 'device_options': this.deviceOptions, 'add_group': this.addGroup, 'remove_group': this.removeGroup, + 'whitelist': this.whitelist, }; } + whitelist(topic, message) { + message = message.toString(); + const IDByFriendlyName = settings.getIeeeAddrByFriendlyName(message); + const deviceID = IDByFriendlyName ? IDByFriendlyName : message; + const whitelisted = settings.whitelistDevice(deviceID); + whitelisted ? logger.info(`Whitelisted '${deviceID}'`) : logger.error(`Failed to whitelist '${deviceID}'`); + this.mqtt.log('device_whitelisted', deviceID); + } + deviceOptions(topic, message) { let json = null; try { diff --git a/lib/util/settings.js b/lib/util/settings.js index 175e6a834..d056034bf 100644 --- a/lib/util/settings.js +++ b/lib/util/settings.js @@ -6,6 +6,7 @@ const fs = require('./fs'); const onChangeHandlers = []; const defaults = { + whitelist: [], ban: [], permit_join: false, mqtt: { @@ -181,6 +182,17 @@ function addDevice(ieeeAddr) { writeRead(); } +function whitelistDevice(ieeeAddr) { + const settings = getSettings(); + if (!settings.whitelist) { + settings.whitelist = []; + } + + settings.whitelist.push(ieeeAddr); + + writeRead(); +} + function banDevice(ieeeAddr) { const settings = getSettings(); if (!settings.ban) { @@ -349,6 +361,7 @@ module.exports = { getGroup, getGroups, getDevices, + whitelistDevice: (ieeeAddr) => whitelistDevice(ieeeAddr), banDevice: (ieeeAddr) => banDevice(ieeeAddr), addDevice: (ieeeAddr) => addDevice(ieeeAddr), removeDevice: (ieeeAddr) => removeDevice(ieeeAddr), diff --git a/lib/zigbee.js b/lib/zigbee.js index 2d25f3a69..49eee5392 100644 --- a/lib/zigbee.js +++ b/lib/zigbee.js @@ -94,9 +94,17 @@ class Zigbee { this.logStartupInfo(); this.getAllClients().forEach((device) => { - if (settings.get().ban.includes(device.ieeeAddr)) { - logger.warn(`Banned device is connected (${device.ieeeAddr}), removing...`); - this.removeDevice(device.ieeeAddr, false, () => {}); + // If set whitelist devices, all other device will be ban or reject to join the network + if (settings.get().whitelist.size>0) { + if (!settings.get().whitelist.includes(device.ieeeAddr)) { + logger.warn(`Blacklist device is connected (${device.ieeeAddr}), removing...`); + this.removeDevice(device.ieeeAddr, true, () => {}); + } + } else { + if (settings.get().ban.includes(device.ieeeAddr)) { + logger.warn(`Banned device is connected (${device.ieeeAddr}), removing...`); + this.removeDevice(device.ieeeAddr, false, () => {}); + } } }); @@ -107,13 +115,23 @@ class Zigbee { logger.debug( `Accept device incoming with ieeeAddr '${devInfo.ieeeAddr}' permit join is '${this.getPermitJoin()}'` ); - - if (settings.get().ban.includes(devInfo.ieeeAddr)) { - logger.info(`Banned device tried to connect (${devInfo.ieeeAddr})`); - callback(null, false); + // If set whitelist devices, all other device will be ban or reject to join the network + if (settings.get().whitelist.size>0) { + if (settings.get().whitelist.includes(devInfo.ieeeAddr)) { + logger.info(`whitelist device tried to connect (${devInfo.ieeeAddr})`); + callback(null, true); + } else { + logger.debug(`Not allowing device '${devInfo.ieeeAddr}' to join`); + callback(null, false); + } } else { - logger.debug(`Allowing device '${devInfo.ieeeAddr}' to join`); - callback(null, true); + if (settings.get().ban.includes(devInfo.ieeeAddr)) { + logger.info(`Banned device tried to connect (${devInfo.ieeeAddr})`); + callback(null, false); + } else { + logger.debug(`Allowing device '${devInfo.ieeeAddr}' to join`); + callback(null, true); + } } }