@mdslab/iotronic-lightning-rod
Advanced tools
Comparing version 1.1.0 to 2.0.0
@@ -1,9 +0,18 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Andrea Rocco Lotronto, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
@@ -16,2 +25,3 @@ //service logging configuration: "board-management" | ||
var board_session = null; | ||
@@ -22,23 +32,58 @@ var spawn = require('child_process').spawn; | ||
exports.execute = function (command, label) { | ||
cmd = command.split(' '); | ||
logger.debug(label + ' COMMAND: ' + command); | ||
var result = spawn(cmd[0], cmd.slice(1)); | ||
var exec = require('child_process').exec; | ||
var Q = require("q"); | ||
result.stdout.on('data', function (data) { | ||
logger.debug(label + ' stdout: ' + data); | ||
}); | ||
result.stderr.on('data', function (data) { | ||
if (command.indexOf('socat') > -1) | ||
logger.info(label + ' stderr: ' + data); | ||
else | ||
logger.error(label + ' stderr: ' + data); | ||
}); | ||
// This function contains the logic that has to be performed if I'm connected to the WAMP server | ||
function manage_WAMP_connection(session) { | ||
return result; | ||
logger.info('[CONFIGURATION] - Board configuration starting...'); | ||
}; | ||
//EXPORTING NETWORK COMMANDS | ||
var manageNetworks = require(LIGHTNINGROD_HOME + '/modules/vnets-manager/manage-networks'); | ||
manageNetworks.exportNetworkCommands(session); | ||
//Topic on which the board can send a message to be registered | ||
var connectionTopic = 'board.connection'; | ||
session.subscribe(connectionTopic, onTopicConnection); | ||
//Registering the board to the Cloud by sending a message to the connection topic | ||
logger.info("[WAMP] - Sending board ID '" + boardCode + "' to topic " + connectionTopic + " to register the board"); | ||
session.publish(connectionTopic, [boardCode, 'connection', session._id]); | ||
} | ||
// This function manages the messages published in "board.connection" topic | ||
function onTopicConnection(args) { | ||
var message = args[0]; | ||
if (message == 'IoTronic-connected') | ||
logger.info("Message on board.connection: " + args[0]) | ||
} | ||
// This function loads the Lightning-rod modules | ||
function moduleLoader (session, device) { | ||
// MODULES LOADING-------------------------------------------------------------------------------------------------- | ||
var manageGpio = require(LIGHTNINGROD_HOME + '/modules/gpio-manager/manage-gpio'); | ||
manageGpio.exportPins(session, lyt_device); | ||
var managePlugins = require(LIGHTNINGROD_HOME + '/modules/plugins-manager/manage-plugins'); | ||
managePlugins.exportPluginCommands(session); | ||
var driversManager = require(LIGHTNINGROD_HOME + "/modules/drivers-manager/manage-drivers"); | ||
driversManager.exportDriverCommands(session); | ||
driversManager.restartDrivers(); | ||
var fsManager = require(LIGHTNINGROD_HOME + "/modules/vfs-manager/manage-fs"); | ||
fsManager.exportFSCommands(session); | ||
var fsLibsManager = require(LIGHTNINGROD_HOME + "/modules/vfs-manager/manage-fs-libs"); | ||
fsLibsManager.exportFSLibs(session); | ||
var manageServices = require(LIGHTNINGROD_HOME + '/modules/services-manager/manage-services'); | ||
manageServices.exportServiceCommands(session); | ||
//------------------------------------------------------------------------------------------------------------------ | ||
} | ||
// Init() LR function in order to control the correct LR configuration: | ||
@@ -132,2 +177,3 @@ // - logging setup | ||
// This function checks the settings correctness | ||
@@ -161,10 +207,10 @@ exports.checkSettings = function (callback) { | ||
port_reverse = nconf.get('config:reverse:server:port_reverse'); | ||
wstt_lib = nconf.get('config:reverse:lib:bin'); | ||
wstun_lib = nconf.get('config:reverse:lib:bin'); | ||
if ((url_reverse == undefined || url_reverse == "") || (port_reverse == undefined || port_reverse == "") || (wstt_lib == undefined || wstt_lib == "")) { | ||
if ((url_reverse == undefined || url_reverse == "") || (port_reverse == undefined || port_reverse == "") || (wstun_lib == undefined || wstun_lib == "")) { | ||
logger.warn('[SYSTEM] - WSTT configuration is wrong or not specified!'); | ||
logger.warn('[SYSTEM] - WSTUN configuration is wrong or not specified!'); | ||
logger.debug(' - url_reverse value: ' + url_reverse); | ||
logger.debug(' - port_reverse value: ' + port_reverse); | ||
logger.debug(' - wstt_lib value: ' + wstt_lib); | ||
logger.debug(' - wstun_lib value: ' + wstun_lib); | ||
@@ -179,2 +225,3 @@ process.exit(); | ||
device = nconf.get('config:device'); | ||
if (device == undefined || device == "") { | ||
@@ -210,3 +257,3 @@ logger.warn('[SYSTEM] - Device "' + device + '" not supported!'); | ||
if (board_position == undefined || Object.keys(board_position).length === 0) { | ||
if ( (board_position == undefined || Object.keys(board_position).length === 0 ) && (reg_status == "registered") ) { | ||
logger.warn('[SYSTEM] - Wrong board coordinates! Set status to "new" to retrive these information.'); | ||
@@ -248,77 +295,45 @@ logger.debug('- Coordinates: ' + JSON.stringify(board_position)); | ||
function onTopicConnection(args) { | ||
var message = args[0]; | ||
if (message == 'Iotronic-connected') | ||
logger.info("Message on board.connection: " + args[0]) | ||
// This function sets the coordinates of the device: called by Iotronic via RPC | ||
exports.setBoardPosition = function (args) { | ||
} | ||
var board_position = args[0]; | ||
logger.info("[SYSTEM] - Set board position: " + JSON.stringify(board_position)); | ||
//This function contains the logic that has to be performed if I'm connected to the WAMP server | ||
exports.manage_WAMP_connection = function (session, details) { | ||
var configFile = JSON.parse(fs.readFileSync(SETTINGS, 'utf8')); | ||
var board_config = configFile.config["board"]; | ||
logger.info("[SYSTEM] --> BOARD CONFIGURATION " + JSON.stringify(board_config)); | ||
logger.info('[CONFIGURATION] - Registered board configuration starting...'); | ||
//EXPORTING NETWORK COMMANDS | ||
var manageNetworks = require(LIGHTNINGROD_HOME + '/modules/vnets-manager/manage-networks'); | ||
manageNetworks.exportNetworkCommands(session); | ||
board_config["position"] = board_position; | ||
logger.info("[SYSTEM] --> BOARD POSITION UPDATED: " + JSON.stringify(board_config["position"])); | ||
//Topic on which the board can send a message to be registered | ||
var connectionTopic = 'board.connection'; | ||
session.subscribe(connectionTopic, onTopicConnection); | ||
//Registering the board to the Cloud by sending a message to the connection topic | ||
logger.info('[WAMP] - Sending board ID ' + boardCode + ' to topic ' + connectionTopic + ' to register the board'); | ||
session.publish(connectionTopic, [boardCode, 'connection', session._id]); | ||
//Updates the settings.json file | ||
fs.writeFile(SETTINGS, JSON.stringify(configFile, null, 4), function (err) { | ||
if (err) { | ||
logger.error('[SYSTEM] --> Error writing settings.json file: ' + err); | ||
} else { | ||
logger.debug("[SYSTEM] --> settings.json configuration file saved to " + SETTINGS); | ||
} | ||
}); | ||
return "Board configuration file updated!"; | ||
/* | ||
//Topic on which the board can listen for commands | ||
var commandTopic = 'board.command'; | ||
//Subscribing to the command topic to receive messages for asyncronous operation to be performed | ||
//Maybe everything can be implemented as RPCs | ||
//Right now the onCommand method of the manageCommands object is invoked as soon as a message is received on the topic | ||
logger.info('[WAMP] - Registering to command topic ' + commandTopic); | ||
var manageCommands = require(LIGHTNINGROD_HOME + '/modules/services-manager/manage-commands'); | ||
session.subscribe(commandTopic, manageCommands.onCommand); | ||
*/ | ||
//If I'm connected to the WAMP server I can export my pins on the Cloud as RPCs | ||
var managePins = require(LIGHTNINGROD_HOME + '/modules/gpio-manager/manage-pins'); | ||
managePins.exportPins(session); | ||
//If I'm connected to the WAMP server I can receive plugins to be scheduled as RPCs | ||
var managePlugins = require(LIGHTNINGROD_HOME + '/modules/plugins-manager/manage-plugins'); | ||
managePlugins.exportPluginCommands(session); | ||
//If I'm connected to the WAMP server I can receive RPC command requests to manage drivers | ||
var driversManager = require(LIGHTNINGROD_HOME + "/modules/drivers-manager/manage-drivers"); | ||
driversManager.exportDriverCommands(session); | ||
driversManager.restartDrivers(); | ||
//If I'm connected to the WAMP server I can receive RPC command requests to manage FUSE filesystem | ||
var fsManager = require(LIGHTNINGROD_HOME + "/modules/vfs-manager/manage-fs"); | ||
fsManager.exportFSCommands(session); | ||
var fsLibsManager = require(LIGHTNINGROD_HOME + "/modules/vfs-manager/manage-fs-libs"); | ||
fsLibsManager.exportFSLibs(session); | ||
var manageServices = require(LIGHTNINGROD_HOME + '/modules/services-manager/manage-services'); | ||
manageServices.exportServiceCommands(session); | ||
}; | ||
// This function sets the coordinates of the device: called by Iotronic via RPC | ||
exports.setBoardPosition = function (args) { | ||
/* | ||
// This function sets the coordinates of the device: called by IoTronic via RPC | ||
exports.updateConf = function (args) { | ||
var board_position = args[0]; | ||
logger.info("[SYSTEM] - Set board position: " + JSON.stringify(board_position)); | ||
var remote_conf = args[0]; | ||
var board_position = args[1]; | ||
logger.info("[SYSTEM] - Set board configuration: " + JSON.stringify(args)); | ||
var configFile = JSON.parse(fs.readFileSync(SETTINGS, 'utf8')); | ||
var board_config = configFile.config["board"]; | ||
logger.info("[SYSTEM] --> BOARD CONFIGURATION " + JSON.stringify(board_config)); | ||
board_config["remote_conf"] = remote_conf; | ||
board_config["position"] = board_position; | ||
logger.info("[SYSTEM] --> BOARD POSITION UPDATED: " + JSON.stringify(board_config["position"])); | ||
logger.info("[SYSTEM] --> BOARD CONF UPDATED: " + JSON.stringify(board_config)); | ||
@@ -338,4 +353,5 @@ //Updates the settings.json file | ||
}; | ||
*/ | ||
// This function manages the wrong/unregistered status of the board | ||
// This function manages the registration status of the board | ||
exports.checkRegistrationStatus = function(args){ | ||
@@ -345,15 +361,98 @@ | ||
logger.error("[SYSTEM] - Connection to Iotronic "+response.result+" - "+response.message); | ||
logger.info("[SYSTEM] - Bye"); | ||
if(response.result == "SUCCESS"){ | ||
process.exit(); | ||
logger.info("[SYSTEM] - Connection to Iotronic "+response.result+" - "+response.message); | ||
// CONNECTION TO IoTronic after access granted. | ||
var configFile = JSON.parse(fs.readFileSync(SETTINGS, 'utf8')); | ||
var board_config = configFile.config["board"]; | ||
logger.info("[CONFIGURATION] - Board configuration parameters: " + JSON.stringify(board_config)); | ||
//PROVISIONING: Iotronic sends coordinates to this device when its status is "new" | ||
if(reg_status === "new"){ | ||
logger.info('[CONFIGURATION] - NEW BOARD CONFIGURATION STARTED... '); | ||
board_session.call("s4t.board.provisioning", [boardCode]).then( | ||
function(result){ | ||
logger.info("\n\nPROVISIONING "+boardCode+" RECEIVED: " + JSON.stringify(result) + "\n\n"); | ||
board_position = result.message.info.coordinates; | ||
board_config["position"] = board_position; | ||
board_config["status"] = "registered"; | ||
logger.info("\n[CONFIGURATION] - BOARD POSITION UPDATED: " + JSON.stringify(board_config["position"])); | ||
//Updates the settings.json file | ||
fs.writeFile(SETTINGS, JSON.stringify(configFile, null, 4), function(err) { | ||
if(err) { | ||
logger.error('Error writing settings.json file: ' + err); | ||
} else { | ||
logger.info("settings.json configuration file saved to " + SETTINGS); | ||
//Calling the manage_WAMP_connection function that contains the logic that has to be performed if the device is connected to the WAMP server | ||
//exports.manage_WAMP_connection(board_session, details); | ||
moduleLoader(board_session, lyt_device); | ||
} | ||
}); | ||
//Create a backup file of settings.json | ||
fs.writeFile(SETTINGS + ".BKP", JSON.stringify(configFile, null, 4), function(err) { | ||
if(err) { | ||
logger.error('Error writing settings.json.BKP file: ' + err); | ||
} else { | ||
logger.info("settings.json.BKP configuration file saved to " + SETTINGS + ".BKP"); | ||
} | ||
}); | ||
}, | ||
function (error){ | ||
logger.error('[WAMP] - Error board provisioning: ' + JSON.stringify(error)); | ||
logger.info("Bye!"); | ||
process.exit(1); | ||
} | ||
); | ||
} else if(reg_status === "registered"){ | ||
moduleLoader(board_session, lyt_device); | ||
} else{ | ||
logger.error('[CONFIGURATION] - WRONG BOARD STATUS: status allowed "new" or "registerd"!'); | ||
process.exit(); | ||
} | ||
}else { | ||
// IF access to IoTronic was rejected | ||
logger.error("[SYSTEM] - Connection to Iotronic "+response.result+" - "+response.message); | ||
logger.info("[SYSTEM] - Bye"); | ||
process.exit(); | ||
} | ||
}; | ||
var exec = require('child_process').exec; | ||
var Q = require("q"); | ||
// Reboot LR | ||
// To execute pre-defined commands in the board shell | ||
exports.execAction = function(args){ | ||
@@ -375,2 +474,7 @@ | ||
logger.info('[SYSTEM] - Rebooting...'); | ||
response.message = "Rebooting"; | ||
response.result = "SUCCESS"; | ||
d.resolve(response); | ||
exec('reboot', function(error, stdout, stderr){ | ||
@@ -402,4 +506,35 @@ | ||
}); | ||
break; | ||
case 'hostname': | ||
exec('echo `hostname`', function(error, stdout, stderr){ | ||
if(error) { | ||
logger.error('[SYSTEM] - Echo result: ' + error); | ||
response.message = error; | ||
response.result = "ERROR"; | ||
d.resolve(response); | ||
} | ||
else if (stderr){ | ||
if (stderr == "") | ||
stderr = "Doing echo..."; | ||
logger.info('[SYSTEM] - Echo result: ' + stderr); | ||
response.message = stderr; | ||
response.result = "WARNING"; | ||
d.resolve(response); | ||
} | ||
else{ | ||
stdout = stdout.replace(/\n$/, ''); | ||
logger.info('[SYSTEM] - Echo result: ' + stdout); | ||
response.message = stdout; | ||
response.result = "SUCCESS"; | ||
d.resolve(response); | ||
} | ||
}); | ||
break; | ||
default: | ||
@@ -425,10 +560,17 @@ | ||
exports.exportManagementCommands = function (session) { | ||
board_session = session; | ||
//Register all the module functions as WAMP RPCs | ||
logger.info('[WAMP-EXPORTS] Management commands exported to the cloud!'); | ||
session.register(boardCode + '.command.setBoardPosition', exports.setBoardPosition); | ||
session.register(boardCode + '.command.checkRegistrationStatus', exports.checkRegistrationStatus); | ||
session.register(boardCode + '.command.execAction', exports.execAction); | ||
session.register('s4t.' + boardCode + '.board.setBoardPosition', exports.setBoardPosition); | ||
session.register('s4t.' + boardCode + '.board.checkRegistrationStatus', exports.checkRegistrationStatus); | ||
session.register('s4t.' + boardCode + '.board.execAction', exports.execAction); | ||
//session.register('s4t.' + boardCode + '.board.updateConf', exports.updateConf); | ||
manage_WAMP_connection(session) | ||
}; | ||
}; | ||
@@ -14,6 +14,6 @@ # Arduino YUN/Linino ONE installation guide | ||
##### Install dependencies via opkg | ||
``` | ||
opkg update | ||
opkg install logrotate nano git unzip socat ip dsniff fuse-utils node-autobahn node-jsonfile node-nconf node-reverse-wstunnel node-tty.js node-ideino-linino-lib node-fuse-bindings node-mknod node-statvfs | ||
opkg install logrotate ntpdate nano git unzip socat ip dsniff fuse-utils node-autobahn node-jsonfile node-nconf node-ideino-linino-lib node-fuse-bindings node-mknod node-statvfs wstun | ||
opkg install kmod-gre kmod-ip6-tunnel kmod-iptunnel4 kmod-iptunnel6 kmod-ipv6 kmod-tun | ||
``` | ||
@@ -23,24 +23,8 @@ | ||
``` | ||
npm install -g --skip-installed --unsafe iotronic-lightning-rod | ||
npm install -g --unsafe @mdslab/iotronic-lightning-rod | ||
``` | ||
If you get some problems during npm dependencies installation phase we suggest you to follow the "Install from source-code" procedure. | ||
If you have some problems during npm dependencies installation phase we suggest you to follow the "Install from source-code" procedure. | ||
##### Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
$NODE_PATH/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: [ "arduino_yun" | "server" | "raspberry_pi"] | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server IP | ||
``` | ||
## Install from source-code | ||
@@ -50,3 +34,3 @@ | ||
``` | ||
npm install -g requestify is-running connection-tester log4js q fs-access util | ||
npm install -g requestify is-running connection-tester@0.1.2 log4js@1.1.1 q fs-access util | ||
``` | ||
@@ -57,11 +41,14 @@ | ||
mkdir /var/lib/iotronic/ && cd /var/lib/iotronic/ | ||
mkdir plugins && mkdir drivers | ||
cd /usr/lib/node_modules/@mdslab/ | ||
mkdir /usr/lib/node_modules/@mdslab/ | ||
git clone git://github.com/MDSLab/s4t-lightning-rod.git | ||
mv s4t-lightning-rod iotronic-lightning-rod | ||
mkdir plugins && mkdir drivers | ||
cp /var/lib/iotronic/iotronic-lightning-rod/etc/init.d/s4t-lightning-rod_yun /etc/init.d/lightning-rod | ||
sed -i "s/<LIGHTNINGROD_HOME>/export LIGHTNINGROD_HOME=\/var\/lib\/iotronic\/iotronic-lightning-rod/g" /etc/init.d/lightning-rod | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/etc/init.d/s4t-lightning-rod_yun /etc/init.d/lightning-rod | ||
sed -i "s/<LIGHTNINGROD_HOME>/export LIGHTNINGROD_HOME=\/usr\/lib\/node_modules\/@mdslab\/iotronic-lightning-rod/g" /etc/init.d/lightning-rod | ||
chmod +x /etc/init.d/lightning-rod | ||
cp /var/lib/iotronic/iotronic-lightning-rod/etc/logrotate.d/lightning-rod.log /etc/logrotate.d/lightning-rod.log | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/etc/logrotate.d/lightning-rod.log /etc/logrotate.d/lightning-rod.log | ||
@@ -72,19 +59,24 @@ mkdir /var/log/iotronic/ | ||
echo "export IOTRONIC_HOME=/var/lib/iotronic" >> /etc/profile | ||
echo "export LIGHTNINGROD_HOME=/var/lib/iotronic/iotronic-lightning-rod" >> /etc/profile | ||
echo "export LIGHTNINGROD_HOME=/usr/lib/node_modules/@mdslab/iotronic-lightning-rod" >> /etc/profile | ||
source /etc/profile | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/settings.json | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/modules/plugins-manager/plugins.example.json /var/lib/iotronic/plugins/plugins.json | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/modules/drivers-manager/drivers.example.json /var/lib/iotronic/drivers/drivers.json | ||
``` | ||
##### Configure Lightning-rod | ||
Note that you need the NODE_ID that is the code returned by the IoTronic service after node registration. | ||
## Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
cp /var/lib/iotronic/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/settings.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/modules/plugins-manager/plugins.example.json /var/lib/iotronic/plugins/plugins.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/modules/drivers-manager/drivers.example.json /var/lib/iotronic/drivers/drivers.json | ||
$NODE_PATH/@mdslab/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: "arduino_yun" | ||
sed -i "s/\"device\":.*\"\"/\"device\": \"arduino_yun\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"code\":.*\"\"/\"code\": \"<NODE_ID>\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"bin\":.*\"\"/\"bin\": \"\/usr\/lib\/node_modules\/node-reverse-wstunnel\/bin\/wstt.js\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"url_wamp\":.*\"\"/\"url_wamp\": \"ws:\/\/<IOTRONIC-SERVER-IP>\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"url_reverse\":.*\"\"/\"url_reverse\": \"ws:\/\/<IOTRONIC-SERVER-IP>\"/g" /var/lib/iotronic/settings.json | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server URL | ||
``` | ||
@@ -95,3 +87,3 @@ | ||
/etc/init.d/cron stop | ||
cp /var/lib/iotronic/iotronic-lightning-rod/etc/cron.d/root_yun /etc/crontabs/root | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/etc/cron.d/root_yun /etc/crontabs/root | ||
/etc/init.d/cron start | ||
@@ -107,3 +99,1 @@ ``` | ||
``` | ||
@@ -20,3 +20,3 @@ # Bundled distribution | ||
- `nconf` - loads stores from a filesystem | ||
- `node-reverse-wstunnel` - is used by LR as a program, not as a CommonJS module. | ||
- `wstun` - is used by LR as a program, not as a CommonJS module. | ||
- `ideino-linino-lib` - Arduino Yun specific - not needed on other boards. Must be installed | ||
@@ -23,0 +23,0 @@ manually. |
@@ -7,9 +7,8 @@ # Raspberry Pi 2 installation guide | ||
#### Install dependencies via apt-get | ||
##### Install dependencies via apt-get | ||
``` | ||
apt-get install python unzip socat dsniff fuse libfuse-dev pkg-config | ||
apt -y install unzip socat dsniff fuse libfuse-dev pkg-config python git ntpdate | ||
``` | ||
#### Install NodeJS 7.x | ||
##### Install latest NodeJS 7.x release | ||
``` | ||
@@ -23,9 +22,5 @@ curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - | ||
npm -v | ||
``` | ||
#### Configure npm NODE_PATH variable | ||
``` | ||
echo "export NODE_PATH=/usr/lib/node_modules" | tee -a /etc/profile | ||
source /etc/profile > /dev/null | ||
echo "NODE_PATH=/usr/lib/node_modules" | tee -a /etc/environment | ||
source /etc/environment > /dev/null | ||
echo $NODE_PATH | ||
@@ -37,69 +32,68 @@ ``` | ||
``` | ||
npm install -g --unsafe iotronic-lightning-rod | ||
npm install -g --unsafe @mdslab/iotronic-lightning-rod | ||
npm install -g --unsafe @mdslab/wstun | ||
``` | ||
##### Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
$NODE_PATH/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: [ "arduino_yun" | "server" | "raspberry_pi"] | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server IP | ||
``` | ||
## Install from source-code | ||
##### Install required NodeJS modules via npm | ||
##### Install required NodeJS modules via npm: | ||
``` | ||
npm install -g npm | ||
npm install -g gyp autobahn jsonfile nconf node-reverse-wstunnel tty.js fuse-bindings requestify is-running connection-tester log4js q secure-keys fs-access mknod util path | ||
# Install statvfs node module compliant with NodeJS 7.x: | ||
npm install -g https://github.com/PlayNetwork/node-statvfs/tarball/v3.0.0 | ||
npm install -g --unsafe gyp autobahn nconf @mdslab/wstun fuse-bindings requestify is-running connection-tester log4js@1.1.1 q fs-access mknod jsonfile | ||
npm install -g --unsafe https://github.com/PlayNetwork/node-statvfs/tarball/v3.0.0 | ||
``` | ||
##### Install Lightning-rod | ||
##### Install the Lightning-rod | ||
``` | ||
mkdir /var/lib/iotronic/ && cd /var/lib/iotronic/ | ||
mkdir plugins && mkdir drivers | ||
mkdir drivers/mountpoints/ | ||
cd /usr/lib/node_modules/ | ||
git clone git://github.com/MDSLab/s4t-lightning-rod.git | ||
mv s4t-lightning-rod iotronic-lightning-rod | ||
mkdir plugins && mkdir drivers | ||
cp /var/lib/iotronic/iotronic-lightning-rod/etc/systemd/system/s4t-lightning-rod.service /etc/systemd/system/lightning-rod.service | ||
sed -i "s/Environment=\"LIGHTNINGROD_HOME=\"/Environment=\"LIGHTNINGROD_HOME=\/var\/lib\/iotronic\/iotronic-lightning-rod\"/g" /etc/systemd/system/lightning-rod.service | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/etc/systemd/system/s4t-lightning-rod.service /etc/systemd/system/lightning-rod.service | ||
sed -i "s/Environment=\"LIGHTNINGROD_HOME=\"/Environment=\"LIGHTNINGROD_HOME=\/usr\/lib\/node_modules\/@mdslab\/iotronic-lightning-rod\"/g" /etc/systemd/system/lightning-rod.service | ||
chmod +x /etc/systemd/system/lightning-rod.service | ||
systemctl daemon-reload | ||
mkdir /var/log/iotronic/ | ||
touch /var/log/iotronic/lightning-rod.log | ||
echo "export IOTRONIC_HOME=/var/lib/iotronic >> /etc/profile | ||
echo "export LIGHTNINGROD_HOME=/var/lib/iotronic/iotronic-lightning-rod >> /etc/profile | ||
source /etc/profile | ||
echo "IOTRONIC_HOME=/var/lib/iotronic" | tee -a /etc/environment | ||
echo "LIGHTNINGROD_HOME=/usr/lib/node_modules/@mdslab/iotronic-lightning-rod" | tee -a /etc/environment | ||
source /etc/environment > /dev/null | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/settings.json | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/modules/plugins-manager/plugins.example.json /var/lib/iotronic/plugins/plugins.json | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/modules/drivers-manager/drivers.example.json /var/lib/iotronic/drivers/drivers.json | ||
``` | ||
##### Configure and start the Lightning-rod | ||
Note that you need the <NODE_ID> that is the code returned by the IoTronic service after node registration: | ||
## Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
cp /var/lib/iotronic/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/iotronic-lightning-rod/settings.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/plugins.example.json /var/lib/iotronic/iotronic-lightning-rod/plugins/plugins.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/drivers.example.json /var/lib/iotronic/iotronic-lightning-rod/drivers/drivers.json | ||
$NODE_PATH/@mdslab/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: "raspberry_pi" | ||
sed -i "s/\"device\":.*\"\"/\"device\": \"raspberry_pi\"/g" /var/lib/iotronic/iotronic-lightning-rod/settings.json | ||
sed -i "s/\"code\":.*\"\"/\"code\": \"<NODE_ID>\"/g" /var/lib/iotronic/iotronic-lightning-rod/settings.json | ||
sed -i "s/\"bin\":.*\"\"/\"bin\": \"\/usr\/lib\/node_modules\/node-reverse-wstunnel\/bin\/wstt.js\"/g" /var/lib/iotronic/iotronic-lightning-rod/settings.json | ||
sed -i "s/\"url_wamp\":.*\"\"/\"url_wamp\": \"ws:\/\/<IOTRONIC-SERVER-IP>\"/g" /var/lib/iotronic/iotronic-lightning-rod/settings.json | ||
sed -i "s/\"url_reverse\":.*\"\"/\"url_reverse\": \"ws:\/\/<IOTRONIC-SERVER-IP>\"/g" /var/lib/iotronic/iotronic-lightning-rod/settings.json | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server URL | ||
``` | ||
Add ENV variables | ||
``` | ||
echo "IOTRONIC_HOME=/var/lib/iotronic" | tee -a /etc/environment | ||
echo "LIGHTNINGROD_HOME=/usr/lib/node_modules/@mdslab/iotronic-lightning-rod" | tee -a /etc/environment | ||
##### Configure logrotate | ||
source /etc/environment > /dev/null | ||
``` | ||
## Configure logrotate | ||
nano /etc/logrotate.d/lightning-rod.log | ||
@@ -116,2 +110,3 @@ ``` | ||
## Start Lightning-rod | ||
@@ -118,0 +113,0 @@ ``` |
# Raspberry Pi 3 installation guide | ||
We tested this procedure on a ubuntu-16.04-preinstalled-server. Everything needs to be run as root. | ||
## Install OS distribution "ubuntu-16.04-preinstalled-server" | ||
@@ -15,9 +16,6 @@ ``` | ||
``` | ||
sudo apt update | ||
sudo apt upgrade | ||
sudo reboot | ||
apt -y install unzip socat dsniff fuse libfuse-dev pkg-config | ||
apt -y install unzip socat dsniff fuse libfuse-dev pkg-config python git ntpdate | ||
``` | ||
##### Install NodeJS 7.x | ||
##### Install latest NodeJS 7.x release | ||
``` | ||
@@ -27,84 +25,81 @@ curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - | ||
node -v | ||
``` | ||
##### Configure npm NODE_PATH variable | ||
``` | ||
echo "export NODE_PATH=/usr/lib/node_modules" | tee -a | ||
source /etc/profile > /dev/null | ||
npm install -g npm | ||
npm config set python `which python2.7` | ||
npm -v | ||
echo "NODE_PATH=/usr/lib/node_modules" | tee -a /etc/environment | ||
source /etc/environment > /dev/null | ||
echo $NODE_PATH | ||
``` | ||
## Install from NPM | ||
``` | ||
npm install -g --skip-installed --unsafe iotronic-lightning-rod | ||
npm install -g --unsafe @mdslab/iotronic-lightning-rod | ||
npm install -g --unsafe @mdslab/wstun | ||
``` | ||
##### Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
$NODE_PATH/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: [ "arduino_yun" | "server" | "raspberry_pi"] | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server IP | ||
``` | ||
## Install from source-code | ||
##### Install required NodeJS modules via npm | ||
##### Install required NodeJS modules via npm: | ||
``` | ||
npm install -g npm | ||
npm install -g gyp autobahn jsonfile nconf node-reverse-wstunnel tty.js fuse-bindings requestify is-running connection-tester log4js q secure-keys fs-access mknod util path | ||
# Install statvfs node module compliant with NodeJS 7.x: | ||
npm install -g https://github.com/PlayNetwork/node-statvfs/tarball/v3.0.0 | ||
npm install -g --unsafe gyp autobahn nconf @mdslab/wstun fuse-bindings requestify is-running connection-tester log4js@1.1.1 q fs-access mknod jsonfile | ||
npm install -g --unsafe https://github.com/PlayNetwork/node-statvfs/tarball/v3.0.0 | ||
``` | ||
##### Install the Lightning-rod | ||
``` | ||
mkdir /var/lib/iotronic/ && cd /var/lib/iotronic/ | ||
mkdir plugins && mkdir drivers | ||
mkdir drivers/mountpoints/ | ||
cd /usr/lib/node_modules/ | ||
git clone git://github.com/MDSLab/s4t-lightning-rod.git | ||
mv s4t-lightning-rod iotronic-lightning-rod | ||
mkdir plugins && mkdir drivers | ||
cp /var/lib/iotronic/iotronic-lightning-rod/etc/systemd/system/s4t-lightning-rod.service /etc/systemd/system/lightning-rod.service | ||
sed -i "s/Environment=\"LIGHTNINGROD_HOME=\"/Environment=\"LIGHTNINGROD_HOME=\/var\/lib\/iotronic\/iotronic-lightning-rod\"/g" /etc/systemd/system/lightning-rod.service | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/etc/systemd/system/s4t-lightning-rod.service /etc/systemd/system/lightning-rod.service | ||
sed -i "s/Environment=\"LIGHTNINGROD_HOME=\"/Environment=\"LIGHTNINGROD_HOME=\/usr\/lib\/node_modules\/@mdslab\/iotronic-lightning-rod\"/g" /etc/systemd/system/lightning-rod.service | ||
chmod +x /etc/systemd/system/lightning-rod.service | ||
systemctl daemon-reload | ||
mkdir /var/log/iotronic/ | ||
touch /var/log/iotronic/lightning-rod.log | ||
echo "export IOTRONIC_HOME=/var/lib/iotronic/iotronic-lightning-rod" >> /etc/profile | ||
echo "export LIGHTNINGROD_HOME=$IOTRONIC_HOME/lightning-rod" >> /etc/profile | ||
source /etc/profile | ||
echo "IOTRONIC_HOME=/var/lib/iotronic" | tee -a /etc/environment | ||
echo "LIGHTNINGROD_HOME=/usr/lib/node_modules/@mdslab/iotronic-lightning-rod" | tee -a /etc/environment | ||
source /etc/environment > /dev/null | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/settings.json | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/modules/plugins-manager/plugins.example.json /var/lib/iotronic/plugins/plugins.json | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/modules/drivers-manager/drivers.example.json /var/lib/iotronic/drivers/drivers.json | ||
``` | ||
##### Configure and start the Lightning-rod | ||
Note that you need the NODE_ID that is the code returned by the IoTronic service after node registration. | ||
## Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
cp /var/lib/iotronic/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/settings.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/plugins.example.json /var/lib/iotronic/plugins/plugins.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/drivers.example.json /var/lib/iotronic/drivers/drivers.json | ||
$NODE_PATH/@mdslab/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: "raspberry_pi" | ||
sed -i "s/\"device\":.*\"\"/\"device\": \"raspberry_pi\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"code\":.*\"\"/\"code\": \"<NODE_ID>\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"bin\":.*\"\"/\"bin\": \"\/usr\/lib\/node_modules\/node-reverse-wstunnel\/bin\/wstt.js\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"url_wamp\":.*\"\"/\"url_wamp\": \"ws:\/\/<IOTRONIC-SERVER-IP>\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"url_reverse\":.*\"\"/\"url_reverse\": \"ws:\/\/<IOTRONIC-SERVER-IP>\"/g" /var/lib/iotronic/settings.json | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server URL | ||
``` | ||
Add ENV variables | ||
``` | ||
echo "IOTRONIC_HOME=/var/lib/iotronic" | tee -a /etc/environment | ||
echo "LIGHTNINGROD_HOME=/usr/lib/node_modules/@mdslab/iotronic-lightning-rod" | tee -a /etc/environment | ||
##### Configure logrotate | ||
source /etc/environment > /dev/null | ||
``` | ||
## Configure logrotate | ||
nano /etc/logrotate.d/lightning-rod.log | ||
@@ -121,2 +116,3 @@ ``` | ||
## Start Lightning-rod | ||
@@ -129,3 +125,3 @@ ``` | ||
tail -f /var/log/iotronic/lightning-rod.log | ||
``` | ||
``` |
@@ -8,14 +8,16 @@ # IoTronic Lightning-rod installation guide for Ubuntu 14.04 | ||
``` | ||
apt -y install nodejs npm nodejs-legacy unzip socat dsniff fuse libfuse-dev pkg-config | ||
apt -y install unzip socat dsniff fuse libfuse-dev pkg-config python git ntpdate | ||
``` | ||
##### Install required NodeJS modules via npm | ||
##### Install latest NodeJS 7.x release | ||
``` | ||
curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - | ||
apt-get install -y nodejs | ||
node -v | ||
npm install -g npm | ||
npm install -g gyp autobahn jsonfile nconf node-reverse-wstunnel tty.js fuse-bindings requestify is-running connection-tester log4js q secure-keys | ||
``` | ||
npm config set python `which python2.7` | ||
npm -v | ||
##### Configure npm NODE_PATH variable | ||
``` | ||
echo "NODE_PATH=/usr/local/lib/node_modules" | sudo tee -a /etc/environment | ||
echo "NODE_PATH=/usr/lib/node_modules" | tee -a /etc/environment | ||
source /etc/environment > /dev/null | ||
@@ -25,30 +27,19 @@ echo $NODE_PATH | ||
## Install from NPM | ||
``` | ||
npm install -g --skip-installed --unsafe iotronic-lightning-rod | ||
``` | ||
npm install -g --unsafe @mdslab/wstun | ||
npm install -g --unsafe @mdslab/iotronic-lightning-rod | ||
##### Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
$NODE_PATH/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: [ "arduino_yun" | "server" | "raspberry_pi"] | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
## Install from source-code | ||
* WAMP server IP | ||
##### Install required NodeJS modules via npm: | ||
``` | ||
npm install -g --unsafe gyp autobahn nconf @mdslab/wstun fuse-bindings requestify is-running connection-tester log4js@1.1.1 q fs-access mknod jsonfile | ||
npm install -g --unsafe https://github.com/PlayNetwork/node-statvfs/tarball/v3.0.0 | ||
``` | ||
## Install from source-code | ||
##### Install Lightning-rod | ||
@@ -71,18 +62,26 @@ ``` | ||
source /etc/environment > /dev/null | ||
``` | ||
##### Configure Lightning-rod | ||
Note that you will need the IP address of a working instance of a WAMP router (<WAMP_IP>), the IP address of a working instance of a Websocket reverse tunnel server (<WS_IP>), and the UUID of the node that you need to have previously registered on the IoTronic (<NODE_UUID>). Also, note that if while installing the IoTronic service, you configured a custom port and realm name for the WAMP router or a custom port for the Websocket reverse tunnel server, you will need to manually change the setting.json, accordingly. | ||
``` | ||
cp /var/lib/iotronic/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/settings.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/plugins.example.json /var/lib/iotronic/plugins/plugins.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/drivers.example.json /var/lib/iotronic/drivers/drivers.json | ||
``` | ||
sed -i "s/\"device\":.*\"\"/\"device\": \"laptop\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"code\":.*\"\"/\"code\": \"<NODE_UUID>\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"bin\":.*\"\"/\"bin\": \"\/usr\/local\/lib\/node_modules\/node-reverse-wstunnel\/bin\/wstt.js\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"url_wamp\":.*\"\"/\"url_wamp\": \"ws:\/\/<WAMP_IP>\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"url_reverse\":.*\"\"/\"url_reverse\": \"ws:\/\/<WS_IP>\"/g" /var/lib/iotronic/settings.json | ||
## Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
$NODE_PATH/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: "server" | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server IP | ||
``` | ||
##### Configure logrotate | ||
@@ -89,0 +88,0 @@ nano /etc/logrotate.d/lightning-rod.log |
@@ -10,5 +10,6 @@ # IoTronic Lightning-rod installation guide for Ubuntu 16.04 | ||
``` | ||
apt -y install unzip socat dsniff fuse libfuse-dev pkg-config python | ||
apt -y install unzip socat dsniff fuse libfuse-dev pkg-config python git ntpdate | ||
``` | ||
##### Install latest NodeJS release | ||
##### Install latest NodeJS 7.x release | ||
``` | ||
@@ -31,29 +32,8 @@ curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash - | ||
``` | ||
npm install -g --unsafe iotronic-lightning-rod | ||
npm install -g --unsafe @mdslab/iotronic-lightning-rod | ||
npm install -g --unsafe @mdslab/wstun | ||
``` | ||
##### Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
$NODE_PATH/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: [ "arduino_yun" | "server" | "raspberry_pi"] | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server IP | ||
``` | ||
Add ENV variables | ||
``` | ||
echo "IOTRONIC_HOME=/var/lib/iotronic" | tee -a /etc/environment | ||
echo "LIGHTNINGROD_HOME=/usr/lib/node_modules/iotronic-lightning-rod" | tee -a /etc/environment | ||
source /etc/environment > /dev/null | ||
``` | ||
## Install from source-code | ||
@@ -63,3 +43,3 @@ | ||
``` | ||
npm install -g --unsafe gyp autobahn jsonfile nconf node-reverse-wstunnel tty.js fuse-bindings requestify is-running connection-tester log4js@1.1.1 q secure-keys fs-access mknod | ||
npm install -g --unsafe gyp autobahn nconf @mdslab/wstun fuse-bindings requestify is-running connection-tester log4js@1.1.1 q fs-access mknod jsonfile | ||
npm install -g --unsafe https://github.com/PlayNetwork/node-statvfs/tarball/v3.0.0 | ||
@@ -71,33 +51,44 @@ ``` | ||
mkdir /var/lib/iotronic/ && cd /var/lib/iotronic/ | ||
mkdir plugins && mkdir drivers | ||
mkdir drivers/mountpoints/ | ||
cd /usr/lib/node_modules/ | ||
git clone git://github.com/MDSLab/s4t-lightning-rod.git | ||
mv s4t-lightning-rod iotronic-lightning-rod | ||
mkdir plugins && mkdir drivers | ||
cp /var/lib/iotronic/iotronic-lightning-rod/etc/systemd/system/s4t-lightning-rod.service /etc/systemd/system/lightning-rod.service | ||
sed -i "s/Environment=\"LIGHTNINGROD_HOME=\"/Environment=\"LIGHTNINGROD_HOME=\/var\/lib\/iotronic\/iotronic-lightning-rod\"/g" /etc/systemd/system/lightning-rod.service | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/etc/systemd/system/s4t-lightning-rod.service /etc/systemd/system/lightning-rod.service | ||
sed -i "s/Environment=\"LIGHTNINGROD_HOME=\"/Environment=\"LIGHTNINGROD_HOME=\/usr\/lib\/node_modules\/@mdslab\/iotronic-lightning-rod\"/g" /etc/systemd/system/lightning-rod.service | ||
chmod +x /etc/systemd/system/lightning-rod.service | ||
systemctl daemon-reload | ||
mkdir /var/log/iotronic/ | ||
touch /var/log/iotronic/lightning-rod.log | ||
echo "IOTRONIC_HOME=/var/lib/iotronic/iotronic-lightning-rod" | tee -a /etc/environment | ||
echo "LIGHTNINGROD_HOME=$IOTRONIC_HOME/lightning-rod" | tee -a /etc/environment | ||
echo "IOTRONIC_HOME=/var/lib/iotronic" | tee -a /etc/environment | ||
echo "LIGHTNINGROD_HOME=/usr/lib/node_modules/@mdslab/iotronic-lightning-rod" | tee -a /etc/environment | ||
source /etc/environment > /dev/null | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/settings.json | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/modules/plugins-manager/plugins.example.json /var/lib/iotronic/plugins/plugins.json | ||
cp /usr/lib/node_modules/@mdslab/iotronic-lightning-rod/modules/drivers-manager/drivers.example.json /var/lib/iotronic/drivers/drivers.json | ||
``` | ||
##### Configure Lightning-rod | ||
Note that you will need the IP address of a working instance of a WAMP router (<WAMP_IP>), the IP address of a working instance of a Websocket reverse tunnel server (<WS_IP>), and the UUID of the node that you need to have previously registered on the IoTronic (<NODE_UUID>). Also, note that if while installing the IoTronic service, you configured a custom port and realm name for the WAMP router or a custom port for the Websocket reverse tunnel server, you will need to manually change the setting.json, accordingly. | ||
## Configure Lightning-rod | ||
At the end of the installation process we have to execute the LR configuration script: | ||
``` | ||
cp /var/lib/iotronic/iotronic-lightning-rod/settings.example.json /var/lib/iotronic/settings.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/modules/plugins-manager/plugins.example.json /var/lib/iotronic/plugins/plugins.json | ||
cp /var/lib/iotronic/iotronic-lightning-rod/modules/drivers-manager/drivers.example.json /var/lib/iotronic/drivers/drivers.json | ||
$NODE_PATH/@mdslab/iotronic-lightning-rod/scripts/lr_configure.sh | ||
``` | ||
This script asks the following information: | ||
``` | ||
* device type: "server" | ||
sed -i "s/\"device\":.*\"\"/\"device\": \"server\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"code\":.*\"\"/\"code\": \"<NODE_UUID>\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"bin\":.*\"\"/\"bin\": \"\/usr\/lib\/node_modules\/node-reverse-wstunnel\/bin\/wstt.js\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"url_wamp\":.*\"\"/\"url_wamp\": \"ws:\/\/<WAMP_IP>\"/g" /var/lib/iotronic/settings.json | ||
sed -i "s/\"url_reverse\":.*\"\"/\"url_reverse\": \"ws:\/\/<WS_IP>\"/g" /var/lib/iotronic/settings.json | ||
* Board ID: UUID released by the registration process managed by IoTronic. | ||
* IoTronic server IP | ||
* WAMP server URL | ||
``` | ||
## Configure logrotate | ||
@@ -104,0 +95,0 @@ nano /etc/logrotate.d/lightning-rod.log |
@@ -1,12 +0,21 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2014 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Andrea Rocco Lotronto, Arthur Warnier, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Andrea Rocco Lotronto, | ||
//# Giovanni Merlino, Arthur Warnier, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
// LIBRARIES | ||
@@ -32,2 +41,3 @@ var fs = require("fs"); | ||
device = null; //valued in checkSettings | ||
lyt_device = null; //valued here in main | ||
@@ -50,2 +60,4 @@ | ||
//Init_Ligthning_Rod(function (check) { | ||
@@ -74,48 +86,40 @@ manageBoard.Init_Ligthning_Rod(function (check) { | ||
logger.info("[SYSTEM] - Iotronic server IP: "+wampIP); | ||
logger.info('[SYSTEM] - DEVICE: ' + device); | ||
var connectionTester = require('connection-tester'); | ||
//---------------------------------------- | ||
// 1. Set WAMP connection configuration | ||
//---------------------------------------- | ||
var wampUrl = nconf.get('config:wamp:url_wamp')+":"+nconf.get('config:wamp:port_wamp')+"/ws"; | ||
var wampRealm = nconf.get('config:wamp:realm'); | ||
var wampConnection = new autobahn.Connection({ | ||
url: wampUrl, | ||
realm: wampRealm, | ||
max_retries: -1 | ||
}); | ||
connectionTester.test(wampIP, 8888, 1000, function (err, output) { | ||
var wampIP = wampUrl.split("//")[1].split(":")[0]; | ||
logger.info("[SYSTEM] - WAMP server IP: "+wampIP); | ||
//logger.debug("[WAMP] - CONNECTION STATUS: "+JSON.stringify(output)); | ||
logger.info("[SYSTEM] - Node ID: "+boardCode); | ||
var reachable = output.success; | ||
var error_test = output.error; | ||
//logger.debug("[WAMP] - CONNECTION STATUS: "+reachable); | ||
//---------------------------------------------------------------------------------------- | ||
// 3. On WAMP connection open the device will load LR libraries and start each LR module | ||
//---------------------------------------------------------------------------------------- | ||
//This function is called as soon as the connection is created successfully | ||
wampConnection.onopen = function (session, details) { | ||
if (!reachable) { | ||
logger.info('[WAMP] - Connection to WAMP server '+ wampUrl + ' created successfully:'); | ||
logger.info('[WAMP] |--> Realm: '+ wampRealm); | ||
logger.info('[WAMP] |--> Session ID: '+ session._id); | ||
//logger.debug('[WAMP] |--> Connection details:\n'+ JSON.stringify(details)); | ||
//CONNECTION STATUS: FALSE | ||
logger.error("[CONNECTION] - Iotronic server unreachable (test result = " + reachable + ")"); | ||
logger.error("[CONNECTION] --> Error reported: " + error_test); | ||
process.exit(); | ||
} else { | ||
// Test if IoTronic is connected to the realm | ||
session.call("s4t.iotronic.isAlive", [boardCode]).then( | ||
logger.info('[SYSTEM] - DEVICE: ' + device); | ||
function(response){ | ||
//---------------------------------------- | ||
// 1. Set WAMP connection configuration | ||
//---------------------------------------- | ||
var wampUrl = nconf.get('config:wamp:url_wamp')+":"+nconf.get('config:wamp:port_wamp')+"/ws"; | ||
var wampRealm = nconf.get('config:wamp:realm'); | ||
var wampConnection = new autobahn.Connection({ | ||
url: wampUrl, | ||
realm: wampRealm, | ||
max_retries: -1 | ||
}); | ||
logger.info("[SYSTEM] - " + response.message ); | ||
var wampIP = wampUrl.split("//")[1].split(":")[0]; | ||
logger.info("[SYSTEM] - WAMP server IP: "+wampIP); | ||
logger.info("[SYSTEM] - Node ID: "+boardCode); | ||
//---------------------------------------------------------------------------------------- | ||
// 3. On WAMP connection open the device will load LR libraries and start each LR module | ||
//---------------------------------------------------------------------------------------- | ||
//This function is called as soon as the connection is created successfully | ||
wampConnection.onopen = function (session, details) { | ||
if (keepWampAlive != null){ | ||
@@ -131,74 +135,5 @@ | ||
logger.info('[WAMP] - Connection to WAMP server '+ wampUrl + ' created successfully:'); | ||
logger.info('[WAMP] |--> Realm: '+ wampRealm); | ||
logger.info('[WAMP] |--> Session ID: '+ session._id); | ||
//logger.debug('[WAMP] |--> Connection details:\n'+ JSON.stringify(details)); | ||
// RPC registration of Board Management Commands | ||
manageBoard.exportManagementCommands(session); | ||
var configFile = JSON.parse(fs.readFileSync(SETTINGS, 'utf8')); | ||
var board_config = configFile.config["board"]; | ||
logger.info("[CONFIGURATION] - Board configuration parameters: " + JSON.stringify(board_config)); | ||
//PROVISIONING: Iotronic sends coordinates to this device when its status is "new" | ||
if(reg_status === "new"){ | ||
logger.info('[CONFIGURATION] - NEW BOARD CONFIGURATION STARTED... '); | ||
session.call("s4t.board.provisioning", [boardCode]).then( | ||
function(result){ | ||
logger.info("\n\nPROVISIONING "+boardCode+" RECEIVED: " + JSON.stringify(result) + "\n\n"); | ||
board_position = result.message[0]; | ||
board_config["position"]=result.message[0]; | ||
board_config["status"]="registered"; | ||
logger.info("\n[CONFIGURATION] - BOARD POSITION UPDATED: " + JSON.stringify(board_config["position"])); | ||
//Updates the settings.json file | ||
fs.writeFile(SETTINGS, JSON.stringify(configFile, null, 4), function(err) { | ||
if(err) { | ||
logger.error('Error writing settings.json file: ' + err); | ||
} else { | ||
logger.info("settings.json configuration file saved to " + SETTINGS); | ||
//Calling the manage_WAMP_connection function that contains the logic that has to be performed if the device is connected to the WAMP server | ||
manageBoard.manage_WAMP_connection(session, details); | ||
} | ||
}); | ||
//Create a backup file of settings.json | ||
fs.writeFile(SETTINGS + ".BKP", JSON.stringify(configFile, null, 4), function(err) { | ||
if(err) { | ||
logger.error('Error writing settings.json.BKP file: ' + err); | ||
} else { | ||
logger.info("settings.json.BKP configuration file saved to " + SETTINGS + ".BKP"); | ||
} | ||
}); | ||
}, session.log); | ||
} else if(reg_status === "registered"){ | ||
//Calling the manage_WAMP_connection function that contains the logic that has to be performed if the device is connected to the WAMP server | ||
manageBoard.manage_WAMP_connection(session, details); | ||
} else{ | ||
logger.error('[CONFIGURATION] - WRONG BOARD STATUS: status allowed "new" or "registerd"!'); | ||
process.exit(); | ||
} | ||
//---------------------------------------------------------------------------------------------------- | ||
@@ -213,3 +148,3 @@ // THIS IS AN HACK TO FORCE RECONNECTION AFTER A BREAK OF INTERNET CONNECTION | ||
var connectionTester = require('connection-tester'); | ||
connectionTester.test(wampIP, 8888, 1000, function (err, output) { | ||
connectionTester.test(wampIP, port_wamp, 1000, function (err, output) { | ||
@@ -226,3 +161,3 @@ //logger.debug("[WAMP] - CONNECTION STATUS: "+JSON.stringify(output)); | ||
//CONNECTION STATUS: FALSE | ||
logger.warn("[CONNECTION-RECOVERY] - INTERNET CONNECTION STATUS: "+reachable+ " - ERROR: "+error_test); | ||
logger.warn("[CONNECTION-RECOVERY] - INTERNET CONNECTION STATUS: " + reachable + " - ERROR: " + error_test); | ||
wamp_check = false; | ||
@@ -237,90 +172,99 @@ online = false; | ||
if(!online){ | ||
// In the previous checks the "online" flag was set to FALSE. | ||
// The connection is come back ("online" is TRUE) | ||
logger.info("[CONNECTION-RECOVERY] - INTERNET CONNECTION STATUS: "+reachable); | ||
logger.info("[CONNECTION-RECOVERY] - INTERNET CONNECTION RECOVERED!"); | ||
logger.info("[CONNECTION-RECOVERY] - INTERNET CONNECTION STATUS: " + reachable); | ||
logger.info("[CONNECTION-RECOVERY] ---> INTERNET CONNECTION RECOVERED!"); | ||
logger.info("[WAMP-RECOVERY] - WAMP connection checks started..."); | ||
//we need to test the WAMP connection | ||
session.publish ('board.connection', [ 'alive-'+boardCode ], {}, { acknowledge: true}).then( | ||
// Test if IoTronic is connected to the realm | ||
session.call("s4t.iotronic.isAlive", [boardCode]).then( | ||
function(publication) { | ||
logger.info("[WAMP-ALIVE-STATUS] - WAMP ALIVE MESSAGE RESPONSE: published -> publication ID is " + JSON.stringify(publication)); | ||
function(response){ | ||
// WAMP connection is established and the previous connection fault didn't compromise the WAMP socket | ||
// so we don't need to restore the WAMP connection and we set the connection status ("online") to TRUE. | ||
wamp_check = true; | ||
logger.info("[WAMP-RECOVERY] - WAMP CONNECTION STATUS: " + response.message); | ||
online = true; | ||
}, | ||
function(error) { | ||
logger.warn("[WAMP-RECOVERY] - WAMP ALIVE MESSAGE: publication error " + JSON.stringify(error)); | ||
function (err) { | ||
// IoTronic is not connected to the realm yet so LR need to try to reconnect later | ||
wamp_check = false; | ||
} | ||
logger.debug("[WAMP-RECOVERY] - WAMP CONNECTION STATUS: " + JSON.stringify(err)); | ||
); | ||
setTimeout(function(){ | ||
//It will wait the WAMP alive message response | ||
setTimeout(function(){ | ||
// WAMP CONNECTION IS NOT ESTABLISHED: if after a connection fault the WAMP connection recovery procedure | ||
// didn't start automatically we need to KILL the WAMP socket through the TCPKILL tool | ||
// (problem noticed in WIFI connection with DSL internet connection). | ||
// If the message sent to WAMP server was correctly published (so "wamp_check" is TRUE) means | ||
// WAMP connection is established and the previous connection fault didn't compromise the WAMP socket | ||
// so we don't need to restore the WAMP connection and we set the connection status ("online") to TRUE. | ||
if (wamp_check){ | ||
logger.warn("[WAMP-RECOVERY] - WAMP CONNECTION STATUS: " + wamp_check); | ||
// WAMP CONNECTION IS ESTABLISHED | ||
logger.debug("[WAMP-ALIVE-STATUS] - WAMP CONNECTION STATUS: " + wamp_check); | ||
online = true; | ||
// Check if the tcpkill process was killed after a previous connection recovery through this check we will avoid to start another tcpkill process | ||
var tcpkill_status = running(tcpkill_pid); | ||
//logger.warn(boardCode+" needs to be restored!"); | ||
//manageNetworks.setSocatOnBoard([socatServer_ip, socatServer_port, socatBoard_ip, net_backend, boardCode, true] ); //TO RESTORE | ||
logger.warn("[WAMP-RECOVERY] - TCPKILL STATUS: " + tcpkill_status + " - PID: " + tcpkill_pid); | ||
} | ||
else{ | ||
// at LR startup "tcpkill_pid" is NULL and in this condition "is-running" module return "true" that is a WRONG result! | ||
if (tcpkill_status === false || tcpkill_pid == null){ | ||
// WAMP CONNECTION IS NOT ESTABLISHED: if after a connection fault the message publishing to WAMP server failed and the WAMP connection recovery procedure | ||
// didn't start automatically we need to KILL the WAMP socket through the TCPKILL tool (problem noticed in WIFI connection with DSL internet connection). | ||
logger.warn("[WAMP-RECOVERY] - Cleaning WAMP socket..."); | ||
var tcpkill_kill_count = 0; | ||
logger.warn("[WAMP-ALIVE-STATUS] - WAMP CONNECTION STATUS: " + wamp_check); | ||
//tcpkill -9 port 8181 | ||
var tcpkill = spawn('tcpkill',['-9','port','8181']); | ||
tcpkill_pid = tcpkill.pid; | ||
// Check if the tcpkill process was killed after a previous connection recovery | ||
// Through this check we will avoid to start another tcpkill process | ||
var tcpkill_status = running(tcpkill_pid); | ||
tcpkill.stdout.on('data', function (data) { | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill stdout: ' + data); | ||
}); | ||
logger.warn("[WAMP-ALIVE-STATUS] - TCPKILL STATUS: " + tcpkill_status + " - PID: " +tcpkill_pid); | ||
tcpkill.stderr.on('data', function (data) { | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill stderr:\n' + data); | ||
// at LR startup "tcpkill_pid" is NULL and in this condition "is-running" module return "true" that is a WRONG result! | ||
if (tcpkill_status === false || tcpkill_pid == null){ | ||
//it will check if tcpkill is in listening state on the port 8181 | ||
if(data.toString().indexOf("listening") > -1){ | ||
logger.warn("[WAMP-RECOVERY] - Cleaning WAMP socket..."); | ||
var tcpkill_kill_count = 0; | ||
// LISTENING: to manage the starting of tcpkill (listening on port 8181) | ||
//tcpkill -9 port 8181 | ||
var tcpkill = spawn('tcpkill',['-9','port','8181']); | ||
tcpkill_pid = tcpkill.pid; | ||
}else if (data.toString().indexOf("win 0") > -1){ | ||
tcpkill.stdout.on('data', function (data) { | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill stdout: ' + data); | ||
}); | ||
// TCPKILL DETECTED WAMP ACTIVITY (WAMP reconnection attempts) | ||
// This is the stage triggered when the WAMP socket was killed by tcpkill and WAMP reconnection process automaticcally started: | ||
// in this phase we need to kill tcpkill to allow WAMP reconnection. | ||
try{ | ||
tcpkill.stderr.on('data', function (data) { | ||
logger.debug('[WAMP-RECOVERY] ... killing tcpkill process with PID: ' + tcpkill_pid); | ||
process.kill(tcpkill_pid); | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill stderr:\n' + data); | ||
//double check: It will test after a while if the tcpkill process has been killed | ||
setTimeout(function(){ | ||
//it will check if tcpkill is in listening state on the port 8181 | ||
if(data.toString().indexOf("listening") > -1){ | ||
if ( running(tcpkill_pid) || tcpkill_pid == null){ | ||
// LISTENING: to manage the starting of tcpkill (listening on port 8181) | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill['+tcpkill_pid+'] listening...'); | ||
tcpkill_kill_count = tcpkill_kill_count + 1; | ||
//tcpkill_pid = tcpkill.pid; | ||
//logger.debug('[WAMP-RECOVERY] ... tcpkill -9 port 8181 - PID ['+tcpkill_pid+']'); | ||
logger.warn("[WAMP-RECOVERY] ... tcpkill still running!!! PID ["+tcpkill_pid+"]"); | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill killing retry_count '+ tcpkill_kill_count); | ||
}else if (data.toString().indexOf("win 0") > -1){ | ||
tcpkill.kill('SIGINT'); | ||
// TCPKILL DETECTED WAMP ACTIVITY (WAMP reconnection attempts) | ||
// This is the stage triggered when the WAMP socket was killed by tcpkill and WAMP reconnection process automaticcally started: | ||
// in this phase we need to kill tcpkill to allow WAMP reconnection. | ||
try{ | ||
} | ||
logger.debug('[WAMP-RECOVERY] ... killing tcpkill process with PID: ' + tcpkill_pid); | ||
process.kill(tcpkill_pid); | ||
}, 3000); | ||
}catch (e) { | ||
logger.error('[WAMP-RECOVERY] ... tcpkill killing error: ', e); | ||
} | ||
tcpkill.kill('SIGINT'); | ||
//double check: It will test after a while if the tcpkill process has been killed | ||
@@ -342,58 +286,32 @@ setTimeout(function(){ | ||
}catch (e) { | ||
logger.error('[WAMP-RECOVERY] ... tcpkill killing error: ', e); | ||
} | ||
/* | ||
tcpkill.kill('SIGINT'); | ||
//double check: It will test after a while if the tcpkill process has been killed | ||
setTimeout(function(){ | ||
}); | ||
if ( running(tcpkill_pid) || tcpkill_pid == null){ | ||
tcpkill.on('close', function (code) { | ||
tcpkill_kill_count = tcpkill_kill_count + 1; | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill killed!'); | ||
logger.info("[WAMP-RECOVERY] - WAMP socket cleaned!"); | ||
logger.warn("[WAMP-RECOVERY] ... tcpkill still running!!! PID ["+tcpkill_pid+"]"); | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill killing retry_count '+ tcpkill_kill_count); | ||
//The previous WAMP socket was KILLED and the automatic WAMP recovery process will start | ||
//so the connection recovery is completed and "online" flag is set again to TRUE | ||
online = true; | ||
tcpkill.kill('SIGINT'); | ||
}); | ||
} | ||
}else{ | ||
}, 3000); | ||
*/ | ||
logger.warn('[WAMP-RECOVERY] ...tcpkill already started!'); | ||
} | ||
} | ||
}); | ||
}, 2 * 1000); | ||
tcpkill.on('close', function (code) { | ||
logger.debug('[WAMP-RECOVERY] ... tcpkill killed!'); | ||
logger.info("[WAMP-RECOVERY] - WAMP socket cleaned!"); | ||
//The previous WAMP socket was KILLED and the automatic WAMP recovery process will start | ||
//so the connection recovery is completed and "online" flag is set again to TRUE | ||
online = true; | ||
}); | ||
}else{ | ||
logger.warn('[WAMP-RECOVERY] ...tcpkill already started!'); | ||
} | ||
} | ||
); | ||
}, 2 * 1000); //time to wait for WAMP alive message response | ||
@@ -417,114 +335,108 @@ } | ||
//---------------------------------------------------------------------------------------------------- | ||
}, | ||
function (err) { | ||
// IoTronic is not connected to the realm yet so LR need to try to reconnect later | ||
logger.error("[SYSTEM] - IoTronic is not online: " + JSON.stringify(err) ); | ||
//if (err.error !== 'wamp.error.no_such_procedure') {} | ||
logger.warn("[SYSTEM] - Lightning-rod reconnecting..."); | ||
}; | ||
wampConnection.close(); | ||
//------------------------------- | ||
// 4. On WAMP connection close | ||
//------------------------------- | ||
//This function is called if there are problems with the WAMP connection | ||
wampConnection.onclose = function (reason, details) { | ||
setTimeout(function(){ | ||
wampConnection.open(); | ||
}, 10 * 1000); //time to wait for the next reconnection attempt | ||
try{ | ||
wamp_check = true; // IMPORTANT: for ethernet connections this flag avoid to start recovery procedure (tcpkill will not start!) | ||
} | ||
); | ||
logger.error('[WAMP] - Error in connecting to WAMP server!'); | ||
logger.error('- Reason: ' + reason); | ||
logger.error('- Reconnection Details: '); | ||
logger.error(" - retry_delay:", details.retry_delay); | ||
logger.error(" - retry_count:", details.retry_count); | ||
logger.error(" - will_retry:", details.will_retry); | ||
if(wampConnection.isOpen){ | ||
logger.info("[WAMP] - connection is open!"); | ||
} | ||
else{ | ||
logger.warn("[WAMP] - connection is closed!"); | ||
} | ||
} | ||
catch(err){ | ||
logger.warn('[WAMP] - Error in WAMP connection: '+ err); | ||
} | ||
//---------------------------------------------------------------------------------------------------- | ||
}; | ||
}; | ||
//------------------------------- | ||
// 4. On WAMP connection close | ||
//------------------------------- | ||
//This function is called if there are problems with the WAMP connection | ||
wampConnection.onclose = function (reason, details) { | ||
//-------------------------------------------------------------- | ||
// 2. The selected device will connect to Iotronic WAMP server | ||
//-------------------------------------------------------------- | ||
switch(device){ | ||
try{ | ||
case 'arduino_yun': | ||
logger.info("[SYSTEM] - Lightning-rod Arduino Yun starting..."); | ||
var yun = require('./device/arduino_yun'); | ||
yun.Main(wampConnection, logger); | ||
break; | ||
wamp_check = true; // IMPORTANT: for ethernet connections this flag avoid to start recovery procedure (tcpkill will not start!) | ||
case 'server': | ||
logger.info("[SYSTEM] - Lightning-rod server starting..."); | ||
var server = require('./device/server'); | ||
server.Main(wampConnection, logger); | ||
break; | ||
logger.error('[WAMP] - Error in connecting to WAMP server!'); | ||
logger.error('- Reason: ' + reason); | ||
logger.error('- Reconnection Details: '); | ||
logger.error(" - retry_delay:", details.retry_delay); | ||
logger.error(" - retry_count:", details.retry_count); | ||
logger.error(" - will_retry:", details.will_retry); | ||
case 'raspberry_pi': | ||
logger.info("[SYSTEM] - Lightning-rod Raspberry Pi starting..."); | ||
var raspberry_pi = require('./device/raspberry_pi'); | ||
raspberry_pi.Main(wampConnection, logger); | ||
break; | ||
case 'android': | ||
logger.info("[SYSTEM] - L-R Android starting..."); | ||
var yun = require('./device/android'); | ||
yun.Main(wampConnection, logger); | ||
break; | ||
default: | ||
logger.warn('[SYSTEM] - Device "' + device + '" not supported!'); | ||
logger.warn('[SYSTEM] - Supported devices are: "server", "arduino_yun", "raspberry_pi".'); | ||
process.exit(); | ||
break; | ||
if(wampConnection.isOpen){ | ||
logger.info("[WAMP] - connection is open!"); | ||
} | ||
else{ | ||
logger.warn("[WAMP] - connection is closed!"); | ||
} | ||
} | ||
catch(err){ | ||
logger.warn('[WAMP] - Error in WAMP connection: '+ err); | ||
} | ||
}); | ||
}; | ||
//-------------------------------------------------------------- | ||
// 2. The selected device will connect to Iotronic WAMP server | ||
//-------------------------------------------------------------- | ||
switch(device){ | ||
case 'arduino_yun': | ||
var YunDevice = require('./device/lyt_arduino_yun'); | ||
lyt_device = new YunDevice(device); | ||
logger.info("[SYSTEM] - Lightning-rod "+ lyt_device.name +" starting..."); | ||
lyt_device.Main(wampConnection, logger); | ||
break; | ||
case 'server': | ||
var ServerDevice = require('./device/lyt_server'); | ||
lyt_device = new ServerDevice(device); | ||
logger.info("[SYSTEM] - Lightning-rod "+ lyt_device.name +" starting..."); | ||
lyt_device.Main(wampConnection, logger); | ||
break; | ||
case 'raspberry_pi': | ||
var RaspDevice = require('./device/lyt_raspberry_pi'); | ||
lyt_device = new RaspDevice(device); | ||
logger.info("[SYSTEM] - Lightning-rod "+ lyt_device.name +" starting..."); | ||
lyt_device.Main(wampConnection, logger); | ||
break; | ||
case 'android': | ||
var AndroidDevice = require('./device/lyt_android'); | ||
lyt_device = new AndroidDevice(device); | ||
logger.info("[SYSTEM] - Lightning-rod "+ lyt_device.name +" starting..."); | ||
lyt_device.Main(wampConnection, logger); | ||
break; | ||
default: | ||
logger.warn('[SYSTEM] - Device "' + device + '" not supported!'); | ||
logger.warn('[SYSTEM] - Supported devices are: "server", "arduino_yun", "raspberry_pi".'); | ||
process.exit(); | ||
break; | ||
} | ||
} | ||
}); | ||
@@ -531,0 +443,0 @@ |
@@ -20,2 +20,3 @@ #!/usr/bin/env node | ||
//############################################################################### | ||
require("./lightning-rod.js"); |
@@ -1,9 +0,18 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
@@ -39,8 +48,7 @@ //service logging configuration: "manageDrivers" | ||
/* | ||
This function mounts all enabled drivers ("autostart" flag set at true) every LR restarting. | ||
In particular: | ||
- at LR starting: each enabled driver will be mounted (by fuse) | ||
- after a Internet/WAMP connection recovery we don't mount again each enabled driver (because it is already mounted) but we will only declare/register again the RPC functions. | ||
*/ | ||
// RPC to mount all enabled drivers ("autostart" flag set at true) every LR restarting. | ||
// In particular: | ||
// - at LR starting: each enabled driver will be mounted (by fuse) | ||
// - after a Internet/WAMP connection recovery we don't mount again each enabled driver (because it is already mounted) but we will only declare/register again the RPC functions. | ||
exports.restartDrivers = function (){ | ||
@@ -60,3 +68,3 @@ | ||
logger.info('[DRIVER] - Restarting enabled drivers on board: '); | ||
logger.info('[DRIVER] - Restarting enabled drivers on board...'); | ||
@@ -222,3 +230,3 @@ for(var i = 0; i < driver_num; i++) { | ||
}else{ | ||
logger.info("[DRIVER] - "+driver_name+" --> Status -> "+status+": this plugin does not have to be started!"); | ||
logger.info("[DRIVER] - " + driver_name + ": this driver does not have to be started!"); | ||
} | ||
@@ -246,116 +254,3 @@ } | ||
// Wrapper for Fuse read-directory function | ||
function readdirFunction(driver_name){ | ||
return function (mountpoint, cb) { | ||
logger.debug("[DRIVER] - "+driver_name+" --> readdir(%s) - files list: %s", mountpoint, JSON.stringify(file_list[driver_name]) ); | ||
//if (mountpoint === '/') return cb(0, [driver_name]); | ||
//if (mountpoint === '/'+driver_name) return cb(0, file_list[driver_name] ); | ||
if (mountpoint === '/') return cb(0, file_list[driver_name] ); | ||
cb(0); | ||
}; | ||
} | ||
// Wrapper for Fuse get-attr function | ||
function getattrFunction(driver_name){ | ||
return function (mountpoint, cb) { | ||
logger.debug("[DRIVER] - "+driver_name+" --> getattr(%s)", mountpoint); | ||
driver_mp_node = mp_list[driver_name]; | ||
if(driver_mp_node[mountpoint].mp != undefined){ | ||
cb(0, driver_mp_node[mountpoint].mp ); | ||
return | ||
} | ||
cb(fuse.ENOENT); | ||
} | ||
} | ||
// Wrapper for Fuse open-file function | ||
function openFunction(driver_name){ | ||
return function (mountpoint, flags, cb) { | ||
fd_index = fd_index + 1; | ||
logger.debug("[DRIVER] - "+driver_name+" --> Open(%s, %d) - fd = %s", mountpoint, flags, fd_index); | ||
cb(0, fd_index); //cb(0, 42) // 42 is an fd | ||
} | ||
} | ||
// Wrapper for Fuse read-file function | ||
function readFunction(driver_name, mirror_board){ | ||
return function (mountpoint, fd, buf, len, pos, cb) { | ||
driver_mp_node = mp_list[driver_name]; | ||
var driver = drivers[driver_name]; | ||
// To read a file of a driver mounted locally that return as result the value of a local endpoint (a sensor, etc.) | ||
if (driver_mp_node['/'].remote === "false"){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Read(%s, %d, %d, %d)", mountpoint, fd, len, pos); | ||
driver[driver_mp_node[mountpoint].read_function]( function(read_content){ | ||
var buffer = new Buffer(read_content.toString(), 'utf-8'); | ||
var str = ''+buffer.slice(pos); | ||
if (!str) | ||
return cb(0); | ||
buf.write(str); | ||
return cb(str.length); | ||
}); | ||
}else{ | ||
// To read a file of a driver mounted locally that return as result the value of a remote endpoint (i.e. a sensor on a remote board, etc.) | ||
// A mirrored board is a board that share its hardware that can be used by a board that mount remotely the same driver. | ||
var filename = mountpoint.replace('/',''); | ||
logger.debug('[DRIVER] - '+driver_name+' - REMOTE CALLING to '+mirror_board + ' RPC called: s4t.'+mirror_board+'.driver.'+driver_name+'.'+filename+'.read'); | ||
// Call the RPC read function of the board that shares the hardware | ||
session_drivers.call('s4t.'+mirror_board+'.driver.'+driver_name+'.'+filename+'.read', [driver_name, filename]).then( | ||
function(read_content){ | ||
var buffer = new Buffer(read_content.toString(), 'utf-8'); | ||
var str = ''+buffer.slice(pos); | ||
if (!str) | ||
return cb(0); | ||
buf.write(str); | ||
return cb(str.length); | ||
} | ||
); | ||
} | ||
} | ||
} | ||
// RPC function that allows to read the value of a file remotely. | ||
// RPC allows to read the value of a file remotely. | ||
// This remote call function is used in two cases: | ||
@@ -410,3 +305,3 @@ // - REMOTE - FALSE: the cloud sends a request to know the content of a local file | ||
return d.resolve(0); | ||
logger.info('[DRIVER] - '+driver_name+' - MIRRORED read remote from '+mirror_board+': ['+filename+'] -> '+ str); | ||
logger.info('[DRIVER] - '+driver_name+' - MIRRORED REMOTE READ from '+mirror_board+': ['+filename+'] -> '+ str); | ||
d.resolve(str); | ||
@@ -417,3 +312,3 @@ | ||
// call failed | ||
logger.warn('[DRIVER] - '+driver_name+' - MIRRORED read remote from '+mirror_board+' failed! - Error: '+ JSON.stringify(error)); | ||
logger.warn('[DRIVER] - '+driver_name+' - MIRRORED REMOTE READ from '+mirror_board+' failed! - Error: '+ JSON.stringify(error)); | ||
var error_log = "ERROR: " + error["error"]; | ||
@@ -433,31 +328,3 @@ d.resolve( error_log ); | ||
// Wrapper for Fuse write-file function. | ||
function writeFunction(driver, driver_name){ | ||
return function (mountpoint, fd, buffer, length, position, cb) { | ||
logger.debug('[DRIVER] - '+driver_name+' --> Writing ', buffer.slice(0, length)); | ||
content = buffer.slice(0, length); | ||
logger.debug('[DRIVER] - '+driver_name+' --> buffer content: ' + content.toString()); | ||
logger.debug('[DRIVER] - '+driver_name+' --> buffer length: ' + length.toString()); | ||
driver_mp_node = mp_list[driver_name]; | ||
if (driver_mp_node[mountpoint].write_function === null){ | ||
cb(fuse.EACCES); | ||
} else { | ||
driver[driver_mp_node[mountpoint].write_function ]( content, function(){ | ||
cb(length); | ||
}); | ||
} | ||
}; | ||
} | ||
// RPC function that allows to write a file remotely. | ||
// RPC allows to write a file remotely. | ||
// This remote call function is used in two cases: | ||
@@ -525,3 +392,3 @@ // - REMOTE - FALSE: the cloud sends a request to write in a local file | ||
// Stub RPC function used for the files that don't have an implemented read/write function. | ||
// Stub RPC to used for the files that don't have an implemented read/write function. | ||
exports.NotAllowedRemoteFunction = function (args){ | ||
@@ -535,354 +402,3 @@ | ||
// Function used to convert file permission rappresentation from base 10 to 8 | ||
function MaskConversion(mode_b10){ | ||
//var mode_b10 = 100644//40755 | ||
mode_b8 = parseInt(mode_b10.toString(10), 8); | ||
//logger.info("from b10 "+mode_b10+" to b8 "+mode_b8) | ||
permission = mode_b8; | ||
return permission | ||
} | ||
/* | ||
function HumanMaskConversion(mode_b10){ | ||
mode_b8 = parseInt(mode_b10.toString(10), 8) | ||
//logger.info("from b10 "+mode_b10+" to b8 "+mode_b8) | ||
permission = mode_b8 | ||
return permission | ||
} | ||
*/ | ||
// Function used to manage the promise of the RPC function registration for each file enabled to be read remotely. | ||
function ManageReadFileRegistration(registration, driver_name, file, driver_mp_node, idx, list){ | ||
driver_mp_node['/'+file.name].reg_read_function = registration; | ||
logger.debug('[WAMP] - '+driver_name+' --> ' + file.name + ' read function registered!'); | ||
if (idx === list.length - 1){ | ||
mp_list[driver_name] = driver_mp_node; | ||
logger.info("[DRIVER] - "+driver_name+" --> RPC read functions successfully registered!"); | ||
} | ||
} | ||
// Function used to manage the promise of the RPC function registration for each file enabled to be written remotely. | ||
function ManageWriteFileRegistration(registration, driver_name, file, driver_mp_node, idx, list){ | ||
driver_mp_node['/'+file.name].reg_write_function = registration; | ||
logger.debug('[WAMP] - '+driver_name+' --> ' + file.name + ' write function registered!'); | ||
if (idx === list.length - 1){ | ||
mp_list[driver_name] = driver_mp_node; | ||
logger.info("[DRIVER] - "+driver_name+" --> RPC write functions successfully registered!"); | ||
} | ||
} | ||
// Function used to register WAMP write/read functions for each enabled file | ||
function RegisterFiles(driver_name, file, driver_mp_node, idx, list){ | ||
if(file.read_function != undefined){ | ||
session_drivers.register('s4t.'+boardCode+'.driver.'+driver_name+'.'+file.name+'.read', exports.readRemote ).then( | ||
function(registration){ | ||
ManageReadFileRegistration(registration, driver_name, file, driver_mp_node, idx, list); | ||
} | ||
); | ||
}else{ | ||
session_drivers.register('s4t.'+boardCode+'.driver.'+driver_name+'.'+file.name+'.read', exports.NotAllowedRemoteFunction ).then( | ||
function(registration){ | ||
ManageReadFileRegistration(registration, driver_name, file, driver_mp_node, idx, list); | ||
} | ||
); | ||
} | ||
if(file.write_function != undefined){ | ||
session_drivers.register('s4t.'+boardCode+'.driver.'+driver_name+'.'+file.name+'.write', exports.writeRemote ).then( | ||
function(registration){ | ||
ManageWriteFileRegistration(registration, driver_name, file, driver_mp_node, idx, list); | ||
} | ||
); | ||
}else{ | ||
session_drivers.register('s4t.'+boardCode+'.driver.'+driver_name+'.'+file.name+'.write', exports.NotAllowedRemoteFunction ).then( | ||
function(registration){ | ||
ManageWriteFileRegistration(registration, driver_name, file, driver_mp_node, idx, list); | ||
} | ||
); | ||
} | ||
} | ||
// Function used to mount via FUSE the driver and register the RPC functions for each file; | ||
// if the driver mounting happens after a connection recovery we will only register again the RPC functions without re-mounting the driver via FUSE. | ||
function LoadDriver(driver_name, mountpoint, remote, mirror_board){ | ||
var driver_path = DRIVERS_STORE+driver_name; | ||
var driver_conf = driver_path+"/"+driver_name+".json"; | ||
var driver_module = driver_path+"/"+driver_name+".js"; | ||
var rest_response = {}; | ||
var d = Q.defer(); | ||
try{ | ||
var driver = require(driver_module); | ||
var driverJSON = JSON.parse(fs.readFileSync(driver_conf, 'utf8')); | ||
logger.debug('[DRIVER] - '+driver_name+' --> JSON file '+ driver_name +'.json successfully parsed!'); | ||
driver_name = driverJSON.name; | ||
var type = driverJSON.type; //logger.info("\tfile type: " + type) | ||
var permissions = MaskConversion(driverJSON.permissions); //logger.info("\tpermissions: " + MaskConversion(permissions)) | ||
//var root_permissions = MaskConversion(driverJSON.root_permissions); | ||
var children = driverJSON.children; //logger.info("Files in the folder:") | ||
logger.debug("[DRIVER] - "+driver_name+" --> driver configuration loaded!"); | ||
mp_list[driver_name]={}; | ||
driver_mp_node = mp_list[driver_name]; | ||
fuse_root_path='/'; | ||
var root_mp = { | ||
mtime: new Date(), | ||
atime: new Date(), | ||
ctime: new Date(), | ||
size: 100, | ||
mode: permissions, | ||
uid: process.getuid(), | ||
gid: process.getgid() | ||
}; | ||
driver_mp_node[fuse_root_path]={ | ||
name: driver_name, | ||
mp: {}, | ||
remote: remote, | ||
mirror_board: mirror_board | ||
}; | ||
driver_mp_node[fuse_root_path].mp=root_mp; | ||
driver_mp_node[fuse_root_path].type = "folder"; | ||
file_list[driver_name]=[]; | ||
children.forEach(function(file, idx, list) { | ||
setTimeout(function() { | ||
logger.debug("[DRIVER] - "+driver_name+" --> analyzing file: "+file.name); | ||
file_list[driver_name].push(file.name); | ||
//fuse_file_path='/'+driver_name+'/'+file.name; | ||
fuse_file_path='/'+file.name; | ||
driver_mp_node[fuse_file_path]={ | ||
name:"", | ||
read_function: null, | ||
write_function: null, | ||
mp: {}, | ||
reg_read_function: null, | ||
reg_write_function: null | ||
}; | ||
if(file.read_function != undefined){ | ||
var read_function = file.read_function; | ||
}else{ | ||
var read_function = null; | ||
} | ||
if(file.write_function != undefined){ | ||
var write_function = file.write_function; | ||
}else{ | ||
var write_function = null; | ||
} | ||
var file_mp = { | ||
mtime: new Date(), | ||
atime: new Date(), | ||
ctime: new Date(), | ||
size: 100, | ||
mode: MaskConversion(file.permissions), | ||
uid: process.getuid(), | ||
gid: process.getgid() | ||
}; | ||
driver_mp_node[fuse_file_path].mp = file_mp; | ||
driver_mp_node[fuse_file_path].name = file.name; | ||
driver_mp_node[fuse_file_path].type = "file"; | ||
driver_mp_node[fuse_file_path].read_function = read_function; | ||
driver_mp_node[fuse_file_path].write_function = write_function; | ||
RegisterFiles(driver_name, file, driver_mp_node, idx, list); | ||
if (idx === list.length - 1){ | ||
logger.info("[DRIVER] - "+driver_name+" --> Available files: %s", JSON.stringify(file_list[driver_name])); | ||
} | ||
}, 100); // end of setTimeout function | ||
}); | ||
if ( reconnected === false ){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> It is necessary to mount the driver (reconnected = " + reconnected + ")"); | ||
try{ | ||
drivers[driver_name] = driver; | ||
var driverlib = drivers[driver_name]; | ||
driverlib['init']( function(init_response){ | ||
if(init_response.result == "SUCCESS"){ | ||
logger.info("[DRIVER] - "+driver_name+" --> " + init_response.message); | ||
fuse.mount(mountpoint, { | ||
readdir: readdirFunction(driver_name), | ||
getattr: getattrFunction(driver_name), | ||
open: openFunction(driver_name), | ||
read: readFunction(driver_name, mirror_board), //read: readFunction(driver_name, filename, mirror_board), | ||
write: writeFunction(driver, driver_name) | ||
}); | ||
rest_response.message = "Driver '"+driver_name+"' successfully mounted!"; | ||
rest_response.result = "SUCCESS"; | ||
d.resolve(rest_response); | ||
} | ||
else{ | ||
logger.warn("[DRIVER] - "+driver_name+" --> " + init_response.message); | ||
rest_response.message = "ERROR during "+driver_name+" initialization -> " +init_response.message; | ||
rest_response.result = "ERROR"; | ||
d.reject(rest_response); | ||
} | ||
}); | ||
} | ||
catch(err){ | ||
rest_response.message = "ERROR during "+driver_name+" (fuse) mounting: " +err; | ||
rest_response.result = "ERROR"; | ||
logger.warn("[DRIVER] - "+driver_name+" --> " + rest_response.message); | ||
d.reject(rest_response); | ||
} | ||
}else{ | ||
logger.debug("[DRIVER] - "+driver_name+" --> It is not necessary to mount the driver (reconnected = " + reconnected + ")"); | ||
if(reconnected === true) reconnected = false; | ||
rest_response.message = "No need to mount driver after reconnection!"; | ||
rest_response.result = "SUCCESS"; | ||
d.resolve(rest_response); | ||
} | ||
} | ||
catch(err){ | ||
rest_response.message = err; | ||
rest_response.result = "ERROR"; | ||
d.reject(rest_response); | ||
} | ||
return d.promise; | ||
} | ||
// Function that creates the directory and then mounts the driver. | ||
function MountpointCreation(driver_name, mountpoint, remote, mirror_board, d){ | ||
fs.mkdir(mountpoint, 0755, function() { | ||
logger.debug("[DRIVER] - "+driver_name+" ----> folder "+mountpoint+" CREATED!"); | ||
AttachMountpoint(driver_name, mountpoint, remote, mirror_board, d); | ||
}); | ||
} | ||
// Function that calls the LoadDriver function that will mount the driver | ||
function AttachMountpoint(driver_name, mountpoint, remote, mirror_board, d) { | ||
LoadDriver(driver_name, mountpoint, remote, mirror_board).then( | ||
function(result){ | ||
manageDriversConf("update", driver_name, null, "mounted", remote, mirror_board, function(mng_result){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Mounting: " + mng_result.message); | ||
d.resolve(result); | ||
logger.info("[DRIVER] - "+driver_name+" --> "+ result.message); | ||
}); | ||
}, | ||
function (error) { | ||
logger.warn("[DRIVER] - "+driver_name+" --> Error in LoadDriver function: "+ JSON.stringify(error)); | ||
d.reject(error); | ||
} | ||
); | ||
} | ||
//This function mounts a driver | ||
// RPC to mount a driver | ||
exports.mountDriver = function (args){ | ||
@@ -936,3 +452,3 @@ | ||
logger.error("[DRIVER] - "+driver_name+" --> "+rest_response.message); | ||
d.reject(rest_response); | ||
d.resolve(rest_response); | ||
@@ -948,3 +464,3 @@ } | ||
logger.error("[DRIVER] - "+driver_name+" --> "+rest_response.message); | ||
d.reject(rest_response); | ||
d.resolve(rest_response); | ||
} | ||
@@ -958,110 +474,3 @@ | ||
// Function to un-register from WAMP server the RPCs of each file of the driver during unmounting | ||
function UnRegister(driver_name, file_node, restarting, rest_response, d, callback){ | ||
var driver_mp_node = mp_list[driver_name]; | ||
// If this data structure is not null means that the driver to unmount was mounted in this session and we need to unregister each RPC function related to each driver file | ||
if (driver_mp_node != null){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Data structures to clean..."); | ||
// Unregistering RPCs for each file | ||
file_node.forEach(function(file, idx, list) { | ||
logger.debug("[DRIVER] - "+driver_name+" --> Unregistering ("+file.name+") read_function: " + JSON.stringify(driver_mp_node['/'+file.name].read_function)); | ||
if ( driver_mp_node['/'+file.name] != undefined) { | ||
logger.debug("[DRIVER] - "+driver_name+" --> WAMP DRIVER STATUS: restarting = "+restarting + " - reconnected = " + reconnected); | ||
if ( restarting === "undefined" && reconnected === false ){ | ||
//Unregistering read RPC functions | ||
session_drivers.unregister(driver_mp_node['/'+file.name].reg_read_function).then( | ||
function () { | ||
// successfully unregistered | ||
logger.debug("[DRIVER] - "+driver_name+" --> RPC read function of "+file.name +" unregistered!"); | ||
}, | ||
function (error) { | ||
// unregister failed | ||
logger.error("[DRIVER] - "+driver_name+" --> Error unregistering RPC read function of "+file); | ||
} | ||
); | ||
//Unregistering write RPC functions | ||
session_drivers.unregister(driver_mp_node['/'+file.name].reg_write_function).then( | ||
function () { | ||
// successfully unregistered | ||
logger.debug("[DRIVER] - "+driver_name+" --> RPC write function of "+file.name +" unregistered!"); | ||
}, | ||
function (error) { | ||
// unregister failed | ||
logger.error("[DRIVER] - "+driver_name+" --> Error unregistering RPC write function of "+file); | ||
} | ||
); | ||
}else{ | ||
logger.debug("[DRIVER] - No need to unregister any WAMP RPC!"); | ||
} | ||
} | ||
else{ | ||
logger.debug("[DRIVER] - "+driver_name+" --> I have not unregistered RPC file ("+file.name+") functions!"); | ||
} | ||
// If it is the last file analyzed we have to clean the driver garbage | ||
if (idx === list.length - 1){ | ||
//DATA cleaning----------------------------------------------------------------------------------------- | ||
try{ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Cleaning driver garbage..."); | ||
file_list[driver_name]=null; | ||
delete file_list[driver_name]; | ||
logger.debug("[DRIVER] - "+driver_name+" --> Files removed from list!" ); | ||
mp_list[driver_name]=null; | ||
delete mp_list[driver_name]; | ||
logger.debug("[DRIVER] - "+driver_name+" --> Mountpoints removed!"); | ||
callback({result:"SUCCESS", message:"RPCs unregistered"}) | ||
} | ||
catch(err){ | ||
logger.error("[DRIVER] - "+driver_name+" --> Data cleaning error during unmounting: "+err); | ||
} | ||
//------------------------------------------------------------------------------------------------------ | ||
} | ||
}); | ||
} | ||
else{ | ||
logger.debug("[DRIVER] - "+driver_name+" --> No data structures to clean..."); | ||
callback({result:"SUCCESS", message:"RPCs unregistered"}); | ||
} | ||
} | ||
//This function unmounts a driver | ||
// RPC to unmount a driver | ||
exports.unmountDriver = function (args){ | ||
@@ -1125,3 +534,3 @@ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Unmounting: " + mng_result.message); | ||
logger.debug("[DRIVER] - "+driver_name+" --> " + mng_result.message); | ||
@@ -1142,3 +551,3 @@ rest_response.message = "Driver '"+driver_name+"' successfully unmounted!"; | ||
logger.error("[DRIVER] - "+driver_name+" --> "+JSON.stringify(rest_response.message)); | ||
d.reject(err); | ||
d.resolve(rest_response); | ||
@@ -1165,3 +574,3 @@ } | ||
logger.error("[DRIVER] - "+driver_name+" --> Error during driver configuration loading: "+err); | ||
d.reject(err); | ||
d.resolve(err); | ||
} | ||
@@ -1173,6 +582,6 @@ | ||
catch(err){ | ||
rest_response.message = "ERROR during '"+driver_name+"' (fuse) unmounting: " +err; | ||
rest_response.message = "Generic error during '"+driver_name+"' (fuse) unmounting: " +err; | ||
rest_response.result = "ERROR"; | ||
logger.error("[DRIVER] - "+driver_name+" --> "+ rest_response.message); | ||
d.reject(err); | ||
d.resolve(err); | ||
} | ||
@@ -1184,3 +593,4 @@ | ||
//This function injects a driver in the board: it is called (via RPC) from the Cloud side to manage a driver injection | ||
// RPC to inject a driver in the board: it is called (via RPC) from the Cloud side to manage a driver injection | ||
exports.injectDriver = function (args){ | ||
@@ -1194,2 +604,4 @@ | ||
logger.info("[DRIVER] - INJECTING driver '" + driver_name + "'..."); | ||
var d = Q.defer(); | ||
@@ -1201,34 +613,31 @@ var rpc_result = ""; | ||
var driver_file_name = driver_folder+'/' + driver_name + '.js'; | ||
var driver_schema_name = driver_folder+'/' + driver_name + '.json'; | ||
// Check driver folder | ||
if ( fs.existsSync(driver_folder) === false ){ | ||
logger.debug("[DRIVER] - Called RPC injectDriver with: \n - driver_name = " + driver_name + "\n - autostart = " + autostart + "\n - driver_code = \n###############################################################################\n" + driver_code + "\n###############################################################################\n\n\n - driver_schema = \n###############################################################################\n" + driver_schema+"\n###############################################################################\n"); | ||
if (loglevel != "debug" || loglevel != "DEBUG") | ||
logger.info("[DRIVER] - Called RPC injectDriver with: driver_name = " + driver_name + ", autostart = " + autostart); | ||
// driver folder creation | ||
fs.mkdir(driver_folder, function() { | ||
// driver file creation | ||
fs.writeFile(driver_file_name, driver_code, function(err) { | ||
if(err) { | ||
var driver_schema_name = driver_folder+'/' + driver_name + '.json'; | ||
rpc_result = 'Error writing '+ driver_file_name +' file: ' + err; | ||
logger.error('[DRIVER] - '+driver_name+' --> ' + rpc_result); | ||
d.resolve(rpc_result); | ||
logger.debug("[DRIVER] - " + driver_name + " - Checking driver environment..."); | ||
} else { | ||
cleanDriverData(driver_name).then( | ||
function (clean_res) { | ||
// driver schema file creation | ||
fs.writeFile(driver_schema_name, driver_schema, function(err) { | ||
if (clean_res.result == "SUCCESS"){ | ||
logger.debug("[DRIVER] - " + driver_name + " --> driver environment is clean!"); | ||
if (loglevel !== "debug" && loglevel !== "DEBUG") | ||
logger.info("[DRIVER] - Called RPC injectDriver with: driver_name = " + driver_name + ", autostart = " + autostart); | ||
else | ||
logger.info("[DRIVER] - Called RPC injectDriver with: \n - driver_name = " + driver_name + "\n - autostart = " + autostart + "\n - driver_code = \n###############################################################################\n" + driver_code + "\n###############################################################################\n\n\n - driver_schema = \n###############################################################################\n" + driver_schema+"\n###############################################################################\n"); | ||
// driver folder creation | ||
fs.mkdir(driver_folder, function() { | ||
// driver file creation | ||
fs.writeFile(driver_file_name, driver_code, function(err) { | ||
if(err) { | ||
rpc_result = 'Error writing '+ driver_schema +' file: ' + err; | ||
rpc_result = 'Error writing '+ driver_file_name +' file: ' + err; | ||
logger.error('[DRIVER] - '+driver_name+' --> ' + rpc_result); | ||
@@ -1240,15 +649,32 @@ | ||
manageDriversConf("update", driver_name, autostart, "injected", null, null, function(mng_result){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Injecting: " + mng_result.message); | ||
// driver schema file creation | ||
fs.writeFile(driver_schema_name, driver_schema, function(err) { | ||
rpc_result = "Driver " + driver_name + " successfully injected!"; | ||
logger.info("[DRIVER] --> " + rpc_result); | ||
if(err) { | ||
d.resolve(rpc_result); | ||
rpc_result = 'Error writing '+ driver_schema +' file: ' + err; | ||
logger.error('[DRIVER] - '+driver_name+' --> ' + rpc_result); | ||
d.resolve(rpc_result); | ||
} else { | ||
manageDriversConf("update", driver_name, autostart, "injected", null, null, function(mng_result){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> " + mng_result.message); | ||
rpc_result = "Driver " + driver_name + " successfully injected!"; | ||
logger.info("[DRIVER] --> " + rpc_result); | ||
d.resolve(rpc_result); | ||
}); | ||
} | ||
}); | ||
} | ||
@@ -1258,17 +684,15 @@ | ||
} | ||
}); | ||
}); | ||
}); | ||
} else{ | ||
rpc_result = "ERROR: "+driver_name+" driver's files already injected! - Remove the previous driver installation!"; | ||
logger.warn("[DRIVER] --> " + rpc_result); | ||
d.resolve(rpc_result); | ||
}else{ | ||
logger.error("[DRIVER] --> " + clean_res.message); | ||
d.resolve(clean_res.message); | ||
} | ||
} | ||
} | ||
); | ||
return d.promise; | ||
@@ -1279,3 +703,80 @@ | ||
// RPC to totally remove a driver from the board | ||
exports.removeDriver = function(args){ | ||
// Parsing the input arguments | ||
var driver_name = String(args[0]); | ||
logger.info("[DRIVER] - REMOVE DRIVER RPC called for " + driver_name + "..."); | ||
var d = Q.defer(); | ||
cleanDriverData(driver_name).then( | ||
function (clean_res) { | ||
if (clean_res.result == "SUCCESS"){ | ||
clean_res.message = "Driver '" + driver_name + "' successfully removed!"; | ||
logger.info("[PLUGIN] --> " + clean_res.message); | ||
d.resolve(clean_res.message); | ||
}else{ | ||
logger.error("[PLUGIN] --> " + clean_res.message); | ||
d.resolve(clean_res.message); | ||
} | ||
} | ||
); | ||
return d.promise; | ||
}; | ||
// Function to clean all plugin data (folder and configuration) | ||
function cleanDriverData(driver_name){ | ||
var response = { | ||
message: '', | ||
result: '' | ||
}; | ||
var d = Q.defer(); | ||
var driver_folder = DRIVERS_STORE + driver_name; | ||
var mp_driver_folder = MP_DRIVERS + driver_name; | ||
if ( fs.existsSync(driver_folder) === true ){ | ||
deleteFolderRecursive(driver_folder); //delete driver files folder | ||
deleteFolderRecursive(mp_driver_folder); //delete driver mountpoint folder | ||
logger.debug("[DRIVER] - " + driver_name + " --> driver folders deleted."); | ||
} | ||
else{ | ||
logger.debug("[DRIVER] - " + driver_name + " --> driver folder already deleted."); | ||
} | ||
manageDriversConf("remove", driver_name, null, null, null, null, function(mng_result) { | ||
if(mng_result.result == "SUCCESS"){ | ||
response.result = mng_result.result; | ||
response.message = "Driver successfully removed!"; | ||
d.resolve(response); | ||
}else{ | ||
d.resolve(mng_result); | ||
} | ||
}); | ||
return d.promise; | ||
} | ||
// Function used to update/manage the status of the driver injected in the board | ||
@@ -1285,11 +786,11 @@ function manageDriversConf(operation, driver_name, autostart, status, remote, mirror_board, callback){ | ||
try{ | ||
var driversConf = JSON.parse(fs.readFileSync(DRIVERS_SETTING, 'utf8')); | ||
var mng_result = {}; | ||
switch(operation){ | ||
case 'update': | ||
logger.debug("[DRIVER] - "+driver_name+" --> Updating drivers.json..."); | ||
@@ -1317,3 +818,2 @@ logger.debug("[DRIVER] - "+driver_name+" --> Parameters specified:\n - status: "+status+"\n - remote: "+remote+ "\n - mirror_board: "+mirror_board+"\n - autostart: "+autostart); | ||
try{ | ||
@@ -1328,3 +828,3 @@ //Updates the JSON file | ||
} else { | ||
mng_result.message = "Drivers changes file saved to " + DRIVERS_SETTING; | ||
mng_result.message = "drivers.json updated"; | ||
mng_result.result = "SUCCESS"; | ||
@@ -1342,9 +842,9 @@ callback(mng_result) | ||
break; | ||
case 'remove': | ||
logger.debug("[DRIVER] - "+driver_name+" --> Removing driver board from drivers.json..."); | ||
if(driversConf["drivers"].hasOwnProperty(driver_name)){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> removing driver data from drivers.json..."); | ||
if(driversConf["drivers"].hasOwnProperty(driver_name)){ | ||
try{ | ||
@@ -1356,11 +856,11 @@ driversConf.drivers[driver_name]=null; | ||
if(err) { | ||
mng_result.message = "drivers.json file updating FAILED: "+err; | ||
mng_result.message = "drivers.json file updating failed: "+err; | ||
mng_result.result = "ERROR"; | ||
logger.debug("[DRIVER] - "+driver_name+" --> " + mng_result.message ); | ||
logger.error("[DRIVER] - "+driver_name+" ----> " + mng_result.message ); | ||
callback(mng_result); | ||
} else { | ||
mng_result.message = "Driver board successfully removed from drivers.json!"; | ||
mng_result.message = "driver data removed!"; | ||
mng_result.result = "SUCCESS"; | ||
logger.debug("[DRIVER] - "+driver_name+" --> " + mng_result.message ); | ||
logger.debug("[DRIVER] - "+driver_name+" ----> " + mng_result.message ); | ||
callback(mng_result); | ||
@@ -1375,16 +875,16 @@ | ||
mng_result.result = "ERROR"; | ||
logger.warn("[DRIVER] - "+driver_name+" --> "+ mng_result.message); | ||
logger.warn("[DRIVER] - "+driver_name+" ----> "+ mng_result.message); | ||
callback(mng_result); | ||
} | ||
}else { | ||
mng_result.message = "Driver already removed from drivers.json"; | ||
mng_result.message = "driver data already removed"; | ||
mng_result.result = "SUCCESS"; | ||
logger.warn("[DRIVER] - "+driver_name+" --> "+ mng_result.message); | ||
logger.debug("[DRIVER] - "+driver_name+" ----> "+ mng_result.message); | ||
callback(mng_result); | ||
} | ||
} | ||
break; | ||
default: | ||
@@ -1397,19 +897,18 @@ //DEBUG MESSAGE | ||
break; | ||
} | ||
} | ||
} | ||
catch(err){ | ||
logger.error('[DRIVER] - '+driver_name+' --> Error parsing drivers.json file in manageDriversConf: '+err); | ||
} | ||
logger.error('[DRIVER] - '+driver_name+' --> Error parsing drivers.json file in manageDriversConf: '+err); | ||
} | ||
} | ||
// Function used to delete all driver files during driver removing from the board | ||
function deleteFolderRecursive(path){ | ||
if( fs.existsSync(path) ) { | ||
@@ -1431,50 +930,591 @@ fs.readdirSync(path).forEach(function(file,index){ | ||
// Function to un-register from WAMP server the RPCs of each file of the driver during unmounting | ||
function UnRegister(driver_name, file_node, restarting, rest_response, d, callback){ | ||
var driver_mp_node = mp_list[driver_name]; | ||
// This function totally removes a driver from the board | ||
exports.removeDriver = function(args){ | ||
// Parsing the input arguments | ||
driver_name = String(args[0]); | ||
// If this data structure is not null means that the driver to unmount was mounted in this session and we need to unregister each RPC function related to each driver file | ||
if (driver_mp_node != null){ | ||
logger.info("[DRIVER] - REMOVE DRIVER RPC called for " + driver_name +"..."); | ||
var d = Q.defer(); | ||
var rpc_result = ""; | ||
var driver_folder = DRIVERS_STORE + driver_name; | ||
var mp_driver_folder = MP_DRIVERS+ driver_name; | ||
logger.debug("[DRIVER] - "+driver_name+" --> Data structures to clean..."); | ||
// Check driver folder | ||
if ( fs.existsSync(driver_folder) === true ){ | ||
// Unregistering RPCs for each file | ||
file_node.forEach(function(file, idx, list) { | ||
manageDriversConf("remove", driver_name, null, null, null, null, function(mng_result){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Unregistering ("+file.name+") read_function: " + JSON.stringify(driver_mp_node['/'+file.name].read_function)); | ||
deleteFolderRecursive(driver_folder); //delete driver files folder | ||
deleteFolderRecursive(mp_driver_folder); //delete driver mountpoint folder | ||
if ( driver_mp_node['/'+file.name] != undefined) { | ||
rpc_result = "Driver " + driver_name + " successfully removed!"; | ||
logger.info("[DRIVER] - "+driver_name+" --> " + rpc_result); | ||
logger.debug("[DRIVER] - "+driver_name+" --> WAMP DRIVER STATUS: restarting = "+restarting + " - reconnected = " + reconnected); | ||
d.resolve(rpc_result); | ||
if ( restarting === "undefined" && reconnected === false ){ | ||
//Unregistering read RPC functions | ||
session_drivers.unregister(driver_mp_node['/'+file.name].reg_read_function).then( | ||
function () { | ||
// successfully unregistered | ||
logger.debug("[DRIVER] - "+driver_name+" --> RPC read function of "+file.name +" unregistered!"); | ||
}, | ||
function (error) { | ||
// unregister failed | ||
logger.error("[DRIVER] - "+driver_name+" --> Error unregistering RPC read function of "+file); | ||
} | ||
); | ||
//Unregistering write RPC functions | ||
session_drivers.unregister(driver_mp_node['/'+file.name].reg_write_function).then( | ||
function () { | ||
// successfully unregistered | ||
logger.debug("[DRIVER] - "+driver_name+" --> RPC write function of "+file.name +" unregistered!"); | ||
}, | ||
function (error) { | ||
// unregister failed | ||
logger.error("[DRIVER] - "+driver_name+" --> Error unregistering RPC write function of "+file); | ||
} | ||
); | ||
}else{ | ||
logger.debug("[DRIVER] - No need to unregister any WAMP RPC!"); | ||
} | ||
} | ||
else{ | ||
logger.debug("[DRIVER] - "+driver_name+" --> I have not unregistered RPC file ("+file.name+") functions!"); | ||
} | ||
// If it is the last file analyzed we have to clean the driver garbage | ||
if (idx === list.length - 1){ | ||
//DATA cleaning----------------------------------------------------------------------------------------- | ||
try{ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Cleaning driver garbage..."); | ||
file_list[driver_name]=null; | ||
delete file_list[driver_name]; | ||
logger.debug("[DRIVER] - "+driver_name+" --> Files removed from list!" ); | ||
mp_list[driver_name]=null; | ||
delete mp_list[driver_name]; | ||
logger.debug("[DRIVER] - "+driver_name+" --> Mountpoints removed!"); | ||
callback({result:"SUCCESS", message:"RPCs unregistered"}) | ||
} | ||
catch(err){ | ||
logger.error("[DRIVER] - "+driver_name+" --> Data cleaning error during unmounting: "+err); | ||
} | ||
//------------------------------------------------------------------------------------------------------ | ||
} | ||
}); | ||
} else{ | ||
rpc_result = "WARNING - Folder of "+driver_name+" driver not found or already deleted!"; | ||
logger.warn("[DRIVER] - "+driver_name+" --> " + rpc_result); | ||
d.resolve(rpc_result); | ||
} | ||
return d.promise; | ||
}; | ||
} | ||
else{ | ||
logger.debug("[DRIVER] - "+driver_name+" --> No data structures to clean..."); | ||
callback({result:"SUCCESS", message:"RPCs unregistered"}); | ||
} | ||
} | ||
// Function used to manage the promise of the RPC function registration for each file enabled to be read remotely. | ||
function ManageReadFileRegistration(registration, driver_name, file, driver_mp_node, idx, list){ | ||
driver_mp_node['/'+file.name].reg_read_function = registration; | ||
logger.debug('[WAMP] - '+driver_name+' --> ' + file.name + ' read function registered!'); | ||
if (idx === list.length - 1){ | ||
mp_list[driver_name] = driver_mp_node; | ||
logger.info("[DRIVER] - "+driver_name+" --> RPC read functions successfully registered!"); | ||
} | ||
} | ||
// Function used to manage the promise of the RPC function registration for each file enabled to be written remotely. | ||
function ManageWriteFileRegistration(registration, driver_name, file, driver_mp_node, idx, list){ | ||
driver_mp_node['/'+file.name].reg_write_function = registration; | ||
logger.debug('[WAMP] - '+driver_name+' --> ' + file.name + ' write function registered!'); | ||
if (idx === list.length - 1){ | ||
mp_list[driver_name] = driver_mp_node; | ||
logger.info("[DRIVER] - "+driver_name+" --> RPC write functions successfully registered!"); | ||
} | ||
} | ||
// Function used to register WAMP write/read functions for each enabled file | ||
function RegisterFiles(driver_name, file, driver_mp_node, idx, list){ | ||
if(file.read_function != undefined){ | ||
session_drivers.register('s4t.'+boardCode+'.driver.'+driver_name+'.'+file.name+'.read', exports.readRemote ).then( | ||
function(registration){ | ||
ManageReadFileRegistration(registration, driver_name, file, driver_mp_node, idx, list); | ||
} | ||
); | ||
}else{ | ||
session_drivers.register('s4t.'+boardCode+'.driver.'+driver_name+'.'+file.name+'.read', exports.NotAllowedRemoteFunction ).then( | ||
function(registration){ | ||
ManageReadFileRegistration(registration, driver_name, file, driver_mp_node, idx, list); | ||
} | ||
); | ||
} | ||
if(file.write_function != undefined){ | ||
session_drivers.register('s4t.'+boardCode+'.driver.'+driver_name+'.'+file.name+'.write', exports.writeRemote ).then( | ||
function(registration){ | ||
ManageWriteFileRegistration(registration, driver_name, file, driver_mp_node, idx, list); | ||
} | ||
); | ||
}else{ | ||
session_drivers.register('s4t.'+boardCode+'.driver.'+driver_name+'.'+file.name+'.write', exports.NotAllowedRemoteFunction ).then( | ||
function(registration){ | ||
ManageWriteFileRegistration(registration, driver_name, file, driver_mp_node, idx, list); | ||
} | ||
); | ||
} | ||
} | ||
// Function used to mount via FUSE the driver and register the RPC functions for each file; | ||
// if the driver mounting happens after a connection recovery we will only register again the RPC functions without re-mounting the driver via FUSE; | ||
function LoadDriver(driver_name, mountpoint, remote, mirror_board){ | ||
var driver_path = DRIVERS_STORE+driver_name; | ||
var driver_conf = driver_path+"/"+driver_name+".json"; | ||
var driver_module = driver_path+"/"+driver_name+".js"; | ||
var rest_response = {}; | ||
var d = Q.defer(); | ||
try{ | ||
var driver = require(driver_module); | ||
var driverJSON = JSON.parse(fs.readFileSync(driver_conf, 'utf8')); | ||
logger.debug('[DRIVER] - '+driver_name+' --> JSON file '+ driver_name +'.json successfully parsed!'); | ||
driver_name = driverJSON.name; | ||
var type = driverJSON.type; //logger.info("\tfile type: " + type) | ||
var permissions = MaskConversion(driverJSON.permissions); //logger.info("\tpermissions: " + MaskConversion(permissions)) | ||
//var root_permissions = MaskConversion(driverJSON.root_permissions); | ||
var children = driverJSON.children; //logger.info("Files in the folder:") | ||
logger.debug("[DRIVER] - "+driver_name+" --> driver configuration loaded!"); | ||
mp_list[driver_name]={}; | ||
driver_mp_node = mp_list[driver_name]; | ||
fuse_root_path='/'; | ||
var root_mp = { | ||
mtime: new Date(), | ||
atime: new Date(), | ||
ctime: new Date(), | ||
size: 100, | ||
mode: permissions, | ||
uid: process.getuid(), | ||
gid: process.getgid() | ||
}; | ||
driver_mp_node[fuse_root_path]={ | ||
name: driver_name, | ||
mp: {}, | ||
remote: remote, | ||
mirror_board: mirror_board | ||
}; | ||
driver_mp_node[fuse_root_path].mp=root_mp; | ||
driver_mp_node[fuse_root_path].type = "folder"; | ||
file_list[driver_name]=[]; | ||
children.forEach(function(file, idx, list) { | ||
setTimeout(function() { | ||
logger.debug("[DRIVER] - "+driver_name+" --> analyzing file: "+file.name); | ||
file_list[driver_name].push(file.name); | ||
//fuse_file_path='/'+driver_name+'/'+file.name; | ||
fuse_file_path='/'+file.name; | ||
driver_mp_node[fuse_file_path]={ | ||
name:"", | ||
read_function: null, | ||
write_function: null, | ||
mp: {}, | ||
reg_read_function: null, | ||
reg_write_function: null | ||
}; | ||
if(file.read_function != undefined){ | ||
var read_function = file.read_function; | ||
}else{ | ||
var read_function = null; | ||
} | ||
if(file.write_function != undefined){ | ||
var write_function = file.write_function; | ||
}else{ | ||
var write_function = null; | ||
} | ||
var file_mp = { | ||
mtime: new Date(), | ||
atime: new Date(), | ||
ctime: new Date(), | ||
size: 100, | ||
mode: MaskConversion(file.permissions), | ||
uid: process.getuid(), | ||
gid: process.getgid() | ||
}; | ||
driver_mp_node[fuse_file_path].mp = file_mp; | ||
driver_mp_node[fuse_file_path].name = file.name; | ||
driver_mp_node[fuse_file_path].type = "file"; | ||
driver_mp_node[fuse_file_path].read_function = read_function; | ||
driver_mp_node[fuse_file_path].write_function = write_function; | ||
RegisterFiles(driver_name, file, driver_mp_node, idx, list); | ||
if (idx === list.length - 1){ | ||
logger.info("[DRIVER] - "+driver_name+" --> Available files: %s", JSON.stringify(file_list[driver_name])); | ||
} | ||
}, 100); // end of setTimeout function | ||
}); | ||
if ( reconnected === false ){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> It is necessary to mount the driver (reconnected = " + reconnected + ")"); | ||
try{ | ||
drivers[driver_name] = driver; | ||
var driverlib = drivers[driver_name]; | ||
driverlib['init']( function(init_response){ | ||
if(init_response.result == "SUCCESS"){ | ||
logger.info("[DRIVER] - "+driver_name+" --> " + init_response.message); | ||
fuse.mount(mountpoint, { | ||
readdir: readdirFunction(driver_name), | ||
getattr: getattrFunction(driver_name), | ||
open: openFunction(driver_name), | ||
read: readFunction(driver_name, mirror_board), //read: readFunction(driver_name, filename, mirror_board), | ||
write: writeFunction(driver, driver_name) | ||
}); | ||
rest_response.message = "Driver '"+driver_name+"' successfully mounted!"; | ||
rest_response.result = "SUCCESS"; | ||
d.resolve(rest_response); | ||
} | ||
else{ | ||
logger.warn("[DRIVER] - "+driver_name+" --> " + init_response.message); | ||
rest_response.message = "ERROR during "+driver_name+" initialization -> " +init_response.message; | ||
rest_response.result = "ERROR"; | ||
d.resolve(rest_response); | ||
} | ||
}); | ||
} | ||
catch(err){ | ||
rest_response.message = "ERROR during "+driver_name+" (fuse) mounting: " +err; | ||
rest_response.result = "ERROR"; | ||
logger.warn("[DRIVER] - "+driver_name+" --> " + rest_response.message); | ||
d.resolve(rest_response); | ||
} | ||
}else{ | ||
logger.debug("[DRIVER] - "+driver_name+" --> It is not necessary to mount the driver (reconnected = " + reconnected + ")"); | ||
if(reconnected === true) reconnected = false; | ||
rest_response.message = "No need to mount driver after reconnection!"; | ||
rest_response.result = "SUCCESS"; | ||
d.resolve(rest_response); | ||
} | ||
} | ||
catch(err){ | ||
rest_response.message = err; | ||
rest_response.result = "ERROR"; | ||
d.resolve(rest_response); | ||
} | ||
return d.promise; | ||
} | ||
// Function that creates the directory and then mounts the driver. | ||
function MountpointCreation(driver_name, mountpoint, remote, mirror_board, d){ | ||
fs.mkdir(mountpoint, 0755, function() { | ||
logger.debug("[DRIVER] - "+driver_name+" ----> folder "+mountpoint+" CREATED!"); | ||
AttachMountpoint(driver_name, mountpoint, remote, mirror_board, d); | ||
}); | ||
} | ||
// Function that calls the LoadDriver function that will mount the driver | ||
function AttachMountpoint(driver_name, mountpoint, remote, mirror_board, d) { | ||
LoadDriver(driver_name, mountpoint, remote, mirror_board).then( | ||
function(result){ | ||
manageDriversConf("update", driver_name, null, "mounted", remote, mirror_board, function(mng_result){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> " + mng_result.message); | ||
d.resolve(result); | ||
logger.info("[DRIVER] - "+driver_name+" --> "+ result.message); | ||
}); | ||
}, | ||
function (error) { | ||
logger.warn("[DRIVER] - "+driver_name+" --> Error in LoadDriver function: "+ JSON.stringify(error)); | ||
d.resolve(error); | ||
} | ||
); | ||
} | ||
// Wrapper for Fuse write-file function. | ||
function writeFunction(driver, driver_name){ | ||
return function (mountpoint, fd, buffer, length, position, cb) { | ||
logger.debug('[DRIVER] - '+driver_name+' --> Writing ', buffer.slice(0, length)); | ||
content = buffer.slice(0, length); | ||
logger.debug('[DRIVER] - '+driver_name+' --> buffer content: ' + content.toString()); | ||
logger.debug('[DRIVER] - '+driver_name+' --> buffer length: ' + length.toString()); | ||
driver_mp_node = mp_list[driver_name]; | ||
if (driver_mp_node[mountpoint].write_function === null){ | ||
cb(fuse.EACCES); | ||
} else { | ||
driver[driver_mp_node[mountpoint].write_function ]( content, function(){ | ||
cb(length); | ||
}); | ||
} | ||
}; | ||
} | ||
// Wrapper for Fuse read-directory function | ||
function readdirFunction(driver_name){ | ||
return function (mountpoint, cb) { | ||
logger.debug("[DRIVER] - "+driver_name+" --> readdir(%s) - files list: %s", mountpoint, JSON.stringify(file_list[driver_name]) ); | ||
//if (mountpoint === '/') return cb(0, [driver_name]); | ||
//if (mountpoint === '/'+driver_name) return cb(0, file_list[driver_name] ); | ||
if (mountpoint === '/') return cb(0, file_list[driver_name] ); | ||
cb(0); | ||
}; | ||
} | ||
// Wrapper for Fuse get-attr function | ||
function getattrFunction(driver_name){ | ||
return function (mountpoint, cb) { | ||
logger.debug("[DRIVER] - "+driver_name+" --> getattr(%s)", mountpoint); | ||
driver_mp_node = mp_list[driver_name]; | ||
if(driver_mp_node[mountpoint].mp != undefined){ | ||
cb(0, driver_mp_node[mountpoint].mp ); | ||
return | ||
} | ||
cb(fuse.ENOENT); | ||
} | ||
} | ||
// Wrapper for Fuse open-file function | ||
function openFunction(driver_name){ | ||
return function (mountpoint, flags, cb) { | ||
fd_index = fd_index + 1; | ||
logger.debug("[DRIVER] - "+driver_name+" --> Open(%s, %d) - fd = %s", mountpoint, flags, fd_index); | ||
cb(0, fd_index); //cb(0, 42) // 42 is an fd | ||
} | ||
} | ||
// Wrapper for Fuse read-file function | ||
function readFunction(driver_name, mirror_board){ | ||
return function (mountpoint, fd, buf, len, pos, cb) { | ||
driver_mp_node = mp_list[driver_name]; | ||
var driver = drivers[driver_name]; | ||
// To read a file of a driver mounted locally that return as result the value of a local endpoint (a sensor, etc.) | ||
if (driver_mp_node['/'].remote === "false"){ | ||
logger.debug("[DRIVER] - "+driver_name+" --> Read(%s, %d, %d, %d)", mountpoint, fd, len, pos); | ||
driver[driver_mp_node[mountpoint].read_function]( function(read_content){ | ||
var buffer = new Buffer(read_content.toString(), 'utf-8'); | ||
var str = ''+buffer.slice(pos); | ||
if (!str) | ||
return cb(0); | ||
buf.write(str); | ||
return cb(str.length); | ||
}); | ||
}else{ | ||
// To read a file of a driver mounted locally that return as result the value of a remote endpoint (i.e. a sensor on a remote board, etc.) | ||
// A mirrored board is a board that share its hardware that can be used by a board that mount remotely the same driver. | ||
var filename = mountpoint.replace('/',''); | ||
logger.debug('[DRIVER] - '+driver_name+' - REMOTE CALLING to '+mirror_board + ' RPC called: s4t.'+mirror_board+'.driver.'+driver_name+'.'+filename+'.read'); | ||
// Call the RPC read function of the board that shares the hardware | ||
session_drivers.call('s4t.'+mirror_board+'.driver.'+driver_name+'.'+filename+'.read', [driver_name, filename]).then( | ||
function(read_content){ | ||
var buffer = new Buffer(read_content.toString(), 'utf-8'); | ||
var str = ''+buffer.slice(pos); | ||
if (!str) | ||
return cb(0); | ||
buf.write(str); | ||
return cb(str.length); | ||
} | ||
); | ||
} | ||
} | ||
} | ||
// Function used to convert file permission rappresentation from base 10 to 8 | ||
function MaskConversion(mode_b10){ | ||
//var mode_b10 = 100644//40755 | ||
mode_b8 = parseInt(mode_b10.toString(10), 8); | ||
//logger.info("from b10 "+mode_b10+" to b8 "+mode_b8) | ||
permission = mode_b8; | ||
return permission | ||
} | ||
/* | ||
function HumanMaskConversion(mode_b10){ | ||
mode_b8 = parseInt(mode_b10.toString(10), 8) | ||
//logger.info("from b10 "+mode_b10+" to b8 "+mode_b8) | ||
permission = mode_b8 | ||
return permission | ||
} | ||
*/ | ||
//This function exports all the functions in the module as WAMP remote procedure calls | ||
@@ -1481,0 +1521,0 @@ exports.exportDriverCommands = function (session){ |
@@ -1,11 +0,19 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2014 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
var plugin_name; | ||
@@ -12,0 +20,0 @@ var plugin_json; |
@@ -1,10 +0,20 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2014 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Andrea Rocco Lotronto, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
//service logging configuration: "managePlugins" | ||
@@ -25,140 +35,4 @@ var logger = log4js.getLogger('managePlugins'); | ||
// This function executes a syncronous plugin ("call" as the exection of a command that returns a value to the "caller"): it is called by Iotronic via RPC | ||
exports.call = function (args, details){ | ||
//Parsing the input arguments | ||
var plugin_name = String(args[0]); | ||
var plugin_json = String(args[1]); | ||
var d = Q.defer(); | ||
// The autostart parameter at RUN stage is OPTIONAL. It is used at this stage if the user needs to change the boot execution configuration of the plugin after the INJECTION stage. | ||
var plugin_autostart = ""; | ||
logger.info('[PLUGIN] - Execution request for \"'+ plugin_name +'\" plugin with parameter json: '+plugin_json); | ||
try{ | ||
//Reading the plugins.json configuration file | ||
var pluginsConf = JSON.parse(fs.readFileSync(PLUGINS_SETTING, 'utf8')); | ||
} | ||
catch(err){ | ||
logger.error('[PLUGIN] --> Error parsing JSON file plugins.json'); | ||
} | ||
//If the plugin exists | ||
if(pluginsConf["plugins"].hasOwnProperty(plugin_name)){ | ||
logger.info("[PLUGIN] --> Plugin successfully loaded!"); | ||
//Check the plugin status | ||
var status = pluginsConf.plugins[plugin_name].status; | ||
if (status == "off" || status == "injected"){ | ||
logger.info("[PLUGIN] --> Plugin " + plugin_name + " being started"); | ||
//Create a new process that has plugin-wrapper as code | ||
var child = cp.fork(LIGHTNINGROD_HOME + '/modules/plugins-manager/call-wrapper'); | ||
//Prepare the message I will send to the process with name of the plugin to start and json file as argument | ||
var input_message = { | ||
"plugin_name": plugin_name, | ||
"plugin_json": JSON.parse(plugin_json) | ||
}; | ||
child.on('message', function(msg) { | ||
if(msg.name != undefined){ | ||
if (msg.status === "alive"){ | ||
//Creating the plugin json schema | ||
var plugin_folder = PLUGINS_STORE + plugin_name; | ||
var schema_outputFilename = plugin_folder + "/" + plugin_name + '.json'; | ||
fs.writeFile(schema_outputFilename, plugin_json, function(err) { | ||
if(err) { | ||
logger.error('[PLUGIN] --> Error parsing '+plugin_name+'.json file: ' + err); | ||
} else { | ||
logger.info('[PLUGIN] --> Plugin JSON schema saved to ' + schema_outputFilename); | ||
// - change the plugin status from "off" to "on" and update the PID value | ||
pluginsConf.plugins[plugin_name].status = "on"; | ||
pluginsConf.plugins[plugin_name].pid = child.pid; | ||
fs.writeFile(PLUGINS_SETTING, JSON.stringify(pluginsConf, null, 4), function(err) { | ||
if(err) { | ||
logger.error('[PLUGIN] --> Error writing plugins.json file: ' + err); | ||
} else { | ||
logger.info("[PLUGIN] --> JSON file plugins.json updated -> " + plugin_name + ': status < '+ pluginsConf.plugins[plugin_name].status + ' > ' + pluginsConf.plugins[plugin_name].pid); | ||
} | ||
}); | ||
} | ||
}); | ||
} else if(msg.status === "finish") { | ||
logger.info("[PLUGIN] --> RESULT: ", msg.logmsg); | ||
d.resolve(msg.logmsg); | ||
} else if(msg.status === "fault") { | ||
logger.info("[PLUGIN] --> RESULT: ", msg.logmsg); | ||
d.resolve(msg.logmsg); | ||
} else if(msg.level === "error") { | ||
logger.error("[PLUGIN] --> "+ msg.name + ": " + msg.logmsg); | ||
} else if(msg.level === "warn") { | ||
logger.warn("[PLUGIN] --> "+ msg.name + ": " + msg.logmsg); | ||
} | ||
else{ | ||
logger.info("[PLUGIN] --> "+ msg.name + ": " + msg.logmsg); | ||
} | ||
} | ||
else{ | ||
//serve per gestire il primo messaggio alla creazione del child | ||
logger.info("[PLUGIN] --> " + msg); | ||
} | ||
}); | ||
//I send the input to the wrapper so that it can launch the proper plugin with the proper json file as argument | ||
child.send(input_message); | ||
return d.promise; | ||
} | ||
else{ | ||
logger.warn("[PLUGIN] --> Call already started!"); | ||
return 'Call already started on this board!'; | ||
} | ||
} | ||
else{ | ||
// Here the plugin does not exist | ||
logger.warn("[PLUGIN] --> Call \"" + plugin_name + "\" does not exist on this board!"); | ||
return 'Call does not exist on this board!'; | ||
} | ||
}; | ||
// This function checks if the plugin process is still alive otherwise starts it | ||
@@ -347,2 +221,3 @@ function pluginStarter(plugin_name, timer, plugin_json_name, skip) { | ||
// This function delete the timer associated with a plugin | ||
@@ -369,3 +244,228 @@ function clearPluginTimer(plugin_name) { | ||
// This function checks if the plugin has to be restarted | ||
// Function used to delete all driver files during driver removing from the board | ||
function deleteFolderRecursive(path){ | ||
if( fs.existsSync(path) ) { | ||
fs.readdirSync(path).forEach(function(file,index){ | ||
var curPath = path + "/" + file; | ||
if(fs.lstatSync(curPath).isDirectory()) { | ||
// recurse | ||
deleteFolderRecursive(curPath); | ||
} else { | ||
// delete file | ||
fs.unlinkSync(curPath); | ||
} | ||
}); | ||
fs.rmdirSync(path); | ||
} | ||
} | ||
// Function to clean all plugin data (folder and configuration) | ||
function cleanPluginData(plugin_name){ | ||
var response = { | ||
message: '', | ||
result: '' | ||
}; | ||
var d = Q.defer(); | ||
var plugin_folder = PLUGINS_STORE + plugin_name; | ||
if ( fs.existsSync(plugin_folder) === true ){ | ||
deleteFolderRecursive(plugin_folder); //delete plugin files and the folder | ||
logger.debug('[PLUGIN] --> Plugin folder deleted.'); | ||
} | ||
else{ | ||
logger.debug('[PLUGIN] --> Plugin folder already deleted.'); | ||
} | ||
logger.debug('[PLUGIN] --> Plugin data cleaning...'); | ||
//Reading the plugins configuration file | ||
var pluginsConf = JSON.parse(fs.readFileSync(PLUGINS_SETTING, 'utf8')); | ||
if( pluginsConf["plugins"].hasOwnProperty(plugin_name) ){ | ||
var pluginStatus = pluginsConf.plugins[plugin_name]['status']; | ||
pluginsConf.plugins[plugin_name]=null; | ||
delete pluginsConf.plugins[plugin_name]; | ||
fs.writeFile(PLUGINS_SETTING, JSON.stringify(pluginsConf, null, 4), function(err) { | ||
if(err) { | ||
response.result = "ERROR"; | ||
response.message = "plugin.json updating FAILED: "+err; | ||
d.resolve(response); | ||
} else { | ||
logger.debug("[PLUGIN] ----> plugins.json file updated!"); | ||
response.result = "SUCCESS"; | ||
d.resolve(response); | ||
} | ||
}); | ||
}else{ | ||
logger.debug("[PLUGIN] ----> plugins.json already clean!"); | ||
response.result = "SUCCESS"; | ||
d.resolve(response); | ||
} | ||
return d.promise; | ||
} | ||
// RPC to execute a syncronous plugin ("call" as the exection of a command that returns a value to the "caller"): it is called by Iotronic via RPC | ||
exports.call = function (args, details){ | ||
//Parsing the input arguments | ||
var plugin_name = String(args[0]); | ||
var plugin_json = String(args[1]); | ||
var d = Q.defer(); | ||
// The autostart parameter at RUN stage is OPTIONAL. It is used at this stage if the user needs to change the boot execution configuration of the plugin after the INJECTION stage. | ||
var plugin_autostart = ""; | ||
logger.info('[PLUGIN] - Execution request for \"'+ plugin_name +'\" plugin with parameter json: '+plugin_json); | ||
try{ | ||
//Reading the plugins.json configuration file | ||
var pluginsConf = JSON.parse(fs.readFileSync(PLUGINS_SETTING, 'utf8')); | ||
} | ||
catch(err){ | ||
logger.error('[PLUGIN] --> Error parsing JSON file plugins.json'); | ||
} | ||
//If the plugin exists | ||
if(pluginsConf["plugins"].hasOwnProperty(plugin_name)){ | ||
logger.info("[PLUGIN] --> Plugin successfully loaded!"); | ||
//Check the plugin status | ||
var status = pluginsConf.plugins[plugin_name].status; | ||
if (status == "off" || status == "injected"){ | ||
logger.info("[PLUGIN] --> Plugin " + plugin_name + " being started"); | ||
//Create a new process that has plugin-wrapper as code | ||
var child = cp.fork(LIGHTNINGROD_HOME + '/modules/plugins-manager/call-wrapper'); | ||
//Prepare the message I will send to the process with name of the plugin to start and json file as argument | ||
var input_message = { | ||
"plugin_name": plugin_name, | ||
"plugin_json": JSON.parse(plugin_json) | ||
}; | ||
child.on('message', function(msg) { | ||
if(msg.name != undefined){ | ||
if (msg.status === "alive"){ | ||
//Creating the plugin json schema | ||
var plugin_folder = PLUGINS_STORE + plugin_name; | ||
var schema_outputFilename = plugin_folder + "/" + plugin_name + '.json'; | ||
fs.writeFile(schema_outputFilename, plugin_json, function(err) { | ||
if(err) { | ||
logger.error('[PLUGIN] --> Error parsing '+plugin_name+'.json file: ' + err); | ||
} else { | ||
logger.info('[PLUGIN] --> Plugin JSON schema saved to ' + schema_outputFilename); | ||
// - change the plugin status from "off" to "on" and update the PID value | ||
pluginsConf.plugins[plugin_name].status = "on"; | ||
pluginsConf.plugins[plugin_name].pid = child.pid; | ||
fs.writeFile(PLUGINS_SETTING, JSON.stringify(pluginsConf, null, 4), function(err) { | ||
if(err) { | ||
logger.error('[PLUGIN] --> Error writing plugins.json file: ' + err); | ||
} else { | ||
logger.info("[PLUGIN] --> JSON file plugins.json updated -> " + plugin_name + ': status < '+ pluginsConf.plugins[plugin_name].status + ' > ' + pluginsConf.plugins[plugin_name].pid); | ||
} | ||
}); | ||
} | ||
}); | ||
} else if(msg.status === "finish") { | ||
logger.info("[PLUGIN] --> RESULT: ", msg.logmsg); | ||
d.resolve(msg.logmsg); | ||
} else if(msg.status === "fault") { | ||
logger.info("[PLUGIN] --> RESULT: ", msg.logmsg); | ||
d.resolve(msg.logmsg); | ||
} else if(msg.level === "error") { | ||
logger.error("[PLUGIN] --> "+ msg.name + ": " + msg.logmsg); | ||
} else if(msg.level === "warn") { | ||
logger.warn("[PLUGIN] --> "+ msg.name + ": " + msg.logmsg); | ||
} | ||
else{ | ||
logger.info("[PLUGIN] --> "+ msg.name + ": " + msg.logmsg); | ||
} | ||
} | ||
else{ | ||
//serve per gestire il primo messaggio alla creazione del child | ||
logger.info("[PLUGIN] --> " + msg); | ||
} | ||
}); | ||
//I send the input to the wrapper so that it can launch the proper plugin with the proper json file as argument | ||
child.send(input_message); | ||
return d.promise; | ||
} | ||
else{ | ||
logger.warn("[PLUGIN] --> Call already started!"); | ||
return 'Call already started on this board!'; | ||
} | ||
} | ||
else{ | ||
// Here the plugin does not exist | ||
logger.warn("[PLUGIN] --> Call \"" + plugin_name + "\" does not exist on this board!"); | ||
return 'Call does not exist on this board!'; | ||
} | ||
}; | ||
// RPC to check if the plugin has to be restarted | ||
exports.pluginKeepAlive = function (plugin_name){ | ||
@@ -433,3 +533,3 @@ | ||
// This function is used to restart all enabled plugins at LR startup...moreover associates a timer with each plugin to check if the plugin process is alive | ||
// RPC to restart all enabled plugins at LR startup...moreover associates a timer with each plugin to check if the plugin process is alive | ||
exports.pluginsLoader = function (){ | ||
@@ -487,3 +587,3 @@ | ||
// This function puts in running an asynchronous plugin in a new process: it is called by Iotronic via RPC | ||
// RPC to put in running an asynchronous plugin in a new process: it is called by Iotronic via RPC | ||
exports.run = function (args){ | ||
@@ -505,3 +605,3 @@ | ||
logger.info('[PLUGIN] - Run plugin RPC called for plugin '+ plugin_name +' plugin...'); | ||
logger.info('[PLUGIN] - Run plugin RPC called for plugin "'+ plugin_name +'" plugin...'); | ||
logger.info("[PLUGIN] --> Input parameters:\n"+ plugin_json); | ||
@@ -516,3 +616,3 @@ | ||
response.message = 'Error parsing plugins.json!'; | ||
logger.error('[PLUGIN] - '+plugin_name + ' plugin execution error: '+response.message); | ||
logger.error('[PLUGIN] - "' + plugin_name + '" plugin execution error: '+response.message); | ||
d.resolve(response); | ||
@@ -530,3 +630,3 @@ } | ||
if (status == "off" || status == "injected"){ | ||
logger.info('[PLUGIN] - '+ plugin_name + ' - Plugin starting...'); | ||
@@ -668,3 +768,3 @@ | ||
response.result = "ERROR"; | ||
response.message = "Plugin \"" + plugin_name + "\" does not exist on this board!"; | ||
response.message = "Plugin '" + plugin_name + "' does not exist on this board!"; | ||
logger.warn('[PLUGIN] - '+plugin_name + ' - '+response.message); | ||
@@ -680,3 +780,3 @@ d.resolve(response); | ||
// This function stop/kill a running asynchronous plugin: it is called by Iotronic via RPC | ||
// RPC to stop/kill a running asynchronous plugin: it is called by Iotronic via RPC | ||
exports.kill = function (args){ | ||
@@ -730,2 +830,6 @@ | ||
clearPluginTimer(plugin_name); | ||
response.result = "SUCCESS"; | ||
response.message = 'Plugin killed!'; | ||
logger.info('[PLUGIN] - stop plugin '+plugin_name + ': '+response.message); | ||
d.resolve(response); | ||
} | ||
@@ -735,6 +839,3 @@ | ||
response.result = "SUCCESS"; | ||
response.message = 'Plugin killed!'; | ||
logger.info('[PLUGIN] - stop plugin '+plugin_name + ': '+response.message); | ||
d.resolve(response); | ||
@@ -744,2 +845,3 @@ } | ||
response.result = "ERROR"; | ||
response.code = "NO-RUN"; | ||
response.message = 'Plugin is not running on this board!'; | ||
@@ -750,3 +852,8 @@ logger.error('[PLUGIN] - stop plugin '+plugin_name + ': '+response.message); | ||
} | ||
}else{ | ||
response.result = "ERROR"; | ||
response.message = "Plugin '" + plugin_name + "' is not injected on this board!"; | ||
logger.error('[PLUGIN] - stop plugin ' + plugin_name + ': '+response.message); | ||
d.resolve(response); | ||
} | ||
@@ -768,3 +875,3 @@ | ||
// This function manage the injection request of a plugin into the device: it is called by Iotronic via RPC | ||
// RPC to manage the injection request of a plugin into the device: it is called by Iotronic via RPC | ||
exports.injectPlugin = function(args){ | ||
@@ -780,3 +887,3 @@ | ||
logger.info("[PLUGIN] - Injecting plugin RPC called for "+plugin_name+" plugin..."); | ||
logger.info("[PLUGIN] --> Parameters injected: { plugin_name : " + plugin_name + ", autostart : " + autostart + " }"); | ||
logger.debug("[PLUGIN] --> Parameters injected: { plugin_name : " + plugin_name + ", autostart : " + autostart + " }"); | ||
logger.debug("[PLUGIN] --> plugin code:\n\n" + JSON.stringify(plugin_code) + "\n\n"); | ||
@@ -793,41 +900,22 @@ | ||
var fileName = plugin_folder + "/" + plugin_name + '.js'; | ||
cleanPluginData(plugin_name).then( | ||
// Check plugin folder | ||
if ( fs.existsSync(plugin_folder) === false ){ | ||
function (clean_res) { | ||
// plugin folder creation | ||
fs.mkdir(plugin_folder, function() { | ||
if (clean_res.result == "SUCCESS"){ | ||
// Writing the file | ||
clean_res.message = "plugin '" + plugin_name + "' environment is clean!"; | ||
logger.debug("[PLUGIN] ----> " + clean_res.message); | ||
fs.writeFile(fileName, plugin_code, function(err) { | ||
// plugin folder creation | ||
fs.mkdir(plugin_folder, function() { | ||
if(err) { | ||
// Writing the file | ||
fs.writeFile(fileName, plugin_code, function(err) { | ||
response.result = "ERROR"; | ||
response.message = 'Error writing '+ fileName +' file: ' + err; | ||
logger.error('[PLUGIN] --> ' + response.message); | ||
d.resolve(response); | ||
} else { | ||
//Reading the plugins configuration file | ||
var pluginsConf = JSON.parse(fs.readFileSync(PLUGINS_SETTING, 'utf8')); | ||
//Update the data structure of the plugin | ||
pluginsConf.plugins[plugin_name] = {}; | ||
pluginsConf.plugins[plugin_name]['status'] = "injected"; | ||
if(autostart != undefined){ | ||
pluginsConf.plugins[plugin_name]['autostart'] = autostart; | ||
} else { | ||
pluginsConf.plugins[plugin_name]['autostart'] = false; | ||
} | ||
//Update plugins.json config file | ||
fs.writeFile(PLUGINS_SETTING, JSON.stringify(pluginsConf, null, 4), function(err) { | ||
if(err) { | ||
response.result = "ERROR"; | ||
response.message = 'Error writing plugins.json file: ' + err; | ||
response.message = 'Error writing '+ fileName +' file: ' + err; | ||
logger.error('[PLUGIN] --> ' + response.message); | ||
@@ -838,27 +926,52 @@ d.resolve(response); | ||
logger.debug("[PLUGIN] --> Plugins configuration file saved to " + PLUGINS_SETTING); | ||
response.result = "SUCCESS"; | ||
response.message = "Plugin "+ plugin_name +" injected successfully!"; | ||
logger.info('[PLUGIN] --> ' + response.message); | ||
d.resolve(response); | ||
//Reading the plugins configuration file | ||
var pluginsConf = JSON.parse(fs.readFileSync(PLUGINS_SETTING, 'utf8')); | ||
//Update the data structure of the plugin | ||
pluginsConf.plugins[plugin_name] = {}; | ||
pluginsConf.plugins[plugin_name]['status'] = "injected"; | ||
if(autostart != undefined){ | ||
pluginsConf.plugins[plugin_name]['autostart'] = autostart; | ||
} else { | ||
pluginsConf.plugins[plugin_name]['autostart'] = false; | ||
} | ||
//Update plugins.json config file | ||
fs.writeFile(PLUGINS_SETTING, JSON.stringify(pluginsConf, null, 4), function(err) { | ||
if(err) { | ||
response.result = "ERROR"; | ||
response.message = 'Error writing plugins.json file: ' + err; | ||
logger.error('[PLUGIN] --> ' + response.message); | ||
d.resolve(response); | ||
} else { | ||
logger.debug("[PLUGIN] --> Configuration in plugins.json updated!"); | ||
response.result = "SUCCESS"; | ||
response.message = "Plugin '"+ plugin_name +"' injected successfully!"; | ||
logger.info('[PLUGIN] --> ' + response.message); | ||
d.resolve(response); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
}); | ||
}); | ||
}); | ||
}else{ | ||
} else{ | ||
logger.error("[PLUGIN] --> " + clean_res.message); | ||
d.resolve(clean_res.message); | ||
} | ||
response.result = "ERROR"; | ||
response.message = "ERROR: "+plugin_name+" plugin's files already injected! - Remove the previous plugin installation!"; | ||
logger.warn('[PLUGIN] --> ' + response.message); | ||
d.resolve(response); | ||
} | ||
} | ||
); | ||
return d.promise; | ||
@@ -869,82 +982,65 @@ | ||
// Function used to delete all driver files during driver removing from the board | ||
function deleteFolderRecursive(path){ | ||
if( fs.existsSync(path) ) { | ||
fs.readdirSync(path).forEach(function(file,index){ | ||
var curPath = path + "/" + file; | ||
if(fs.lstatSync(curPath).isDirectory()) { | ||
// recurse | ||
deleteFolderRecursive(curPath); | ||
} else { | ||
// delete file | ||
fs.unlinkSync(curPath); | ||
} | ||
}); | ||
fs.rmdirSync(path); | ||
} | ||
} | ||
// This function manage the removal of a plugin from the device: it is called by Iotronic via RPC | ||
// RPC to manage the removal of a plugin from the device: it is called by Iotronic via RPC | ||
exports.removePlugin = function(args){ | ||
// Parsing the input arguments | ||
plugin_name = String(args[0]); | ||
var plugin_name = String(args[0]); | ||
logger.info("[PLUGIN] - Removing plugin RPC called for " + plugin_name +" plugin..."); | ||
var d = Q.defer(); | ||
var response = { | ||
message: '', | ||
result: '' | ||
}; | ||
var plugin_folder = PLUGINS_STORE + plugin_name; | ||
var pluginFileName = plugin_folder + "/" + plugin_name + '.js'; | ||
var pluginConfFileName = plugin_folder + "/" + plugin_name+'.json'; | ||
var d = Q.defer(); | ||
if ( fs.existsSync(plugin_folder) === true ){ | ||
//Reading the plugins.json configuration file | ||
var pluginsConf = JSON.parse(fs.readFileSync(PLUGINS_SETTING, 'utf8')); | ||
var pid = pluginsConf.plugins[plugin_name].pid; | ||
deleteFolderRecursive(plugin_folder); //delete plugin files folder | ||
// if the plugin is not running the pid is NULL or "", in this condition "is-running" module return "true" that is a WRONG result! | ||
if (running(pid) == false || pid == null || pid == ""){ | ||
logger.debug('[PLUGIN] --> Plugin data cleaning...'); | ||
if ( fs.existsSync(plugin_folder) === true ){ | ||
//Reading the plugins configuration file | ||
var pluginsConf = JSON.parse(fs.readFileSync(PLUGINS_SETTING, 'utf8')); | ||
cleanPluginData(plugin_name).then( | ||
if( pluginsConf["plugins"].hasOwnProperty(plugin_name) ){ | ||
function (clean_res) { | ||
var pluginStatus = pluginsConf.plugins[plugin_name]['status']; | ||
if (clean_res.result == "SUCCESS"){ | ||
pluginsConf.plugins[plugin_name]=null; | ||
delete pluginsConf.plugins[plugin_name]; | ||
logger.debug("[PLUGIN] --> Plugin board successfully removed from plugins.json!" ); | ||
response.message = "Plugin '" + plugin_name + "' successfully removed!"; | ||
response.result = clean_res.result; | ||
logger.info("[PLUGIN] --> " + response.message); | ||
d.resolve(response); | ||
fs.writeFile(PLUGINS_SETTING, JSON.stringify(pluginsConf, null, 4), function(err) { | ||
}else{ | ||
if(err) { | ||
response = "plugin.json file updating FAILED: "+err; | ||
logger.error("[PLUGIN] --> plugin.json updating FAILED: "+err); | ||
d.resolve(response); | ||
logger.error("[PLUGIN] --> " + clean_res.message); | ||
d.resolve(clean_res); | ||
} else { | ||
} | ||
logger.debug("[PLUGIN] --> plugins.json file updated!"); | ||
response = plugin_name+" completely removed from board!"; | ||
logger.info("[PLUGIN] --> " + plugin_name + " - plugin completely removed from board!"); | ||
d.resolve(response); | ||
} | ||
}); | ||
); | ||
}else{ | ||
logger.warn("[PLUGIN] --> plugins.json already clean!"); | ||
response = plugin_name+" completely removed from board!"; | ||
logger.info("[PLUGIN] --> " + plugin_name + " - plugin completely removed from board!"); | ||
response.message = "Plugin folder ("+plugin_folder+") not found!"; | ||
response.result = "WARNING"; | ||
logger.warn("[PLUGIN] --> " + response.message); | ||
d.resolve(response); | ||
} | ||
}else{ | ||
response = "Plugin "+pluginFileName+" not found!"; | ||
logger.warn("[PLUGIN] --> Plugin "+pluginFileName+" not found!"); | ||
response.message = "Plugin '" + plugin_name + "' is still running! Please stop it before remove it from the board."; | ||
response.result = "WARNING"; | ||
logger.warn("[PLUGIN] --> " + response.message); | ||
d.resolve(response); | ||
@@ -954,101 +1050,100 @@ | ||
return d.promise; | ||
}; | ||
/* | ||
fs.exists(pluginFileName, function(exists) { | ||
if(exists) { | ||
logger.debug('[PLUGIN] --> File '+pluginFileName+' exists. Deleting now ...'); | ||
// RPC called to restart a plugin | ||
exports.restartPlugin = function(args){ | ||
fs.unlink(pluginFileName, function(err) { | ||
var plugin_name = String(args[0]); | ||
if(err) { | ||
response = "[PLUGIN] --> Plugin file removing FAILED: "+err; | ||
logger.error(response); | ||
d.resolve(response); | ||
} | ||
}); | ||
} else { | ||
response = "Plugin "+pluginFileName+" not found!"; | ||
logger.warn("[PLUGIN] --> Plugin "+pluginFileName+" not found!"); | ||
} | ||
logger.debug('[PLUGIN] --> Plugin data cleaning...'); | ||
logger.info('[PLUGIN] - Restart plugin RPC called for plugin "'+ plugin_name +'" plugin...'); | ||
//Reading the plugins configuration file | ||
var d = Q.defer(); | ||
var response = { | ||
message: '', | ||
result: '' | ||
}; | ||
// Get the plugin's configuration. | ||
try{ | ||
//Reading the plugins.json configuration file | ||
var pluginsConf = JSON.parse(fs.readFileSync(PLUGINS_SETTING, 'utf8')); | ||
if( pluginsConf["plugins"].hasOwnProperty(plugin_name) ){ | ||
//If the plugin exists | ||
if(pluginsConf["plugins"].hasOwnProperty(plugin_name)){ | ||
var pluginStatus = pluginsConf.plugins[plugin_name]['status']; | ||
pluginsConf.plugins[plugin_name]=null; | ||
delete pluginsConf.plugins[plugin_name]; | ||
logger.debug("[PLUGIN] --> Plugin board successfully removed from plugins.json!" ); | ||
fs.writeFile(PLUGINS_SETTING, JSON.stringify(pluginsConf, null, 4), function(err) { | ||
exports.kill([plugin_name]).then( | ||
if(err) { | ||
response = "plugin.json file updating FAILED: "+err; | ||
logger.error("[PLUGIN] --> plugin.json updating FAILED: "+err); | ||
d.resolve(response); | ||
} else { | ||
logger.debug("[PLUGIN] --> plugins.json file updated!"); | ||
fs.exists(pluginConfFileName, function(exists) { | ||
function (response) { | ||
if(exists) { | ||
if(response.result == "SUCCESS" || response.code == "NO-RUN"){ | ||
fs.unlink(pluginConfFileName, function (err) { | ||
if (err){ | ||
response = pluginConfFileName+" file deleting FAILED: "+err; | ||
logger.warn("[PLUGIN] --> "+pluginConfFileName+" file deleting FAILED: "+err); | ||
var plugin_json_name = PLUGINS_STORE + plugin_name + "/" + plugin_name + '.json'; | ||
var plugin_json_schema = JSON.parse(fs.readFileSync(plugin_json_name, 'utf8')); | ||
exports.run([plugin_name, JSON.stringify(plugin_json_schema)]).then( | ||
function (response) { | ||
if(response.result == "SUCCESS"){ | ||
response.result = "SUCCESS"; | ||
response.message = "Plugin '"+plugin_name+"' successfully restarted"; | ||
logger.info("[PLUGIN] - " + response.message); | ||
d.resolve(response); | ||
}else{ | ||
logger.debug("[PLUGIN] --> "+pluginConfFileName+" file successfully deleted!"); | ||
response = plugin_name+" completely removed from board!"; | ||
logger.info("[PLUGIN] --> " + plugin_name + " - plugin completely removed from board!"); | ||
response.result = "ERROR"; | ||
response.message = "Error restarting plugin '"+plugin_name+"' during starting procedure!"; | ||
logger.error("[PLUGIN] - " + response.message); | ||
d.resolve(response); | ||
} | ||
}); | ||
}else{ | ||
logger.warn("[PLUGIN] --> "+pluginConfFileName+" file does not exist! - Plugin was in status: " + pluginStatus); | ||
response = plugin_name+" completely removed from board!"; | ||
logger.info("[PLUGIN] --> " + plugin_name + " - plugin completely removed from board!"); | ||
d.resolve(response); | ||
} | ||
}); | ||
} | ||
} | ||
); | ||
}); | ||
}else{ | ||
logger.warn("[PLUGIN] --> plugins.json already clean!"); | ||
response = plugin_name+" completely removed from board!"; | ||
logger.info("[PLUGIN] --> " + plugin_name + " - plugin completely removed from board!"); | ||
d.resolve(response); | ||
} | ||
}); | ||
*/ | ||
}else { | ||
return d.promise; | ||
}; | ||
response.result = "ERROR"; | ||
response.message = "Error restarting plugin '" + plugin_name + "' during killing procedure!"; | ||
logger.error("[PLUGIN] - " + response.message); | ||
d.resolve(response); | ||
} | ||
} | ||
); | ||
}else{ | ||
// the plugin does not exist | ||
response.result = "ERROR"; | ||
response.message = "Call \"" + plugin_name + "\" does not exist on this board!"; | ||
logger.error("[PLUGIN] - " + response.message); | ||
d.resolve(response); | ||
} | ||
} | ||
catch(err){ | ||
logger.error('[PLUGIN] --> Error parsing JSON file plugins.json'); | ||
} | ||
return d.promise; | ||
}; | ||
//This function exports all the functions in the module as WAMP remote procedure calls | ||
@@ -1058,7 +1153,8 @@ exports.exportPluginCommands = function (session){ | ||
//Register all the module functions as WAMP RPCs | ||
session.register('s4t'+ boardCode+'.plugin.run', exports.run); | ||
session.register('s4t'+ boardCode+'.plugin.kill', exports.kill); | ||
session.register('s4t'+ boardCode+'.plugin.inject', exports.injectPlugin); | ||
session.register('s4t'+ boardCode+'.plugin.call', exports.call); | ||
session.register('s4t'+ boardCode+'.plugin.remove', exports.removePlugin); | ||
session.register('s4t.'+ boardCode+'.plugin.run', exports.run); | ||
session.register('s4t.'+ boardCode+'.plugin.kill', exports.kill); | ||
session.register('s4t.'+ boardCode+'.plugin.inject', exports.injectPlugin); | ||
session.register('s4t.'+ boardCode+'.plugin.call', exports.call); | ||
session.register('s4t.'+ boardCode+'.plugin.remove', exports.removePlugin); | ||
session.register('s4t.'+ boardCode+'.plugin.restart', exports.restartPlugin); | ||
@@ -1065,0 +1161,0 @@ logger.info('[WAMP-EXPORTS] Plugin commands exported to the cloud!'); |
@@ -1,10 +0,20 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
SETTINGS = process.env.IOTRONIC_HOME+'/settings.json'; | ||
@@ -24,15 +34,8 @@ nconf = require('nconf'); | ||
var requestify = require('requestify'); | ||
var Q = require("q"); | ||
var ckan_addr = 'smartme-data.unime.it'; | ||
var ckan_host = 'http://'+ckan_addr; | ||
exports.getLogger = function (){ | ||
return logger; | ||
}; | ||
@@ -58,3 +61,2 @@ exports.getPosition = function (){ | ||
exports.getLocalTime = function (){ | ||
@@ -74,67 +76,1 @@ | ||
}; | ||
exports.sendToCKAN = function (m_authid, m_resourceid, record, callback){ | ||
var http = require('http'); | ||
var payload = { | ||
resource_id : m_resourceid, | ||
method: 'insert', | ||
records : record | ||
}; | ||
var payloadJSON = JSON.stringify(payload); | ||
var header = { | ||
'Content-Type': "application/json", | ||
'Authorization' : m_authid, | ||
'Content-Length': Buffer.byteLength(payloadJSON) | ||
}; | ||
var options = { | ||
host: ckan_addr, | ||
port: 80, | ||
path: '/api/3/action/datastore_upsert', | ||
method: 'POST', | ||
headers: header | ||
}; | ||
var req = http.request(options, function(res) { | ||
res.setEncoding('utf-8'); | ||
var responseString = ''; | ||
res.on('data', function(data) { | ||
console.log('On data:' + data); | ||
}); | ||
res.on('end', function() {}); | ||
}); | ||
req.on('error', function(e) { | ||
console.log('On Error:' + e); | ||
}); | ||
req.write(payloadJSON); | ||
req.end(); | ||
callback(payloadJSON); | ||
}; | ||
exports.getCKANdataset = function(id, callback){ | ||
requestify.get(ckan_host + '/api/rest/dataset/'+id).then( function(response) { | ||
var dataCKAN = response.getBody(); | ||
callback(dataCKAN); | ||
}); | ||
}; |
@@ -1,10 +0,20 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2014 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Andrea Rocco Lotronto, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
var plugin_name; | ||
@@ -11,0 +21,0 @@ var plugin_json; |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments, callback){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments, callback){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments, callback){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments, callback){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments, callback){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments, callback){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Francesco Longo, Giovanni Merlino | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
//JSON to send | ||
@@ -2,0 +20,0 @@ // { |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments){ | ||
@@ -2,0 +20,0 @@ |
@@ -0,1 +1,19 @@ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2015-2016 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
exports.main = function (arguments){ | ||
@@ -2,0 +20,0 @@ |
@@ -1,10 +0,20 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2014 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Andrea Rocco Lotronto, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2017 Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
//service logging configuration: "manageCommands" | ||
@@ -37,3 +47,3 @@ var logger = log4js.getLogger('manageServices'); | ||
logger.debug("[SERVICE] - RPC enableService called: " + args) | ||
logger.debug("[SERVICE] - RPC enableService called: " + args); | ||
@@ -47,3 +57,3 @@ //Looking for the process in the array | ||
logger.info('[SERVICE] - Restoring tunnel for '+ serviceName + 'service...'); | ||
logger.info("[SERVICE] - Restoring tunnel for '"+ serviceName + "' service..."); | ||
@@ -220,3 +230,3 @@ //Killing the process | ||
//Getting the path of the wstt.js module from the configuration file | ||
//Getting the path of the wstun.js module from the configuration file | ||
var reverseTunnellingClient = nconf.get('config:reverse:lib:bin'); | ||
@@ -265,67 +275,4 @@ | ||
/* | ||
exports.exportService = function(args){ | ||
//Parsing arguments | ||
serviceName = args[1]; | ||
remotePort = args[2]; | ||
operation = args[3]; | ||
//Getting information from the configuration file | ||
localPort = nconf.get('config:board:services:'+serviceName+':port'); | ||
reverseTunnellingServer = nconf.get('config:reverse:server:url_reverse')+":"+nconf.get('config:reverse:server:port_reverse'); | ||
logger.info('[SERVICE] - '+ operation + ' service ' + serviceName + ' on local port ' + localPort + ' with remote port ' + remotePort + ' contacting remote server ' + reverseTunnellingServer); | ||
//Getting the path of the wstt.js module from the configuration file | ||
var reverseTunnellingClient = nconf.get('config:reverse:lib:bin'); | ||
//If the operation is start | ||
if(operation === "start"){ | ||
//I spawn a process executing the reverse tunnel client with appropriate parameters | ||
var spawn = require('child_process').spawn; | ||
logger.debug('[SERVICE] - Executing command: ' + reverseTunnellingClient + ' -r '+remotePort+':'+'127.0.0.1'+':'+localPort + ' ' + reverseTunnellingServer); | ||
//I insert the new service in the array so that I can find it later when I have to stop the service | ||
var newService = { | ||
key: serviceName, | ||
process: spawn(reverseTunnellingClient, ['-r '+remotePort+':'+'127.0.0.1'+':'+localPort, reverseTunnellingServer]) | ||
}; | ||
servicesProcess.push(newService); | ||
newService.process.stdout.on('data', function(data){ | ||
logger.debug('[SERVICE] - '+newService.key+' stdout of process ' + newService.process.pid + ': '+data); | ||
}); | ||
newService.process.stderr.on('data', function(data){ | ||
logger.debug('[SERVICE] - '+newService.key+' stderr of process ' + newService.process.pid + ': '+ data); | ||
}); | ||
newService.process.on('close', function(code){ | ||
logger.debug('[SERVICE] - '+newService.key+' child process ' + newService.process.pid + ' exited with code '+ code); | ||
}); | ||
} | ||
if(operation === "stop"){ | ||
//Looking for the process in the array | ||
var i = findValue(servicesProcess, serviceName, 'key'); | ||
//Killing the process | ||
logger.info('[SERVICE] - Killing '+serviceName+' process: ' + servicesProcess[i].process.pid); | ||
servicesProcess[i].process.kill('SIGINT'); | ||
servicesProcess.splice(i,1); | ||
} | ||
}; | ||
*/ | ||
//This function exports all the functions in the module as WAMP remote procedure calls | ||
@@ -344,3 +291,3 @@ exports.exportServiceCommands = function (session){ | ||
function (response) { | ||
logger.info('[SERVICE] --> response from IoTronic: ' + response.message); | ||
logger.info('[SERVICE] --> Response from IoTronic: ' + response.message); | ||
logger.info('[SERVICE] --> Services restoring completed!'); | ||
@@ -347,0 +294,0 @@ } |
@@ -1,10 +0,20 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
//service logging configuration: "manageFS" | ||
@@ -11,0 +21,0 @@ var logger = log4js.getLogger('manage-FS-libs'); |
@@ -1,10 +0,20 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, Nicola Peditto | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
//service logging configuration: "manageFS" | ||
@@ -11,0 +21,0 @@ var logger = log4js.getLogger('manageFS'); |
@@ -1,11 +0,22 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Arthur Warnier, Fabio Verboso, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, | ||
//# Nicola Peditto, Fabio Verboso | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
//service logging configuration: "manageNetworks" | ||
@@ -24,3 +35,3 @@ var logger = log4js.getLogger('manageNetworks'); | ||
var socat_pid = null; | ||
var wstt_pid = null; | ||
var wstun_pid = null; | ||
@@ -49,3 +60,3 @@ | ||
logger.info("[VNET] - Network manager loaded!"); | ||
logger.info("[VNET] - Network Manager loaded!"); | ||
@@ -75,4 +86,4 @@ | ||
logger.info("[VNET] - Socat parameters received: " + socatRes); | ||
logger.info("[VNET] - Network backend used: " + net_backend); | ||
logger.info("[VNET] --> Socat parameters received: " + socatRes); | ||
logger.info("[VNET] --> Network backend used: " + net_backend); | ||
@@ -90,7 +101,7 @@ exports.initNetwork(socatServer_ip, socatServer_port, socatBoard_ip, net_backend); | ||
// 1. creates the SOCAT tunnel using the parameter received from Iotronic. | ||
// 2. On SOCAT tunnel completion it will create the WSTT tunnel. | ||
// 2. On SOCAT tunnel completion it will create the WSTUN tunnel. | ||
// 3. On tunnels completion it will advise Iotronic; later Iotronic will add this device to its VLANs. | ||
exports.initNetwork = function (socatServer_ip, socatServer_port, socatBoard_ip, net_backend) { | ||
logger.info("[VNET] - Network initialization..."); | ||
//logger.info("[VNET] --> Network initialization..."); | ||
@@ -105,9 +116,9 @@ var spawn = require('child_process').spawn; | ||
var socat_config = configFile.config["socat"]; | ||
var wstt_config = configFile.config["reverse"]; | ||
var wstun_config = configFile.config["reverse"]; | ||
logger.info("[VNET] - Boot status:"); | ||
logger.info("[VNET] --> Network Boot status:"); | ||
// Kill Socat and WSTT processes to clean network status after a network failure | ||
logger.info("[VNET] --> Boot Socat PID: " + socat_pid); | ||
// Kill Socat and WSTUN processes to clean network status after a network failure | ||
logger.info("[VNET] ----> Boot Socat PID: " + socat_pid); | ||
@@ -144,14 +155,14 @@ if (socat_pid != null) { | ||
logger.info("[VNET] --> Boot WSTT PID: " + wstt_pid); | ||
logger.info("[VNET] ----> Boot WSTUN PID: " + wstun_pid); | ||
if (wstt_pid != null) { | ||
if (wstun_pid != null) { | ||
logger.warn("[VNET] ... WSTT cleaning PID [" + wstt_pid + "]"); | ||
logger.warn("[VNET] ... WSTUN cleaning PID [" + wstun_pid + "]"); | ||
try{ | ||
process.kill(wstt_pid) | ||
process.kill(wstun_pid) | ||
}catch (e) { | ||
logger.error('[VNET] ... WSTT cleaning error: ', e); | ||
logger.error('[VNET] ... WSTUN cleaning error: ', e); | ||
@@ -161,11 +172,11 @@ } | ||
} else { | ||
var wstt_pid_conf = nconf.get('config:reverse:pid'); | ||
var wstun_pid_conf = nconf.get('config:reverse:pid'); | ||
if (wstt_pid_conf != "") { | ||
if (wstun_pid_conf != "") { | ||
if (running(wstt_pid_conf)) { | ||
logger.warn("[VNET] ... WSTT first cleaning PID [" + wstt_pid_conf + "]"); | ||
process.kill(wstt_pid_conf) | ||
if (running(wstun_pid_conf)) { | ||
logger.warn("[VNET] ... WSTUN first cleaning PID [" + wstun_pid_conf + "]"); | ||
process.kill(wstun_pid_conf) | ||
}else{ | ||
logger.debug("[VNET] ... WSTT no cleaning needed!"); | ||
logger.debug("[VNET] ... WSTUN no cleaning needed!"); | ||
} | ||
@@ -184,3 +195,3 @@ | ||
"socatServer_ip": socatServer_ip, | ||
"net_backend": net_backend, | ||
"net_backend": net_backend | ||
//"socatServer_port":socatServer_port, //TO RESTORE | ||
@@ -198,22 +209,21 @@ //"boardCode": boardCode //TO RESTORE | ||
// START WSTT ------------------------------------------------------------------------------------------------ | ||
logger.info("[VNET] - WSTT activating..."); | ||
// START WSTUN ------------------------------------------------------------------------------------------------ | ||
logger.info("[VNET] - WSTUN activating..."); | ||
logger.debug("[VNET] - WSTT - " + rtpath + ' -r ' + socatServer_port + ':localhost:' + basePort, reverseS_url); | ||
var wstt_proc = spawn(rtpath, ['-r ' + socatServer_port + ':localhost:' + basePort, reverseS_url]); | ||
//logger.debug("[VNET] - WSTT - " + rtpath + ' -r '+ socatServer_port +':localhost:'+basePort,reverseS_url); | ||
logger.debug("[VNET] - WSTUN - " + rtpath + ' -r ' + socatServer_port + ':localhost:' + basePort, reverseS_url); | ||
var wstun_proc = spawn(rtpath, ['-r ' + socatServer_port + ':localhost:' + basePort, reverseS_url]); | ||
// Save WSTT PID to clean network status after a network failure | ||
wstt_pid = wstt_proc.pid; | ||
wstt_config["pid"] = wstt_pid; | ||
update_net_conf(configFile, "WSTT"); | ||
// Save WSTUN PID to clean network status after a network failure | ||
wstun_pid = wstun_proc.pid; | ||
wstun_config["pid"] = wstun_pid; | ||
update_net_conf(configFile, "WSTUN"); | ||
wstt_proc.stdout.on('data', function (data) { | ||
logger.debug('[VNET] - WSTT - stdout: ' + data); | ||
wstun_proc.stdout.on('data', function (data) { | ||
logger.debug('[VNET] - WSTUN - stdout: ' + data); | ||
}); | ||
wstt_proc.stderr.on('data', function (data) { | ||
logger.debug('[VNET] - WSTT - stderr: ' + data); | ||
wstun_proc.stderr.on('data', function (data) { | ||
logger.debug('[VNET] - WSTUN - stderr: ' + data); | ||
}); | ||
wstt_proc.on('close', function (code) { | ||
logger.warn('[VNET] - WSTT - process exited with code ' + code); | ||
wstun_proc.on('close', function (code) { | ||
logger.warn('[VNET] - WSTUN - process exited with code ' + code); | ||
}); | ||
@@ -224,3 +234,3 @@ //------------------------------------------------------------------------------------------------------------ | ||
logger.info('[VNET] - Sending notification to IOTRONIC: ' + msg.status + ' - ' + msg.logmsg + ' - PID: ' + msg.pid + ' - wstt pid: ' + wstt_pid); | ||
logger.info('[VNET] - Sending notification to IOTRONIC: ' + msg.status + ' - ' + msg.logmsg + ' - PID: ' + msg.pid + ' - wstun pid: ' + wstun_pid); | ||
@@ -232,9 +242,15 @@ // Save Socat PID to clean network status after a network failure | ||
session_wamp.call('s4t.iotronic.vnet.result_network_board', [msg.logmsg, boardCode]).then( | ||
function (response) { | ||
logger.info('[VNET] --> response from IOTRONIC: \n' + response.message); | ||
logger.info('[VNET] - TUNNELS CONFIGURATION BOARD SIDE COMPLETED!'); | ||
} | ||
); | ||
try{ | ||
session_wamp.call('s4t.iotronic.vnet.result_network_board', [msg.logmsg, boardCode]).then( | ||
function (response) { | ||
logger.info('[VNET] --> response from IOTRONIC: \n' + response.message); | ||
logger.info('[VNET] - TUNNELS CONFIGURATION BOARD SIDE COMPLETED!'); | ||
} | ||
); | ||
}catch (e) { | ||
logger.error('[VNET] --> Error calling IoTronic (RPC: s4t.iotronic.vnet.result_network_board): ', e); | ||
} | ||
} | ||
@@ -395,5 +411,4 @@ | ||
add_vlan_iface.on('close', function (code) { | ||
add_vlan_iface.on('close', function () { | ||
logger.info('--> DELETED ' + iface); | ||
}); | ||
@@ -413,5 +428,5 @@ | ||
//Register all the module functions as WAMP RPCs | ||
session.register('s4t'+ boardCode + '.vnet.setSocatOnBoard', exports.setSocatOnBoard); | ||
session.register('s4t'+ boardCode + '.vnet.addToNetwork', exports.addToNetwork); | ||
session.register('s4t'+ boardCode + '.vnet.removeFromNetwork', exports.removeFromNetwork); | ||
session.register('s4t.'+ boardCode + '.vnet.setSocatOnBoard', exports.setSocatOnBoard); | ||
session.register('s4t.'+ boardCode + '.vnet.addToNetwork', exports.addToNetwork); | ||
session.register('s4t.'+ boardCode + '.vnet.removeFromNetwork', exports.removeFromNetwork); | ||
@@ -418,0 +433,0 @@ logger.info('[WAMP-EXPORTS] Network commands exported to the cloud!'); |
@@ -1,9 +0,19 @@ | ||
/* | ||
* Apache License | ||
* Version 2.0, January 2004 | ||
* http://www.apache.org/licenses/ | ||
* | ||
* Copyright (c) 2015 2016 Dario Bruneo, Francesco Longo, Giovanni Merlino, Fabio Verboso, Nicola Peditto | ||
* | ||
*/ | ||
//############################################################################################ | ||
//## | ||
//# Copyright (C) 2014-2017 Dario Bruneo, Francesco Longo, Giovanni Merlino, | ||
//# Nicola Peditto, Fabio Verboso | ||
//## | ||
//# Licensed under the Apache License, Version 2.0 (the "License"); | ||
//# you may not use this file except in compliance with the License. | ||
//# You may obtain a copy of the License at | ||
//## | ||
//# http://www.apache.org/licenses/LICENSE-2.0 | ||
//## | ||
//# Unless required by applicable law or agreed to in writing, software | ||
//# distributed under the License is distributed on an "AS IS" BASIS, | ||
//# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
//# See the License for the specific language governing permissions and | ||
//# limitations under the License. | ||
//## | ||
//############################################################################################ | ||
@@ -100,3 +110,3 @@ nconf = require('nconf'); | ||
logger.debug('[VNET] --> WSTT configuration completed!'); | ||
logger.debug('[VNET] --> WSTUN configuration completed!'); | ||
@@ -103,0 +113,0 @@ //ip link set $TUNNAME up |
{ | ||
"name": "@mdslab/iotronic-lightning-rod", | ||
"version": "1.1.0", | ||
"version": "2.0.0", | ||
"description": "Implementation of the Lightning-rod, the Stack4Things node-side probe (this version works with the standalone version of IoTronic) http://stack4things.unime.it/", | ||
@@ -19,3 +19,2 @@ "main": "lightning-rod.js", | ||
"dependencies": { | ||
"node-reverse-wstunnel": ">=0.1.2", | ||
"autobahn": ">=0.9.9", | ||
@@ -26,3 +25,3 @@ "nconf": ">=0.8.4", | ||
"connection-tester": ">=0.1.1", | ||
"log4js": "<=1.1.0", | ||
"log4js":"<=1.1.1", | ||
"q": ">=0.9.7", | ||
@@ -29,0 +28,0 @@ "fs-access": ">=1.0.1", |
@@ -15,3 +15,2 @@ { | ||
}, | ||
"reverse": | ||
@@ -28,3 +27,2 @@ { | ||
}, | ||
"socat":{ | ||
@@ -36,3 +34,2 @@ "client":{ | ||
}, | ||
"board": | ||
@@ -42,17 +39,2 @@ { | ||
"status": "new", | ||
"services":{ | ||
"ssh":{ | ||
"port":"22" | ||
}, | ||
"tty":{ | ||
"port":"2233" | ||
}, | ||
"ideino":{ | ||
"port":"2424" | ||
}, | ||
"osjs":{ | ||
"port":"8000" | ||
} | ||
}, | ||
"position":{ | ||
@@ -66,3 +48,4 @@ "altitude":0, | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
276079
10
5204
11
65
2
0
+ Addedlog4js@1.1.1(transitive)
+ Addedstreamroller@0.4.1(transitive)
- Removednode-reverse-wstunnel@>=0.1.2
- Removedd@1.0.2(transitive)
- Removedes5-ext@0.10.64(transitive)
- Removedes6-iterator@2.0.3(transitive)
- Removedes6-symbol@3.1.4(transitive)
- Removedesniff@2.0.1(transitive)
- Removedevent-emitter@0.3.5(transitive)
- Removedext@1.7.0(transitive)
- Removedlog4js@1.1.0(transitive)
- Removedminimist@0.0.10(transitive)
- Removednext-tick@1.1.0(transitive)
- Removednode-reverse-wstunnel@1.0.0(transitive)
- Removedoptimist@0.6.1(transitive)
- Removedstreamroller@0.2.2(transitive)
- Removedtype@2.7.3(transitive)
- Removedtypedarray-to-buffer@3.1.5(transitive)
- Removedunder_score@0.1.0(transitive)
- Removedutf-8-validate@5.0.10(transitive)
- Removedwebsocket@1.0.35(transitive)
- Removedwordwrap@0.0.3(transitive)
- Removedyaeti@0.0.6(transitive)
Updatedlog4js@<=1.1.1