UNPKG

@iotile/iotile-device

Version:

A typescript library for interfacing with IOTile BLE devices

112 lines 5.53 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const iotile_reports_1 = require("./iotile-reports"); const iotile_common_1 = require("@iotile/iotile-common"); class SignedListReportMerger { mergeReports(user, system) { this.checkReportsForMerging(user, system); let mergedLength = 20 + (16 * (user.readings.length + system.readings.length)) + 24; let merged = new ArrayBuffer(mergedLength); this.insertMergedHeader(merged, user, system); let readings = this.mergeReadings(merged, user, system); this.insertMergedFooter(merged, readings.lowestID, readings.highestID); return new iotile_reports_1.SignedListReport(system.header.uuid, iotile_reports_1.COMBINED_REPORT_STREAMER, merged, system.receivedTime); } checkReportsForMerging(user, system) { let userHeader = user.header; let systemHeader = system.header; if (user.validity != iotile_reports_1.SignatureStatus.Valid || system.validity != iotile_reports_1.SignatureStatus.Valid) { throw new iotile_common_1.ArgumentError("You can only merge reports that have valid signatures"); } if (userHeader.uuid != systemHeader.uuid) { throw new iotile_common_1.ArgumentError("Reports did not come from the same device"); } if (userHeader.selector != iotile_reports_1.SignedReportSelectors.UserOutputs) { throw new iotile_common_1.ArgumentError("User report did not select user readings"); } if (systemHeader.selector != iotile_reports_1.SignedReportSelectors.SystemOutputs) { throw new iotile_common_1.ArgumentError("System report did not select system readings"); } if (systemHeader.sentTime < userHeader.sentTime) { throw new iotile_common_1.ArgumentError("System report was sent before user report"); } if (systemHeader.reportID < userHeader.reportID) { throw new iotile_common_1.ArgumentError("System report ID was lower than user report"); } } insertMergedHeader(merged, user, system) { let userHeader = user.header; let systemHeader = system.header; let header = iotile_common_1.packArrayBuffer('BBHLLLBBH', 1, merged.byteLength & 0xFF, merged.byteLength >> 8, userHeader.uuid, systemHeader.reportID, systemHeader.sentTime, 0, iotile_reports_1.COMBINED_REPORT_STREAMER, iotile_reports_1.SignedReportSelectors.CombinedOutputs); iotile_common_1.copyArrayBuffer(merged, header, 0, 0, header.byteLength); } mergeReadings(merged, user, system) { let userI = 0; let systemI = 0; let totalReadings = user.readings.length + system.readings.length; let insertI = 0; let lowest = 0xFFFFFFFF; let highest = 0; let readings = []; let now = new Date(); let onTime = new Date(now.valueOf() - (system.header.sentTime * 1000)); while (insertI < totalReadings) { let pickSystem = this.pickNextReading(user, userI, system, systemI); let reading; if (pickSystem) { reading = system.readings[systemI++]; } else { reading = user.readings[userI++]; } if (reading.id != 0 && reading.id < lowest) { lowest = reading.id; } if (reading.id != 0 && reading.id > highest) { highest = reading.id; } readings.push(new iotile_reports_1.RawReading(reading.stream, reading.value, reading.timestamp, onTime, reading.id)); this.insertReading(merged, (20 + 16 * insertI), reading.timestamp, reading.stream, reading.value, reading.id); insertI += 1; } return { lowestID: lowest, highestID: highest, readings: readings }; } pickNextReading(user, userI, system, systemI) { if (userI == user.readings.length && systemI == system.readings.length) { throw new iotile_common_1.ArgumentError("Both reports have been exhausted, no more readings to pick"); } if (userI == user.readings.length) { return true; } else if (systemI == system.readings.length) { return false; } let userReading = user.readings[userI]; let systemReading = system.readings[systemI]; if (userReading.id < systemReading.id) { return false; } else { return true; } } insertReading(merged, offset, timestamp, stream, value, readingID) { let reading = iotile_common_1.packArrayBuffer('HHLLL', stream, 0, readingID, timestamp, value); iotile_common_1.copyArrayBuffer(merged, reading, 0, offset, reading.byteLength); } insertMergedFooter(merged, lowest, highest) { let footerStart = merged.byteLength - 24; let idRange = iotile_common_1.packArrayBuffer("LL", lowest, highest); iotile_common_1.copyArrayBuffer(merged, idRange, 0, footerStart, idRange.byteLength); let calc = new iotile_common_1.SHA256Calculator(); let signedData = merged.slice(0, merged.byteLength - 16); let signature = calc.calculateSignature(signedData); iotile_common_1.copyArrayBuffer(merged, signature, 0, merged.byteLength - 16, 16); } } exports.SignedListReportMerger = SignedListReportMerger; //# sourceMappingURL=report-merger.js.map