diff --git a/index.html b/index.html
index 16c6e93..de5e6c1 100644
--- a/index.html
+++ b/index.html
@@ -89,6 +89,9 @@
+
@@ -284,7 +287,8 @@
await this.connection.sendCommandAddUpdateContact(publicKey, type, flags, outPathLen, outPath, advName, lastAdvert, advLat, advLon);
},
async sendCommandSyncNextMessage() {
- await this.connection.sendCommandSyncNextMessage();
+ const message = await this.connection.syncNextMessage();
+ console.log("syncNextMessage", message);
},
async sendMessage(contact) {
@@ -298,6 +302,17 @@
const response = await this.connection.sendTextMessage(contact.publicKey, message);
console.log(response);
+ },
+ async sendChannelTextMessage() {
+
+ // ask user for message
+ const message = prompt("Enter message to send");
+ if(!message){
+ return;
+ }
+
+ await this.connection.sendChannelTextMessage(0, message);
+
},
async resetPath(contact) {
diff --git a/src/connection/connection.js b/src/connection/connection.js
index 58e1a45..350d06a 100644
--- a/src/connection/connection.js
+++ b/src/connection/connection.js
@@ -41,6 +41,16 @@ class Connection extends EventEmitter {
await this.sendToRadioFrame(data.toBytes());
}
+ async sendCommandSendChannelTxtMsg(txtType, channelIdx, senderTimestamp, text) {
+ const data = new BufferWriter();
+ data.writeByte(Constants.CommandCodes.SendChannelTxtMsg);
+ data.writeByte(txtType);
+ data.writeByte(channelIdx);
+ data.writeUInt32LE(senderTimestamp);
+ data.writeString(text);
+ await this.sendToRadioFrame(data.toBytes());
+ }
+
async sendCommandGetContacts(since) {
const data = new BufferWriter();
data.writeByte(Constants.CommandCodes.GetContacts);
@@ -153,6 +163,8 @@ class Connection extends EventEmitter {
this.onNoMoreMessagesResponse(bufferReader);
} else if(responseCode === Constants.ResponseCodes.ContactMsgRecv){
this.onContactMsgRecvResponse(bufferReader);
+ } else if(responseCode === Constants.ResponseCodes.ChannelMsgRecv){
+ this.onChannelMsgRecvResponse(bufferReader);
} else if(responseCode === Constants.ResponseCodes.ContactsStart){
this.onContactsStartResponse(bufferReader);
} else if(responseCode === Constants.ResponseCodes.Contact){
@@ -274,6 +286,16 @@ class Connection extends EventEmitter {
});
}
+ onChannelMsgRecvResponse(bufferReader) {
+ this.emit(Constants.ResponseCodes.ChannelMsgRecv, {
+ channelIdx: bufferReader.readInt8(), // reserved (0 for now, ie. 'public')
+ pathLen: bufferReader.readByte(), // 0xFF if was sent direct, otherwise hop count for flood-mode
+ txtType: bufferReader.readByte(),
+ senderTimestamp: bufferReader.readUInt32LE(),
+ text: bufferReader.readString(),
+ });
+ }
+
getSelfInfo() {
return new Promise(async (resolve, reject) => {
@@ -343,25 +365,71 @@ class Connection extends EventEmitter {
});
}
+ sendChannelTextMessage(channelIdx, text) {
+ return new Promise(async (resolve, reject) => {
+ try {
+
+ // resolve promise when we receive ok
+ const onOk = () => {
+ this.off(Constants.ResponseCodes.Ok, onOk);
+ this.off(Constants.ResponseCodes.Err, onErr);
+ resolve();
+ }
+
+ // reject promise when we receive err
+ const onErr = () => {
+ this.off(Constants.ResponseCodes.Ok, onOk);
+ this.off(Constants.ResponseCodes.Err, onErr);
+ reject();
+ }
+
+ // compose message
+ const txtType = Constants.TxtTypes.Plain;
+ const senderTimestamp = Math.floor(Date.now() / 1000);
+
+ // send message
+ await this.sendCommandSendChannelTxtMsg(txtType, channelIdx, senderTimestamp, text);
+
+ } catch(e) {
+ reject(e);
+ }
+ });
+ }
+
syncNextMessage() {
return new Promise(async (resolve, reject) => {
- // resolve promise when we receive the message
+ // resolve promise when we receive a contact message
const onContactMessageReceived = (message) => {
this.off(Constants.ResponseCodes.ContactMsgRecv, onContactMessageReceived);
+ this.off(Constants.ResponseCodes.ChannelMsgRecv, onChannelMessageReceived);
this.off(Constants.ResponseCodes.NoMoreMessages, onNoMoreMessagesReceived);
- resolve(message);
+ resolve({
+ contactMessage: message,
+ });
+ }
+
+ // resolve promise when we receive a channel message
+ const onChannelMessageReceived = (message) => {
+ this.off(Constants.ResponseCodes.ContactMsgRecv, onContactMessageReceived);
+ this.off(Constants.ResponseCodes.ChannelMsgRecv, onChannelMessageReceived);
+ this.off(Constants.ResponseCodes.NoMoreMessages, onNoMoreMessagesReceived);
+ resolve({
+ channelMessage: 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.NoMoreMessages, onNoMoreMessagesReceived);
resolve(null);
}
// listen for events
this.once(Constants.ResponseCodes.ContactMsgRecv, onContactMessageReceived);
+ this.once(Constants.ResponseCodes.ChannelMsgRecv, onChannelMessageReceived);
this.once(Constants.ResponseCodes.NoMoreMessages, onNoMoreMessagesReceived);
// sync next message from device
diff --git a/src/constants.js b/src/constants.js
index 0a3c5c0..304160b 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -14,7 +14,7 @@ class Constants {
static CommandCodes = {
AppStart: 1,
SendTxtMsg: 2,
- SendChannelTxtMsg: 3, // todo
+ SendChannelTxtMsg: 3,
GetContacts: 4,
GetDeviceTime: 5,
SetDeviceTime: 6,
@@ -38,14 +38,14 @@ class Constants {
SelfInfo: 5,
Sent: 6,
ContactMsgRecv: 7,
- ChannelMsgRecv: 8, // todo
+ ChannelMsgRecv: 8,
CurrTime: 9,
NoMoreMessages: 10,
}
static PushCodes = {
Advert: 0x80,
- PathUpdated: 0x81, // todo
+ PathUpdated: 0x81,
SendConfirmed: 0x82,
MsgWaiting: 0x83,
}