From e9abeb9bb6edcba0984bfbbb1c941f220a579646 Mon Sep 17 00:00:00 2001 From: Christian Risi <75698846+CnF-Gris@users.noreply.github.com> Date: Fri, 6 Dec 2024 19:12:01 +0000 Subject: [PATCH] V0.5.9 Arroyo Toad There's a bug during conversion from buffer to unix timestamp --- .devcontainer/devcontainer.json | 1 + Private/Message.bin | Bin 244 -> 244 bytes deno.json | 8 +++ deno.lock | 23 +++++++ src/classes/Field.ts | 12 ++++ src/classes/Location.ts | 15 +++++ src/classes/Message.ts | 68 +++++++++++++++++++++ src/enums/DeviceType.ts | 4 ++ src/enums/MessageType.ts | 8 +++ src/enums/SignatureType.ts | 3 + src/mod.ts | 1 + src/utils/deserializer.ts | 103 ++++++++++++++++++++++++++++++++ tests/main_test.ts | 12 ++++ 13 files changed, 258 insertions(+) create mode 100644 deno.json create mode 100644 deno.lock create mode 100644 src/classes/Field.ts create mode 100644 src/classes/Location.ts create mode 100644 src/classes/Message.ts create mode 100644 src/enums/DeviceType.ts create mode 100644 src/enums/MessageType.ts create mode 100644 src/enums/SignatureType.ts create mode 100644 src/mod.ts create mode 100644 src/utils/deserializer.ts create mode 100644 tests/main_test.ts diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 7b01e89..33d288d 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -11,6 +11,7 @@ "customizations": { "vscode": { "extensions": [ + "denoland.vscode-deno", "fabiospampinato.vscode-highlight", "fabiospampinato.vscode-todo-plus" ] diff --git a/Private/Message.bin b/Private/Message.bin index 259dc27698872dce7f9339df22b3512f997ea2e1..0c254f9b1377043333b89907439001f583f373a5 100644 GIT binary patch delta 157 zcmV;O0Am020rUY60RR913IG5AvOsG<^dw` z0DT7-3K*Q0DcNAU(#ZUaBY;Bl-1OwY%h+Jm&dT#@e$$vBLlgnPvxHSW$p8ab3CDY^ zWqE2sK0lkkwF7=z3tfgQDW!ozSr!`wFCMN4ivjr8Rq(SMb?8KdnDlN5S#y6h24gB% LF{=g7&ZYt^s2W8_ delta 157 zcmV;O0Am020rUY60RR913IG5A+9|zui-E?G4`F`+IL|X>jLR;TL?#CX!zw>Y7_#ms zgHot}AbtUzALQSpQ72dvV6k$%LS+r)R?1TQ$3s#;cBmPtjLa|qX$S4XZ2?aP-7}>p zRa_rI{GFxFgT!_Fhaf7uLZG$Iy4(dw4=wjLs+8X4)q&oJf%b% diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..3907642 --- /dev/null +++ b/deno.json @@ -0,0 +1,8 @@ +{ + "tasks": { + "dev": "deno run --watch ./src/main.ts" + }, + "imports": { + "@std/assert": "jsr:@std/assert@1" + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..b94ec0c --- /dev/null +++ b/deno.lock @@ -0,0 +1,23 @@ +{ + "version": "4", + "specifiers": { + "jsr:@std/assert@1": "1.0.9", + "jsr:@std/internal@^1.0.5": "1.0.5" + }, + "jsr": { + "@std/assert@1.0.9": { + "integrity": "a9f0c611a869cc791b26f523eec54c7e187aab7932c2c8e8bea0622d13680dcd", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" + } + }, + "workspace": { + "dependencies": [ + "jsr:@std/assert@1" + ] + } +} diff --git a/src/classes/Field.ts b/src/classes/Field.ts new file mode 100644 index 0000000..d50e39d --- /dev/null +++ b/src/classes/Field.ts @@ -0,0 +1,12 @@ +export class Field { + public key: Uint8Array + public value: Uint8Array + + constructor( + key: Uint8Array, + value: Uint8Array + ) { + this.key = key + this.value = value + } +} \ No newline at end of file diff --git a/src/classes/Location.ts b/src/classes/Location.ts new file mode 100644 index 0000000..150b3e1 --- /dev/null +++ b/src/classes/Location.ts @@ -0,0 +1,15 @@ +export class DeviceLocation { + public x: bigint; + public y: bigint; + public z: bigint; + + constructor( + x: bigint, + y: bigint, + z: bigint, + ) { + this.x = x; + this.y = y; + this.z = z; + } +} diff --git a/src/classes/Message.ts b/src/classes/Message.ts new file mode 100644 index 0000000..01ad8e8 --- /dev/null +++ b/src/classes/Message.ts @@ -0,0 +1,68 @@ +import { DeviceType } from "../enums/DeviceType.ts"; +import { MessageType } from "../enums/MessageType.ts"; +import { SignatureType } from "../enums/SignatureType.ts"; +import { Field } from "./Field.ts"; +import { DeviceLocation } from "./Location.ts"; + +export class Message { + public version: number; + public messageType: MessageType; + public RESERVED: number; + public deviceType: DeviceType; + public signatureType: SignatureType; + + public timestamp: bigint; + public deviceID: bigint; + public location: DeviceLocation; + public fields: Field[]; + public signature: Uint8Array; + + constructor( + version: number, + messageType: MessageType, + deviceType: DeviceType, + RESERVED: number, + signatureType: SignatureType, + timestamp: bigint, + deviceID: bigint, + location: DeviceLocation, + fields: Field[], + signature: Uint8Array, + ) { + this.version = version; + this.messageType = messageType; + this.RESERVED = RESERVED; + this.deviceType = deviceType; + this.signatureType = signatureType; + this.timestamp = timestamp; + this.deviceID = deviceID; + this.location = location; + this.fields = fields; + this.signature = signature; + } + + public toString() { + let description = ` +Message ---------------------- + +\tVersion: \t${this.version} +\tMessage Type: \t${this.messageType} +\tDevice Type: \t${this.deviceType} +\tRESERVED: \t${this.RESERVED} +\tSignature Type: \t${this.signatureType} +\tTimestamp: \t${ new Date(Number(this.timestamp / 10000000n))} +\tDevice ID: \t${this.deviceID} +\tLocation: \tX: ${this.location.x}\tY: ${this.location.y}\tZ: ${this.location.z} +\tFields: \n`; + + this.fields.forEach((element) => { + description += `\t\t${new TextDecoder().decode(element.key)}: ${ + new TextDecoder().decode(element.value) + }\n`; + }); + + description +=`\tSignature: \t${new TextDecoder().decode(this.signature)}` + + return description + } +} diff --git a/src/enums/DeviceType.ts b/src/enums/DeviceType.ts new file mode 100644 index 0000000..feedf4f --- /dev/null +++ b/src/enums/DeviceType.ts @@ -0,0 +1,4 @@ +export enum DeviceType { + EDGE_SENSOR = 0, + SCANNER_SENSOR = 1 +} \ No newline at end of file diff --git a/src/enums/MessageType.ts b/src/enums/MessageType.ts new file mode 100644 index 0000000..ea28f89 --- /dev/null +++ b/src/enums/MessageType.ts @@ -0,0 +1,8 @@ +export enum MessageType { + KEEPALIVE = 0, + DATA = 1, + INFO = 2, + WARNING =50, + ERROR = 100, + CRITICAL = 255, +} \ No newline at end of file diff --git a/src/enums/SignatureType.ts b/src/enums/SignatureType.ts new file mode 100644 index 0000000..f191119 --- /dev/null +++ b/src/enums/SignatureType.ts @@ -0,0 +1,3 @@ +export enum SignatureType { + P521 = 10 +} \ No newline at end of file diff --git a/src/mod.ts b/src/mod.ts new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/mod.ts @@ -0,0 +1 @@ + diff --git a/src/utils/deserializer.ts b/src/utils/deserializer.ts new file mode 100644 index 0000000..4c03d69 --- /dev/null +++ b/src/utils/deserializer.ts @@ -0,0 +1,103 @@ +import { Field } from "../classes/Field.ts"; +import { Message } from "../classes/Message.ts"; +import { DeviceType } from "../enums/DeviceType.ts"; +import { MessageType } from "../enums/MessageType.ts"; +import { SignatureType } from "../enums/SignatureType.ts"; +import { DeviceLocation } from "../classes/Location.ts"; + +export function deserializerV1(buffer: ArrayBuffer) { + const version: number = new Uint8Array(buffer.slice(0, 1))[0]; + + // UGLY Force typecasting + const messageType: MessageType = MessageType[ + MessageType[ + new Uint8Array(buffer.slice(1, 2))[0] + ] as keyof typeof MessageType + ]; + + // UGLY Force typecasting + const deviceType: DeviceType = DeviceType[ + DeviceType[ + new Uint8Array(buffer.slice(2, 3))[0] + ] as keyof typeof DeviceType + ]; + + const RESERVED: number = new Uint8Array(buffer.slice(3, 4))[0]; + + // UGLY Force typecasting + const signatureType: number = SignatureType[ + SignatureType[ + new Uint32Array(buffer.slice(4, 8))[0] + ] as keyof typeof SignatureType + ]; + + const timestamp: bigint = new BigUint64Array(buffer.slice(8, 16))[0]; + + // UGLY: sum the 2 bigints to a sing bigint + const deviceID_Buffer = new BigUint64Array(buffer.slice(16, 32)); + const deviceID: bigint = (deviceID_Buffer[1] << 64n) + deviceID_Buffer[0]; + + const locX: bigint = new BigUint64Array(buffer.slice(32, 40))[0]; + const locY: bigint = new BigUint64Array(buffer.slice(40, 48))[0]; + const locZ: bigint = new BigUint64Array(buffer.slice(48, 56))[0]; + + let index = 56; + + let MORE_FIELDS = true; + let fields: Field[] = Array(); + + while (MORE_FIELDS) { + const nextchunk = new BigUint64Array(buffer.slice(index, index + 8))[0]; + + if (nextchunk === 0n) { + MORE_FIELDS = false; + continue; + } + + const key_value_counts = new Uint32Array(buffer.slice(index, index + 8)); + const key_count = key_value_counts[0]; + const value_count = key_value_counts[1]; + index += 8; + + const key = new Uint8Array(buffer.slice(index, index + key_count)); + index += key_count; + const value = new Uint8Array(buffer.slice(index, index + value_count)); + index += value_count; + + fields.push(new Field(key, value)); + } + + const paddingBytes = (8 - (index % 8)) % 8; + + index += paddingBytes + 8; + + const signature = new Uint8Array(buffer.slice(index)) + + if (signature.length != signatureBytesMapper(signatureType)) { + throw new Error("This signature is not valid") + } + + return new Message( + version, + messageType, + deviceType, + RESERVED, + signatureType, + timestamp, + deviceID, + new DeviceLocation(locX, locY, locZ), + fields, + signature + ) + +} + +export function signatureBytesMapper(signatureType: SignatureType) { + switch (signatureType) { + case SignatureType.P521 : { + return 132 + } + } +} + + diff --git a/tests/main_test.ts b/tests/main_test.ts new file mode 100644 index 0000000..444fdcd --- /dev/null +++ b/tests/main_test.ts @@ -0,0 +1,12 @@ +import { assertEquals } from "@std/assert"; +import { deserializerV1 } from "../src/utils/deserializer.ts"; + + +Deno.test(async function deserializerV1Test() { + + const messageBuffer = (await Deno.readFile("./Private/Message.bin")).buffer + const msg = deserializerV1(messageBuffer) + console.log(msg.toString()) + //Assert + +})