diff --git a/examples/companion_radio/DataStore.cpp b/examples/companion_radio/DataStore.cpp index eac027b8..62e24feb 100644 --- a/examples/companion_radio/DataStore.cpp +++ b/examples/companion_radio/DataStore.cpp @@ -324,9 +324,11 @@ void DataStore::loadChannels(DataStoreHost* host) { uint8_t channel_idx = 0; while (!full) { ChannelDetails ch; - uint8_t unused[4]; + ChannelHeader header; + + bool success = (file.read((uint8_t*)&header, sizeof(ChannelHeader)) == sizeof(ChannelHeader)); + ch.flags.noStore = header.flags.noStore; - bool success = (file.read(unused, 4) == 4); success = success && (file.read((uint8_t *)ch.name, 32) == 32); success = success && (file.read((uint8_t *)ch.channel.secret, 32) == 32); @@ -347,11 +349,12 @@ void DataStore::saveChannels(DataStoreHost* host) { if (file) { uint8_t channel_idx = 0; ChannelDetails ch; - uint8_t unused[4]; - memset(unused, 0, 4); - + while (host->getChannelForSave(channel_idx, ch)) { - bool success = (file.write(unused, 4) == 4); + ChannelHeader header{}; + header.flags.noStore = ch.flags.noStore; + + bool success = (file.write((uint8_t *)&header, sizeof(ChannelHeader)) == sizeof(ChannelHeader)); success = success && (file.write((uint8_t *)ch.name, 32) == 32); success = success && (file.write((uint8_t *)ch.channel.secret, 32) == 32); diff --git a/examples/companion_radio/DataStore.h b/examples/companion_radio/DataStore.h index 62580942..e90110b0 100644 --- a/examples/companion_radio/DataStore.h +++ b/examples/companion_radio/DataStore.h @@ -5,6 +5,12 @@ #include #include "NodePrefs.h" +struct ChannelHeader { + ChannelFlags flags; + uint8_t unused[3]; +}; +static_assert(sizeof(ChannelHeader) == 4, "ChannelHeader must be 4 bytes"); + class DataStoreHost { public: virtual bool onContactLoaded(const ContactInfo& contact) =0; diff --git a/examples/companion_radio/MyMesh.cpp b/examples/companion_radio/MyMesh.cpp index c0075a22..c148a38e 100644 --- a/examples/companion_radio/MyMesh.cpp +++ b/examples/companion_radio/MyMesh.cpp @@ -52,6 +52,8 @@ #define CMD_SEND_PATH_DISCOVERY_REQ 52 #define CMD_SET_FLOOD_SCOPE 54 // v8+ #define CMD_SEND_CONTROL_DATA 55 // v8+ +#define CMD_GET_CHANNEL_FLAG_NOSTORE 56 +#define CMD_SET_CHANNEL_FLAG_NOSTORE 57 #define RESP_CODE_OK 0 #define RESP_CODE_ERR 1 @@ -77,6 +79,7 @@ #define RESP_CODE_CUSTOM_VARS 21 #define RESP_CODE_ADVERT_PATH 22 #define RESP_CODE_TUNING_PARAMS 23 +#define RESP_CODE_CHANNEL_FLAG_NOSTORE 24 // a reply to CMD_GET_CHANNEL_FLAG_NOSTORE #define SEND_TIMEOUT_BASE_MILLIS 500 #define FLOOD_SEND_TIMEOUT_FACTOR 16.0f @@ -455,7 +458,14 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe } memcpy(&out_frame[i], text, tlen); i += tlen; - addToOfflineQueue(out_frame, i); + + ChannelDetails channel_details; + bool foundDetails = getChannel(channel_idx, channel_details); + if (foundDetails && channel_details.flags.noStore && !_serial->isConnected()) { + MESH_DEBUG_PRINTLN("INFO: not storing message for noStore channel"); + } else { + addToOfflineQueue(out_frame, i); + } if (_serial->isConnected()) { uint8_t frame[1]; @@ -469,8 +479,7 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe #ifdef DISPLAY_CLASS // Get the channel name from the channel index const char *channel_name = "Unknown"; - ChannelDetails channel_details; - if (getChannel(channel_idx, channel_details)) { + if (foundDetails) { channel_name = channel_details.name; } if (_ui) _ui->newMsg(path_len, channel_name, text, offline_queue_len); @@ -1553,6 +1562,30 @@ void MyMesh::handleCmdFrame(size_t len) { } else { writeErrFrame(ERR_CODE_TABLE_FULL); } + } else if (cmd_frame[0] == CMD_GET_CHANNEL_FLAG_NOSTORE && len >= 2) { + uint8_t channel_idx = cmd_frame[1]; + ChannelDetails channel; + if (getChannel(channel_idx, channel)) { + out_frame[0] = RESP_CODE_CHANNEL_FLAG_NOSTORE; + out_frame[1] = static_cast(channel.flags.noStore); + _serial->writeFrame(out_frame, 2); + } else { + writeErrFrame(ERR_CODE_NOT_FOUND); + } + } else if (cmd_frame[0] == CMD_SET_CHANNEL_FLAG_NOSTORE && len >= 3) { + uint8_t channel_idx = cmd_frame[1]; + ChannelDetails channel; + if (getChannel(channel_idx, channel)) { + channel.flags.noStore = static_cast(cmd_frame[2]); + if (setChannel(channel_idx, channel)) { + saveChannels(); + writeOKFrame(); + } else { + writeErrFrame(ERR_CODE_NOT_FOUND); + } + } else { + writeErrFrame(ERR_CODE_NOT_FOUND); + } } else { writeErrFrame(ERR_CODE_UNSUPPORTED_CMD); MESH_DEBUG_PRINTLN("ERROR: unknown command: %02X", cmd_frame[0]); diff --git a/src/helpers/ChannelDetails.h b/src/helpers/ChannelDetails.h index b9d38d4f..1933cc18 100644 --- a/src/helpers/ChannelDetails.h +++ b/src/helpers/ChannelDetails.h @@ -3,7 +3,13 @@ #include #include +struct ChannelFlags { + bool noStore : 1; + uint8_t reserved : 7; // remaining 7 bits unused +}; + struct ChannelDetails { mesh::GroupChannel channel; char name[32]; -}; + ChannelFlags flags; +}; \ No newline at end of file