UNPKG

@iotile/iotile-device

Version:

A typescript library for interfacing with IOTile BLE devices

69 lines (68 loc) 2.78 kB
/** * Helper class that is able to rearrange the bluetooth notitications inside a SignedListReport. * * This class is necessary because some bluetooth stacks, notably Android, don't push notifications * in order to applications when they come in very near to each other in time. This causes * reports that span multiple notification packets (20 bytes each) to be corrupted since the * chunks of the report are reassembled out of order. * * ReportReassembler uses heuristics and other knowledge of the internal structure and invariants * of a SignedListReport to detect when out-of-order packets are received and place them back * into the correct order. * * It works by recognizing that the individual readings in a report are 16 bytes long * whereas the reports are chunked into 20-byte packets. So every packet contains at * least part of 2 readings including the majority or all of 1 reading. By looking * at if readings that cross packet boundaries make sense we can infer what order the * packets should have been received in. There are 4 main criteria we use to determine * if a reading makes sense: * * 1. The stream id must be selected by the report selector. Each report has specific * criteria for what readings are included so every stream id must match the selector * included in the report header. * 2. The reading id must be monotonically increasing. * 3. The reading timestamp can only decrease if there has been a reboot (included as * a reboot stream event). * 4. There is a 16-bit reserved field in each reading for alignment purposes that must be * 0. * * If there are multiple potential chunks that match all of those 4 criteria, then the one * with the lowest reading id is chosen. In practice we have found that this reliably fixes * out of order packets with near 100% success. */ export interface DecodedChunk { streams: (number | null)[]; reserved: (number | null)[]; ids: (number | null)[]; timestamps: (number | null)[]; values: (number | null)[]; offset: number; index: number; } export interface Transposition { src: number; dst: number; } export declare class ReportReassembler { private currentReport; private header; private originalSignature; private sigCalculator; private errors; constructor(report: ArrayBuffer); isValid(): boolean; getTranspositions(): Transposition[]; getFixedReport(): ArrayBuffer; fixOutOfOrderChunks(): boolean; private sortCandidates; private moveChunk; private extractLatest; private fillChunk; private decodeChunk; private dumpChunk; private maskChunk; private validateChunk; private findCandidates; private calculateSignature; private checkSignature; }