Send want_config_id on connect to trigger initial sync (#6)
CI / build + unit (push) Successful in 39s
CI / build + unit (push) Successful in 39s
Send want_config_id on connect to trigger initial sync (#6) Firmware only streams myInfo/channels/configComplete after receiving a ToRadio with want_config_id — the service previously wrote nothing on connect, so /api/channels stayed [] and myNodeNum null. v0.1.4.
This commit was merged in pull request #6.
This commit is contained in:
@@ -6,13 +6,16 @@ import { describe, expect, it } from 'vitest';
|
||||
import { extractFrames, frame } from './codec.js';
|
||||
import { MeshService } from './mesh.service.js';
|
||||
|
||||
function startBridge(): Promise<{
|
||||
function startBridge(onSocket?: (s: net.Socket) => void): Promise<{
|
||||
port: number;
|
||||
sockets: net.Socket[];
|
||||
close: () => void;
|
||||
}> {
|
||||
const sockets: net.Socket[] = [];
|
||||
const server = net.createServer((socket) => sockets.push(socket));
|
||||
const server = net.createServer((socket) => {
|
||||
onSocket?.(socket); // attached at accept time, before any data can arrive
|
||||
sockets.push(socket);
|
||||
});
|
||||
return new Promise((resolve) => {
|
||||
server.listen(0, '127.0.0.1', () => {
|
||||
resolve({
|
||||
@@ -117,6 +120,63 @@ describe('MeshService channel pipeline', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('MeshService connect', () => {
|
||||
it('sends want_config_id on connect and applies the initial sync', async () => {
|
||||
const out: Uint8Array[] = [];
|
||||
const bridge = await startBridge((s) => s.on('data', (c) => out.push(c)));
|
||||
process.env.MESH_HOST = '127.0.0.1';
|
||||
process.env.MESH_PORT = String(bridge.port);
|
||||
const svc = new MeshService();
|
||||
try {
|
||||
svc.onModuleInit();
|
||||
await waitFor(() => svc.status().connected && out.length > 0);
|
||||
|
||||
const merged = new Uint8Array(out.reduce((n, c) => n + c.length, 0));
|
||||
let off = 0;
|
||||
for (const c of out) {
|
||||
merged.set(c, off);
|
||||
off += c.length;
|
||||
}
|
||||
const { packets } = extractFrames(merged);
|
||||
expect(packets.length).toBeGreaterThan(0);
|
||||
const tr = fromBinary(P.Mesh.ToRadioSchema, packets[0]);
|
||||
expect(tr.payloadVariant?.case).toBe('wantConfigId');
|
||||
const nonce =
|
||||
tr.payloadVariant && tr.payloadVariant.case === 'wantConfigId'
|
||||
? tr.payloadVariant.value
|
||||
: -1;
|
||||
expect(nonce).toBeGreaterThan(0);
|
||||
|
||||
// feed back the initial sync: myInfo, then configCompleteId echoing the nonce
|
||||
bridge.sockets[0].write(
|
||||
frame(
|
||||
toBinary(
|
||||
P.Mesh.FromRadioSchema,
|
||||
create(P.Mesh.FromRadioSchema, {
|
||||
payloadVariant: { case: 'myInfo', value: { myNodeNum: 1234 } },
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
bridge.sockets[0].write(
|
||||
frame(
|
||||
toBinary(
|
||||
P.Mesh.FromRadioSchema,
|
||||
create(P.Mesh.FromRadioSchema, {
|
||||
payloadVariant: { case: 'configCompleteId', value: nonce },
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await waitFor(() => svc.status().myNodeNum === 1234);
|
||||
} finally {
|
||||
svc.onModuleDestroy();
|
||||
bridge.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('MeshService send', () => {
|
||||
it('sends on the test channel (index 2) by default, never primary', async () => {
|
||||
const bridge = await startBridge();
|
||||
@@ -143,11 +203,13 @@ describe('MeshService send', () => {
|
||||
off += c.length;
|
||||
}
|
||||
const { packets } = extractFrames(merged);
|
||||
if (!packets.length) return undefined;
|
||||
const tr = fromBinary(P.Mesh.ToRadioSchema, packets[0]);
|
||||
return tr.payloadVariant?.case === 'packet'
|
||||
? tr.payloadVariant.value
|
||||
: undefined;
|
||||
// outbound now starts with the want_config_id frame — find the text packet
|
||||
for (const p of packets) {
|
||||
const tr = fromBinary(P.Mesh.ToRadioSchema, p);
|
||||
if (tr.payloadVariant?.case === 'packet')
|
||||
return tr.payloadVariant.value;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
await waitFor(() => readOutbound() !== undefined);
|
||||
|
||||
Reference in New Issue
Block a user