meshcore.js/src/advert.js
Luc Patiny 3f899c8445 chore: enforce prettier configuration
In order to avoid reformatting of the code this PR add a prettier configuration as well as scripts to automatically format apply the rules
2025-11-17 06:10:08 +01:00

97 lines
2.4 KiB
JavaScript

import BufferReader from './buffer_reader.js';
import BufferWriter from './buffer_writer.js';
class Advert {
static ADV_TYPE_NONE = 0;
static ADV_TYPE_CHAT = 1;
static ADV_TYPE_REPEATER = 2;
static ADV_TYPE_ROOM = 3;
static ADV_LATLON_MASK = 0x10;
static ADV_BATTERY_MASK = 0x20;
static ADV_TEMPERATURE_MASK = 0x40;
static ADV_NAME_MASK = 0x80;
constructor(publicKey, timestamp, signature, appData) {
this.publicKey = publicKey;
this.timestamp = timestamp;
this.signature = signature;
this.appData = appData;
this.parsed = this.parseAppData();
}
static fromBytes(bytes) {
// read bytes
const bufferReader = new BufferReader(bytes);
const publicKey = bufferReader.readBytes(32);
const timestamp = bufferReader.readUInt32LE();
const signature = bufferReader.readBytes(64);
const appData = bufferReader.readRemainingBytes();
return new Advert(publicKey, timestamp, signature, appData);
}
getFlags() {
return this.appData[0];
}
getType() {
const flags = this.getFlags();
return flags & 0x0f;
}
getTypeString() {
const type = this.getType();
if (type === Advert.ADV_TYPE_NONE) return 'NONE';
if (type === Advert.ADV_TYPE_CHAT) return 'CHAT';
if (type === Advert.ADV_TYPE_REPEATER) return 'REPEATER';
if (type === Advert.ADV_TYPE_ROOM) return 'ROOM';
return null;
}
async isVerified() {
const { ed25519 } = await import('@noble/curves/ed25519');
// build signed data
const bufferWriter = new BufferWriter();
bufferWriter.writeBytes(this.publicKey);
bufferWriter.writeUInt32LE(this.timestamp);
bufferWriter.writeBytes(this.appData);
// verify signature
return ed25519.verify(
this.signature,
bufferWriter.toBytes(),
this.publicKey,
);
}
parseAppData() {
// read app data
const bufferReader = new BufferReader(this.appData);
const flags = bufferReader.readByte();
// parse lat lon
var lat = null;
var lon = null;
if (flags & Advert.ADV_LATLON_MASK) {
lat = bufferReader.readInt32LE();
lon = bufferReader.readInt32LE();
}
// parse name (remainder of app data)
var name = null;
if (flags & Advert.ADV_NAME_MASK) {
name = bufferReader.readString();
}
return {
type: this.getTypeString(),
lat: lat,
lon: lon,
name: name,
};
}
}
export default Advert;