3
Fork 0

Added project

This commit is contained in:
Willem Cazander 2022-11-13 01:46:38 +01:00
parent fe9aa14dfd
commit 2d73cc8845
186 changed files with 21174 additions and 0 deletions

View file

@ -0,0 +1,291 @@
var XDeviceEncryption = require('./xdevice-encryption');
var Mongoose = require('mongoose');
var XSystemState = Mongoose.model( 'xsystem-state' );
var XNode = Mongoose.model( 'xnode' );
var XNodeBase = Mongoose.model( 'xnode-base' );
var XNodeBaseCommand = Mongoose.model( 'xnode-base-command' );
var XNodeData = Mongoose.model( 'xnode-data' );
var XNodeDataValue = Mongoose.model( 'xnode-data-value' );
var Async = require('async');
var Winston = require('winston');
var Log = Winston.loggers.get('main');
var createXnodeBase = function(created_ip,callbackResult) {
Async.series({
cnt_base_net_id: function(callback) {
XSystemState.incHexByName('_a_seq_base_net_id', function(err, xprop) {
callback(err,xprop.value);
});
},
cnt_base_net_key: function(callback){
XSystemState.incHexByName('_a_seq_base_net_key', function(err, xprop) {
callback(err,xprop.value);
});
},
cnt_base_net_mac: function(callback){
XSystemState.incHexByName('_a_seq_base_net_mac', function(err, xprop) {
callback(err,xprop.value);
});
},
cnt_base_rf_key: function(callback){
XSystemState.incHexByName('_a_seq_base_rf_key', function(err, xprop) {
callback(err,xprop.value);
});
}
},
function(err, result) {
if (err) {
callbackResult(err);
return;
}
var xnodeBase = new XNodeBase();
xnodeBase.created_ip = created_ip;
xnodeBase.net_id = result.cnt_base_net_id;
xnodeBase.net_key = result.cnt_base_net_key;
xnodeBase.net_mac = result.cnt_base_net_mac;
xnodeBase.rf_key = result.cnt_base_rf_key;
xnodeBase.init_index = 0;
xnodeBase.save(function(err,xnodeBase) {
Log.debug("XDeviceConnectorA.createXnodeBase _id="+xnodeBase._id+" net_id="+xnodeBase.net_id);
callbackResult(err,xnodeBase);
});
});
}
var handleInit = function(req,res,next) {
Log.debug('XDeviceConnectorA.handleInit');
var net_id = req.body.ni;
if (net_id == 0) {
createXnodeBase(req.ip,function(err,xnodeBase) {
if (err) { return next(err); }
Log.info('XDeviceConnectorA.handleInit response: Xinet_id '+xnodeBase.net_id);
res.send('Xinet_id '+xnodeBase.net_id+'\n');
});
} else {
XNodeBase.findOneByNetId(net_id,function(err,xnodeBase) {
if (err) { return next(err); }
if (xnodeBase == null) {
Log.warn('XDeviceConnectorA.handleInit illegal net_id='+req.body.ni);
res.send('X');
return;
}
if (xnodeBase.init_index > 4) {
Log.error('initXnode stateError, device was already init-ited.');
res.send('XXreboot');
return;
}
xnodeBase.init_index++;
xnodeBase.save(function(err) {
var result;
if (xnodeBase.init_index == 1) {
result = 'Xinet_key '+xnodeBase.net_key;
} else if (xnodeBase.init_index == 2) {
result = 'Xinet_mac '+xnodeBase.net_mac;
} else if (xnodeBase.init_index == 3) {
result = 'Xirf_key '+xnodeBase.rf_key;
} else if (xnodeBase.init_index == 4) {
result = 'Xireboot';
XNodeBaseCommand.insert(net_id,'help',req.ip,next); // trigger node data on next ping :)
} else {
result = 'X'; // code error
}
Log.info('XDeviceConnectorA.initXnode response net_id='+xnodeBase.net_id+' step='+xnodeBase.init_index+' reply='+result);
res.send(result);
});
});
}
};
var replyCommand = function(req,res,next) {
XNodeBaseCommand.findOpenByNetId(req.body.ni, function ( err, data ) {
if (err) { return next(err); }
if (data.length > 0) {
Log.debug('XDeviceConnectorA.replyCommand send cmd: '+data[0].command);
data[0].send_date = new Date();
data[0].save(function(err) {
if (err) { return next(err); }
res.send('XX'+data[0].command);
});
} else {
res.send('X');
}
});
}
var logData = function(xnode,data_raw,data_text,req) {
var xdata = new XNodeData();
xdata.remote_ip = req.ip;
xdata.node_id = xnode.node_id;
xdata.net_id = req.body.ni;
xdata.data_raw = data_raw;
xdata.data_text = data_text;
xdata.save(function(err,xdata) {
if (err) { return next(err); }
Log.debug("XDeviceConnectorA.logData _id="+xdata._id+" net_id="+xdata.net_id+" node_id="+xdata.node_id+" data_text.length="+xdata.data_text.length);
});
}
var logDataValue = function(xnode,data_text,req, next) {
if (data_text.indexOf('help') > 0) {
return; // done't save help cmds as values.
}
if (data_text.indexOf('#ERR') > 0) {
return; // done't save errors.
}
var data_lines = data_text.split('\n');
for(var i = 0; i < data_lines.length; i ++) {
var data_line = data_lines[i];
var data_rows = data_line.split('=');
var data_name = data_rows[0];
var data_value = data_rows[1];
if (data_name.length == 0) {
continue;
}
xval = new XNodeDataValue();
xval.net_id = xnode.net_id;
xval.node_id = xnode.node_id;
xval.name = data_name;
xval.value = data_value;
xval.save(function(err,xval) {
if (err) { return next(err); }
Log.debug("XDeviceConnectorA.logDataValue _id="+xval._id+" net_id="+xval.net_id+" node_id="+xval.node_id+" name="+xval.name+" value="+xval.value);
});
}
}
var logRxCount = function(xnode,data_text,next) {
xnode.rx_date=new Date();
xnode.rx_requests++;
xnode.rx_bytes=data_text.length + xnode.rx_bytes;
xnode.save(function(err,xnode) {
if (err) { return next(err); }
Log.debug("XDeviceConnectorA.logRxCount _id="+xnode._id+" rx_requests="+xnode.rx_requests);
});
}
var updateMetaInfo = function(xnode,req, next) {
if (xnode.info_date == null) {
xnode.info_date = new Date(new Date().getTime() - 60*60*1000 - 1000); // triggers update
}
var dateLastHour = new Date(new Date().getTime() - 60*60*1000);
if (dateLastHour.getTime() > xnode.info_date.getTime() ) {
if (xnode.node_id == 1) {
XNodeBaseCommand.insert(xnode.net_id,'sys_info',req.ip, next);
XNodeBaseCommand.insert(xnode.net_id,'rf_info',req.ip, next);
XNodeBaseCommand.insert(xnode.net_id,'net_info',req.ip, next);
XNodeBaseCommand.insert(xnode.net_id,'net_info_eth0',req.ip, next);
} else {
Log.debug("todo");
//XNodeBaseCommand.insert(xnode.net_id,'@2 sys_info',req.ip, next);
//XNodeBaseCommand.insert(xnode.net_id,'@2 rf_info',req.ip, next);
}
xnode.info_date = new Date();
xnode.save(function(err,xsat) {
if (err) { return next(err); }
Log.debug("XDeviceConnectorA.updateMetaInfo _id="+xnode._id);
});
}
}
var handleDataNode = function(xnode,req,res,next) {
var net_id = req.body.ni;
var node_id = req.body.nn;
var data_raw = req.body.nd;
Log.debug('XDeviceConnectorA.handleDataNode ni='+xnode.net_id);
// log.debug('XDeviceConnectorA.handleData TODO FIX XXTEA');
// var result = XDeviceEncryption.xxteaDecrypt(req.body.nd,xnode.hw_net_key);
// log.debug('XDeviceConnectorA.handleData xxteaDecrypt='+result+' hw_net_key='+xnode.hw_net_key);
var data_text = data_raw;
logRxCount (xnode,data_text,next);
logData (xnode,data_raw,data_text,req);
logDataValue (xnode,data_text, req, next);
updateMetaInfo (xnode,req, next);
replyCommand (req,res,next);
}
var handleData = function(req,res,next) {
var net_id = req.body.ni;
var node_id = req.body.nn;
if (net_id == '000000000000') {
Log.warn('XDeviceConnectorA.handleData zero net_id='+net_id);
res.send('X');
return;
}
if (node_id == 0) {
Log.warn('XDeviceConnectorA.handleData zero node_id='+node_id);
res.send('X');
return;
}
Log.debug('XDeviceConnectorA.handleData ni='+net_id+' nn='+node_id);
XNode.findByNetIdAndNodeId(net_id,node_id,function(err,xnode) {
if (err) { return next(err); }
if (xnode == null) {
Log.debug('XDeviceConnectorA.handleData creating new XNode.');
xnode = new XNode();
xnode.net_id = net_id;
xnode.node_id = node_id;
xnode.save(function(err) {
if (err) { return next(err); }
handleDataNode(xnode,req,res,next);
});
} else {
handleDataNode(xnode,req,res,next);
}
});
}
var handlePing = function(req,res,next) {
var net_id = req.body.ni;
if (net_id == '000000000000') {
Log.debug('XDeviceConnectorA.handlePing zero net_id='+net_id);
res.send('X');
return;
}
Log.debug('XDeviceConnectorA.handlePing net_id='+net_id);
XNodeBase.findOneByNetId(net_id,function(err,xnodeBase) {
if (err) { return next(err); }
if (xnodeBase == null) {
Log.warn('XDeviceConnectorA.handlePing illegal net_id='+net_id);
res.send('X');
return;
}
xnodeBase.ping_counter++;
xnodeBase.ping_last_date=new Date();
xnodeBase.save(function(err) {
if (err) { return next(err); }
if (req.body.rc == 0) {
res.send('X'); // no cmd on first ping.
} else {
replyCommand(req,res,next);
}
});
});
}
exports.deviceControl = function(req, res, next) {
var postType = req.body.pt;
var url = req.originalUrl || req.url;
var ip = req.ip;
Log.debug('POST '+url+' ip='+ip+' pt='+postType+' rc='+req.body.rc+' ni='+req.body.ni);
if (postType == 'i') {
handleInit(req,res,next);
return;
}
if (postType == 'p') {
handlePing(req,res,next);
return;
}
if (postType == 'd') {
handleData(req,res,next);
return;
}
Log.warn('XDeviceConnectorA.deviceControl unknown postType='+postType);
res.send('X');
}

