Bug fixes in structure parsing

This commit is contained in:
2026-03-16 13:16:06 +01:00
parent 16f638301b
commit 38b617728c
5 changed files with 31 additions and 20 deletions

View File

@@ -378,6 +378,13 @@ export class Frame implements IFrame {
if (routingSection) { if (routingSection) {
structure.push(routingSection); structure.push(routingSection);
} }
// Add data type identifier section
structure.push({
name: "data type",
data: new TextEncoder().encode(this.payload.charAt(0)).buffer,
isString: true,
fields: [{ type: FieldType.CHAR, name: "identifier", length: 1 }],
});
if (payloadsegment) { if (payloadsegment) {
structure.push(...payloadsegment); structure.push(...payloadsegment);
} }
@@ -2306,34 +2313,34 @@ const parseFrame = (data: string): Frame => {
pathFields.push({ pathFields.push({
type: FieldType.CHAR, type: FieldType.CHAR,
name: `Path separator ${i}`, name: `path separator ${i}`,
length: 1, length: 1,
}); });
pathFields.push({ pathFields.push({
type: FieldType.STRING, type: FieldType.STRING,
name: `Repeater ${i}`, name: `repeater ${i}`,
length: pathStr.length, length: pathStr.length,
}); });
} }
const routingSection: Segment = { const routingSection: Segment = {
name: "Routing", name: "routing",
data: encoder.encode(data.slice(0, routeSepIndex)).buffer, data: encoder.encode(data.slice(0, routeSepIndex + 1)).buffer,
isString: true, isString: true,
fields: [ fields: [
{ {
type: FieldType.STRING, type: FieldType.STRING,
name: "Source address", name: "source address",
length: sourceStr.length, length: sourceStr.length,
}, },
{ type: FieldType.CHAR, name: "Route separator", length: 1 }, { type: FieldType.CHAR, name: "route separator", length: 1 },
{ {
type: FieldType.STRING, type: FieldType.STRING,
name: "Destination address", name: "destination address",
length: destinationStr.length, length: destinationStr.length,
}, },
...pathFields, ...pathFields,
{ type: FieldType.CHAR, name: "Payload separator", length: 1 }, { type: FieldType.CHAR, name: "payload separator", length: 1 },
], ],
}; };

View File

