domotz-remote-pawn
Version:
Domotz Agent
154 lines (133 loc) • 6.6 kB
JavaScript
/** 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/>.
**/
var GET_HARD_TIMEOUT_SETTING = 'configuration.settings.snmp.hard_timeout.get';
var DEFAULT_GET_HARD_TIMEOUT_VALUE = 12000;
var GET_SOFT_TIMEOUT_SETTING = 'configuration.settings.snmp.soft_timeout.get';
var DEFAULT_GET_SOFT_TIMEOUT_VALUE = 5000;
var TimedSnmpSession = require('./timedSnmpSession');
var snmpGet = 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;
myConsole.debug('Message Payload %s ', JSON.stringify(options));
var oidsMapping = cmdUtils.extractFromOptions(options, 'oids', {});
var host = cmdUtils.extractFromOptions(options, 'host', 'localhost');
myConsole.debug('Host %s ', JSON.stringify(host));
var oids = snmpCommon.extractOids(oidsMapping);
myConsole.debug('Oids %s ', JSON.stringify(oids));
var hardTimeout = parseInt(settingsManager.getSetting(GET_HARD_TIMEOUT_SETTING, DEFAULT_GET_HARD_TIMEOUT_VALUE));
var softTimeout = parseInt(settingsManager.getSetting(GET_SOFT_TIMEOUT_SETTING, DEFAULT_GET_SOFT_TIMEOUT_VALUE));
options.timeout = options.timeout || softTimeout;
myConsole.debug('Hard Timeout %s, Soft Timeout %s ', hardTimeout, options.timeout);
var transformer = message.customTransformer ? message.customTransformer : snmpCommon.transformer;
function extractOidsResponse(response) {
myConsole.info('Got response - number of returned oids: %s', response.length);
var values = {};
for (var i = 0; i < response.length; i++) {
var oid = response[i].oid;
if (!snmp.isVarbindError(response[i])) {
var value = transformer(oidsMapping[oid])(response[i].value, response[i].type);
myConsole.verbose('SNMP value retrieved: %s=%s', oid, value);
values[oid] = value;
} else {
myConsole.warn('SNMP get - error retrieving oid: %s => varbind error: s', oid, snmp.varbindError(response[i]));
}
}
return { oids: values };
}
function extractErrorResponse(error, response) {
if (snmpCommon.isEmpty(error) && response === undefined) {
myConsole.info('warn: ignoring callback since error is empty and response is undefined');
response = { error: error };
} else {
myConsole.debug('SNMP error received: %s', error.toString());
response = { error: error };
}
return response;
}
return {
execute: function (callback, authProvider) {
var callbackCalled = false;
function safeCallbackCall(data) {
if (!callbackCalled) {
callbackCalled = true;
callback(data);
}
}
var bindings = snmpCommon.getInterfaceBindings(options, resourceLocator);
var snmpSession = null;
try {
snmpSession = snmpCommon.getSession(bindings, host, options, authProvider);
} catch (error) {
safeCallbackCall({ error: error.toString() });
return;
}
myConsole.debug('using version %d', snmpSession.version);
myConsole.debug('Sending SNMP (%d) get request to host %s for oids: %s', snmpSession.version, host, JSON.stringify(oids));
snmpSession.on('error', function (error) {
var errorMessage = error.toString();
myConsole.error('socket error %s', errorMessage);
if (error.name === 'RangeError') {
myConsole.error('RangeError Detected, falling back to getNative (socket error) %s', errorMessage);
var getNative = resourceLocator.snmpGetNative(JSON.parse(JSON.stringify(message)), resourceLocator);
getNative.execute(safeCallbackCall);
} else {
try {
snmpSession.close();
} catch (error) {
myConsole.error('Cannot close session: ' + error);
} finally {
safeCallbackCall({ error: errorMessage });
}
}
});
var timedSnmpSession = new TimedSnmpSession(snmpSession, { host: host, oids: oids }, myConsole);
timedSnmpSession.get(
oids,
function (error, response) {
if (error) {
response = extractErrorResponse(error, response);
} else if (response !== null && response !== undefined) {
response = extractOidsResponse(response);
} else {
response = { error: 'invalid SNMP response' };
}
if (response && response.error && response.error.stack) {
delete response.error.stack;
}
myConsole.debug('command execution concluded, yielding result: %s', JSON.stringify(response));
try {
snmpSession.close();
} catch (error) {
myConsole.error('cannot close session: ' + error);
} finally {
safeCallbackCall(response);
}
},
hardTimeout
);
},
describe: function () {
return cid + ' - snmpGet - ' + host + ' - ' + JSON.stringify(oids);
},
};
};
module.exports.command = snmpGet;