diff --git a/packages/web/src/core/stores/nodeDBStore/index.ts b/packages/web/src/core/stores/nodeDBStore/index.ts index 632cc7573..573adac91 100644 --- a/packages/web/src/core/stores/nodeDBStore/index.ts +++ b/packages/web/src/core/stores/nodeDBStore/index.ts @@ -270,12 +270,18 @@ function nodeDBFactory( } const node = nodeDB.nodeMap.get(data.from); const nowSec = Math.floor(Date.now() / 1000); // lastHeard is in seconds(!) + const hopsAway = + data.hopLimit > data.hopStart || + (data.hopStart === 0 && !data.hasBitfield) + ? undefined + : data.hopStart - data.hopLimit; if (node) { const updated = { ...node, lastHeard: data.time > 0 ? data.time : nowSec, snr: data.snr, + hopsAway, }; nodeDB.nodeMap = new Map(nodeDB.nodeMap).set(data.from, updated); } else { @@ -285,6 +291,7 @@ function nodeDBFactory( num: data.from, lastHeard: data.time > 0 ? data.time : nowSec, // fallback to now if time is 0 or negative, snr: data.snr, + hopsAway, }), ); } diff --git a/packages/web/src/core/stores/nodeDBStore/nodeDBStore.test.tsx b/packages/web/src/core/stores/nodeDBStore/nodeDBStore.test.tsx index fadb65d41..5b2c10340 100644 --- a/packages/web/src/core/stores/nodeDBStore/nodeDBStore.test.tsx +++ b/packages/web/src/core/stores/nodeDBStore/nodeDBStore.test.tsx @@ -95,18 +95,43 @@ describe("NodeDB store", () => { const { useNodeDBStore } = await freshStore(); const db = useNodeDBStore.getState().addNodeDB(1); - db.processPacket({ from: 50, time: 1111, snr: 7 } as any); + db.processPacket({ + from: 50, + time: 1111, + snr: 7, + hopStart: 5, + hopLimit: 2, + hasBitfield: true, + } as any); expect(db.getNode(50)).toBeTruthy(); expect(db.getNode(50)?.lastHeard).toBe(1111); expect(db.getNode(50)?.snr).toBe(7); - - db.processPacket({ from: 50, time: 2222, snr: 9 } as any); + expect(db.getNode(50)?.hopsAway).toBe(3); + + db.processPacket({ + from: 50, + time: 2222, + snr: 9, + hopStart: 6, + hopLimit: 3, + hasBitfield: true, + } as any); expect(db.getNode(50)?.lastHeard).toBe(2222); expect(db.getNode(50)?.snr).toBe(9); - - db.processPacket({ from: 50, time: 0, snr: 9 } as any); + expect(db.getNode(50)?.hopsAway).toBe(3); + + // when hopStart===0 and hasBitfield is false, hopsAway should be undefined + db.processPacket({ + from: 50, + time: 0, + snr: 9, + hopStart: 0, + hopLimit: 0, + hasBitfield: false, + } as any); expect(db.getNode(50)?.lastHeard).toBeCloseTo(Date.now() / 1000, -1); // within 1s, note lastHeard is in seconds expect(db.getNode(50)?.snr).toBe(9); + expect(db.getNode(50)?.hopsAway).toBeUndefined(); }); it("addUser and addPosition updates existing or creates new nodes", async () => { diff --git a/packages/web/src/core/stores/nodeDBStore/types.ts b/packages/web/src/core/stores/nodeDBStore/types.ts index 82523ec2c..1aacef55a 100644 --- a/packages/web/src/core/stores/nodeDBStore/types.ts +++ b/packages/web/src/core/stores/nodeDBStore/types.ts @@ -14,6 +14,9 @@ type ProcessPacketParams = { from: number; snr: number; time: number; + hopStart: number; + hopLimit: number; + hasBitfield: boolean; }; export type { NodeError, ProcessPacketParams, NodeErrorType }; diff --git a/packages/web/src/core/subscriptions.ts b/packages/web/src/core/subscriptions.ts index f20f5443d..03913f8e6 100644 --- a/packages/web/src/core/subscriptions.ts +++ b/packages/web/src/core/subscriptions.ts @@ -116,6 +116,11 @@ export const subscribeAll = ( from: meshPacket.from, snr: meshPacket.rxSnr, time: meshPacket.rxTime, + hopStart: meshPacket.hopStart, + hopLimit: meshPacket.hopLimit, + hasBitfield: + meshPacket.payloadVariant.case === "decoded" && + meshPacket.payloadVariant.value.bitfield !== undefined, }); });