domotz-remote-pawn
Version:
Domotz Agent
160 lines (141 loc) • 5.38 kB
JavaScript
/** This file is part of Domotz Agent.
* Copyright (C) 2016 Domotz Ltd
*
* 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/>.
*
* Created by Iacopo Papalini <iacopo@domotz.com> on 08/09/16.
*
* You need fing installed on the device in order to enable the device
* network jamming
*/
const JAMMED_FILE_NAME = "jammed.txt";
const LOG_PREFIX = "FING_JAM_DEVICES - ";
var jamDevicesFileManager = function (macListFile) {
"use strict";
var fs = require('fs');
var previousMacAddresses = [];
function listChanged(macAddresses) {
if (macAddresses.length !== previousMacAddresses.length) {
return true;
}
else {
for (var i = macAddresses.length; i-- > 0;) {
if (macAddresses[i] !== previousMacAddresses[i]) {
return true;
}
}
}
return false;
}
function writeFile(contents) {
console.debug(LOG_PREFIX + 'Synchronously writing file %s', macListFile);
try {
fs.writeFileSync(macListFile, contents + '\n');
console.debug(LOG_PREFIX + 'File written %s (%s)', macListFile, JSON.stringify(contents));
return contents.length > 0;
} catch (e) {
console.error("Cannot write file %s, killing fing", macListFile);
return false;
}
}
function writeFileIfListChanged(macAddresses) {
/**
* Using the macAddresses list, writes its contents in the macListFile.
* @returns boolean true if the fing process should run after the update
*/
if (listChanged(macAddresses)) {
console.info(LOG_PREFIX + "Jammed device list changed");
} else {
return macAddresses.length > 0;
}
previousMacAddresses = macAddresses;
var contents = macAddresses.join('\n');
return writeFile(contents);
}
return {
write: writeFileIfListChanged
};
};
var fingProcessManager = function (fingCommand, macListFile, childProcess) {
"use strict";
var fingProcess = null;
var fingParameters = ["--kickout", '-', '--kocfg', macListFile].join(' ');
function isFingRunning() {
if (fingProcess !== null) {
console.debug(LOG_PREFIX + "Fing process is running");
return true;
} else {
console.debug(LOG_PREFIX + "Fing process not existing");
return false;
}
}
function assureFingIsRunning() {
if (!isFingRunning()) {
console.info(LOG_PREFIX + 'Starting fing');
fingProcess = childProcess.exec(fingCommand + " " + fingParameters + " " + " >/dev/null");
fingProcess.on('exit', function (code, signal) {
fingProcess = null;
console.info(LOG_PREFIX + "Fing process exited with %s", code || signal);
});
} else {
console.debug(LOG_PREFIX + "Fing already running, not executed");
}
}
function assureFingIsNotRunning() {
if (isFingRunning()) {
console.info(LOG_PREFIX + 'Killing fing');
fingProcess.kill();
} else {
console.info(LOG_PREFIX + "Fing not running, not killing it");
}
}
return {
assureFingIsRunning: assureFingIsRunning,
assureFingIsNotRunning: assureFingIsNotRunning
};
};
var fingWrapper = function (childProcess, engineRequest) {
"use strict";
var env = process.env;
var macListFile = (env.DOMOTZ_ROOT_DIR || '/opt/domotz') + "/etc/" + JAMMED_FILE_NAME;
var fingCommand = (env.FING_BINARY_FULL_PATH || '/usr/bin/fing');
var fileWriter = jamDevicesFileManager(macListFile);
var processManager = fingProcessManager(fingCommand, macListFile, childProcess);
function handleServerResponse(data) {
var shouldRun = fileWriter.write(data);
if (shouldRun) {
processManager.assureFingIsRunning();
}
else {
processManager.assureFingIsNotRunning();
}
}
return {
updateMacAddresses: function () {
console.info(LOG_PREFIX + "Updating mac addresses list");
engineRequest.sendWithPromise('/device/jammed', 'GET').
then(function (data) {
handleServerResponse(data);
}).
catch(function () {
console.error(LOG_PREFIX + 'Cannot update list, assuming no device to jam');
handleServerResponse([]);
});
}
};
};
module.exports.fingWrapper = fingWrapper;
// For testing purposes only
module.exports._fileManager = jamDevicesFileManager;
module.exports._fingProcessManager = fingProcessManager;