From 45caf394f0fa84c37b731d04b98cfb8c2d4120e3 Mon Sep 17 00:00:00 2001 From: Kevin Hester Date: Tue, 16 Feb 2021 15:41:52 +0800 Subject: [PATCH] WIP multichannel support --- .vscode/settings.json | 10 +- docs/software/TODO.md | 18 +++ proto | 2 +- src/graphics/Screen.cpp | 11 +- src/graphics/Screen.h | 9 -- src/mesh/Channels.cpp | 228 +++++++++++++++++++++++++++++ src/mesh/Channels.h | 51 +++++++ src/mesh/NodeDB.cpp | 165 ++------------------- src/mesh/NodeDB.h | 19 --- src/mesh/PhoneAPI.cpp | 5 +- src/mesh/PhoneAPI.h | 12 +- src/mesh/RadioInterface.cpp | 13 +- src/mesh/Router.cpp | 1 - src/mesh/generated/deviceonly.pb.h | 18 +-- src/mesh/generated/mesh.pb.c | 4 + src/mesh/generated/mesh.pb.h | 122 ++++++++------- src/mesh/mesh-pb-constants.h | 3 + src/plugins/RangeTestPlugin.cpp | 5 +- 18 files changed, 421 insertions(+), 275 deletions(-) create mode 100644 src/mesh/Channels.cpp create mode 100644 src/mesh/Channels.h 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);