diff --git a/index.html b/index.html
index ddd46d0..1d178c3 100644
--- a/index.html
+++ b/index.html
@@ -110,6 +110,9 @@
+
@@ -526,6 +529,14 @@
alert("Failed to get battery voltage!");
}
},
+ async getChannels() {
+ try {
+ const response = await this.connection.getChannels();
+ console.log(response);
+ } catch(e) {
+ alert("Failed to get channels!");
+ }
+ },
async login(contact) {
// ask user for password
diff --git a/src/buffer_reader.js b/src/buffer_reader.js
index a4f5e07..3dfe896 100644
--- a/src/buffer_reader.js
+++ b/src/buffer_reader.js
@@ -5,6 +5,10 @@ class BufferReader {
this.buffer = new Uint8Array(data);
}
+ getRemainingBytesCount() {
+ return this.buffer.length - this.pointer;
+ }
+
readByte() {
return this.readBytes(1)[0];
}
@@ -16,8 +20,7 @@ class BufferReader {
}
readRemainingBytes() {
- const remainingBytesCount = this.buffer.length - this.pointer;
- return this.readBytes(remainingBytesCount);
+ return this.readBytes(this.getRemainingBytesCount());
}
readString() {
@@ -47,6 +50,12 @@ class BufferReader {
return view.getInt8(0);
}
+ readUInt8() {
+ const bytes = this.readBytes(1);
+ const view = new DataView(bytes.buffer);
+ return view.getUint8(0);
+ }
+
readUInt16LE() {
const bytes = this.readBytes(2);
const view = new DataView(bytes.buffer);
diff --git a/src/connection/connection.js b/src/connection/connection.js
index 5eb2a89..5b6bb67 100644
--- a/src/connection/connection.js
+++ b/src/connection/connection.js
@@ -231,6 +231,13 @@ class Connection extends EventEmitter {
await this.sendToRadioFrame(data.toBytes());
}
+ async sendCommandGetChannel(channelIdx) {
+ const data = new BufferWriter();
+ data.writeByte(Constants.CommandCodes.GetChannel);
+ data.writeByte(channelIdx);
+ await this.sendToRadioFrame(data.toBytes());
+ }
+
onFrameReceived(frame) {
// emit received frame
@@ -271,6 +278,8 @@ class Connection extends EventEmitter {
this.onPrivateKeyResponse(bufferReader);
} else if(responseCode === Constants.ResponseCodes.Disabled){
this.onDisabledResponse(bufferReader);
+ } else if(responseCode === Constants.ResponseCodes.ChannelInfo){
+ this.onChannelInfoResponse(bufferReader);
} else if(responseCode === Constants.PushCodes.Advert){
this.onAdvertPush(bufferReader);
} else if(responseCode === Constants.PushCodes.PathUpdated){
@@ -430,6 +439,23 @@ class Connection extends EventEmitter {
});
}
+ onChannelInfoResponse(bufferReader) {
+
+ const idx = bufferReader.readUInt8();
+ const remainingBytesLength = bufferReader.getRemainingBytesCount();
+
+ // 128-bit keys
+ if(remainingBytesLength === 16){
+ this.emit(Constants.ResponseCodes.ChannelInfo, {
+ channelIdx: idx,
+ secret: bufferReader.readBytes(remainingBytesLength),
+ });
+ } else {
+ console.log(`ChannelInfo has unexpected key length: ${remainingBytesLength}`);
+ }
+
+ }
+
onSelfInfoResponse(bufferReader) {
this.emit(Constants.ResponseCodes.SelfInfo, {
type: bufferReader.readByte(),
@@ -1504,6 +1530,62 @@ class Connection extends EventEmitter {
});
}
+ getChannel(channelIdx) {
+ return new Promise(async (resolve, reject) => {
+ try {
+
+ // resolve promise when we receive channel info response
+ const onChannelInfoResponse = (response) => {
+ this.off(Constants.ResponseCodes.ChannelInfo, onChannelInfoResponse);
+ this.off(Constants.ResponseCodes.Err, onErr);
+ resolve(response);
+ }
+
+ // reject promise when we receive err
+ const onErr = () => {
+ this.off(Constants.ResponseCodes.ChannelInfo, onChannelInfoResponse);
+ this.off(Constants.ResponseCodes.Err, onErr);
+ reject();
+ }
+
+ // listen for events
+ this.once(Constants.ResponseCodes.ChannelInfo, onChannelInfoResponse);
+ this.once(Constants.ResponseCodes.Err, onErr);
+
+ // get channel
+ await this.sendCommandGetChannel(channelIdx);
+
+ } catch(e) {
+ reject(e);
+ }
+ });
+ }
+
+ getChannels() {
+ return new Promise(async (resolve, reject) => {
+
+ // add channels we receive to a list
+ var channelIdx = 0;
+ const channels = [];
+ while(true){
+
+ // try to get next channel
+ try {
+ const channel = await this.getChannel(channelIdx);
+ channels.push(channel);
+ } catch(e){
+ break;
+ }
+
+ channelIdx++;
+
+ }
+
+ return resolve(channels);
+
+ });
+ }
+
}
export default Connection;
diff --git a/src/constants.js b/src/constants.js
index 5dbc360..2941cd9 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -39,6 +39,8 @@ class Constants {
SendRawData: 25,
SendLogin: 26, // todo
SendStatusReq: 27, // todo
+ GetChannel: 31,
+ SetChannel: 32,
}
static ResponseCodes = {
@@ -58,6 +60,7 @@ class Constants {
DeviceInfo: 13,
PrivateKey: 14,
Disabled: 15,
+ ChannelInfo: 18,
}
static PushCodes = {