UNPKG

domotz-remote-pawn

Version:

Domotz Agent

163 lines (141 loc) 7.08 kB
/** This file is part of Domotz Agent. * Copyright (C) 2016 Domotz UK LLP * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. **/ const DEFAULT_MAX_REPETITIONS = 24; var SUBTREE_HARD_TIMEOUT_SETTING = 'configuration.settings.snmp.hard_timeout.subtree'; var DEFAULT_SUBTREE_HARD_TIMEOUT_VALUE = 300000; var SUBTREE_SOFT_TIMEOUT_SETTING = 'configuration.settings.snmp.soft_timeout.subtree'; var DEFAULT_SUBTREE_SOFT_TIMEOUT_VALUE = 45000; var TimedSnmpSession = require('./timedSnmpSession'); var snmpSubtrees = function (message, resourceLocator) { var snmp = resourceLocator.netSnmp; var cmdUtils = resourceLocator.utils.command; var snmpCommon = resourceLocator.snmpCommon; var cid = message.correlationId; var settingsManager = resourceLocator.settingsManager; var myConsole = resourceLocator.log.decorateLogs().decorate(String(cid)); var options = message.payload; var oidsMapping = cmdUtils.extractFromOptions(options, 'oids', {}); var host = cmdUtils.extractFromOptions(options, 'host', 'localhost'); var oids = snmpCommon.extractOids(oidsMapping); var transformer = message.customTransformer ? message.customTransformer : snmpCommon.transformer; var hardTimeout = parseInt(settingsManager.getSetting(SUBTREE_HARD_TIMEOUT_SETTING, DEFAULT_SUBTREE_HARD_TIMEOUT_VALUE)); var softTimeout = parseInt(settingsManager.getSetting(SUBTREE_SOFT_TIMEOUT_SETTING, DEFAULT_SUBTREE_SOFT_TIMEOUT_VALUE)); options.timeout = options.timeout || softTimeout; myConsole.debug('Hard Timeout %s, Soft Timeout %s ', hardTimeout, options.timeout); // Adjust the default var maxRepetitions = options.maxRepetitions || DEFAULT_MAX_REPETITIONS; delete options.maxRepetitions; return { execute: function (callback, authProvider) { var bindings = snmpCommon.getInterfaceBindings(options, resourceLocator); var snmpSession = null; try { snmpSession = snmpCommon.getSession(bindings, host, options, authProvider); } catch (error) { callback({ error: error.toString() }); return; } var timedSnmpSession = new TimedSnmpSession(snmpSession, { host: host, oids: oids }, myConsole); myConsole.debug('using version %d', snmpSession.version); var response = { oids: {} }; var waiting = {}; for (var j = 0; j < oids.length; j++) { oid = oids[j]; response.oids[oid] = { error: 'Unrecognized oid' }; } snmpSession.on('error', function (error) { var errorMessage = error.toString(); myConsole.error('(socket error) %s', errorMessage); try { snmpSession.close(); } catch (error) { myConsole.error('cannot close session: ' + error); } }); function done(oid) { return function (error) { myConsole.debug('response received for oid: %s', oid); if (error) { myConsole.info('error retrieving oid: %s => %s', oid, error.message); response.oids[oid] = { error: error }; } waiting[oid] = false; for (var i = 0; i < oids.length; i++) { if (waiting[oids[i]]) { myConsole.debug('still waiting for oid: %s', oids[i]); return; } } if (response && response.error && response.error.stack) { delete response.error.stack; } myConsole.debug('command execution concluded, yielding result of %s bytes', JSON.stringify(response).length); try { snmpSession.close(); } catch (error) { myConsole.error('cannot close session: %s', error); } finally { callback(response); } }; } function valueArrived(oid) { return function (varbinds) { myConsole.verbose('varbind callback invoked for oid: %s', oid); if (response.oids[oid].error !== undefined) { response.oids[oid] = {}; } var values = 0; for (var i = 0; i < varbinds.length; i++) { if (snmp.isVarbindError(varbinds[i])) { myConsole.warn('error retrieving oid: %s => varbind error: %s', oid, snmp.varbindError(varbinds[i])); response.oids[oid] = { error: snmp.varbindError(varbinds[i]) }; break; } else { var subOid = varbinds[i].oid.substring(oid.length + 1); var value = transformer(oidsMapping[oid])(varbinds[i].value, varbinds[i].type); myConsole.verbose('SNMP value arrived: [%s].[%s]: %s', oid, subOid, value); response.oids[oid][subOid] = value; values++; } } myConsole.verbose( '%s values arrived for oid %s. Original data: %s. Result: %s', values, oid, JSON.stringify(varbinds), JSON.stringify(response) ); }; } var oid; for (var i = 0; i < oids.length; i++) { oid = oids[i]; timedSnmpSession.subtree(oid, maxRepetitions, valueArrived(oid), done(oid), hardTimeout); } myConsole.debug('version (%d) => request to host %s for oids: %s', options.version, host, JSON.stringify(oids)); // Initialise structures for multi oid retrieval for (var k = 0; k < oids.length; k++) { waiting[oids[k]] = true; } }, describe: function () { return 'snmpSubtrees - ' + host + ' - ' + JSON.stringify(oids); }, }; }; module.exports.command = snmpSubtrees;