Implement SmartSource header parser

This commit is contained in:
D. Berge
2020-09-02 08:59:22 +02:00
parent 3864dd43f5
commit d683f00594

View File

@@ -1,10 +1,234 @@
const NavHeaderError = require('./error');
function detect (buffer) {
return false;
const s = buffer.indexOf("*SMSRC");
return s != -1 ? s : false;
}
function parse (buffer) {
return; // undefined
let offset = buffer.indexOf("*SMSRC");
if (offset == -1) {
return; // undefined
}
function ascii (length, start = offset) {
// const start = offset;
const end = start+length;
offset = end;
// const v = buffer.subarray(start, end).toString('ascii');
// console.log("s, e", start, end, offset);
// console.log("v = ", v);
// return v;
return buffer.subarray(start, end).toString('ascii');
}
const header = {
header: (buf, ctx) => {
const header = ascii(6);
if (header != "*SMSRC") {
throw new NavHeaderError("Expected SmartSource marker not found at position " + s, buf);
}
},
blk_siz: (buf, ctx) => {
return Number(ascii(4));
},
line: (buf, ctx) => {
return ascii(30).trim();
},
shot: (buf, ctx) => {
return Number(ascii(10));
},
mask: (buf, ctx) => {
return Number(ascii(2));
},
trg_mode: (buf, ctx) => {
const trg_mode = ascii(1);
switch (trg_mode) {
case "I":
return "internal";
case "E":
return "external";
default:
throw new NavHeaderError("Unknown SmartSource trigger mode: " + trg_mode, buf);
}
},
time: (buf, ctx) => {
const time = ascii(17);
'20/08/30:05:45:58'
return new Date(time.replace(/(\d{2})\/(\d{2})\/(\d{2}):(\d{2}):(\d{2}):(\d{2})/, "20$1-$2-$3T$4:$5:$6Z"));
},
src_number: (buf, ctx) => {
return Number(ascii(1));
},
num_subarray: (buf, ctx) => {
return Number(ascii(1));
},
num_guns: (buf, ctx) => {
return Number(ascii(2));
},
num_active: (buf, ctx) => {
return Number(ascii(2));
},
num_delta: (buf, ctx) => {
return Number(ascii(2));
},
num_auto: (buf, ctx) => {
return Number(ascii(2));
},
num_nofire: (buf, ctx) => {
return Number(ascii(2));
},
spread: (buf, ctx) => {
// Convert to ms
return Number(ascii(4))/10;
},
volume: (buf, ctx) => {
return Number(ascii(6));
},
avg_delta: (buf, ctx) => {
return Number(ascii(5));
},
std_delta: (buf, ctx) => {
return Number(ascii(5));
},
baroPress: (buf, ctx) => {
// Converted to millibars
return Number(ascii(6))/100;
},
manifold: (buf, ctx) => {
return Number(ascii(4)); // PSI
},
spare: (buf, ctx) => {
return ascii(88).trim();
},
};
const gun = {
string: (buf, ctx) => {
return Number(ascii(1));
},
gun: (buf, ctx) => {
return Number(ascii(2));
},
source: (buf, ctx) => {
return Number(ascii(1));
},
mode: (buf, ctx) => {
const v = ascii(1);
switch (v) {
case "A":
case "M":
case "O":
case "D":
return v;
default:
throw new NavHeaderError("Unrecognised SmartSource gun mode value: "+v, buf);
}
},
detect: (buf, ctx) => {
const v = ascii(1);
switch (v) {
case "P":
case "Z":
case "L":
return v;
default:
throw new NavHeaderError("Unrecognised SmartSource detect value: "+v, buf);
}
},
autofire: (buf, ctx) => {
const v = ascii(1);
switch (v) {
case "N": return false;
case "Y": return true;
default:
throw new NavHeaderError("Unrecognised SmartSource autofire value: "+v, buf);
}
},
spare: (buf, ctx) => {
return ascii(1).trim();
},
aimport: (buf, ctx) => {
// Convert to ms
return Number(ascii(6))/10;
},
firetime: (buf, ctx) => {
// Convert to ms
return Number(ascii(6))/10;
},
delay: (buf, ctx) => {
// Convert to ms
return Number(ascii(4))/10;
},
depth: (buf, ctx) => {
// Convert to metres
return Number(ascii(4))/10;
},
pressure: (buf, ctx) => {
return Number(ascii(4));
},
volume: (buf, ctx) => {
return Number(ascii(4));
},
filltime: (buf, ctx) => {
return Number(ascii(4));
}
};
const smartsource = {};
smartsource._type = "smartsource";
smartsource._received = new Date();
for (const key of Object.keys(header)) {
smartsource[key] = header[key](buffer, smartsource);
}
smartsource.guns = [];
for (let n=0; n<smartsource.num_guns; n++) {
const gunItem = {};
for (const key of Object.keys(gun)) {
gunItem[key] = gun[key](buffer, gunItem);
}
smartsource.guns.push(gunItem);
}
return smartsource;
}
module.exports = {