View file

@ -0,0 +1,120 @@
var winston = require('winston');
var log = winston.loggers.get('main');
var delta = 0x9E3779B9;
var XXTEA_NUM_ROUNDS = 32;
//var xxxteaEncrypt = function(unsigned long v[2]) {
// unsigned int i;
// unsigned long v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
// for (i=0; i < XXTEA_NUM_ROUNDS; i++) {
// v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + XBHardware.config.net_key.u32[sum & 3]);
// sum += delta;
// v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + XBHardware.config.net_key.u32[(sum>>11) & 3]);
// }
// v[0]=v0; v[1]=v1;
//}
var xxxteaDecrypt = function(vArray,keyBuff) {
log.debug('XDeviceEncryption.xxxteaDecrypt vArray='+JSON.stringify(vArray)+' keyBuff='+JSON.stringify(keyBuff));
var v0=vArray.v0;
var v1=vArray.v1;
log.debug('XDeviceEncryption.xxxteaDecrypt start v0='+v0.toString(16)+' v1='+v1.toString(16));
var delta=0x9E3779B9
var sum=delta*XXTEA_NUM_ROUNDS;
for (var i=0; i < XXTEA_NUM_ROUNDS; i++) {
v1 -= (((v0 << 4) ^ (v0 >>> 5)) + v0) ^ (sum + keyBuff.readUInt32BE((sum>>>11) & 3));
var v1Org = v1;
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >>> 5)) + v1) ^ (sum + keyBuff.readUInt32BE(sum & 3));
//log.debug('XDeviceEncryption.xxxteaDecrypt v0='+v0.toString(16)+' v1='+v1.toString(16));
if (v0 < 0) { v0 = Math.pow(2,32) + v0; }
if (v0 > Math.pow(2,32)) { v0 = v0 - Math.pow(2,32); }
if (v1 < 0) { v1 = Math.pow(2,32) + v1; }
if (v1 > Math.pow(2,32)) { v1 = v1 - Math.pow(2,32); }
}
//v0 = v0 & 0xFFFFFFFF;
//v1 = v1 & 0xFFFFFFFF;
var result = {v0: v0,v1: v1};
log.debug('XDeviceEncryption.xxxteaDecrypt result='+JSON.stringify(result));
return result;
}
// public static method encrypt
exports.xxteaEncrypt = function(string, key) {
log.debug('XDeviceEncryption.xxteaEncrypt key='+key+' data='+string);
if (string.length == 0) {
return('');
}
//var v = strToLongs(Utf8.encode(string));
//var k = strToLongs(Utf8.encode(key).slice(0,16));
var v = buffToLongs(new Buffer(string, 'hex'));
var k = buffToLongs(new Buffer(key, 'hex'));
//if (v.length <= 1) v[1] = 0; // algorithm doesn't work for n<2 so fudge by adding a null
var n = v.length;
// ---- <TEA coding> ----
var z = v[n-1], y = v[0], delta = 0x9E3779B9;
var mx, e, q = Math.floor(6 + 52/n), sum = 0;
while (q-- > 0) { // 6 + 52/n operations gives between 6 & 32 mixes on each word
sum += delta;
e = sum>>>2 & 3;
for (var p = 0; p < n; p++) {
y = v[(p+1)%n];
mx = (z>>>5 ^ y<<2) + (y>>>3 ^ z<<4) ^ (sum^y) + (k[p&3 ^ e] ^ z);
z = v[p] += mx;
}
}
// ---- </TEA> ----
var buff = longsToBuff(v);
return buff.toString('ascii');
}
exports.xxteaDecrypt = function(data, key) {
log.debug('XDeviceEncryption.xxteaDecrypt key='+key+' data='+data);
if (data.length == 0) {
return('');
}
var d = new Buffer(data, 'hex');
var k = new Buffer(key, 'hex');
var n = d.length;
var r = new Buffer(n);
log.debug('XDeviceEncryption.xxteaDecrypt dataBuffer='+d.toString('hex'));
// ---- <TEA decoding> ----
for (var i=0;i<n/4-1;i=i+2) {
//log.debug('XDeviceEncryption.xxteaDecrypt n='+n+' i='+i+' c='+(i*4)+' cc='+(i*4+1)+' r='+d.readUInt32LE(i*4).toString(16)+' r1='+d.readUInt32BE(i*4).toString(16));
var ed = {v0: d.readUInt32BE(i*4),v1: d.readUInt32BE((i+1)*4)};
var dd = xxxteaDecrypt(ed,k);
r.writeUInt32BE(dd.v0,i*4);
r.writeUInt32BE(dd.v1,(i+1)*4);
}
return r.toString('ascii');
//var plaintext = longsToStr(v);
//plaintext = plaintext.replace(/\0+$/,'');
//return plaintext;
//return new Buffer(plaintext,'utf8').toString('ascii');
//var plaintext = longsToStr(v);
//plaintext = plaintext.replace(/\0+$/,'');// strip trailing null chars resulting from filling 4-char blocks:
//return Utf8.decode(plaintext);
}