@@ -1,6 +1,10 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { Frame } from "../src/frame"; import { Frame } from "../src/frame";
import type { Payload, StationCapabilitiesPayload } from "../src/frame.types"; import {
DataType,
type Payload,
type StationCapabilitiesPayload,
} from "../src/frame.types";
import { Dissected } from "@hamradio/packet"; import { Dissected } from "@hamradio/packet";
describe("Frame.decodeCapabilities", () => { describe("Frame.decodeCapabilities", () => {
@@ -9,7 +13,7 @@ describe("Frame.decodeCapabilities", () => {
const frame = Frame.fromString(data); const frame = Frame.fromString(data);
const decoded = frame.decode() as StationCapabilitiesPayload; const decoded = frame.decode() as StationCapabilitiesPayload;
expect(decoded).not.toBeNull(); expect(decoded).not.toBeNull();
expect(decoded.type).toBe("capabilities"); expect(decoded.type).toBe(DataType.StationCapabilities);
expect(Array.isArray(decoded.capabilities)).toBeTruthy(); expect(Array.isArray(decoded.capabilities)).toBeTruthy();
expect(decoded.capabilities).toContain("IGATE"); expect(decoded.capabilities).toContain("IGATE");
expect(decoded.capabilities).toContain("MSG_CNT"); expect(decoded.capabilities).toContain("MSG_CNT");
@@ -23,7 +27,7 @@ describe("Frame.decodeCapabilities", () => {
structure: Dissected; structure: Dissected;
}; };
expect(res.payload).not.toBeNull(); expect(res.payload).not.toBeNull();
if (res.payload && res.payload.type !== "capabilities") if (res.payload && res.payload.type !== DataType.StationCapabilities)
throw new Error("expected capabilities payload"); throw new Error("expected capabilities payload");
expect(res.structure).toBeDefined(); expect(res.structure).toBeDefined();
const caps = res.structure.find((s) => s.name === "capabilities"); const caps = res.structure.find((s) => s.name === "capabilities");

View File

@@ -1,6 +1,6 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { Frame } from "../src/frame"; import { Frame } from "../src/frame";
import type { RawGPSPayload } from "../src/frame.types"; import { DataType, type RawGPSPayload } from "../src/frame.types";
import { Dissected } from "@hamradio/packet"; import { Dissected } from "@hamradio/packet";
describe("Raw GPS decoding", () => { describe("Raw GPS decoding", () => {
@@ -13,7 +13,7 @@ describe("Raw GPS decoding", () => {
const payload = f.decode(false) as RawGPSPayload | null; const payload = f.decode(false) as RawGPSPayload | null;
expect(payload).not.toBeNull(); expect(payload).not.toBeNull();
expect(payload?.type).toBe("raw-gps"); expect(payload?.type).toBe(DataType.RawGPS);
expect(payload?.sentence).toBe(sentence); expect(payload?.sentence).toBe(sentence);
expect(payload?.position).toBeDefined(); expect(payload?.position).toBeDefined();
expect(typeof payload?.position?.latitude).toBe("number"); expect(typeof payload?.position?.latitude).toBe("number");
@@ -32,7 +32,7 @@ describe("Raw GPS decoding", () => {
}; };
expect(result.payload).not.toBeNull(); expect(result.payload).not.toBeNull();
expect(result.payload?.type).toBe("raw-gps"); expect(result.payload?.type).toBe(DataType.RawGPS);
expect(result.payload?.sentence).toBe(sentence); expect(result.payload?.sentence).toBe(sentence);
expect(result.payload?.position).toBeDefined(); expect(result.payload?.position).toBeDefined();
expect(typeof result.payload?.position?.latitude).toBe("number"); expect(typeof result.payload?.position?.latitude).toBe("number");

View File

@@ -837,19 +837,19 @@ describe("Packet dissection with sections", () => {
expect(result.structure).toBeDefined(); expect(result.structure).toBeDefined();
expect(result.structure.length).toBeGreaterThan(0); expect(result.structure.length).toBeGreaterThan(0);
const routingSection = result.structure.find((s) => s.name === "Routing"); const routingSection = result.structure.find((s) => s.name === "routing");
expect(routingSection).toBeDefined(); expect(routingSection).toBeDefined();
expect(routingSection?.fields).toBeDefined(); expect(routingSection?.fields).toBeDefined();
expect(routingSection?.fields?.length).toBeGreaterThan(0); expect(routingSection?.fields?.length).toBeGreaterThan(0);
const sourceField = routingSection?.fields?.find( const sourceField = routingSection?.fields?.find(
(a) => a.name === "Source address", (a) => a.name === "source address",
); );
expect(sourceField).toBeDefined(); expect(sourceField).toBeDefined();
expect(sourceField?.length).toBeGreaterThan(0); expect(sourceField?.length).toBeGreaterThan(0);
const destField = routingSection?.fields?.find( const destField = routingSection?.fields?.find(
(a) => a.name === "Destination address", (a) => a.name === "destination address",
); );
expect(destField).toBeDefined(); expect(destField).toBeDefined();
expect(destField?.length).toBeGreaterThan(0); expect(destField?.length).toBeGreaterThan(0);

View File

@@ -1,7 +1,7 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { Dissected } from "@hamradio/packet"; import { Dissected } from "@hamradio/packet";
import { Frame } from "../src/frame"; import { Frame } from "../src/frame";
import type { UserDefinedPayload } from "../src/frame.types"; import { DataType, type UserDefinedPayload } from "../src/frame.types";
describe("Frame.decodeUserDefined", () => { describe("Frame.decodeUserDefined", () => {
it("parses packet type only", () => { it("parses packet type only", () => {
@@ -9,7 +9,7 @@ describe("Frame.decodeUserDefined", () => {
const frame = Frame.fromString(data); const frame = Frame.fromString(data);
const decoded = frame.decode() as UserDefinedPayload; const decoded = frame.decode() as UserDefinedPayload;
expect(decoded).not.toBeNull(); expect(decoded).not.toBeNull();
expect(decoded.type).toBe("user-defined"); expect(decoded.type).toBe(DataType.UserDefined);
expect(decoded.userPacketType).toBe("01"); expect(decoded.userPacketType).toBe("01");
expect(decoded.data).toBe(""); expect(decoded.data).toBe("");
}); });
@@ -22,7 +22,7 @@ describe("Frame.decodeUserDefined", () => {
structure: Dissected; structure: Dissected;
}; };
expect(res.payload).not.toBeNull(); expect(res.payload).not.toBeNull();
expect(res.payload.type).toBe("user-defined"); expect(res.payload.type).toBe(DataType.UserDefined);
expect(res.payload.userPacketType).toBe("TEX"); expect(res.payload.userPacketType).toBe("TEX");
expect(res.payload.data).toBe("Hello world"); expect(res.payload.data).toBe("Hello world");