add ability to send and receive channel data

This commit is contained in:
liamcottle 2026-03-24 00:11:52 +13:00
parent b4efd2b1c0
commit a06dbbebfd
2 changed files with 83 additions and 0 deletions

View file

@ -268,6 +268,17 @@ class Connection extends EventEmitter {
await this.sendToRadioFrame(data.toBytes());
}
async sendCommandSendChannelData(channelIdx, pathLen, path, dataType, payload) {
const data = new BufferWriter();
data.writeByte(Constants.CommandCodes.SendChannelData);
data.writeByte(channelIdx);
data.writeByte(pathLen);
data.writeBytes(path);
data.writeUInt16LE(dataType);
data.writeBytes(payload);
await this.sendToRadioFrame(data.toBytes());
}
async sendCommandGetChannel(channelIdx) {
const data = new BufferWriter();
data.writeByte(Constants.CommandCodes.GetChannel);
@ -366,6 +377,8 @@ class Connection extends EventEmitter {
this.onSignStartResponse(bufferReader);
} else if(responseCode === Constants.ResponseCodes.Signature){
this.onSignatureResponse(bufferReader);
} else if(responseCode === Constants.ResponseCodes.ChannelDataRecv){
this.onChannelDataRecvResponse(bufferReader);
} else if(responseCode === Constants.PushCodes.Advert){
this.onAdvertPush(bufferReader);
} else if(responseCode === Constants.PushCodes.PathUpdated){
@ -612,6 +625,27 @@ class Connection extends EventEmitter {
});
}
onChannelDataRecvResponse(bufferReader) {
const snr = bufferReader.readInt8() / 4;
const reserved1 = bufferReader.readByte();
const reserved2 = bufferReader.readByte();
const channelIdx = bufferReader.readInt8();
const pathLen = bufferReader.readByte(); // 0xFF if was sent direct, otherwise path_len for flood-mode
const dataType = bufferReader.readUInt16LE();
const dataLen = bufferReader.readUInt8();
const data = bufferReader.readBytes(dataLen);
this.emit(Constants.ResponseCodes.ChannelDataRecv, {
snr: snr,
reserved1: reserved1,
reserved2: reserved2,
channelIdx: channelIdx,
pathLen: pathLen,
dataType: dataType,
dataLen: dataLen,
data: data,
});
}
onSelfInfoResponse(bufferReader) {
this.emit(Constants.ResponseCodes.SelfInfo, {
type: bufferReader.readByte(),
@ -971,6 +1005,7 @@ class Connection extends EventEmitter {
const onContactMessageReceived = (message) => {
this.off(Constants.ResponseCodes.ContactMsgRecv, onContactMessageReceived);
this.off(Constants.ResponseCodes.ChannelMsgRecv, onChannelMessageReceived);
this.off(Constants.ResponseCodes.ChannelDataRecv, onChannelDataReceived);
this.off(Constants.ResponseCodes.NoMoreMessages, onNoMoreMessagesReceived);
resolve({
contactMessage: message,
@ -981,16 +1016,29 @@ class Connection extends EventEmitter {
const onChannelMessageReceived = (message) => {
this.off(Constants.ResponseCodes.ContactMsgRecv, onContactMessageReceived);
this.off(Constants.ResponseCodes.ChannelMsgRecv, onChannelMessageReceived);
this.off(Constants.ResponseCodes.ChannelDataRecv, onChannelDataReceived);
this.off(Constants.ResponseCodes.NoMoreMessages, onNoMoreMessagesReceived);
resolve({
channelMessage: message,
});
}
// resolve promise when we receive channel data
const onChannelDataReceived = (message) => {
this.off(Constants.ResponseCodes.ContactMsgRecv, onContactMessageReceived);
this.off(Constants.ResponseCodes.ChannelMsgRecv, onChannelMessageReceived);
this.off(Constants.ResponseCodes.ChannelDataRecv, onChannelDataReceived);
this.off(Constants.ResponseCodes.NoMoreMessages, onNoMoreMessagesReceived);
resolve({
channelData: message,
});
}
// resolve promise when we have no more messages to receive
const onNoMoreMessagesReceived = () => {
this.off(Constants.ResponseCodes.ContactMsgRecv, onContactMessageReceived);
this.off(Constants.ResponseCodes.ChannelMsgRecv, onChannelMessageReceived);
this.off(Constants.ResponseCodes.ChannelDataRecv, onChannelDataReceived);
this.off(Constants.ResponseCodes.NoMoreMessages, onNoMoreMessagesReceived);
resolve(null);
}
@ -998,6 +1046,7 @@ class Connection extends EventEmitter {
// listen for events
this.once(Constants.ResponseCodes.ContactMsgRecv, onContactMessageReceived);
this.once(Constants.ResponseCodes.ChannelMsgRecv, onChannelMessageReceived);
this.once(Constants.ResponseCodes.ChannelDataRecv, onChannelDataReceived);
this.once(Constants.ResponseCodes.NoMoreMessages, onNoMoreMessagesReceived);
// sync next message from device
@ -1807,6 +1856,37 @@ class Connection extends EventEmitter {
});
}
sendChannelData(channelIdx, pathLen, path, dataType, payload) {
return new Promise(async (resolve, reject) => {
try {
// resolve promise when we receive ok
const onOk = (response) => {
this.off(Constants.ResponseCodes.Ok, onOk);
this.off(Constants.ResponseCodes.Err, onErr);
resolve(response);
}
// reject promise when we receive err
const onErr = () => {
this.off(Constants.ResponseCodes.Ok, onOk);
this.off(Constants.ResponseCodes.Err, onErr);
reject();
}
// listen for events
this.once(Constants.ResponseCodes.Ok, onOk);
this.once(Constants.ResponseCodes.Err, onErr);
// send channel data
await this.sendCommandSendChannelData(channelIdx, pathLen, path, dataType, payload);
} catch(e) {
reject(e);
}
});
}
clearFloodScope() {
return this.setFloodScope([]);
}

View file

@ -54,6 +54,8 @@ class Constants {
SendBinaryReq: 50,
SetFloodScope: 54,
SendChannelData: 62,
}
static ResponseCodes = {
@ -76,6 +78,7 @@ class Constants {
ChannelInfo: 18,
SignStart: 19,
Signature: 20,
ChannelDataRecv: 27,
}
static PushCodes = {