implement zero hop repeater ping

This commit is contained in:
liamcottle 2025-03-10 02:40:31 +13:00
parent 78d34c10cd
commit d1bf08fec4
2 changed files with 92 additions and 0 deletions

View file

@ -138,6 +138,7 @@
<div v-if="contact.type === 1" @click="sendMessage(contact)" class="hover:underline cursor-pointer">Message</div>
<div v-if="contact.type === 2" @click="showCommandLine(contact)" class="hover:underline cursor-pointer">CLI</div>
<div v-if="contact.type === 2" @click="statusRequest(contact)" class="hover:underline cursor-pointer">GetStats</div>
<div v-if="contact.type === 2" @click="pingRepeater(contact)" class="hover:underline cursor-pointer">Ping</div>
<div @click="setPath(contact)" class="hover:underline cursor-pointer">Set Path</div>
<div @click="shareContact(contact)" class="hover:underline cursor-pointer">Share (Zero Hop)</div>
<div @click="exportContact(contact)" class="hover:underline cursor-pointer">Export</div>
@ -501,6 +502,14 @@
}
},
async pingRepeater(contact) {
try {
const response = await this.connection.pingRepeaterZeroHop(contact.publicKey);
console.log(response);
} catch(e) {
console.log(e);
}
},
async reboot() {
try {
await this.connection.reboot();

View file

@ -3,6 +3,7 @@ import BufferReader from "../buffer_reader.js";
import Constants from "../constants.js";
import EventEmitter from "../events.js";
import BufferUtils from "../buffer_utils.js";
import Packet from "../packet.js";
class Connection extends EventEmitter {
@ -1421,6 +1422,88 @@ class Connection extends EventEmitter {
});
}
pingRepeaterZeroHop(contactPublicKey, timeoutMillis) {
return new Promise(async (resolve, reject) => {
try {
// create raw data using custom packet
const bufferWriter = new BufferWriter();
bufferWriter.writeUInt32LE(Date.now()); // timestamp millis so every ping is unique
bufferWriter.writeBytes([0x70, 0x69, 0x6E, 0x67]); // "ping" as bytes
bufferWriter.writeBytes(contactPublicKey.subarray(0, 2)); // 2 bytes from the repeaters public key, so we don't use another repeaters ping response
const rawBytes = bufferWriter.toBytes();
var startMillis = Date.now();
// resolve promise when we receive expected response
const onLogRxDataPush = (response) => {
// calculate round trip time
const endMillis = Date.now();
const durationMillis = endMillis - startMillis;
// parse packet from rx data, and make sure it's expected type
const packet = Packet.fromBytes(response.raw);
if(packet.payload_type !== Packet.PAYLOAD_TYPE_RAW_CUSTOM){
return;
}
// make sure the payload we sent, is the payload we received
if(!BufferUtils.areBuffersEqual(packet.payload, rawBytes)){
return;
}
// ping successful remove all listeners
this.off(Constants.ResponseCodes.Err, onErr);
this.off(Constants.PushCodes.LogRxData, onLogRxDataPush);
// send back results
resolve({
rtt: durationMillis,
snr: response.lastSnr,
rssi: response.lastRssi,
});
}
// reject promise when we receive err
const onErr = () => {
this.off(Constants.ResponseCodes.Err, onErr);
this.off(Constants.PushCodes.LogRxData, onLogRxDataPush);
reject();
}
// listen for events
this.once(Constants.ResponseCodes.Err, onErr);
this.on(Constants.PushCodes.LogRxData, onLogRxDataPush);
// check if a timeout was provided
if(timeoutMillis != null){
setTimeout(() => {
// stop listening for events
this.off(Constants.ResponseCodes.Err, onErr);
this.off(Constants.PushCodes.LogRxData, onLogRxDataPush);
// reject since it timed out
reject("timeout");
}, timeoutMillis);
}
// send raw data to repeater, for it to repeat zero hop
await this.sendCommandSendRawData([
// we set the repeater we want to ping as the path
// it should repeat our packet, and we can listen for it
contactPublicKey.subarray(0, 1),
], rawBytes);
} catch(e) {
reject(e);
}
});
}
}
export default Connection;