diff --git a/.vscode/settings.json b/.vscode/settings.json
index f78fe51b8..965532c24 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -68,5 +68,13 @@
"protobufs",
"wifi"
],
- "C_Cpp.dimInactiveRegions": true
+ "C_Cpp.dimInactiveRegions": true,
+ "protoc": {
+ "compile_on_save": false,
+ "compile_all_path": "/home/kevinh/development/meshtastic/meshtastic-esp32/proto",
+ "options": [
+ "--java_out=/tmp",
+ "-I=/home/kevinh/development/meshtastic/meshtastic-esp32/proto"
+ ]
+ }
}
\ No newline at end of file
diff --git a/docs/software/TODO.md b/docs/software/TODO.md
index f6df164b0..ded8796de 100644
--- a/docs/software/TODO.md
+++ b/docs/software/TODO.md
@@ -2,6 +2,24 @@
You probably don't care about this section - skip to the next one.
+1.2 cleanup & multichannel:
+
+* remove deprecated
+* allow chaning packets in single transmission
+* fix setchannel in phoneapi.cpp
+* set mynodeinfo.max_channels
+* set mynodeinfo.num_bands (formerly num_channels)
+* send a hint that can be used to select which channel to try and hash against with each message
+* change syncword
+* move acks into routing
+* make all subpackets different versions of data
+* move routing control into a data packet
+* make a primaryChannel global and properly maintain it when the phone sends setChannel
+* move setCrypto call into packet send and packet decode code
+* implement'small locations' change?
+* move battery level out of position?
+* DOUBLE CHECK android app can still upgrade 1.1 and 1.0 loads
+
eink:
* new battery level sensing
diff --git a/proto b/proto
index 0cadaed39..481beb41b 160000
--- a/proto
+++ b/proto
@@ -1 +1 @@
-Subproject commit 0cadaed3953f66cf1edc99d0fa53e4fd5ebf56d6
+Subproject commit 481beb41ba8c8f39bfc6b3f397d6107af04dfb93
diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index 40ea25237..f7193260f 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -32,6 +32,7 @@ along with this program. If not, see .
#include "main.h"
#include "mesh-pb-constants.h"
#include "plugins/TextMessagePlugin.h"
+#include "mesh/Channels.h"
#include "target_specific.h"
#include "utils.h"
@@ -790,9 +791,6 @@ int32_t Screen::runOnce()
showingBootScreen = false;
}
- // Update the screen last, after we've figured out what to show.
- debug_info()->setChannelNameStatus(getChannelName());
-
// Process incoming commands.
for (;;) {
ScreenCmd cmd;
@@ -1022,7 +1020,8 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
char channelStr[20];
{
concurrency::LockGuard guard(&lock);
- snprintf(channelStr, sizeof(channelStr), "%s", channelName.c_str());
+ auto chName = channels.getPrimaryName();
+ snprintf(channelStr, sizeof(channelStr), "%s", chName);
}
// Display power status
@@ -1229,8 +1228,8 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat
display->drawString(x, y, String("USB"));
}
- display->drawString(x + SCREEN_WIDTH - display->getStringWidth("Mode " + String(channelSettings.modem_config)), y,
- "Mode " + String(channelSettings.modem_config));
+ auto mode = "Mode " + String(channels.getPrimary().modem_config);
+ display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
// Line 2
uint32_t currentMillis = millis();
diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h
index 041da4865..9be119a48 100644
--- a/src/graphics/Screen.h
+++ b/src/graphics/Screen.h
@@ -39,13 +39,6 @@ class DebugInfo
DebugInfo(const DebugInfo &) = delete;
DebugInfo &operator=(const DebugInfo &) = delete;
- /// Sets the name of the channel.
- void setChannelNameStatus(const char *name)
- {
- concurrency::LockGuard guard(&lock);
- channelName = name;
- }
-
private:
friend Screen;
@@ -56,8 +49,6 @@ class DebugInfo
void drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
void drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
- std::string channelName;
-
/// Protects all of internal state.
concurrency::Lock lock;
};
diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp
new file mode 100644
index 000000000..584a83bc8
--- /dev/null
+++ b/src/mesh/Channels.cpp
@@ -0,0 +1,228 @@
+#include "Channels.h"
+#include "NodeDB.h"
+#include "CryptoEngine.h"
+
+#include
+
+/// A usable psk - which has been constructed based on the (possibly short psk) in channelSettings
+static uint8_t activePSK[32];
+static uint8_t activePSKSize;
+
+/// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128)
+static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
+ 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf};
+
+Channels channels;
+
+/**
+ * Validate a channel, fixing any errors as needed
+ */
+Channel &fixupChannel(size_t chIndex)
+{
+ assert(chIndex < devicestate.channels_count);
+
+ Channel *ch = devicestate.channels + chIndex;
+
+ ch->index = chIndex; // Preinit the index so it be ready to share with the phone (we'll never change it later)
+
+ if (!ch->has_settings) {
+ // No settings! Must disable and skip
+ ch->role = Channel_Role_DISABLED;
+ } else {
+ ChannelSettings &channelSettings = ch->settings;
+
+ // Convert the old string "Default" to our new short representation
+ if (strcmp(channelSettings.name, "Default") == 0)
+ *channelSettings.name = '\0';
+
+ // Convert any old usage of the defaultpsk into our new short representation.
+ if (channelSettings.psk.size == sizeof(defaultpsk) &&
+ memcmp(channelSettings.psk.bytes, defaultpsk, sizeof(defaultpsk)) == 0) {
+ *channelSettings.psk.bytes = 1;
+ channelSettings.psk.size = 1;
+ }
+ }
+
+ return *ch;
+}
+
+
+
+/**
+ * Write a default channel to the specified channel index
+ */
+void initDefaultChannel(size_t chIndex)
+{
+ assert(chIndex < devicestate.channels_count);
+ Channel *ch = devicestate.channels + chIndex;
+ ChannelSettings &channelSettings = ch->settings;
+
+ // radioConfig.modem_config = RadioConfig_ModemConfig_Bw125Cr45Sf128; // medium range and fast
+ // channelSettings.modem_config = ChannelSettings_ModemConfig_Bw500Cr45Sf128; // short range and fast, but wide
+ // bandwidth so incompatible radios can talk together
+ channelSettings.modem_config = ChannelSettings_ModemConfig_Bw125Cr48Sf4096; // slow and long range
+
+ channelSettings.tx_power = 0; // default
+ uint8_t defaultpskIndex = 1;
+ channelSettings.psk.bytes[0] = defaultpskIndex;
+ channelSettings.psk.size = 1;
+ strcpy(channelSettings.name, "");
+
+ ch->has_settings = true;
+ ch->role = Channel_Role_PRIMARY;
+}
+
+/** Given a channel index, change to use the crypto key specified by that index
+ */
+void setCrypto(size_t chIndex)
+{
+
+ assert(chIndex < devicestate.channels_count);
+ Channel *ch = devicestate.channels + chIndex;
+ ChannelSettings &channelSettings = ch->settings;
+
+ memset(activePSK, 0, sizeof(activePSK)); // In case the user provided a short key, we want to pad the rest with zeros
+ memcpy(activePSK, channelSettings.psk.bytes, channelSettings.psk.size);
+ activePSKSize = channelSettings.psk.size;
+ if (activePSKSize == 0)
+ DEBUG_MSG("Warning: User disabled encryption\n");
+ else if (activePSKSize == 1) {
+ // Convert the short single byte variants of psk into variant that can be used more generally
+
+ uint8_t pskIndex = activePSK[0];
+ DEBUG_MSG("Expanding short PSK #%d\n", pskIndex);
+ if (pskIndex == 0)
+ activePSKSize = 0; // Turn off encryption
+ else {
+ memcpy(activePSK, defaultpsk, sizeof(defaultpsk));
+ activePSKSize = sizeof(defaultpsk);
+ // Bump up the last byte of PSK as needed
+ uint8_t *last = activePSK + sizeof(defaultpsk) - 1;
+ *last = *last + pskIndex - 1; // index of 1 means no change vs defaultPSK
+ }
+ } else if (activePSKSize < 16) {
+ // Error! The user specified only the first few bits of an AES128 key. So by convention we just pad the rest of the key
+ // with zeros
+ DEBUG_MSG("Warning: User provided a too short AES128 key - padding\n");
+ activePSKSize = 16;
+ } else if (activePSKSize < 32 && activePSKSize != 16) {
+ // Error! The user specified only the first few bits of an AES256 key. So by convention we just pad the rest of the key
+ // with zeros
+ DEBUG_MSG("Warning: User provided a too short AES256 key - padding\n");
+ activePSKSize = 32;
+ }
+
+ // Tell our crypto engine about the psk
+ crypto->setKey(activePSKSize, activePSK);
+}
+
+void Channels::initDefaults()
+{
+ devicestate.channels_count = MAX_CHANNELS;
+ for (int i = 0; i < devicestate.channels_count; i++)
+ fixupChannel(i);
+ initDefaultChannel(0);
+}
+
+void Channels::onConfigChanged()
+{
+ // Make sure the phone hasn't mucked anything up
+ for (int i = 0; i < devicestate.channels_count; i++) {
+ auto ch = fixupChannel(i);
+
+ if(ch.role == Channel_Role_PRIMARY)
+ primaryIndex = i;
+ }
+
+ setCrypto(0); // FIXME: for the time being (still single channel - just use our only channel as the crypto key)
+}
+
+Channel &Channels::getChannel(size_t chIndex)
+{
+ assert(chIndex < devicestate.channels_count);
+ Channel *ch = devicestate.channels + chIndex;
+ return *ch;
+}
+
+void Channels::setChannel(const Channel &c) {
+ Channel &old = getChannel(c.index);
+
+ // if this is the new primary, demote any existing roles
+ if(c.role == Channel_Role_PRIMARY)
+ for (int i = 0; i < devicestate.channels_count; i++)
+ if(devicestate.channels[i].role == Channel_Role_PRIMARY)
+ devicestate.channels[i].role = Channel_Role_SECONDARY;
+
+ old = c; // slam in the new settings/role
+}
+
+const char *Channels::getName(size_t chIndex)
+{
+ // Convert the short "" representation for Default into a usable string
+ ChannelSettings &channelSettings = getChannel(chIndex).settings;
+ const char *channelName = channelSettings.name;
+ if (!*channelName) { // emptystring
+ // Per mesh.proto spec, if bandwidth is specified we must ignore modemConfig enum, we assume that in that case
+ // the app fucked up and forgot to set channelSettings.name
+
+ if (channelSettings.bandwidth != 0)
+ channelName = "Unset";
+ else
+ switch (channelSettings.modem_config) {
+ case ChannelSettings_ModemConfig_Bw125Cr45Sf128:
+ channelName = "Medium";
+ break;
+ case ChannelSettings_ModemConfig_Bw500Cr45Sf128:
+ channelName = "ShortFast";
+ break;
+ case ChannelSettings_ModemConfig_Bw31_25Cr48Sf512:
+ channelName = "LongAlt";
+ break;
+ case ChannelSettings_ModemConfig_Bw125Cr48Sf4096:
+ channelName = "LongSlow";
+ break;
+ default:
+ channelName = "Invalid";
+ break;
+ }
+ }
+
+ return channelName;
+}
+
+/**
+* Generate a short suffix used to disambiguate channels that might have the same "name" entered by the human but different PSKs.
+* The ideas is that the PSK changing should be visible to the user so that they see they probably messed up and that's why they
+their nodes
+* aren't talking to each other.
+*
+* This string is of the form "#name-X".
+*
+* Where X is either:
+* (for custom PSKS) a letter from A to Z (base26), and formed by xoring all the bytes of the PSK together,
+* OR (for the standard minimially secure PSKs) a number from 0 to 9.
+*
+* This function will also need to be implemented in GUI apps that talk to the radio.
+*
+* https://github.com/meshtastic/Meshtastic-device/issues/269
+*/
+const char *Channels::getPrimaryName()
+{
+ static char buf[32];
+
+ char suffix;
+ auto channelSettings = getPrimary();
+ if (channelSettings.psk.size != 1) {
+ // We have a standard PSK, so generate a letter based hash.
+ uint8_t code = 0;
+ for (int i = 0; i < activePSKSize; i++)
+ code ^= activePSK[i];
+
+ suffix = 'A' + (code % 26);
+ } else {
+ suffix = '0' + channelSettings.psk.bytes[0];
+ }
+
+ snprintf(buf, sizeof(buf), "#%s-%c", channelSettings.name, suffix);
+ return buf;
+}
\ No newline at end of file
diff --git a/src/mesh/Channels.h b/src/mesh/Channels.h
new file mode 100644
index 000000000..5654fb1f2
--- /dev/null
+++ b/src/mesh/Channels.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "mesh-pb-constants.h"
+#include
+
+class Channels
+{
+ size_t primaryIndex = 0;
+
+ public:
+ const ChannelSettings &getPrimary() { return getChannel(getPrimaryIndex()).settings; }
+
+ Channel &getChannel(size_t chIndex);
+
+ /** Using the index inside the channel, update the specified channel's settings and role. If this channel is being promoted to be
+ * primary, force all other channels to be secondary.
+ */
+ void setChannel(const Channel &c);
+
+ const char *getName(size_t chIndex);
+
+ /** The index of the primary channel */
+ size_t getPrimaryIndex() const { return primaryIndex; }
+
+ /**
+ * Generate a short suffix used to disambiguate channels that might have the same "name" entered by the human but different PSKs.
+ * The ideas is that the PSK changing should be visible to the user so that they see they probably messed up and that's why they
+their nodes
+ * aren't talking to each other.
+ *
+ * This string is of the form "#name-X".
+ *
+ * Where X is either:
+ * (for custom PSKS) a letter from A to Z (base26), and formed by xoring all the bytes of the PSK together,
+ * OR (for the standard minimially secure PSKs) a number from 0 to 9.
+ *
+ * This function will also need to be implemented in GUI apps that talk to the radio.
+ *
+ * https://github.com/meshtastic/Meshtastic-device/issues/269
+ */
+ const char *getPrimaryName();
+
+ /// Called by NodeDB on initial boot when the radio config settings are unset. Set a default single channel config.
+ void initDefaults();
+
+ /// called when the user has just changed our radio config and we might need to change channel keys
+ void onConfigChanged();
+};
+
+/// Singleton channel table
+extern Channels channels;
\ No newline at end of file
diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp
index b8f0b5697..9347ef0fd 100644
--- a/src/mesh/NodeDB.cpp
+++ b/src/mesh/NodeDB.cpp
@@ -7,7 +7,6 @@
#include "CryptoEngine.h"
#include "FSCommon.h"
#include "GPS.h"
-#include "main.h"
#include "MeshRadio.h"
#include "NodeDB.h"
#include "PacketHistory.h"
@@ -16,6 +15,8 @@
#include "Router.h"
#include "configuration.h"
#include "error.h"
+#include "main.h"
+#include "Channels.h"
#include "mesh-pb-constants.h"
#include
#include
@@ -30,7 +31,6 @@ NodeDB nodeDB;
EXT_RAM_ATTR DeviceState devicestate;
MyNodeInfo &myNodeInfo = devicestate.my_node;
RadioConfig &radioConfig = devicestate.radio;
-ChannelSettings &channelSettings = radioConfig.channel_settings;
/** The current change # for radio settings. Starts at 0 on boot and any time the radio settings
* might have changed is incremented. Allows others to detect they might now be on a new channel.
@@ -64,49 +64,6 @@ static uint8_t ourMacAddr[6];
*/
NodeNum displayedNodeNum;
-/// A usable (but bigger) version of the channel name in the channelSettings object
-const char *channelName;
-
-/// A usable psk - which has been constructed based on the (possibly short psk) in channelSettings
-static uint8_t activePSK[32];
-static uint8_t activePSKSize;
-
-/**
- * Generate a short suffix used to disambiguate channels that might have the same "name" entered by the human but different PSKs.
- * The ideas is that the PSK changing should be visible to the user so that they see they probably messed up and that's why they
-their nodes
- * aren't talking to each other.
- *
- * This string is of the form "#name-X".
- *
- * Where X is either:
- * (for custom PSKS) a letter from A to Z (base26), and formed by xoring all the bytes of the PSK together,
- * OR (for the standard minimially secure PSKs) a number from 0 to 9.
- *
- * This function will also need to be implemented in GUI apps that talk to the radio.
- *
- * https://github.com/meshtastic/Meshtastic-device/issues/269
- */
-const char *getChannelName()
-{
- static char buf[32];
-
- char suffix;
- if (channelSettings.psk.size != 1) {
- // We have a standard PSK, so generate a letter based hash.
- uint8_t code = 0;
- for (int i = 0; i < activePSKSize; i++)
- code ^= activePSK[i];
-
- suffix = 'A' + (code % 26);
- } else {
- suffix = '0' + channelSettings.psk.bytes[0];
- }
-
- snprintf(buf, sizeof(buf), "#%s-%c", channelName, suffix);
- return buf;
-}
-
NodeDB::NodeDB() : nodes(devicestate.node_db), numNodes(&devicestate.node_db_count) {}
bool NodeDB::resetRadioConfig()
@@ -115,104 +72,19 @@ bool NodeDB::resetRadioConfig()
radioGeneration++;
- /// 16 bytes of random PSK for our _public_ default channel that all devices power up on (AES128)
- static const uint8_t defaultpsk[] = {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59,
- 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0xbf};
-
if (radioConfig.preferences.factory_reset) {
DEBUG_MSG("Performing factory reset!\n");
installDefaultDeviceState();
didFactoryReset = true;
- } else if (!channelSettings.psk.size) {
- DEBUG_MSG("Setting default preferences!\n");
+ } else if (devicestate.channels_count == 0) {
+ DEBUG_MSG("Setting default channel and radio preferences!\n");
+
+ channels.initDefaults();
- radioConfig.has_channel_settings = true;
radioConfig.has_preferences = true;
-
- // radioConfig.modem_config = RadioConfig_ModemConfig_Bw125Cr45Sf128; // medium range and fast
- // channelSettings.modem_config = ChannelSettings_ModemConfig_Bw500Cr45Sf128; // short range and fast, but wide
- // bandwidth so incompatible radios can talk together
- channelSettings.modem_config = ChannelSettings_ModemConfig_Bw125Cr48Sf4096; // slow and long range
-
- channelSettings.tx_power = 0; // default
- uint8_t defaultpskIndex = 1;
- channelSettings.psk.bytes[0] = defaultpskIndex;
- channelSettings.psk.size = 1;
- strcpy(channelSettings.name, "");
}
- // Convert the old string "Default" to our new short representation
- if (strcmp(channelSettings.name, "Default") == 0)
- *channelSettings.name = '\0';
-
- // Convert the short "" representation for Default into a usable string
- channelName = channelSettings.name;
- if (!*channelName) { // emptystring
- // Per mesh.proto spec, if bandwidth is specified we must ignore modemConfig enum, we assume that in that case
- // the app fucked up and forgot to set channelSettings.name
-
- if (channelSettings.bandwidth != 0)
- channelName = "Unset";
- else
- switch (channelSettings.modem_config) {
- case ChannelSettings_ModemConfig_Bw125Cr45Sf128:
- channelName = "Medium";
- break;
- case ChannelSettings_ModemConfig_Bw500Cr45Sf128:
- channelName = "ShortFast";
- break;
- case ChannelSettings_ModemConfig_Bw31_25Cr48Sf512:
- channelName = "LongAlt";
- break;
- case ChannelSettings_ModemConfig_Bw125Cr48Sf4096:
- channelName = "LongSlow";
- break;
- default:
- channelName = "Invalid";
- break;
- }
- }
-
- // Convert any old usage of the defaultpsk into our new short representation.
- if (channelSettings.psk.size == sizeof(defaultpsk) &&
- memcmp(channelSettings.psk.bytes, defaultpsk, sizeof(defaultpsk)) == 0) {
- *channelSettings.psk.bytes = 1;
- channelSettings.psk.size = 1;
- }
-
- memset(activePSK, 0, sizeof(activePSK)); // In case the user provided a short key, we want to pad the rest with zeros
- memcpy(activePSK, channelSettings.psk.bytes, channelSettings.psk.size);
- activePSKSize = channelSettings.psk.size;
- if(activePSKSize == 0)
- DEBUG_MSG("Warning: User disabled encryption\n");
- else if (activePSKSize == 1) {
- // Convert the short single byte variants of psk into variant that can be used more generally
-
- uint8_t pskIndex = activePSK[0];
- DEBUG_MSG("Expanding short PSK #%d\n", pskIndex);
- if (pskIndex == 0)
- activePSKSize = 0; // Turn off encryption
- else {
- memcpy(activePSK, defaultpsk, sizeof(defaultpsk));
- activePSKSize = sizeof(defaultpsk);
- // Bump up the last byte of PSK as needed
- uint8_t *last = activePSK + sizeof(defaultpsk) - 1;
- *last = *last + pskIndex - 1; // index of 1 means no change vs defaultPSK
- }
- } else if(activePSKSize < 16) {
- // Error! The user specified only the first few bits of an AES128 key. So by convention we just pad the rest of the key
- // with zeros
- DEBUG_MSG("Warning: User provided a too short AES128 key - padding\n");
- activePSKSize = 16;
- } else if(activePSKSize < 32 && activePSKSize != 16) {
- // Error! The user specified only the first few bits of an AES256 key. So by convention we just pad the rest of the key
- // with zeros
- DEBUG_MSG("Warning: User provided a too short AES256 key - padding\n");
- activePSKSize = 32;
- }
-
- // Tell our crypto engine about the psk
- crypto->setKey(activePSKSize, activePSK);
+ channels.onConfigChanged();
// temp hack for quicker testing
// devicestate.no_save = true;
@@ -251,7 +123,6 @@ void NodeDB::installDefaultDeviceState()
devicestate.has_my_node = true;
devicestate.has_radio = true;
devicestate.has_owner = true;
- devicestate.radio.has_channel_settings = true;
devicestate.radio.has_preferences = true;
devicestate.node_db_count = 0;
devicestate.receive_queue_count = 0; // Not yet implemented FIXME
@@ -289,17 +160,14 @@ void NodeDB::init()
loadFromDisk();
// saveToDisk();
- // We set node_num and packet_id _after_ loading from disk, because we always want to use the values this
- // rom was compiled for, not what happens to be in the save file.
- myNodeInfo.node_num_bits = sizeof(NodeNum) * 8;
- myNodeInfo.packet_id_bits = sizeof(PacketId) * 8;
+ myNodeInfo.max_channels = MAX_CHANNELS; // tell others the max # of channels we can understand
myNodeInfo.error_code =
CriticalErrorCode_None; // For the error code, only show values from this boot (discard value from flash)
myNodeInfo.error_address = 0;
// likewise - we always want the app requirements to come from the running appload
- myNodeInfo.min_app_version = 20120; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
+ myNodeInfo.min_app_version = 20200; // format is Mmmss (where M is 1+the numeric major number. i.e. 20120 means 1.1.20
// Note! We do this after loading saved settings, so that if somehow an invalid nodenum was stored in preferences we won't
// keep using that nodenum forever. Crummy guess at our nodenum (but we will check against the nodedb to avoid conflicts)
@@ -539,12 +407,6 @@ void NodeDB::updateFrom(const MeshPacket &mp)
info->snr = mp.rx_snr; // keep the most recent SNR we received for this node.
switch (p.which_payloadVariant) {
- case SubPacket_position_tag: {
- // handle a legacy position packet
- DEBUG_MSG("WARNING: Processing a (deprecated) position packet from %d\n", mp.from);
- updatePosition(mp.from, p.position);
- break;
- }
case SubPacket_data_tag: {
if (mp.to == NODENUM_BROADCAST || mp.to == nodeDB.getNodeNum())
@@ -552,12 +414,6 @@ void NodeDB::updateFrom(const MeshPacket &mp)
break;
}
- case SubPacket_user_tag: {
- DEBUG_MSG("WARNING: Processing a (deprecated) user packet from %d\n", mp.from);
- updateUser(mp.from, p.user);
- break;
- }
-
default: {
notifyObservers(); // If the node counts have changed, notify observers
}
@@ -601,10 +457,9 @@ void recordCriticalError(CriticalErrorCode code, uint32_t address)
String lcd = String("Critical error ") + code + "!\n";
screen->print(lcd.c_str());
DEBUG_MSG("NOTE! Recording critical error %d, address=%lx\n", code, address);
-
+
// Record error to DB
myNodeInfo.error_code = code;
myNodeInfo.error_address = address;
myNodeInfo.error_count++;
-
}
diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h
index 5174f5642..29c35369f 100644
--- a/src/mesh/NodeDB.h
+++ b/src/mesh/NodeDB.h
@@ -11,9 +11,7 @@
extern DeviceState devicestate;
extern MyNodeInfo &myNodeInfo;
extern RadioConfig &radioConfig;
-extern ChannelSettings &channelSettings;
extern User &owner;
-extern const char *channelName;
/// Given a node, return how many seconds in the past (vs now) that we last heard from it
uint32_t sinceLastSeen(const NodeInfo *n);
@@ -130,23 +128,6 @@ extern NodeNum displayedNodeNum;
extern NodeDB nodeDB;
-/**
- * Generate a short suffix used to disambiguate channels that might have the same "name" entered by the human but different PSKs.
- * The ideas is that the PSK changing should be visible to the user so that they see they probably messed up and that's why they
-their nodes
- * aren't talking to each other.
- *
- * This string is of the form "#name-XY".
- *
- * Where X is a letter from A to Z (base26), and formed by xoring all the bytes of the PSK together.
- * Y is not yet used but should eventually indicate 'speed/range' of the link
- *
- * This function will also need to be implemented in GUI apps that talk to the radio.
- *
- * https://github.com/meshtastic/Meshtastic-device/issues/269
- */
-const char *getChannelName();
-
/*
If is_router is set, we use a number of different default values
diff --git a/src/mesh/PhoneAPI.cpp b/src/mesh/PhoneAPI.cpp
index f9c9b6175..6ec09b2ca 100644
--- a/src/mesh/PhoneAPI.cpp
+++ b/src/mesh/PhoneAPI.cpp
@@ -4,6 +4,7 @@
#include "NodeDB.h"
#include "PowerFSM.h"
#include "RadioInterface.h"
+#include "Channels.h"
#include
#if FromRadio_size > MAX_TO_FROM_RADIO_SIZE
@@ -279,9 +280,9 @@ void PhoneAPI::handleSetOwner(const User &o)
service.reloadOwner();
}
-void PhoneAPI::handleSetChannel(const ChannelSettings &cc)
+void PhoneAPI::handleSetChannel(const Channel &cc)
{
- radioConfig.channel_settings = cc;
+ channels.setChannel(cc);
bool didReset = service.reloadConfig();
if (didReset) {
diff --git a/src/mesh/PhoneAPI.h b/src/mesh/PhoneAPI.h
index 663d6824c..6d4e8d626 100644
--- a/src/mesh/PhoneAPI.h
+++ b/src/mesh/PhoneAPI.h
@@ -83,14 +83,6 @@ class PhoneAPI
*/
bool available();
- //
- // The following routines are only public for now - until the rev1 bluetooth API is removed
- //
-
- void handleSetOwner(const User &o);
- void handleSetChannel(const ChannelSettings &cc);
- void handleSetRadio(const RadioConfig &r);
-
protected:
/// Are we currently connected to a client?
bool isConnected = false;
@@ -109,6 +101,10 @@ class PhoneAPI
*/
virtual void onNowHasData(uint32_t fromRadioNum) {}
+ void handleSetOwner(const User &o);
+ void handleSetChannel(const Channel &cc);
+ void handleSetRadio(const RadioConfig &r);
+
private:
/**
* Handle a packet that the phone wants us to send. It is our responsibility to free the packet to the pool
diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp
index 0884c260d..0d99ca2ff 100644
--- a/src/mesh/RadioInterface.cpp
+++ b/src/mesh/RadioInterface.cpp
@@ -6,6 +6,7 @@
#include "assert.h"
#include "configuration.h"
#include "sleep.h"
+#include "Channels.h"
#include
#include
#include
@@ -36,7 +37,7 @@ void initRegion()
myRegion = r;
DEBUG_MSG("Wanted region %d, using %s\n", radioConfig.preferences.region, r->name);
- myNodeInfo.num_channels = myRegion->numChannels; // Tell our android app how many channels we have
+ myNodeInfo.num_bands = myRegion->numChannels; // Tell our android app how many channels we have
}
/**
@@ -125,12 +126,6 @@ void printPacket(const char *prefix, const MeshPacket *p)
case SubPacket_data_tag:
DEBUG_MSG(" Portnum=%d", s.data.portnum);
break;
- case SubPacket_position_tag:
- DEBUG_MSG(" Payload:Position");
- break;
- case SubPacket_user_tag:
- DEBUG_MSG(" Payload:User");
- break;
case 0:
DEBUG_MSG(" Payload:None");
break;
@@ -252,6 +247,7 @@ void RadioInterface::applyModemConfig()
// Set up default configuration
// No Sync Words in LORA mode
+ auto channelSettings = channels.getPrimary();
if (channelSettings.spread_factor == 0) {
switch (channelSettings.modem_config) {
case ChannelSettings_ModemConfig_Bw125Cr45Sf128: ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium
@@ -296,7 +292,8 @@ void RadioInterface::applyModemConfig()
assert(myRegion); // Should have been found in init
// If user has manually specified a channel num, then use that, otherwise generate one by hashing the name
- int channel_num = (channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName)) % myRegion->numChannels;
+ const char *channelName = channels.getName(channels.getPrimaryIndex());
+ int channel_num = channelSettings.channel_num ? channelSettings.channel_num - 1 : hash(channelName) % myRegion->numChannels;
freq = myRegion->freq + myRegion->spacing * channel_num;
DEBUG_MSG("Set radio: name=%s, config=%u, ch=%d, power=%d\n", channelName, channelSettings.modem_config, channel_num, power);
diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp
index 43d939c31..5178e229b 100644
--- a/src/mesh/Router.cpp
+++ b/src/mesh/Router.cpp
@@ -80,7 +80,6 @@ PacketId generatePacketId()
i++;
PacketId id = (i % numPacketId) + 1; // return number between 1 and numPacketId (ie - never zero)
- myNodeInfo.current_packet_id = id; // Kinda crufty - we keep updating this so the phone can see a current value
return id;
}
diff --git a/src/mesh/generated/deviceonly.pb.h b/src/mesh/generated/deviceonly.pb.h
index 99d838d39..e1f4c4010 100644
--- a/src/mesh/generated/deviceonly.pb.h
+++ b/src/mesh/generated/deviceonly.pb.h
@@ -27,8 +27,8 @@ typedef struct _DeviceState {
uint32_t version;
bool no_save;
bool did_gps_reset;
- pb_size_t secondary_channels_count;
- ChannelSettings secondary_channels[7];
+ pb_size_t channels_count;
+ Channel channels[8];
} DeviceState;
@@ -37,8 +37,8 @@ extern "C" {
#endif
/* Initializer values for message structs */
-#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0, 0, {ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default, ChannelSettings_init_default}}
-#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0, 0, {ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero, ChannelSettings_init_zero}}
+#define DeviceState_init_default {false, RadioConfig_init_default, false, MyNodeInfo_init_default, false, User_init_default, 0, {NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default, NodeInfo_init_default}, 0, {MeshPacket_init_default}, false, MeshPacket_init_default, 0, 0, 0, 0, {Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default, Channel_init_default}}
+#define DeviceState_init_zero {false, RadioConfig_init_zero, false, MyNodeInfo_init_zero, false, User_init_zero, 0, {NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero, NodeInfo_init_zero}, 0, {MeshPacket_init_zero}, false, MeshPacket_init_zero, 0, 0, 0, 0, {Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero, Channel_init_zero}}
/* Field tags (for use in manual encoding/decoding) */
#define DeviceState_radio_tag 1
@@ -50,7 +50,7 @@ extern "C" {
#define DeviceState_version_tag 8
#define DeviceState_no_save_tag 9
#define DeviceState_did_gps_reset_tag 11
-#define DeviceState_secondary_channels_tag 12
+#define DeviceState_channels_tag 12
/* Struct field encoding specification for nanopb */
#define DeviceState_FIELDLIST(X, a) \
@@ -63,7 +63,7 @@ X(a, STATIC, OPTIONAL, MESSAGE, rx_text_message, 7) \
X(a, STATIC, SINGULAR, UINT32, version, 8) \
X(a, STATIC, SINGULAR, BOOL, no_save, 9) \
X(a, STATIC, SINGULAR, BOOL, did_gps_reset, 11) \
-X(a, STATIC, REPEATED, MESSAGE, secondary_channels, 12)
+X(a, STATIC, REPEATED, MESSAGE, channels, 12)
#define DeviceState_CALLBACK NULL
#define DeviceState_DEFAULT NULL
#define DeviceState_radio_MSGTYPE RadioConfig
@@ -72,7 +72,7 @@ X(a, STATIC, REPEATED, MESSAGE, secondary_channels, 12)
#define DeviceState_node_db_MSGTYPE NodeInfo
#define DeviceState_receive_queue_MSGTYPE MeshPacket
#define DeviceState_rx_text_message_MSGTYPE MeshPacket
-#define DeviceState_secondary_channels_MSGTYPE ChannelSettings
+#define DeviceState_channels_MSGTYPE Channel
extern const pb_msgdesc_t DeviceState_msg;
@@ -80,10 +80,10 @@ extern const pb_msgdesc_t DeviceState_msg;
#define DeviceState_fields &DeviceState_msg
/* Maximum encoded size of messages (where known) */
-#define DeviceState_size 6266
+#define DeviceState_size 6265
#ifdef __cplusplus
} /* extern "C" */
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/src/mesh/generated/mesh.pb.c b/src/mesh/generated/mesh.pb.c
index 0bf5fbe38..872447623 100644
--- a/src/mesh/generated/mesh.pb.c
+++ b/src/mesh/generated/mesh.pb.c
@@ -27,6 +27,9 @@ PB_BIND(MeshPacket, MeshPacket, 2)
PB_BIND(ChannelSettings, ChannelSettings, AUTO)
+PB_BIND(Channel, Channel, AUTO)
+
+
PB_BIND(RadioConfig, RadioConfig, 2)
@@ -59,3 +62,4 @@ PB_BIND(ToRadio, ToRadio, 2)
+
diff --git a/src/mesh/generated/mesh.pb.h b/src/mesh/generated/mesh.pb.h
index 397a313ea..691b4cd78 100644
--- a/src/mesh/generated/mesh.pb.h
+++ b/src/mesh/generated/mesh.pb.h
@@ -100,6 +100,12 @@ typedef enum _ChannelSettings_ModemConfig {
ChannelSettings_ModemConfig_Bw125Cr48Sf4096 = 3
} ChannelSettings_ModemConfig;
+typedef enum _Channel_Role {
+ Channel_Role_DISABLED = 0,
+ Channel_Role_PRIMARY = 1,
+ Channel_Role_SECONDARY = 2
+} Channel_Role;
+
typedef enum _LogRecord_Level {
LogRecord_Level_UNSET = 0,
LogRecord_Level_CRITICAL = 50,
@@ -142,25 +148,23 @@ typedef struct _LogRecord {
typedef struct _MyNodeInfo {
uint32_t my_node_num;
bool has_gps;
- int32_t num_channels;
+ uint32_t num_bands;
char region[12];
char hw_model[16];
char firmware_version[12];
CriticalErrorCode error_code;
uint32_t error_address;
uint32_t error_count;
- uint32_t packet_id_bits;
- uint32_t current_packet_id;
- uint32_t node_num_bits;
uint32_t message_timeout_msec;
uint32_t min_app_version;
+ uint32_t max_channels;
} MyNodeInfo;
typedef struct _Position {
- int32_t altitude;
- int32_t battery_level;
int32_t latitude_i;
int32_t longitude_i;
+ int32_t altitude;
+ int32_t battery_level;
uint32_t time;
} Position;
@@ -222,6 +226,13 @@ typedef struct _User {
pb_byte_t macaddr[6];
} User;
+typedef struct _Channel {
+ uint32_t index;
+ bool has_settings;
+ ChannelSettings settings;
+ Channel_Role role;
+} Channel;
+
typedef struct _NodeInfo {
uint32_t num;
bool has_user;
@@ -235,21 +246,17 @@ typedef struct _NodeInfo {
typedef struct _RadioConfig {
bool has_preferences;
RadioConfig_UserPreferences preferences;
- bool has_channel_settings;
- ChannelSettings channel_settings;
} RadioConfig;
typedef struct _SubPacket {
+ uint32_t original_id;
pb_size_t which_payloadVariant;
union {
- Position position;
Data data;
- User user;
RouteDiscovery route_request;
RouteDiscovery route_reply;
ErrorReason error_reason;
};
- uint32_t original_id;
bool want_response;
uint32_t dest;
pb_size_t which_ackVariant;
@@ -289,7 +296,7 @@ typedef struct _FromRadio {
LogRecord log_record;
uint32_t config_complete_id;
bool rebooted;
- ChannelSettings channel;
+ Channel channel;
};
} FromRadio;
@@ -300,7 +307,7 @@ typedef struct _ToRadio {
uint32_t want_config_id;
RadioConfig set_radio;
User set_owner;
- ChannelSettings set_channel;
+ Channel set_channel;
};
} ToRadio;
@@ -342,6 +349,10 @@ typedef struct _ToRadio {
#define _ChannelSettings_ModemConfig_MAX ChannelSettings_ModemConfig_Bw125Cr48Sf4096
#define _ChannelSettings_ModemConfig_ARRAYSIZE ((ChannelSettings_ModemConfig)(ChannelSettings_ModemConfig_Bw125Cr48Sf4096+1))
+#define _Channel_Role_MIN Channel_Role_DISABLED
+#define _Channel_Role_MAX Channel_Role_SECONDARY
+#define _Channel_Role_ARRAYSIZE ((Channel_Role)(Channel_Role_SECONDARY+1))
+
#define _LogRecord_Level_MIN LogRecord_Level_UNSET
#define _LogRecord_Level_MAX LogRecord_Level_CRITICAL
#define _LogRecord_Level_ARRAYSIZE ((LogRecord_Level)(LogRecord_Level_CRITICAL+1))
@@ -356,13 +367,14 @@ extern "C" {
#define Data_init_default {_PortNum_MIN, {0, {0}}}
#define User_init_default {"", "", "", {0}}
#define RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}}
-#define SubPacket_init_default {0, {Position_init_default}, 0, 0, 0, 0, {0}, 0}
+#define SubPacket_init_default {0, 0, {Data_init_default}, 0, 0, 0, {0}, 0}
#define MeshPacket_init_default {0, 0, 0, {SubPacket_init_default}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN}
#define ChannelSettings_init_default {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
-#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default, false, ChannelSettings_init_default}
+#define Channel_init_default {0, false, ChannelSettings_init_default, _Channel_Role_MIN}
+#define RadioConfig_init_default {false, RadioConfig_UserPreferences_init_default}
#define RadioConfig_UserPreferences_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define NodeInfo_init_default {0, false, User_init_default, false, Position_init_default, 0, 0}
-#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0}
+#define MyNodeInfo_init_default {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0}
#define LogRecord_init_default {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_default {0, 0, {MeshPacket_init_default}}
#define ToRadio_init_default {0, {MeshPacket_init_default}}
@@ -370,13 +382,14 @@ extern "C" {
#define Data_init_zero {_PortNum_MIN, {0, {0}}}
#define User_init_zero {"", "", "", {0}}
#define RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}}
-#define SubPacket_init_zero {0, {Position_init_zero}, 0, 0, 0, 0, {0}, 0}
+#define SubPacket_init_zero {0, 0, {Data_init_zero}, 0, 0, 0, {0}, 0}
#define MeshPacket_init_zero {0, 0, 0, {SubPacket_init_zero}, 0, 0, 0, 0, 0, 0, _MeshPacket_Priority_MIN}
#define ChannelSettings_init_zero {0, _ChannelSettings_ModemConfig_MIN, {0, {0}}, "", 0, 0, 0, 0, 0, 0, 0}
-#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero, false, ChannelSettings_init_zero}
+#define Channel_init_zero {0, false, ChannelSettings_init_zero, _Channel_Role_MIN}
+#define RadioConfig_init_zero {false, RadioConfig_UserPreferences_init_zero}
#define RadioConfig_UserPreferences_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, _RegionCode_MIN, _ChargeCurrent_MIN, _LocationSharing_MIN, _GpsOperation_MIN, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define NodeInfo_init_zero {0, false, User_init_zero, false, Position_init_zero, 0, 0}
-#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0, 0, 0}
+#define MyNodeInfo_init_zero {0, 0, 0, "", "", "", _CriticalErrorCode_MIN, 0, 0, 0, 0, 0}
#define LogRecord_init_zero {"", 0, "", _LogRecord_Level_MIN}
#define FromRadio_init_zero {0, 0, {MeshPacket_init_zero}}
#define ToRadio_init_zero {0, {MeshPacket_init_zero}}
@@ -401,22 +414,20 @@ extern "C" {
#define LogRecord_level_tag 4
#define MyNodeInfo_my_node_num_tag 1
#define MyNodeInfo_has_gps_tag 2
-#define MyNodeInfo_num_channels_tag 3
+#define MyNodeInfo_num_bands_tag 3
#define MyNodeInfo_region_tag 4
#define MyNodeInfo_hw_model_tag 5
#define MyNodeInfo_firmware_version_tag 6
#define MyNodeInfo_error_code_tag 7
#define MyNodeInfo_error_address_tag 8
#define MyNodeInfo_error_count_tag 9
-#define MyNodeInfo_packet_id_bits_tag 10
-#define MyNodeInfo_current_packet_id_tag 11
-#define MyNodeInfo_node_num_bits_tag 12
#define MyNodeInfo_message_timeout_msec_tag 13
#define MyNodeInfo_min_app_version_tag 14
+#define MyNodeInfo_max_channels_tag 15
+#define Position_latitude_i_tag 1
+#define Position_longitude_i_tag 2
#define Position_altitude_tag 3
#define Position_battery_level_tag 4
-#define Position_latitude_i_tag 7
-#define Position_longitude_i_tag 8
#define Position_time_tag 9
#define RadioConfig_UserPreferences_position_broadcast_secs_tag 1
#define RadioConfig_UserPreferences_send_owner_interval_tag 2
@@ -465,20 +476,20 @@ extern "C" {
#define User_long_name_tag 2
#define User_short_name_tag 3
#define User_macaddr_tag 4
+#define Channel_index_tag 1
+#define Channel_settings_tag 2
+#define Channel_role_tag 3
#define NodeInfo_num_tag 1
#define NodeInfo_user_tag 2
#define NodeInfo_position_tag 3
#define NodeInfo_next_hop_tag 5
#define NodeInfo_snr_tag 7
#define RadioConfig_preferences_tag 1
-#define RadioConfig_channel_settings_tag 2
-#define SubPacket_position_tag 1
+#define SubPacket_original_id_tag 2
#define SubPacket_data_tag 3
-#define SubPacket_user_tag 4
#define SubPacket_route_request_tag 6
#define SubPacket_route_reply_tag 7
#define SubPacket_error_reason_tag 13
-#define SubPacket_original_id_tag 2
#define SubPacket_want_response_tag 5
#define SubPacket_dest_tag 9
#define SubPacket_success_id_tag 10
@@ -508,14 +519,14 @@ extern "C" {
#define ToRadio_want_config_id_tag 100
#define ToRadio_set_radio_tag 101
#define ToRadio_set_owner_tag 102
-#define ToRadio_set_channel_tag 103
+#define ToRadio_set_channel_tag 104
/* Struct field encoding specification for nanopb */
#define Position_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 1) \
+X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 2) \
X(a, STATIC, SINGULAR, INT32, altitude, 3) \
X(a, STATIC, SINGULAR, INT32, battery_level, 4) \
-X(a, STATIC, SINGULAR, SINT32, latitude_i, 7) \
-X(a, STATIC, SINGULAR, SINT32, longitude_i, 8) \
X(a, STATIC, SINGULAR, FIXED32, time, 9)
#define Position_CALLBACK NULL
#define Position_DEFAULT NULL
@@ -540,13 +551,11 @@ X(a, STATIC, REPEATED, INT32, route, 2)
#define RouteDiscovery_DEFAULT NULL
#define SubPacket_FIELDLIST(X, a) \
-X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,position,position), 1) \
+X(a, STATIC, SINGULAR, UINT32, original_id, 2) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,data,data), 3) \
-X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,user,user), 4) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,route_request,route_request), 6) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,route_reply,route_reply), 7) \
X(a, STATIC, ONEOF, UENUM, (payloadVariant,error_reason,error_reason), 13) \
-X(a, STATIC, SINGULAR, UINT32, original_id, 2) \
X(a, STATIC, SINGULAR, BOOL, want_response, 5) \
X(a, STATIC, SINGULAR, UINT32, dest, 9) \
X(a, STATIC, ONEOF, UINT32, (ackVariant,success_id,ackVariant.success_id), 10) \
@@ -554,9 +563,7 @@ X(a, STATIC, ONEOF, UINT32, (ackVariant,fail_id,ackVariant.fail_id), 11)
X(a, STATIC, SINGULAR, UINT32, source, 12)
#define SubPacket_CALLBACK NULL
#define SubPacket_DEFAULT NULL
-#define SubPacket_payloadVariant_position_MSGTYPE Position
#define SubPacket_payloadVariant_data_MSGTYPE Data
-#define SubPacket_payloadVariant_user_MSGTYPE User
#define SubPacket_payloadVariant_route_request_MSGTYPE RouteDiscovery
#define SubPacket_payloadVariant_route_reply_MSGTYPE RouteDiscovery
@@ -591,13 +598,19 @@ X(a, STATIC, SINGULAR, BOOL, downlink_enabled, 17)
#define ChannelSettings_CALLBACK NULL
#define ChannelSettings_DEFAULT NULL
+#define Channel_FIELDLIST(X, a) \
+X(a, STATIC, SINGULAR, UINT32, index, 1) \
+X(a, STATIC, OPTIONAL, MESSAGE, settings, 2) \
+X(a, STATIC, SINGULAR, UENUM, role, 3)
+#define Channel_CALLBACK NULL
+#define Channel_DEFAULT NULL
+#define Channel_settings_MSGTYPE ChannelSettings
+
#define RadioConfig_FIELDLIST(X, a) \
-X(a, STATIC, OPTIONAL, MESSAGE, preferences, 1) \
-X(a, STATIC, OPTIONAL, MESSAGE, channel_settings, 2)
+X(a, STATIC, OPTIONAL, MESSAGE, preferences, 1)
#define RadioConfig_CALLBACK NULL
#define RadioConfig_DEFAULT NULL
#define RadioConfig_preferences_MSGTYPE RadioConfig_UserPreferences
-#define RadioConfig_channel_settings_MSGTYPE ChannelSettings
#define RadioConfig_UserPreferences_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, position_broadcast_secs, 1) \
@@ -659,18 +672,16 @@ X(a, STATIC, SINGULAR, FLOAT, snr, 7)
#define MyNodeInfo_FIELDLIST(X, a) \
X(a, STATIC, SINGULAR, UINT32, my_node_num, 1) \
X(a, STATIC, SINGULAR, BOOL, has_gps, 2) \
-X(a, STATIC, SINGULAR, INT32, num_channels, 3) \
+X(a, STATIC, SINGULAR, UINT32, num_bands, 3) \
X(a, STATIC, SINGULAR, STRING, region, 4) \
X(a, STATIC, SINGULAR, STRING, hw_model, 5) \
X(a, STATIC, SINGULAR, STRING, firmware_version, 6) \
X(a, STATIC, SINGULAR, UENUM, error_code, 7) \
X(a, STATIC, SINGULAR, UINT32, error_address, 8) \
X(a, STATIC, SINGULAR, UINT32, error_count, 9) \
-X(a, STATIC, SINGULAR, UINT32, packet_id_bits, 10) \
-X(a, STATIC, SINGULAR, UINT32, current_packet_id, 11) \
-X(a, STATIC, SINGULAR, UINT32, node_num_bits, 12) \
X(a, STATIC, SINGULAR, UINT32, message_timeout_msec, 13) \
-X(a, STATIC, SINGULAR, UINT32, min_app_version, 14)
+X(a, STATIC, SINGULAR, UINT32, min_app_version, 14) \
+X(a, STATIC, SINGULAR, UINT32, max_channels, 15)
#define MyNodeInfo_CALLBACK NULL
#define MyNodeInfo_DEFAULT NULL
@@ -699,20 +710,20 @@ X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,channel,channel), 10)
#define FromRadio_payloadVariant_node_info_MSGTYPE NodeInfo
#define FromRadio_payloadVariant_radio_MSGTYPE RadioConfig
#define FromRadio_payloadVariant_log_record_MSGTYPE LogRecord
-#define FromRadio_payloadVariant_channel_MSGTYPE ChannelSettings
+#define FromRadio_payloadVariant_channel_MSGTYPE Channel
#define ToRadio_FIELDLIST(X, a) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,packet,packet), 1) \
X(a, STATIC, ONEOF, UINT32, (payloadVariant,want_config_id,want_config_id), 100) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_radio,set_radio), 101) \
X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_owner,set_owner), 102) \
-X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_channel,set_channel), 103)
+X(a, STATIC, ONEOF, MESSAGE, (payloadVariant,set_channel,set_channel), 104)
#define ToRadio_CALLBACK NULL
#define ToRadio_DEFAULT NULL
#define ToRadio_payloadVariant_packet_MSGTYPE MeshPacket
#define ToRadio_payloadVariant_set_radio_MSGTYPE RadioConfig
#define ToRadio_payloadVariant_set_owner_MSGTYPE User
-#define ToRadio_payloadVariant_set_channel_MSGTYPE ChannelSettings
+#define ToRadio_payloadVariant_set_channel_MSGTYPE Channel
extern const pb_msgdesc_t Position_msg;
extern const pb_msgdesc_t Data_msg;
@@ -721,6 +732,7 @@ extern const pb_msgdesc_t RouteDiscovery_msg;
extern const pb_msgdesc_t SubPacket_msg;
extern const pb_msgdesc_t MeshPacket_msg;
extern const pb_msgdesc_t ChannelSettings_msg;
+extern const pb_msgdesc_t Channel_msg;
extern const pb_msgdesc_t RadioConfig_msg;
extern const pb_msgdesc_t RadioConfig_UserPreferences_msg;
extern const pb_msgdesc_t NodeInfo_msg;
@@ -737,6 +749,7 @@ extern const pb_msgdesc_t ToRadio_msg;
#define SubPacket_fields &SubPacket_msg
#define MeshPacket_fields &MeshPacket_msg
#define ChannelSettings_fields &ChannelSettings_msg
+#define Channel_fields &Channel_msg
#define RadioConfig_fields &RadioConfig_msg
#define RadioConfig_UserPreferences_fields &RadioConfig_UserPreferences_msg
#define NodeInfo_fields &NodeInfo_msg
@@ -746,20 +759,21 @@ extern const pb_msgdesc_t ToRadio_msg;
#define ToRadio_fields &ToRadio_msg
/* Maximum encoded size of messages (where known) */
-#define Position_size 39
+#define Position_size 37
#define Data_size 246
#define User_size 72
#define RouteDiscovery_size 88
#define SubPacket_size 275
#define MeshPacket_size 322
#define ChannelSettings_size 95
-#define RadioConfig_size 405
+#define Channel_size 105
+#define RadioConfig_size 308
#define RadioConfig_UserPreferences_size 305
-#define NodeInfo_size 132
-#define MyNodeInfo_size 106
+#define NodeInfo_size 130
+#define MyNodeInfo_size 89
#define LogRecord_size 81
-#define FromRadio_size 414
-#define ToRadio_size 409
+#define FromRadio_size 331
+#define ToRadio_size 325
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/mesh/mesh-pb-constants.h b/src/mesh/mesh-pb-constants.h
index fd3b2cedf..ed1c4f7e8 100644
--- a/src/mesh/mesh-pb-constants.h
+++ b/src/mesh/mesh-pb-constants.h
@@ -16,6 +16,9 @@
/// max number of nodes allowed in the mesh
#define MAX_NUM_NODES (member_size(DeviceState, node_db) / member_size(DeviceState, node_db[0]))
+/// Max number of channels allowed
+#define MAX_CHANNELS (member_size(DeviceState, channels) / member_size(DeviceState, channels[0]))
+
/// helper function for encoding a record as a protobuf, any failures to encode are fatal and we will panic
/// returns the encoded packet size
size_t pb_encode_to_bytes(uint8_t *destbuf, size_t destbufsize, const pb_msgdesc_t *fields, const void *src_struct);
diff --git a/src/plugins/RangeTestPlugin.cpp b/src/plugins/RangeTestPlugin.cpp
index 8f03589c2..58150f5bb 100644
--- a/src/plugins/RangeTestPlugin.cpp
+++ b/src/plugins/RangeTestPlugin.cpp
@@ -145,8 +145,9 @@ bool RangeTestPluginRadio::handleReceived(const MeshPacket &mp)
DEBUG_MSG("mp.from %d\n", mp.from);
DEBUG_MSG("mp.rx_snr %f\n", mp.rx_snr);
DEBUG_MSG("mp.hop_limit %d\n", mp.hop_limit);
- DEBUG_MSG("mp.decoded.position.latitude_i %d\n", mp.decoded.position.latitude_i);
- DEBUG_MSG("mp.decoded.position.longitude_i %d\n", mp.decoded.position.longitude_i);
+ //deprecated and unpopulated for sometime
+ //DEBUG_MSG("mp.decoded.position.latitude_i %d\n", mp.decoded.position.latitude_i);
+ //DEBUG_MSG("mp.decoded.position.longitude_i %d\n", mp.decoded.position.longitude_i);
DEBUG_MSG("---- Node Information of Received Packet (mp.from):\n");
DEBUG_MSG("n->user.long_name %s\n", n->user.long_name);
DEBUG_MSG("n->user.short_name %s\n", n->user.short_name);