mirror of
https://github.com/jwetzell/psn-js.git
synced 2026-08-15 12:23:58 +00:00
convert to typescript
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
module.exports = {
|
||||
PACKET_HEADER_SIZE: 16,
|
||||
MAX_UDP_PACKET_SIZE: 1500,
|
||||
CHUNK_HEADER_SIZE: 4,
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export class Constants {
|
||||
static readonly PACKET_HEADER_SIZE = 16;
|
||||
static readonly MAX_UDP_PACKET_SIZE = 1500;
|
||||
static readonly CHUNK_HEADER_SIZE = 4;
|
||||
}
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
const packetDecoder = require('./decoders/packet');
|
||||
|
||||
class Decoder {
|
||||
// TODO(jwetzell): check if these last packet headers are necessary to hold on to
|
||||
lastInfoPacketHeader;
|
||||
|
||||
lastDataPacketHeader;
|
||||
|
||||
infoPacketFrames = {};
|
||||
|
||||
dataPacketFrames = {};
|
||||
|
||||
constructor() {
|
||||
this.system_name = '';
|
||||
|
||||
this.trackers = {};
|
||||
}
|
||||
|
||||
updateInfo(framePackets) {
|
||||
framePackets.forEach((packet) => {
|
||||
if (packet.system_name) {
|
||||
this.system_name = packet.system_name.system_name;
|
||||
}
|
||||
|
||||
if (packet.tracker_list?.trackers) {
|
||||
Object.entries(packet.tracker_list.trackers).forEach(([trackerId, tracker]) => {
|
||||
this.trackers[trackerId] = {
|
||||
...this.trackers[trackerId],
|
||||
...tracker.tracker_name,
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateData(framePackets) {
|
||||
framePackets.forEach((packet) => {
|
||||
if (packet.tracker_list) {
|
||||
Object.entries(packet.tracker_list.trackers).forEach(([trackerId, tracker]) => {
|
||||
this.trackers[trackerId] = {
|
||||
...this.trackers[trackerId],
|
||||
...tracker,
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete
|
||||
decode(packetBuf) {
|
||||
const packet = packetDecoder(packetBuf);
|
||||
if (packet.id === 0x6756) {
|
||||
const infoPacket = packet;
|
||||
if (infoPacket) {
|
||||
if (infoPacket.has_subchunks > 0) {
|
||||
const currentInfoPacketHeader = infoPacket.packet_header;
|
||||
if (!currentInfoPacketHeader) {
|
||||
// NOTE(jwetzell): not sure that info packets without a header subchunk are valid?
|
||||
throw new Error('malformed packet');
|
||||
}
|
||||
|
||||
const systemSubChunk = infoPacket.system_name;
|
||||
if (!systemSubChunk) {
|
||||
// NOTE(jwetzell): not sure that info packets without a system subchunk are valid?
|
||||
throw new Error('malformed packet');
|
||||
}
|
||||
|
||||
if (this.infoPacketFrames[currentInfoPacketHeader.frame_id] === undefined) {
|
||||
this.infoPacketFrames[currentInfoPacketHeader.frame_id] = [];
|
||||
}
|
||||
this.infoPacketFrames[currentInfoPacketHeader.frame_id].push(infoPacket);
|
||||
|
||||
if (
|
||||
this.infoPacketFrames[currentInfoPacketHeader.frame_id].length ===
|
||||
currentInfoPacketHeader.frame_packet_count
|
||||
) {
|
||||
this.updateInfo(this.infoPacketFrames[currentInfoPacketHeader.frame_id]);
|
||||
delete this.infoPacketFrames[currentInfoPacketHeader.frame_id];
|
||||
}
|
||||
|
||||
this.lastInfoPacketHeader = currentInfoPacketHeader;
|
||||
}
|
||||
}
|
||||
} else if (packet.id === 0x6755) {
|
||||
const dataPacket = packet;
|
||||
if (dataPacket.has_subchunks) {
|
||||
const currentDataPacketHeader = dataPacket.packet_header;
|
||||
if (!currentDataPacketHeader) {
|
||||
// NOTE(jwetzell): not sure that info packets without a header subchunk are valid?
|
||||
throw new Error('malformed packet');
|
||||
}
|
||||
if (this.dataPacketFrames[currentDataPacketHeader.frame_id] === undefined) {
|
||||
this.dataPacketFrames[currentDataPacketHeader.frame_id] = [];
|
||||
}
|
||||
this.dataPacketFrames[currentDataPacketHeader.frame_id].push(dataPacket);
|
||||
if (
|
||||
this.dataPacketFrames[currentDataPacketHeader.frame_id].length === currentDataPacketHeader.frame_packet_count
|
||||
) {
|
||||
this.updateData(this.dataPacketFrames[currentDataPacketHeader.frame_id]);
|
||||
delete this.dataPacketFrames[currentDataPacketHeader.frame_id];
|
||||
}
|
||||
this.lastDataPacketHeader = currentDataPacketHeader;
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Decoder;
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
import { DataPacketChunk } from './decoders/data/data-packet-chunk';
|
||||
import { InfoPacketChunk } from './decoders/info/info-packet-chunk';
|
||||
import { InfoTrackerChunk } from './decoders/info/info-tracker-chunk';
|
||||
import packetDecoder from './decoders/packet';
|
||||
import { PacketHeaderChunk } from './decoders/packet-header-chunk';
|
||||
|
||||
export class Decoder {
|
||||
// TODO(jwetzell): check if these last packet headers are necessary to hold on to
|
||||
lastInfoPacketHeader?: PacketHeaderChunk;
|
||||
|
||||
lastDataPacketHeader?: PacketHeaderChunk;
|
||||
|
||||
infoPacketFrames: { [key: number]: InfoPacketChunk[] } = {};
|
||||
|
||||
dataPacketFrames: { [key: number]: DataPacketChunk[] } = {};
|
||||
|
||||
trackers: { [key: string]: InfoTrackerChunk } = {};
|
||||
|
||||
system_name: string = '';
|
||||
constructor() {}
|
||||
|
||||
updateInfo(framePackets: InfoPacketChunk[]) {
|
||||
framePackets.forEach((packet) => {
|
||||
if (packet.system_name) {
|
||||
this.system_name = packet.system_name.system_name;
|
||||
}
|
||||
|
||||
if (packet.tracker_list?.trackers) {
|
||||
Object.entries(packet.tracker_list.trackers).forEach(([trackerId, tracker]) => {
|
||||
if (!this.trackers[trackerId]) {
|
||||
this.trackers[trackerId] = {};
|
||||
}
|
||||
this.trackers[trackerId].tracker_name = tracker.tracker_name;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateData(framePackets: DataPacketChunk[]) {
|
||||
framePackets.forEach((packet) => {
|
||||
if (packet.tracker_list) {
|
||||
Object.entries(packet.tracker_list.trackers).forEach(([trackerId, tracker]) => {
|
||||
this.trackers[trackerId] = {
|
||||
...this.trackers[trackerId],
|
||||
...tracker,
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO(jwetzell): add invalid frame id decoding. Scenario where a frame id is reused before one is complete
|
||||
decode(packetBuf: Buffer): DataPacketChunk | InfoPacketChunk | undefined {
|
||||
const packet = packetDecoder(packetBuf);
|
||||
if (packet === undefined) {
|
||||
return packet;
|
||||
}
|
||||
|
||||
if (packet.id === 0x6756) {
|
||||
const infoPacket = packet as InfoPacketChunk;
|
||||
if (infoPacket && infoPacket.has_subchunks) {
|
||||
const currentInfoPacketHeader = infoPacket.packet_header;
|
||||
if (!currentInfoPacketHeader) {
|
||||
// NOTE(jwetzell): not sure that info packets without a header subchunk are valid?
|
||||
throw new Error('malformed packet');
|
||||
}
|
||||
|
||||
const systemSubChunk = infoPacket.system_name;
|
||||
if (!systemSubChunk) {
|
||||
// NOTE(jwetzell): not sure that info packets without a system subchunk are valid?
|
||||
throw new Error('malformed packet');
|
||||
}
|
||||
if (currentInfoPacketHeader.frame_id) {
|
||||
if (this.infoPacketFrames[currentInfoPacketHeader.frame_id] === undefined) {
|
||||
this.infoPacketFrames[currentInfoPacketHeader.frame_id] = [];
|
||||
}
|
||||
this.infoPacketFrames[currentInfoPacketHeader.frame_id].push(infoPacket);
|
||||
|
||||
if (
|
||||
this.infoPacketFrames[currentInfoPacketHeader.frame_id].length ===
|
||||
currentInfoPacketHeader.frame_packet_count
|
||||
) {
|
||||
this.updateInfo(this.infoPacketFrames[currentInfoPacketHeader.frame_id]);
|
||||
delete this.infoPacketFrames[currentInfoPacketHeader.frame_id];
|
||||
}
|
||||
}
|
||||
|
||||
this.lastInfoPacketHeader = currentInfoPacketHeader;
|
||||
}
|
||||
} else if (packet.id === 0x6755) {
|
||||
const dataPacket = packet as DataPacketChunk;
|
||||
if (dataPacket.has_subchunks) {
|
||||
const currentDataPacketHeader = dataPacket.packet_header;
|
||||
if (!currentDataPacketHeader) {
|
||||
// NOTE(jwetzell): not sure that info packets without a header subchunk are valid?
|
||||
throw new Error('malformed packet');
|
||||
}
|
||||
|
||||
if (currentDataPacketHeader.frame_id) {
|
||||
if (this.dataPacketFrames[currentDataPacketHeader.frame_id] === undefined) {
|
||||
this.dataPacketFrames[currentDataPacketHeader.frame_id] = [];
|
||||
}
|
||||
this.dataPacketFrames[currentDataPacketHeader.frame_id].push(dataPacket);
|
||||
if (
|
||||
this.dataPacketFrames[currentDataPacketHeader.frame_id].length ===
|
||||
currentDataPacketHeader.frame_packet_count
|
||||
) {
|
||||
this.updateData(this.dataPacketFrames[currentDataPacketHeader.frame_id]);
|
||||
delete this.dataPacketFrames[currentDataPacketHeader.frame_id];
|
||||
}
|
||||
}
|
||||
this.lastDataPacketHeader = currentDataPacketHeader;
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,13 @@
|
||||
module.exports = (buffer, dataDecoder) => {
|
||||
export interface Chunk {
|
||||
id?: number;
|
||||
has_subchunks?: boolean;
|
||||
data_len?: number;
|
||||
chunk_data?: Buffer;
|
||||
}
|
||||
|
||||
export default (buffer: Buffer, dataDecoder: Function): Chunk => {
|
||||
let offset = 0;
|
||||
const chunk = {};
|
||||
const chunk: Chunk = {};
|
||||
chunk.id = buffer.readUInt16LE(offset);
|
||||
offset += 2;
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
const { CHUNK_HEADER_SIZE } = require('../../constants');
|
||||
const chunk = require('../chunk');
|
||||
const packetHeaderChunk = require('../packet-header-chunk');
|
||||
const dataTrackerListChunk = require('./data-tracker-list-chunk');
|
||||
|
||||
function decodeDataPacketChunk(dataPacketChunk) {
|
||||
if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data) {
|
||||
let offset = 0;
|
||||
while (offset < dataPacketChunk.data_len) {
|
||||
const chunkId = dataPacketChunk.chunk_data.readUInt16LE(offset);
|
||||
switch (chunkId) {
|
||||
case 0x0000:
|
||||
dataPacketChunk.packet_header = packetHeaderChunk(dataPacketChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += dataPacketChunk.packet_header.data_len;
|
||||
break;
|
||||
case 0x0001:
|
||||
dataPacketChunk.tracker_list = dataTrackerListChunk(dataPacketChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += dataPacketChunk.tracker_list.data_len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (buffer) => chunk(buffer, decodeDataPacketChunk);
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Constants } from '../../constants';
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
import packetHeaderChunk, { PacketHeaderChunk } from '../packet-header-chunk';
|
||||
import dataTrackerListChunk, { DataTrackerListChunk } from './data-tracker-list-chunk';
|
||||
|
||||
export interface DataPacketChunk extends Chunk {
|
||||
packet_header: PacketHeaderChunk;
|
||||
tracker_list: DataTrackerListChunk;
|
||||
}
|
||||
|
||||
function decodeDataPacketChunk(dataPacketChunk: DataPacketChunk) {
|
||||
if (dataPacketChunk.has_subchunks && dataPacketChunk.chunk_data && dataPacketChunk.data_len) {
|
||||
let offset = 0;
|
||||
while (offset < dataPacketChunk.data_len) {
|
||||
const chunkId = dataPacketChunk.chunk_data.readUInt16LE(offset);
|
||||
switch (chunkId) {
|
||||
case 0x0000:
|
||||
dataPacketChunk.packet_header = packetHeaderChunk(dataPacketChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (dataPacketChunk.packet_header?.data_len) {
|
||||
offset += dataPacketChunk.packet_header.data_len;
|
||||
}
|
||||
break;
|
||||
case 0x0001:
|
||||
dataPacketChunk.tracker_list = dataTrackerListChunk(dataPacketChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (dataPacketChunk.tracker_list.data_len) {
|
||||
offset += dataPacketChunk.tracker_list.data_len;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default (buffer: Buffer): DataPacketChunk => chunk(buffer, decodeDataPacketChunk) as DataPacketChunk;
|
||||
@@ -1,41 +0,0 @@
|
||||
const { CHUNK_HEADER_SIZE } = require('../../constants');
|
||||
const chunk = require('../chunk');
|
||||
const dataTrackerFieldChunk = require('./data-tracker-field-chunk');
|
||||
|
||||
function decodeTrackerChunk(trackerChunk) {
|
||||
if (trackerChunk.chunk_data && trackerChunk.data_len > 0) {
|
||||
let offset = 0;
|
||||
while (offset < trackerChunk.data_len) {
|
||||
const trackerFieldChunk = dataTrackerFieldChunk(trackerChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += trackerFieldChunk.data_len;
|
||||
switch (trackerFieldChunk.id) {
|
||||
case 0x0000:
|
||||
trackerChunk.pos = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0001:
|
||||
trackerChunk.speed = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0002:
|
||||
trackerChunk.ori = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0003:
|
||||
trackerChunk.status = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0004:
|
||||
trackerChunk.accel = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0005:
|
||||
trackerChunk.trgtpos = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0006:
|
||||
trackerChunk.timestamp = trackerFieldChunk;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (buffer) => chunk(buffer, decodeTrackerChunk);
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Constants } from '../../constants';
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
import dataTrackerFieldChunk, { DataTrackerFieldChunk } from './data-tracker-field-chunk';
|
||||
|
||||
export interface DataTrackerChunk extends Chunk {
|
||||
pos: DataTrackerFieldChunk;
|
||||
speed: DataTrackerFieldChunk;
|
||||
ori: DataTrackerFieldChunk;
|
||||
status: DataTrackerFieldChunk;
|
||||
accel: DataTrackerFieldChunk;
|
||||
trgtpos: DataTrackerFieldChunk;
|
||||
timestamp: DataTrackerFieldChunk;
|
||||
}
|
||||
|
||||
function decodeTrackerChunk(trackerChunk: DataTrackerChunk) {
|
||||
if (trackerChunk.chunk_data && trackerChunk.data_len) {
|
||||
let offset = 0;
|
||||
while (offset < trackerChunk.data_len) {
|
||||
const trackerFieldChunk = dataTrackerFieldChunk(trackerChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (trackerFieldChunk.data_len) {
|
||||
offset += trackerFieldChunk.data_len;
|
||||
switch (trackerFieldChunk.id) {
|
||||
case 0x0000:
|
||||
trackerChunk.pos = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0001:
|
||||
trackerChunk.speed = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0002:
|
||||
trackerChunk.ori = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0003:
|
||||
trackerChunk.status = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0004:
|
||||
trackerChunk.accel = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0005:
|
||||
trackerChunk.trgtpos = trackerFieldChunk;
|
||||
break;
|
||||
case 0x0006:
|
||||
trackerChunk.timestamp = trackerFieldChunk;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default (buffer: Buffer): DataTrackerChunk => chunk(buffer, decodeTrackerChunk) as DataTrackerChunk;
|
||||
@@ -1,43 +0,0 @@
|
||||
/* eslint-disable no-case-declarations */
|
||||
const chunk = require('../chunk');
|
||||
|
||||
function readXYZ(trackerFieldChunk, prefix) {
|
||||
if (prefix === undefined) {
|
||||
prefix = '';
|
||||
}
|
||||
|
||||
trackerFieldChunk[`${prefix}x`] = trackerFieldChunk.chunk_data.readFloatLE(0);
|
||||
trackerFieldChunk[`${prefix}y`] = trackerFieldChunk.chunk_data.readFloatLE(4);
|
||||
trackerFieldChunk[`${prefix}z`] = trackerFieldChunk.chunk_data.readFloatLE(8);
|
||||
}
|
||||
function decodeTrackerFieldChunk(trackerFieldChunk) {
|
||||
if (trackerFieldChunk.id !== undefined) {
|
||||
switch (trackerFieldChunk.id) {
|
||||
case 0x0000:
|
||||
readXYZ(trackerFieldChunk, 'pos_');
|
||||
break;
|
||||
case 0x0001:
|
||||
readXYZ(trackerFieldChunk, 'speed_');
|
||||
break;
|
||||
case 0x0002:
|
||||
readXYZ(trackerFieldChunk, 'ori_');
|
||||
break;
|
||||
case 0x0003:
|
||||
trackerFieldChunk.validity = trackerFieldChunk.chunk_data.readFloatLE();
|
||||
break;
|
||||
case 0x0004:
|
||||
readXYZ(trackerFieldChunk, 'accel_');
|
||||
break;
|
||||
case 0x0005:
|
||||
readXYZ(trackerFieldChunk, 'trgtpos_');
|
||||
break;
|
||||
case 0x0006:
|
||||
trackerFieldChunk.tracker_timestamp = trackerFieldChunk.chunk_data.readBigUInt64LE();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (buffer) => chunk(buffer, decodeTrackerFieldChunk);
|
||||
@@ -0,0 +1,50 @@
|
||||
/* eslint-disable no-case-declarations */
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
|
||||
export interface DataTrackerFieldChunk extends Chunk {
|
||||
[key: string]: number | bigint | number[] | Buffer | undefined | boolean;
|
||||
}
|
||||
|
||||
function readXYZ(trackerFieldChunk: DataTrackerFieldChunk, prefix: string = '') {
|
||||
if (trackerFieldChunk.chunk_data) {
|
||||
trackerFieldChunk[`${prefix}x`] = trackerFieldChunk.chunk_data.readFloatLE(0);
|
||||
trackerFieldChunk[`${prefix}y`] = trackerFieldChunk.chunk_data.readFloatLE(4);
|
||||
trackerFieldChunk[`${prefix}z`] = trackerFieldChunk.chunk_data.readFloatLE(8);
|
||||
}
|
||||
}
|
||||
function decodeTrackerFieldChunk(trackerFieldChunk: DataTrackerFieldChunk) {
|
||||
if (trackerFieldChunk.id !== undefined) {
|
||||
switch (trackerFieldChunk.id) {
|
||||
case 0x0000:
|
||||
readXYZ(trackerFieldChunk, 'pos_');
|
||||
break;
|
||||
case 0x0001:
|
||||
readXYZ(trackerFieldChunk, 'speed_');
|
||||
break;
|
||||
case 0x0002:
|
||||
readXYZ(trackerFieldChunk, 'ori_');
|
||||
break;
|
||||
case 0x0003:
|
||||
if (trackerFieldChunk.chunk_data) {
|
||||
trackerFieldChunk.validity = trackerFieldChunk.chunk_data.readFloatLE();
|
||||
}
|
||||
break;
|
||||
case 0x0004:
|
||||
readXYZ(trackerFieldChunk, 'accel_');
|
||||
break;
|
||||
case 0x0005:
|
||||
readXYZ(trackerFieldChunk, 'trgtpos_');
|
||||
break;
|
||||
case 0x0006:
|
||||
if (trackerFieldChunk.chunk_data) {
|
||||
trackerFieldChunk.tracker_timestamp = trackerFieldChunk.chunk_data.readBigUInt64LE();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default (buffer: Buffer): DataTrackerFieldChunk =>
|
||||
chunk(buffer, decodeTrackerFieldChunk) as DataTrackerFieldChunk;
|
||||
@@ -1,17 +0,0 @@
|
||||
const { CHUNK_HEADER_SIZE } = require('../../constants');
|
||||
const chunk = require('../chunk');
|
||||
const dataTrackerChunk = require('./data-tracker-chunk');
|
||||
|
||||
function decodeDataTrackerListChunk(dataTrackerListChunk) {
|
||||
dataTrackerListChunk.trackers = {};
|
||||
|
||||
// TODO(jwetzell): add error handling
|
||||
let offset = 0;
|
||||
while (offset < dataTrackerListChunk.chunk_data.length) {
|
||||
const trackerChunk = dataTrackerChunk(dataTrackerListChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += trackerChunk.data_len;
|
||||
dataTrackerListChunk.trackers[trackerChunk.id] = trackerChunk;
|
||||
}
|
||||
}
|
||||
module.exports = (buffer) => chunk(buffer, decodeDataTrackerListChunk);
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Constants } from '../../constants';
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
import dataTrackerChunk, { DataTrackerChunk } from './data-tracker-chunk';
|
||||
|
||||
export interface DataTrackerListChunk extends Chunk {
|
||||
trackers: {
|
||||
[key: number]: DataTrackerChunk;
|
||||
};
|
||||
}
|
||||
|
||||
function decodeDataTrackerListChunk(dataTrackerListChunk: DataTrackerListChunk) {
|
||||
dataTrackerListChunk.trackers = {};
|
||||
|
||||
// TODO(jwetzell): add error handling
|
||||
let offset = 0;
|
||||
if (dataTrackerListChunk.chunk_data) {
|
||||
while (offset < dataTrackerListChunk.chunk_data.length) {
|
||||
const trackerChunk = dataTrackerChunk(dataTrackerListChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (trackerChunk.data_len) {
|
||||
offset += trackerChunk.data_len;
|
||||
}
|
||||
if (trackerChunk.id) {
|
||||
dataTrackerListChunk.trackers[trackerChunk.id] = trackerChunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export default (buffer: Buffer): DataTrackerListChunk =>
|
||||
chunk(buffer, decodeDataTrackerListChunk) as DataTrackerListChunk;
|
||||
@@ -1,35 +0,0 @@
|
||||
const { CHUNK_HEADER_SIZE } = require('../../constants');
|
||||
const chunk = require('../chunk');
|
||||
const packetHeaderChunk = require('../packet-header-chunk');
|
||||
const infoSystemNameChunk = require('./info-system-name-chunk');
|
||||
const infoTrackerListChunk = require('./info-tracker-list-chunk');
|
||||
|
||||
function decodeInfoPacketChunk(infoPacketChunk) {
|
||||
if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data) {
|
||||
let offset = 0;
|
||||
while (offset < infoPacketChunk.data_len) {
|
||||
const chunkId = infoPacketChunk.chunk_data.readUInt16LE(offset);
|
||||
switch (chunkId) {
|
||||
case 0x0000:
|
||||
infoPacketChunk.packet_header = packetHeaderChunk(infoPacketChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += infoPacketChunk.packet_header.data_len;
|
||||
break;
|
||||
case 0x0001:
|
||||
infoPacketChunk.system_name = infoSystemNameChunk(infoPacketChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += infoPacketChunk.system_name.data_len;
|
||||
break;
|
||||
case 0x0002:
|
||||
infoPacketChunk.tracker_list = infoTrackerListChunk(infoPacketChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += infoPacketChunk.tracker_list.data_len;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (buffer) => chunk(buffer, decodeInfoPacketChunk);
|
||||
@@ -0,0 +1,47 @@
|
||||
import { Constants } from '../../constants';
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
import packetHeaderChunk, { PacketHeaderChunk } from '../packet-header-chunk';
|
||||
import infoSystemNameChunk, { InfoSystemNameChunk } from './info-system-name-chunk';
|
||||
import infoTrackerListChunk, { InfoTrackerListChunk } from './info-tracker-list-chunk';
|
||||
|
||||
export interface InfoPacketChunk extends Chunk {
|
||||
packet_header: PacketHeaderChunk;
|
||||
system_name: InfoSystemNameChunk;
|
||||
tracker_list: InfoTrackerListChunk;
|
||||
}
|
||||
|
||||
function decodeInfoPacketChunk(infoPacketChunk: InfoPacketChunk) {
|
||||
if (infoPacketChunk.has_subchunks && infoPacketChunk.chunk_data && infoPacketChunk.data_len) {
|
||||
let offset = 0;
|
||||
while (offset < infoPacketChunk.data_len) {
|
||||
const chunkId = infoPacketChunk.chunk_data.readUInt16LE(offset);
|
||||
switch (chunkId) {
|
||||
case 0x0000:
|
||||
infoPacketChunk.packet_header = packetHeaderChunk(infoPacketChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (infoPacketChunk.packet_header?.data_len) {
|
||||
offset += infoPacketChunk.packet_header.data_len;
|
||||
}
|
||||
break;
|
||||
case 0x0001:
|
||||
infoPacketChunk.system_name = infoSystemNameChunk(infoPacketChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (infoPacketChunk.system_name?.data_len) {
|
||||
offset += infoPacketChunk.system_name.data_len;
|
||||
}
|
||||
break;
|
||||
case 0x0002:
|
||||
infoPacketChunk.tracker_list = infoTrackerListChunk(infoPacketChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (infoPacketChunk.tracker_list?.data_len) {
|
||||
offset += infoPacketChunk.tracker_list.data_len;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default (buffer: Buffer): InfoPacketChunk => chunk(buffer, decodeInfoPacketChunk) as InfoPacketChunk;
|
||||
@@ -1,9 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
function decodeSystemNameChunk(systemNameChunk) {
|
||||
if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) {
|
||||
systemNameChunk.system_name = systemNameChunk.chunk_data.subarray(0, systemNameChunk.data_len).toString();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (buffer) => chunk(buffer, decodeSystemNameChunk);
|
||||
@@ -0,0 +1,13 @@
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
|
||||
export interface InfoSystemNameChunk extends Chunk {
|
||||
system_name: string;
|
||||
}
|
||||
|
||||
function decodeSystemNameChunk(systemNameChunk: InfoSystemNameChunk) {
|
||||
if (systemNameChunk.chunk_data !== undefined && systemNameChunk.data_len !== undefined) {
|
||||
systemNameChunk.system_name = systemNameChunk.chunk_data.subarray(0, systemNameChunk.data_len).toString();
|
||||
}
|
||||
}
|
||||
|
||||
export default (buffer: Buffer): InfoSystemNameChunk => chunk(buffer, decodeSystemNameChunk) as InfoSystemNameChunk;
|
||||
@@ -1,24 +0,0 @@
|
||||
const { CHUNK_HEADER_SIZE } = require('../../constants');
|
||||
const chunk = require('../chunk');
|
||||
const infoTrackerNameChunk = require('./info-tracker-name-chunk');
|
||||
|
||||
function decodeInfoTrackerChunk(infoTrackerChunk) {
|
||||
if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data) {
|
||||
let offset = 0;
|
||||
while (offset < infoTrackerChunk.data_len) {
|
||||
const chunkId = infoTrackerChunk.chunk_data.readUInt16LE(offset);
|
||||
switch (chunkId) {
|
||||
case 0x0000:
|
||||
infoTrackerChunk.tracker_name = infoTrackerNameChunk(infoTrackerChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += infoTrackerChunk.tracker_name.data_len;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = (buffer) => chunk(buffer, decodeInfoTrackerChunk);
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Constants } from '../../constants';
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
import infoTrackerNameChunk, { InfoTrackerNameChunk } from './info-tracker-name-chunk';
|
||||
|
||||
export interface InfoTrackerChunk extends Chunk {
|
||||
tracker_name?: InfoTrackerNameChunk;
|
||||
}
|
||||
|
||||
function decodeInfoTrackerChunk(infoTrackerChunk: InfoTrackerChunk) {
|
||||
if (infoTrackerChunk.has_subchunks && infoTrackerChunk.chunk_data && infoTrackerChunk.data_len) {
|
||||
let offset = 0;
|
||||
while (offset < infoTrackerChunk.data_len) {
|
||||
const chunkId = infoTrackerChunk.chunk_data.readUInt16LE(offset);
|
||||
switch (chunkId) {
|
||||
case 0x0000:
|
||||
infoTrackerChunk.tracker_name = infoTrackerNameChunk(infoTrackerChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (infoTrackerChunk.tracker_name?.data_len) {
|
||||
offset += infoTrackerChunk?.tracker_name?.data_len;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default (buffer: Buffer): InfoTrackerChunk => chunk(buffer, decodeInfoTrackerChunk);
|
||||
@@ -1,17 +0,0 @@
|
||||
const { CHUNK_HEADER_SIZE } = require('../../constants');
|
||||
const chunk = require('../chunk');
|
||||
const infoTrackerChunk = require('./info-tracker-chunk');
|
||||
|
||||
function decodeInfoTrackerListChunk(infoTrackerListChunk) {
|
||||
infoTrackerListChunk.trackers = {};
|
||||
if (infoTrackerListChunk.has_subchunks && infoTrackerListChunk.chunk_data) {
|
||||
let offset = 0;
|
||||
while (offset < infoTrackerListChunk.data_len) {
|
||||
const trackerChunk = infoTrackerChunk(infoTrackerListChunk.chunk_data.subarray(offset));
|
||||
offset += CHUNK_HEADER_SIZE;
|
||||
offset += trackerChunk.data_len;
|
||||
infoTrackerListChunk.trackers[trackerChunk.id] = trackerChunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
module.exports = (buffer) => chunk(buffer, decodeInfoTrackerListChunk);
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Constants } from '../../constants';
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
import infoTrackerChunk, { InfoTrackerChunk } from './info-tracker-chunk';
|
||||
|
||||
export interface InfoTrackerListChunk extends Chunk {
|
||||
trackers: {
|
||||
[key: number]: InfoTrackerChunk;
|
||||
};
|
||||
}
|
||||
function decodeInfoTrackerListChunk(infoTrackerListChunk: InfoTrackerListChunk) {
|
||||
infoTrackerListChunk.trackers = {};
|
||||
if (infoTrackerListChunk.has_subchunks && infoTrackerListChunk.chunk_data) {
|
||||
let offset = 0;
|
||||
if (infoTrackerListChunk.data_len) {
|
||||
while (offset < infoTrackerListChunk.data_len) {
|
||||
const trackerChunk = infoTrackerChunk(infoTrackerListChunk.chunk_data.subarray(offset));
|
||||
offset += Constants.CHUNK_HEADER_SIZE;
|
||||
if (trackerChunk.data_len) {
|
||||
offset += trackerChunk.data_len;
|
||||
}
|
||||
if (trackerChunk.id) {
|
||||
infoTrackerListChunk.trackers[trackerChunk.id] = trackerChunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export default (buffer: Buffer): InfoTrackerListChunk =>
|
||||
chunk(buffer, decodeInfoTrackerListChunk) as InfoTrackerListChunk;
|
||||
@@ -1,8 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
function decodeTrackerNameChunk(trackerNameChunk) {
|
||||
if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) {
|
||||
trackerNameChunk.tracker_name = trackerNameChunk.chunk_data.subarray(0, trackerNameChunk.data_len).toString();
|
||||
}
|
||||
}
|
||||
module.exports = (buffer) => chunk(buffer, decodeTrackerNameChunk);
|
||||
@@ -0,0 +1,11 @@
|
||||
import chunk, { Chunk } from '../chunk';
|
||||
export interface InfoTrackerNameChunk extends Chunk {
|
||||
tracker_name: string;
|
||||
}
|
||||
|
||||
function decodeTrackerNameChunk(trackerNameChunk: InfoTrackerNameChunk) {
|
||||
if (trackerNameChunk.chunk_data !== undefined && trackerNameChunk.data_len !== undefined) {
|
||||
trackerNameChunk.tracker_name = trackerNameChunk.chunk_data.subarray(0, trackerNameChunk.data_len).toString();
|
||||
}
|
||||
}
|
||||
export default (buffer: Buffer): InfoTrackerNameChunk => chunk(buffer, decodeTrackerNameChunk) as InfoTrackerNameChunk;
|
||||
@@ -1,12 +0,0 @@
|
||||
const chunk = require('./chunk');
|
||||
|
||||
function decodePacketHeaderChunk(packetHeaderChunk) {
|
||||
// TODO(jwetzell): remove the string conversion
|
||||
packetHeaderChunk.packet_timestamp = packetHeaderChunk.chunk_data.readBigUInt64LE(0);
|
||||
packetHeaderChunk.version_high = packetHeaderChunk.chunk_data.readUInt8(8);
|
||||
packetHeaderChunk.version_low = packetHeaderChunk.chunk_data.readUInt8(9);
|
||||
packetHeaderChunk.frame_id = packetHeaderChunk.chunk_data.readUInt8(10);
|
||||
packetHeaderChunk.frame_packet_count = packetHeaderChunk.chunk_data.readUInt8(11);
|
||||
}
|
||||
|
||||
module.exports = (buffer) => chunk(buffer, decodePacketHeaderChunk);
|
||||
@@ -0,0 +1,21 @@
|
||||
import chunk, { Chunk } from './chunk';
|
||||
export interface PacketHeaderChunk extends Chunk {
|
||||
packet_timestamp?: bigint;
|
||||
version_high?: number;
|
||||
version_low?: number;
|
||||
frame_id?: number;
|
||||
frame_packet_count?: number;
|
||||
}
|
||||
|
||||
function decodePacketHeaderChunk(packetHeaderChunk: PacketHeaderChunk) {
|
||||
// TODO(jwetzell): remove the string conversion
|
||||
if (packetHeaderChunk.chunk_data) {
|
||||
packetHeaderChunk.packet_timestamp = packetHeaderChunk.chunk_data.readBigUInt64LE(0);
|
||||
packetHeaderChunk.version_high = packetHeaderChunk.chunk_data.readUInt8(8);
|
||||
packetHeaderChunk.version_low = packetHeaderChunk.chunk_data.readUInt8(9);
|
||||
packetHeaderChunk.frame_id = packetHeaderChunk.chunk_data.readUInt8(10);
|
||||
packetHeaderChunk.frame_packet_count = packetHeaderChunk.chunk_data.readUInt8(11);
|
||||
}
|
||||
}
|
||||
|
||||
export default (buffer: Buffer): PacketHeaderChunk => chunk(buffer, decodePacketHeaderChunk);
|
||||
@@ -1,14 +0,0 @@
|
||||
const dataPacketChunk = require('./data/data-packet-chunk');
|
||||
const infoPacketChunk = require('./info/info-packet-chunk');
|
||||
|
||||
module.exports = (buffer) => {
|
||||
const chunkId = buffer.readUInt16LE();
|
||||
switch (chunkId) {
|
||||
case 0x6756:
|
||||
return infoPacketChunk(buffer);
|
||||
case 0x6755:
|
||||
return dataPacketChunk(buffer);
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import infoPacketChunk, { InfoPacketChunk } from './info/info-packet-chunk';
|
||||
|
||||
import dataPacketChunk, { DataPacketChunk } from './data/data-packet-chunk';
|
||||
|
||||
export default (buffer: Buffer): InfoPacketChunk | DataPacketChunk | undefined => {
|
||||
const chunkId = buffer.readUInt16LE();
|
||||
switch (chunkId) {
|
||||
case 0x6756:
|
||||
return infoPacketChunk(buffer);
|
||||
case 0x6755:
|
||||
return dataPacketChunk(buffer);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
@@ -1,34 +1,39 @@
|
||||
const { MAX_UDP_PACKET_SIZE, PACKET_HEADER_SIZE, CHUNK_HEADER_SIZE } = require('./constants');
|
||||
const dataPacketChunk = require('./encoders/data/data-packet-chunk');
|
||||
const dataTrackerListChunk = require('./encoders/data/data-tracker-list-chunk');
|
||||
const infoPacketChunk = require('./encoders/info/info-packet-chunk');
|
||||
const infoSystemNameChunk = require('./encoders/info/info-system-name-chunk');
|
||||
const infoTrackerListChunk = require('./encoders/info/info-tracker-list-chunk');
|
||||
const packetHeaderChunk = require('./encoders/packet-header-chunk');
|
||||
import { Tracker } from './models/tracker';
|
||||
|
||||
class Encoder {
|
||||
constructor(systemName, versionHigh = 2, versionLow = 3) {
|
||||
import { Constants } from './constants';
|
||||
import dataPacketChunk from './encoders/data/data-packet-chunk';
|
||||
import dataTrackerListChunk from './encoders/data/data-tracker-list-chunk';
|
||||
import infoPacketChunk from './encoders/info/info-packet-chunk';
|
||||
import infoSystemNameChunk from './encoders/info/info-system-name-chunk';
|
||||
import infoTrackerListChunk from './encoders/info/info-tracker-list-chunk';
|
||||
import packetHeaderChunk from './encoders/packet-header-chunk';
|
||||
|
||||
export class Encoder {
|
||||
private systemName: string;
|
||||
private versionHigh: number;
|
||||
private versionLow: number;
|
||||
dataFrameId: number = 1;
|
||||
infoFrameId: number = 1;
|
||||
constructor(systemName: string, versionHigh: number = 2, versionLow: number = 3) {
|
||||
this.systemName = systemName;
|
||||
this.versionHigh = versionHigh;
|
||||
this.versionLow = versionLow;
|
||||
this.dataFrameId = 1;
|
||||
this.infoFrameId = 1;
|
||||
}
|
||||
|
||||
getInfoPackets(timestamp, trackers) {
|
||||
getInfoPackets(timestamp: bigint, trackers: Tracker[]) {
|
||||
const systemNameChunk = infoSystemNameChunk(this.systemName);
|
||||
|
||||
const trackerChunks = trackers.map((tracker) => tracker.getInfoChunk());
|
||||
const trackerChunks = trackers.map((tracker: Tracker) => tracker.getInfoChunk());
|
||||
|
||||
const infoPackets = [];
|
||||
const infoPackets: Buffer[] = [];
|
||||
|
||||
const trackerChunksLists = [];
|
||||
let currentTrackerList = [];
|
||||
const trackerChunksLists: Buffer[][] = [];
|
||||
let currentTrackerList: Buffer[] = [];
|
||||
|
||||
let currentInfoPacketSize = PACKET_HEADER_SIZE + systemNameChunk.length + CHUNK_HEADER_SIZE;
|
||||
let currentInfoPacketSize = Constants.MAX_UDP_PACKET_SIZE + systemNameChunk.length + Constants.CHUNK_HEADER_SIZE;
|
||||
|
||||
trackerChunks.forEach((trackerChunk) => {
|
||||
if (currentInfoPacketSize + trackerChunk.length > MAX_UDP_PACKET_SIZE) {
|
||||
trackerChunks.forEach((trackerChunk: Buffer) => {
|
||||
if (currentInfoPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) {
|
||||
trackerChunksLists.push(currentTrackerList);
|
||||
currentTrackerList = [];
|
||||
currentInfoPacketSize = 0;
|
||||
@@ -54,17 +59,17 @@ class Encoder {
|
||||
return infoPackets;
|
||||
}
|
||||
|
||||
getDataPackets(timestamp, trackers) {
|
||||
getDataPackets(timestamp: bigint, trackers: Tracker[]) {
|
||||
const allTrackerChunks = trackers.map((tracker) => tracker.getDataChunk());
|
||||
const dataPackets = [];
|
||||
const dataPackets: Buffer[] = [];
|
||||
|
||||
const trackerChunksLists = [];
|
||||
let currentTrackerList = [];
|
||||
const trackerChunksLists: Buffer[][] = [];
|
||||
let currentTrackerList: Buffer[] = [];
|
||||
|
||||
let currentDataPacketSize = PACKET_HEADER_SIZE + CHUNK_HEADER_SIZE;
|
||||
let currentDataPacketSize = Constants.PACKET_HEADER_SIZE + Constants.CHUNK_HEADER_SIZE;
|
||||
|
||||
allTrackerChunks.forEach((trackerChunk) => {
|
||||
if (currentDataPacketSize + trackerChunk.length > MAX_UDP_PACKET_SIZE) {
|
||||
if (currentDataPacketSize + trackerChunk.length > Constants.MAX_UDP_PACKET_SIZE) {
|
||||
trackerChunksLists.push(currentTrackerList);
|
||||
currentTrackerList = [];
|
||||
currentDataPacketSize = 0;
|
||||
@@ -91,5 +96,3 @@ class Encoder {
|
||||
return dataPackets;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Encoder;
|
||||
@@ -1,4 +1,4 @@
|
||||
module.exports = (id, chunkData, hasSubchunks) => {
|
||||
export default (id: number, chunkData: Buffer, hasSubchunks: boolean): Buffer => {
|
||||
if (chunkData.length > 0x7fff) {
|
||||
throw new Error('chunkData can not be greater than 32767 bytes');
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
module.exports = (packetHeaderChunk, trackerListChunk) =>
|
||||
chunk(0x6755, Buffer.concat([packetHeaderChunk, trackerListChunk]), true);
|
||||
@@ -0,0 +1,3 @@
|
||||
import chunk from '../chunk';
|
||||
export default (packetHeaderChunk: Buffer, trackerListChunk: Buffer): Buffer =>
|
||||
chunk(0x6755, Buffer.concat([packetHeaderChunk, trackerListChunk]), true);
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
const chunk = require('../chunk');
|
||||
import chunk from '../chunk';
|
||||
|
||||
module.exports = (x, y, z) => {
|
||||
export default (x: number, y: number, z: number): Buffer => {
|
||||
const buf = Buffer.alloc(12);
|
||||
buf.writeFloatLE(x);
|
||||
buf.writeFloatLE(y, 4);
|
||||
@@ -1,3 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
module.exports = (trackerId, fieldChunks) => chunk(trackerId, Buffer.concat(fieldChunks), fieldChunks.length > 0);
|
||||
@@ -0,0 +1,4 @@
|
||||
import chunk from '../chunk';
|
||||
|
||||
export default (trackerId: number, fieldChunks: Buffer[]): Buffer =>
|
||||
chunk(trackerId, Buffer.concat(fieldChunks), fieldChunks.length > 0);
|
||||
@@ -1,3 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
module.exports = (trackerChunks) => chunk(0x0001, Buffer.concat(trackerChunks), true);
|
||||
@@ -0,0 +1,3 @@
|
||||
import chunk from '../chunk';
|
||||
|
||||
export default (trackerChunks: Buffer[]) => chunk(0x0001, Buffer.concat(trackerChunks), true);
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
const chunk = require('../chunk');
|
||||
import chunk from '../chunk';
|
||||
|
||||
module.exports = (x, y, z) => {
|
||||
export default (x: number, y: number, z: number): Buffer => {
|
||||
const buf = Buffer.alloc(12);
|
||||
buf.writeFloatLE(x);
|
||||
buf.writeFloatLE(y, 4);
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
const chunk = require('../chunk');
|
||||
import chunk from '../chunk';
|
||||
|
||||
module.exports = (x, y, z) => {
|
||||
export default (x: number, y: number, z: number): Buffer => {
|
||||
const buf = Buffer.alloc(12);
|
||||
buf.writeFloatLE(x);
|
||||
buf.writeFloatLE(y, 4);
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
const chunk = require('../chunk');
|
||||
import chunk from '../chunk';
|
||||
|
||||
module.exports = (x, y, z) => {
|
||||
export default (x: number, y: number, z: number): Buffer => {
|
||||
const buf = Buffer.alloc(12);
|
||||
buf.writeFloatLE(x);
|
||||
buf.writeFloatLE(y, 4);
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
const chunk = require('../chunk');
|
||||
import chunk from '../chunk';
|
||||
|
||||
module.exports = (validity) => {
|
||||
export default (validity: number): Buffer => {
|
||||
const buf = Buffer.alloc(4);
|
||||
buf.writeFloatLE(validity);
|
||||
return chunk(0x0003, buf, false);
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
const chunk = require('../chunk');
|
||||
import chunk from '../chunk';
|
||||
|
||||
module.exports = (timestamp) => {
|
||||
export default (timestamp: bigint): Buffer => {
|
||||
const buf = Buffer.alloc(8);
|
||||
buf.writeBigUInt64LE(BigInt(timestamp));
|
||||
return chunk(0x0006, buf, false);
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
const chunk = require('../chunk');
|
||||
import chunk from '../chunk';
|
||||
|
||||
module.exports = (x, y, z) => {
|
||||
export default (x: number, y: number, z: number): Buffer => {
|
||||
const buf = Buffer.alloc(12);
|
||||
buf.writeFloatLE(x);
|
||||
buf.writeFloatLE(y, 4);
|
||||
@@ -1,4 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
module.exports = (packetHeaderChunk, systemNameChunk, trackerListChunk) =>
|
||||
chunk(0x6756, Buffer.concat([packetHeaderChunk, systemNameChunk, trackerListChunk]), true);
|
||||
@@ -0,0 +1,4 @@
|
||||
import chunk from '../chunk';
|
||||
|
||||
export default (packetHeaderChunk: Buffer, systemNameChunk: Buffer, trackerListChunk: Buffer): Buffer =>
|
||||
chunk(0x6756, Buffer.concat([packetHeaderChunk, systemNameChunk, trackerListChunk]), true);
|
||||
@@ -1,3 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
module.exports = (systemName) => chunk(0x0001, Buffer.from(systemName), false);
|
||||
@@ -0,0 +1,3 @@
|
||||
import chunk from '../chunk';
|
||||
|
||||
export default (systemName: string): Buffer => chunk(0x0001, Buffer.from(systemName), false);
|
||||
@@ -1,3 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
module.exports = (trackerId, trackerNameChunk) => chunk(trackerId, trackerNameChunk, true);
|
||||
@@ -0,0 +1,3 @@
|
||||
import chunk from '../chunk';
|
||||
|
||||
export default (trackerId: number, trackerNameChunk: Buffer): Buffer => chunk(trackerId, trackerNameChunk, true);
|
||||
@@ -1,3 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
module.exports = (trackerChunks) => chunk(0x0002, Buffer.concat(trackerChunks), true);
|
||||
@@ -0,0 +1,3 @@
|
||||
import chunk from '../chunk';
|
||||
|
||||
export default (trackerChunks: Buffer[]): Buffer => chunk(0x0002, Buffer.concat(trackerChunks), true);
|
||||
@@ -1,3 +0,0 @@
|
||||
const chunk = require('../chunk');
|
||||
|
||||
module.exports = (trackerName) => chunk(0x0000, Buffer.from(trackerName), false);
|
||||
@@ -0,0 +1,3 @@
|
||||
import chunk from '../chunk';
|
||||
|
||||
export default (trackerName: string) => chunk(0x0000, Buffer.from(trackerName), false);
|
||||
@@ -1,6 +1,12 @@
|
||||
const chunk = require('./chunk');
|
||||
import chunk from './chunk';
|
||||
|
||||
module.exports = (timestamp, versionHigh, versionLow, frameId, framePacketCount) => {
|
||||
export default (
|
||||
timestamp: bigint,
|
||||
versionHigh: number,
|
||||
versionLow: number,
|
||||
frameId: number,
|
||||
framePacketCount: number
|
||||
): Buffer => {
|
||||
if (frameId > 255) {
|
||||
throw new Error('frame id must be >= 0 and <= 255');
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export { Decoder } from './decoder';
|
||||
export { Encoder } from './encoder';
|
||||
export { Tracker } from './models/tracker';
|
||||
@@ -1,128 +0,0 @@
|
||||
const dataTrackerAccelChunk = require('../encoders/data/data-tracker-accel-chunk');
|
||||
const dataTrackerChunk = require('../encoders/data/data-tracker-chunk');
|
||||
const dataTrackerOriChunk = require('../encoders/data/data-tracker-ori-chunk');
|
||||
const dataTrackerPosChunk = require('../encoders/data/data-tracker-pos-chunk');
|
||||
const dataTrackerSpeedChunk = require('../encoders/data/data-tracker-speed-chunk');
|
||||
const dataTrackerStatusChunk = require('../encoders/data/data-tracker-status-chunk');
|
||||
const dataTrackerTimestampChunk = require('../encoders/data/data-tracker-timestamp-chunk');
|
||||
const dataTrackerTrgtposChunk = require('../encoders/data/data-tracker-trgtpos-chunk');
|
||||
const infoTrackerChunk = require('../encoders/info/info-tracker-chunk');
|
||||
const infoTrackerNameChunk = require('../encoders/info/info-tracker-name-chunk');
|
||||
|
||||
class Tracker {
|
||||
/**
|
||||
* @constructor
|
||||
* @param {number} id - tracker id
|
||||
* @param {string} name - tracker name
|
||||
*/
|
||||
constructor(id, name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.pos = undefined;
|
||||
this.speed = undefined;
|
||||
this.ori = undefined;
|
||||
this.validity = undefined;
|
||||
this.accel = undefined;
|
||||
this.trgtpos = undefined;
|
||||
this.timestamp = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {float} x
|
||||
* @param {float} y
|
||||
* @param {float} z
|
||||
*/
|
||||
setPos(x, y, z) {
|
||||
this.pos = [x, y, z];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {float} x
|
||||
* @param {float} y
|
||||
* @param {float} z
|
||||
*/
|
||||
setSpeed(x, y, z) {
|
||||
this.speed = [x, y, z];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {float} x
|
||||
* @param {float} y
|
||||
* @param {float} z
|
||||
*/
|
||||
setOri(x, y, z) {
|
||||
this.ori = [x, y, z];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {float} validity
|
||||
*/
|
||||
setStatus(validity) {
|
||||
this.validity = validity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {float} x
|
||||
* @param {float} y
|
||||
* @param {float} z
|
||||
*/
|
||||
setAccel(x, y, z) {
|
||||
this.accel = [x, y, z];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {float} x
|
||||
* @param {float} y
|
||||
* @param {float} z
|
||||
*/
|
||||
setTrgtPos(x, y, z) {
|
||||
this.trgtpos = [x, y, z];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {BigInt} timestamp
|
||||
*/
|
||||
setTimestamp(timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
getDataChunk() {
|
||||
const fieldChunks = [];
|
||||
|
||||
if (this.pos) {
|
||||
fieldChunks.push(dataTrackerPosChunk(...this.pos));
|
||||
}
|
||||
|
||||
if (this.speed) {
|
||||
fieldChunks.push(dataTrackerSpeedChunk(...this.speed));
|
||||
}
|
||||
|
||||
if (this.ori) {
|
||||
fieldChunks.push(dataTrackerOriChunk(...this.ori));
|
||||
}
|
||||
|
||||
if (this.validity) {
|
||||
fieldChunks.push(dataTrackerStatusChunk(this.validity));
|
||||
}
|
||||
|
||||
if (this.accel) {
|
||||
fieldChunks.push(dataTrackerAccelChunk(...this.accel));
|
||||
}
|
||||
|
||||
if (this.trgtpos) {
|
||||
fieldChunks.push(dataTrackerTrgtposChunk(...this.trgtpos));
|
||||
}
|
||||
|
||||
if (this.timestamp) {
|
||||
fieldChunks.push(dataTrackerTimestampChunk(this.timestamp));
|
||||
}
|
||||
|
||||
return dataTrackerChunk(this.id, fieldChunks);
|
||||
}
|
||||
|
||||
getInfoChunk() {
|
||||
return infoTrackerChunk(this.id, infoTrackerNameChunk(this.name));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Tracker;
|
||||
@@ -0,0 +1,100 @@
|
||||
import dataTrackerAccelChunk from '../encoders/data/data-tracker-accel-chunk';
|
||||
import dataTrackerChunk from '../encoders/data/data-tracker-chunk';
|
||||
import dataTrackerOriChunk from '../encoders/data/data-tracker-ori-chunk';
|
||||
import dataTrackerPosChunk from '../encoders/data/data-tracker-pos-chunk';
|
||||
import dataTrackerSpeedChunk from '../encoders/data/data-tracker-speed-chunk';
|
||||
import dataTrackerStatusChunk from '../encoders/data/data-tracker-status-chunk';
|
||||
import dataTrackerTimestampChunk from '../encoders/data/data-tracker-timestamp-chunk';
|
||||
import dataTrackerTrgtposChunk from '../encoders/data/data-tracker-trgtpos-chunk';
|
||||
import infoTrackerChunk from '../encoders/info/info-tracker-chunk';
|
||||
import infoTrackerNameChunk from '../encoders/info/info-tracker-name-chunk';
|
||||
|
||||
export class Tracker {
|
||||
id: number;
|
||||
name: string;
|
||||
pos?: [number, number, number];
|
||||
speed?: [number, number, number];
|
||||
ori?: [number, number, number];
|
||||
validity?: number;
|
||||
accel?: [number, number, number];
|
||||
trgtpos?: [number, number, number];
|
||||
timestamp?: bigint;
|
||||
|
||||
constructor(id: number, name: string) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.pos = undefined;
|
||||
this.speed = undefined;
|
||||
this.ori = undefined;
|
||||
this.validity = undefined;
|
||||
this.accel = undefined;
|
||||
this.trgtpos = undefined;
|
||||
this.timestamp = undefined;
|
||||
}
|
||||
|
||||
setPos(x: number, y: number, z: number) {
|
||||
this.pos = [x, y, z];
|
||||
}
|
||||
|
||||
setSpeed(x: number, y: number, z: number) {
|
||||
this.speed = [x, y, z];
|
||||
}
|
||||
|
||||
setOri(x: number, y: number, z: number) {
|
||||
this.ori = [x, y, z];
|
||||
}
|
||||
|
||||
setStatus(validity: number) {
|
||||
this.validity = validity;
|
||||
}
|
||||
|
||||
setAccel(x: number, y: number, z: number) {
|
||||
this.accel = [x, y, z];
|
||||
}
|
||||
|
||||
setTrgtPos(x: number, y: number, z: number) {
|
||||
this.trgtpos = [x, y, z];
|
||||
}
|
||||
|
||||
setTimestamp(timestamp: bigint) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
getDataChunk() {
|
||||
const fieldChunks: Buffer[] = [];
|
||||
|
||||
if (this.pos) {
|
||||
fieldChunks.push(dataTrackerPosChunk(...this.pos));
|
||||
}
|
||||
|
||||
if (this.speed) {
|
||||
fieldChunks.push(dataTrackerSpeedChunk(...this.speed));
|
||||
}
|
||||
|
||||
if (this.ori) {
|
||||
fieldChunks.push(dataTrackerOriChunk(...this.ori));
|
||||
}
|
||||
|
||||
if (this.validity) {
|
||||
fieldChunks.push(dataTrackerStatusChunk(this.validity));
|
||||
}
|
||||
|
||||
if (this.accel) {
|
||||
fieldChunks.push(dataTrackerAccelChunk(...this.accel));
|
||||
}
|
||||
|
||||
if (this.trgtpos) {
|
||||
fieldChunks.push(dataTrackerTrgtposChunk(...this.trgtpos));
|
||||
}
|
||||
|
||||
if (this.timestamp) {
|
||||
fieldChunks.push(dataTrackerTimestampChunk(this.timestamp));
|
||||
}
|
||||
|
||||
return dataTrackerChunk(this.id, fieldChunks);
|
||||
}
|
||||
|
||||
getInfoChunk() {
|
||||
return infoTrackerChunk(this.id, infoTrackerNameChunk(this.name));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user