domotz-remote-pawn
Version:
Domotz Agent
155 lines (140 loc) • 5.96 kB
JavaScript
var jayson = require('jayson');
var fs = require('fs');
const DEFAULT_ROUTER_IP = '192.168.0.1';
const DEFAULT_PASSWORD = 'domotz';
const DOMOTZ_API_PATH = 'ubus';
const GET_SESSION_COMMAND = 'login';
const BLOCK_COMMAND = 'block';
const UNBLOCK_COMMAND = 'unblock';
const GET_BLOCKED_MAC_COMMAND = 'get_blocked_macs';
const LOGIN_TOKEN = '00000000000000000000000000000000';
const UBUS_USERNAME = 'domotz';
const UBUS_PASSWD_FILE = '/etc/domotz-password.txt';
const UBUS_IP_FILE = '/etc/luxul_api_ip';
const LOG_PREFIX = 'LUXUL_JAM_DEVICES - ';
var luxulUbusManager = function (q) {
var routerIp = routerIp ? routerIp : 'http://' + (readLuxulFileSync(UBUS_IP_FILE) || DEFAULT_ROUTER_IP);
var pass = pass ? pass : readLuxulFileSync(UBUS_PASSWD_FILE) || DEFAULT_PASSWORD;
('use strict');
function readLuxulFileSync(file) {
var content = null;
try {
var row = fs.readFileSync(file, 'utf8');
content = row
.toString()
.split('\n')
.map(function (line) {
return line.trim();
})
.filter(Boolean);
} catch (error) {
console.error('%s:Error reading file %s stack_trace: %s', LOG_PREFIX, file, JSON.stringify(error));
}
return content;
}
function messageBuilder(token, topic, command, commandParameters) {
var paramsContent = [token, topic, command, commandParameters];
var message = {
id: 1,
method: 'call',
params: paramsContent,
};
return message;
}
function requestToLuxulWithDeferred(message, deferred) {
var url = [[routerIp, '8008'].join(':'), DOMOTZ_API_PATH].join('/');
var client = jayson.client.http(url);
client.request(message.method, message.params, message.id, function (error, response) {
try {
if (error) {
deferred.reject('error connecting to luxul ubus: ' + JSON.stringify(error));
}
var resp = message.params[0] === LOGIN_TOKEN ? response.result[1].ubus_rpc_session : response.result;
deferred.resolve(resp);
} catch (err) {
deferred.reject('Exception connectiong to luxul ubus');
}
});
}
var getSessionToken = function () {
var auth = {
username: UBUS_USERNAME,
password: pass.toString(),
};
var message = messageBuilder(LOGIN_TOKEN, 'session', GET_SESSION_COMMAND, auth);
var deferred = q.defer();
requestToLuxulWithDeferred(message, deferred);
return deferred.promise;
};
var getBlockedDevices = function (token) {
var message = messageBuilder(token, 'luxul.firewall', GET_BLOCKED_MAC_COMMAND, {});
var deferred = q.defer();
requestToLuxulWithDeferred(message, deferred);
return deferred.promise;
};
var blockUnblockMacAddress = function (token, action, macList) {
var macs = {};
if (!macList || !macList.constructor === Array || (macList.constructor === Array && macList.length === 0)) {
console.debug('%s Empty mac list. Nothing to do', LOG_PREFIX);
return q(null);
}
macs[action] = macList.map(function (address) {
return address.hasOwnProperty('mac')
? address
: {
mac: address,
};
});
var deferred = q.defer();
var message = messageBuilder(token, 'luxul.firewall', action, macs);
requestToLuxulWithDeferred(message, deferred);
return deferred.promise;
};
var handleBlockingFeatureResponse = function (data, actionType) {
if (data === null || data.constructor === Array || (data.constructor === Array && data.length === 0)) {
console.info('%s - %s : empty data response', LOG_PREFIX, actionType);
return;
}
if (data.length > 0 && data.result[0] > 0) {
throw new Error(actionType + ' feature fail with error: ' + JSON.stringify(data.error));
} else {
console.info('%s - %s feature executed - result=%s', LOG_PREFIX, actionType, JSON.stringify(data));
}
};
return {
getSessionToken: getSessionToken,
getBlockedDevices: getBlockedDevices,
blockDeviceList: function (macList) {
return getSessionToken().then(function (token) {
blockUnblockMacAddress(token, BLOCK_COMMAND, macList).then(function (data) {
handleBlockingFeatureResponse(data, 'Block');
});
});
},
unblockDeviceList: function (macList) {
return getSessionToken().then(function (token) {
blockUnblockMacAddress(token, UNBLOCK_COMMAND, macList).then(function (data) {
handleBlockingFeatureResponse(data, 'Unblock');
});
});
},
unblockAllDevices: function () {
return getSessionToken().then(function (token) {
getBlockedDevices(token)
.then(function (ubusResponse) {
if (ubusResponse && ubusResponse.response === 0) {
return ubusResponse.data[0].macs;
}
throw new Error('Unable to retrieve blocked mac list ' + JSON.stringify(ubusResponse));
})
.then(function (blockedMacAddresses) {
return blockUnblockMacAddress(UNBLOCK_COMMAND, blockedMacAddresses);
})
.then(function (data) {
handleBlockingFeatureResponse(data, 'UnblockAll');
});
});
},
};
};
module.exports = luxulUbusManager;