reorg code, integration publish/subscribe working, still some TODOs
This commit is contained in:
parent
043a95d9ef
commit
1af6d56e2d
35 changed files with 3052 additions and 1401 deletions
54
sensor/sensor-app.js
Normal file
54
sensor/sensor-app.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
//SENSOR
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
|
||||
const Config = require('../config');
|
||||
const ChainUtil = require('../chain-util');
|
||||
const Sensor = require('./sensor');
|
||||
|
||||
const {
|
||||
DEFAULT_PORT_BROKER_SENSOR_HANDSHAKE,
|
||||
DEFAULT_PORT_SENSOR_API,
|
||||
} = require('../constants');
|
||||
|
||||
'use strict';
|
||||
|
||||
const CONFIGS_STORAGE_LOCATION = "./settings.json";
|
||||
|
||||
const config = new Config(CONFIGS_STORAGE_LOCATION);
|
||||
|
||||
const keyPair = config.get({
|
||||
key: "sensor-keypair",
|
||||
default: ChainUtil.genKeyPair(),
|
||||
transform: ChainUtil.deserializeKeyPair
|
||||
});
|
||||
const apiPort = config.get({
|
||||
key: "sensor-api-port",
|
||||
default: DEFAULT_PORT_SENSOR_API
|
||||
});
|
||||
const sensorId = config.get({
|
||||
key: "sensor-id",
|
||||
default: "Test sensor"
|
||||
});
|
||||
const brokerLocation = config.get({
|
||||
key: "sensor-broker-location",
|
||||
default: "ws://127.0.0.1:" + DEFAULT_PORT_BROKER_SENSOR_HANDSHAKE
|
||||
});
|
||||
const brokerPublicKey = config.get({
|
||||
key: "sensor-broker-publickey",
|
||||
default: null
|
||||
});
|
||||
|
||||
const sensor = new Sensor(keyPair, sensorId, brokerLocation, brokerPublicKey);
|
||||
|
||||
const app = express();
|
||||
app.use(bodyParser.json());
|
||||
|
||||
|
||||
app.listen(apiPort, () => console.log(`Listening on port ${apiPort}`));
|
||||
|
||||
app.post('/send', (req, res) => {
|
||||
console.log(`sending: ${JSON.stringify(req.body)}`);
|
||||
sensor.send(JSON.stringify(req.body));
|
||||
res.json("sent");
|
||||
});
|
108
sensor/sensor.js
Normal file
108
sensor/sensor.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
const Websocket = require('ws');
|
||||
|
||||
const ChainUtil = require('../chain-util');
|
||||
const crypto = require('crypto');
|
||||
|
||||
const STATE_SERVER_HELLOING = 0;
|
||||
const STATE_SERVER_FINNING = 1;
|
||||
const STATE_OPERATIONAL = 2;
|
||||
|
||||
function onServerHelloing(sensor, data) {
|
||||
const serverNonce = data.toString();
|
||||
|
||||
if (typeof serverNonce !== 'string') {
|
||||
console.log("Bad server hello");
|
||||
sensor.close();
|
||||
return;
|
||||
}
|
||||
sensor.serverNonce = serverNonce;
|
||||
|
||||
crypto.randomBytes(2048, (err, buf) => {
|
||||
if (err) {
|
||||
console.log(`Couldn't generate client nonce: ${err}`);
|
||||
sensor.close();
|
||||
return;
|
||||
}
|
||||
|
||||
sensor.clientNonce = buf.toString('hex');
|
||||
|
||||
sensor.socket.send(JSON.stringify({
|
||||
owner: sensor.keyPair.getPublic().encode('hex'),
|
||||
sensor: sensor.sensorId,
|
||||
signature: sensor.keyPair.sign(sensor.serverNonce + sensor.clientNonce),
|
||||
clientNonce: sensor.clientNonce
|
||||
}));
|
||||
sensor.state = STATE_SERVER_FINNING;
|
||||
});
|
||||
}
|
||||
|
||||
function onServerFinning(sensor, data) {
|
||||
const signature = JSON.parse(data);
|
||||
if (typeof signature !== 'object') {
|
||||
console.log("Bad server fin");
|
||||
sensor.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (sensor.brokerPublicKey !== null) {
|
||||
const verifyRes = ChainUtil.verifySignature(sensor.brokerPublicKey, data, sensor.clientNonce + sensor.serverNonce);
|
||||
if (!verifyRes.result) {
|
||||
console.log("Bad server fin singature: " + verifyRes.reason);
|
||||
sensor.close();
|
||||
return;
|
||||
}
|
||||
console.log("Broker authed, operational");
|
||||
} else {
|
||||
console.log("No broker public key stored, blindly trusting the broker");
|
||||
}
|
||||
|
||||
sensor.state = STATE_OPERATIONAL;
|
||||
for (const msg of sensor.queue) {
|
||||
sensor.send(msg);
|
||||
}
|
||||
}
|
||||
|
||||
function onOperational(_, _) {
|
||||
}
|
||||
|
||||
function onSocketMessage(sensor, data) {
|
||||
switch (sensor.state) {
|
||||
case STATE_SERVER_HELLOING: onServerHelloing(sensor, data); break;
|
||||
case STATE_SERVER_FINNING: onServerFinning(sensor, data); break;
|
||||
case STATE_OPERATIONAL: onOperational(sensor, data); break;
|
||||
default: throw Error("Invalid internal state");
|
||||
}
|
||||
}
|
||||
|
||||
function onConnection(sensor) {
|
||||
sensor.socket.on('message', (data) => {
|
||||
onSocketMessage(sensor, data);
|
||||
});
|
||||
}
|
||||
|
||||
class Sensor {
|
||||
constructor(keyPair, sensorId, brokerLocation, brokerPublicKey) {
|
||||
this.keyPair = keyPair;
|
||||
this.sensorId = sensorId;
|
||||
this.brokerPublicKey = brokerPublicKey;
|
||||
this.state = STATE_SERVER_HELLOING;
|
||||
this.queue = [];
|
||||
|
||||
this.socket = new Websocket(brokerLocation);
|
||||
this.socket.on('open', (_) => onConnection(this));
|
||||
}
|
||||
|
||||
send(data) {
|
||||
if (this.state != STATE_OPERATIONAL) {
|
||||
this.queue.push(data);
|
||||
} else {
|
||||
this.socket.send(data);
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Sensor;
|
Loading…
Add table
Add a link
Reference in a new issue