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
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