@iotile/iotile-device
Version:
A typescript library for interfacing with IOTile BLE devices
69 lines (68 loc) • 2.85 kB
TypeScript
/**
* 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;
}