mirror of
https://github.com/meshcore-dev/meshcore.js.git
synced 2026-04-20 22:13:49 +00:00
implement path tracing
This commit is contained in:
parent
85d82b13c1
commit
9e3171bd78
5 changed files with 131 additions and 0 deletions
42
index.html
42
index.html
|
|
@ -119,6 +119,9 @@
|
|||
<button @click="deleteChannel" class="border border-gray-500 px-2 bg-gray-100 hover:bg-gray-200 rounded">
|
||||
DeleteChannel
|
||||
</button>
|
||||
<button @click="sendTrace" class="border border-gray-500 px-2 bg-gray-100 hover:bg-gray-200 rounded">
|
||||
SendTrace
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -557,6 +560,45 @@
|
|||
alert("Failed to delete channel!");
|
||||
}
|
||||
},
|
||||
getRandomInt(min, max) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
},
|
||||
async sendTrace() {
|
||||
|
||||
// ask user for path
|
||||
const pathString = prompt("Enter path as hex string eg: 12,3f,4d");
|
||||
if(!pathString){
|
||||
return;
|
||||
}
|
||||
|
||||
const pathHex = pathString.replaceAll(",", "");
|
||||
const pathBytes = BufferUtils.hexToBytes(pathHex);
|
||||
console.log(pathBytes);
|
||||
|
||||
try {
|
||||
|
||||
console.log(`TRACE request for path: ${pathString}`);
|
||||
const response = await this.connection.tracePath(pathBytes);
|
||||
|
||||
console.log("TRACE response", response);
|
||||
const responseList = [];
|
||||
for(var i = 0; i < response.pathLen; i++){
|
||||
const pathHash = response.pathHashes[i];
|
||||
const pathSnr = response.pathSnrs[i] / 4;
|
||||
responseList.push(`Hop ${i + 1}: hash=${pathHash.toString(16)}, snr=${pathSnr}`);
|
||||
}
|
||||
responseList.push(`Trace Received: snr=${response.lastSnr}`);
|
||||
|
||||
console.log(responseList.join("\n"));
|
||||
alert(responseList.join("\n"));
|
||||
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
},
|
||||
async login(contact) {
|
||||
|
||||
// ask user for password
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ class BufferUtils {
|
|||
}).join('');
|
||||
}
|
||||
|
||||
static hexToBytes(hex) {
|
||||
return Uint8Array.from(hex.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
|
||||
}
|
||||
|
||||
static base64ToBytes(base64) {
|
||||
return Uint8Array.from(atob(base64), (c) => {
|
||||
return c.charCodeAt(0);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import Constants from "../constants.js";
|
|||
import EventEmitter from "../events.js";
|
||||
import BufferUtils from "../buffer_utils.js";
|
||||
import Packet from "../packet.js";
|
||||
import RandomUtils from "../random_utils.js";
|
||||
|
||||
class Connection extends EventEmitter {
|
||||
|
||||
|
|
@ -247,6 +248,16 @@ class Connection extends EventEmitter {
|
|||
await this.sendToRadioFrame(data.toBytes());
|
||||
}
|
||||
|
||||
async sendCommandSendTracePath(tag, auth, path) {
|
||||
const data = new BufferWriter();
|
||||
data.writeByte(Constants.CommandCodes.SendTracePath);
|
||||
data.writeUInt32LE(tag);
|
||||
data.writeUInt32LE(auth);
|
||||
data.writeByte(0); // flags
|
||||
data.writeBytes(path);
|
||||
await this.sendToRadioFrame(data.toBytes());
|
||||
}
|
||||
|
||||
onFrameReceived(frame) {
|
||||
|
||||
// emit received frame
|
||||
|
|
@ -305,6 +316,8 @@ class Connection extends EventEmitter {
|
|||
this.onStatusResponsePush(bufferReader);
|
||||
} else if(responseCode === Constants.PushCodes.LogRxData){
|
||||
this.onLogRxDataPush(bufferReader);
|
||||
} else if(responseCode === Constants.PushCodes.TraceData){
|
||||
this.onTraceDataPush(bufferReader);
|
||||
} else {
|
||||
console.log("unhandled frame", frame);
|
||||
}
|
||||
|
|
@ -368,6 +381,21 @@ class Connection extends EventEmitter {
|
|||
});
|
||||
}
|
||||
|
||||
onTraceDataPush(bufferReader) {
|
||||
const reserved = bufferReader.readByte();
|
||||
const pathLen = bufferReader.readUInt8();
|
||||
this.emit(Constants.PushCodes.TraceData, {
|
||||
reserved: reserved,
|
||||
pathLen: pathLen,
|
||||
flags: bufferReader.readUInt8(),
|
||||
tag: bufferReader.readUInt32LE(),
|
||||
authCode: bufferReader.readUInt32LE(),
|
||||
pathHashes: bufferReader.readBytes(pathLen),
|
||||
pathSnrs: bufferReader.readBytes(pathLen),
|
||||
lastSnr: bufferReader.readInt8() / 4,
|
||||
});
|
||||
}
|
||||
|
||||
onOkResponse(bufferReader) {
|
||||
this.emit(Constants.ResponseCodes.Ok, {
|
||||
|
||||
|
|
@ -1632,6 +1660,49 @@ class Connection extends EventEmitter {
|
|||
});
|
||||
}
|
||||
|
||||
tracePath(path) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
try {
|
||||
|
||||
// generate a random tag for this trace, so we can listen for the correct response
|
||||
const tag = RandomUtils.getRandomInt(0, 4294967295);
|
||||
|
||||
// resolve promise when we receive trace data
|
||||
const onTraceDataPush = (response) => {
|
||||
|
||||
// make sure tag matches
|
||||
if(response.tag !== tag){
|
||||
console.log("ignoring trace data for a different trace request");
|
||||
return;
|
||||
}
|
||||
|
||||
// resolve
|
||||
this.off(Constants.PushCodes.TraceData, onTraceDataPush);
|
||||
this.off(Constants.ResponseCodes.Err, onErr);
|
||||
resolve(response);
|
||||
|
||||
}
|
||||
|
||||
// reject promise when we receive err
|
||||
const onErr = () => {
|
||||
this.off(Constants.PushCodes.TraceData, onTraceDataPush);
|
||||
this.off(Constants.ResponseCodes.Err, onErr);
|
||||
reject();
|
||||
}
|
||||
|
||||
// listen for events
|
||||
this.on(Constants.PushCodes.TraceData, onTraceDataPush);
|
||||
this.once(Constants.ResponseCodes.Err, onErr);
|
||||
|
||||
// trace path
|
||||
await this.sendCommandSendTracePath(tag, 0, path);
|
||||
|
||||
} catch(e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Connection;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ class Constants {
|
|||
SendStatusReq: 27, // todo
|
||||
GetChannel: 31,
|
||||
SetChannel: 32,
|
||||
// todo sign commands
|
||||
SendTracePath: 36,
|
||||
}
|
||||
|
||||
static ResponseCodes = {
|
||||
|
|
@ -73,6 +75,7 @@ class Constants {
|
|||
LoginFail: 0x86, // not usable yet
|
||||
StatusResponse: 0x87,
|
||||
LogRxData: 0x88,
|
||||
TraceData: 0x89,
|
||||
}
|
||||
|
||||
static AdvType = {
|
||||
|
|
|
|||
11
src/random_utils.js
Normal file
11
src/random_utils.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
class RandomUtils {
|
||||
|
||||
static getRandomInt(min, max) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RandomUtils;
|
||||
Loading…
Add table
Add a link
Reference in a new issue