diff --git a/docs/software/TODO.md b/docs/software/TODO.md index c4769c2ef..b30b58795 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -17,6 +17,7 @@ You probably don't care about this section - skip to the next one. * DONE remove region specific builds from the firmware * restrict settings operations to the admin channel * add gui in android app for setting region +* make an alpha channel for the python API * "FIXME - move the radioconfig/user/channel READ operations into SettingsMessage as well" * DONE scrub protobufs to make sure they are absoloute minimum wiresize (in particular Data, ChannelSets and positions) * change syncword diff --git a/proto b/proto index 4396b3689..6421b29ef 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 4396b3689719ac292f9628752b5b1c78288ab2e7 +Subproject commit 6421b29ef45dbd34d7c6c43f4be48a7906e66ad9 diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index dc1383bdf..8b5d5cb6b 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -1,13 +1,9 @@ #include "Channels.h" -#include "NodeDB.h" #include "CryptoEngine.h" +#include "NodeDB.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}; @@ -17,19 +13,19 @@ Channels channels; /** * Validate a channel, fixing any errors as needed */ -Channel &fixupChannel(size_t chIndex) +Channel &Channels::fixupChannel(ChannelIndex chIndex) { - assert(chIndex < devicestate.channels_count); + auto ch = getByIndex(chIndex); - 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) - 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) { + if (!ch.has_settings) { // No settings! Must disable and skip - ch->role = Channel_Role_DISABLED; + ch.role = Channel_Role_DISABLED; + memset(&ch.settings, 0, sizeof(ch.settings)); + ch.has_settings = true; } else { - ChannelSettings &channelSettings = ch->settings; + ChannelSettings &channelSettings = ch.settings; // Convert the old string "Default" to our new short representation if (strcmp(channelSettings.name, "Default") == 0) @@ -43,19 +39,16 @@ Channel &fixupChannel(size_t chIndex) } } - return *ch; + return ch; } - - /** * Write a default channel to the specified channel index */ -void initDefaultChannel(size_t chIndex) +void Channels::initDefaultChannel(ChannelIndex chIndex) { - assert(chIndex < devicestate.channels_count); - Channel *ch = devicestate.channels + chIndex; - ChannelSettings &channelSettings = ch->settings; + auto ch = getByIndex(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 @@ -68,30 +61,28 @@ void initDefaultChannel(size_t chIndex) channelSettings.psk.size = 1; strcpy(channelSettings.name, ""); - ch->has_settings = true; - ch->role = Channel_Role_PRIMARY; + ch.has_settings = true; + ch.role = Channel_Role_PRIMARY; } /** Given a channel index, change to use the crypto key specified by that index */ -void Channels::setCrypto(size_t chIndex) +void Channels::setCrypto(ChannelIndex chIndex) { - assert(chIndex < devicestate.channels_count); - Channel *ch = devicestate.channels + chIndex; - ChannelSettings &channelSettings = ch->settings; - assert(ch->has_settings); + auto ch = getByIndex(chIndex); + ChannelSettings &channelSettings = ch.settings; + assert(ch.has_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) { - if(ch->role == Channel_Role_SECONDARY) { - DEBUG_MSG("Unset PSK for secondary channel %s. using primary key\n", ch->settings.name); + if (ch.role == Channel_Role_SECONDARY) { + DEBUG_MSG("Unset PSK for secondary channel %s. using primary key\n", ch.settings.name); setCrypto(primaryIndex); } else DEBUG_MSG("Warning: User disabled encryption\n"); - } - else if (activePSKSize == 1) { + } 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]; @@ -135,27 +126,28 @@ void Channels::onConfigChanged() for (int i = 0; i < devicestate.channels_count; i++) { auto ch = fixupChannel(i); - if(ch.role == Channel_Role_PRIMARY) + if (ch.role == Channel_Role_PRIMARY) primaryIndex = i; } setCrypto(primaryIndex); // FIXME: for the time being (still single channel - just use our only channel as the crypto key) } -Channel &Channels::getChannel(size_t chIndex) +Channel &Channels::getByIndex(ChannelIndex chIndex) { assert(chIndex < devicestate.channels_count); Channel *ch = devicestate.channels + chIndex; return *ch; } -void Channels::setChannel(const Channel &c) { - Channel &old = getChannel(c.index); +void Channels::setChannel(const Channel &c) +{ + Channel &old = getByIndex(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) + 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 @@ -164,7 +156,7 @@ void Channels::setChannel(const Channel &c) { const char *Channels::getName(size_t chIndex) { // Convert the short "" representation for Default into a usable string - ChannelSettings &channelSettings = getChannel(chIndex).settings; + ChannelSettings &channelSettings = getByIndex(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 diff --git a/src/mesh/Channels.h b/src/mesh/Channels.h index ec64cd49b..913c316dc 100644 --- a/src/mesh/Channels.h +++ b/src/mesh/Channels.h @@ -3,41 +3,57 @@ #include "mesh-pb-constants.h" #include +typedef uint8_t ChannelIndex; +typedef uint8_t ChannelHash; + +/** The container/on device API for working with channels */ class Channels { - size_t primaryIndex = 0; - + /// The index of the primary channel + ChannelIndex primaryIndex = 0; + + /** The channel index that was requested for sending/receving. Note: if this channel is a secondary + channel and does not have a PSK, we will use the PSK from the primary channel. If this channel is disabled + no sending or receiving will be allowed */ + ChannelIndex activeChannelIndex = 0; + + /// The in-use psk - which has been constructed based on the (possibly short psk) in channelSettings + uint8_t activePSK[32]; + uint8_t activePSKSize = 0; + public: - const ChannelSettings &getPrimary() { return getChannel(getPrimaryIndex()).settings; } + const ChannelSettings &getPrimary() { return getByIndex(getPrimaryIndex()).settings; } - Channel &getChannel(size_t chIndex); + /** Return the Channel for a specified index */ + Channel &getByIndex(ChannelIndex 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. + /** 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; } + ChannelIndex 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 - */ + * 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. @@ -47,33 +63,43 @@ their nodes void onConfigChanged(); /** Given a channel hash setup crypto for decoding that channel (or the primary channel if that channel is unsecured) - * + * * This method is called before decoding inbound packets - * + * * @return false if no suitable channel could be found. */ - bool setCryptoByHash(uint8_t channelHash); + bool setActiveByHash(ChannelHash channelHash); /** Given a channel index setup crypto for encoding that channel (or the primary channel if that channel is unsecured) - * + * * This method is called before encoding inbound packets - * + * * @eturn the (0 to 255) hash for that channel - if no suitable channel could be found, return -1 */ - int16_t setCryptoByIndex(uint8_t channelIndex); + int16_t setActiveByIndex(ChannelIndex channelIndex); -private: + private: /** Given a channel index, change to use the crypto key specified by that index */ - void setCrypto(size_t chIndex); + void setCrypto(ChannelIndex chIndex); /** Return the channel index for the specified channel hash, or -1 for not found */ - int8_t getChannelIndexByHash(uint8_t channelHash); + int8_t getIndexByHash(ChannelHash channelHash); - /** Given a channel number, return the (0 to 255) hash for that channel + /** Given a channel number, return the (0 to 255) hash for that channel * If no suitable channel could be found, return -1 - */ - int16_t getChannelHash(size_t channelNum); + */ + int16_t getHash(ChannelIndex channelNum); + + /** + * Validate a channel, fixing any errors as needed + */ + Channel &fixupChannel(ChannelIndex chIndex); + + /** + * Write a default channel to the specified channel index + */ + void initDefaultChannel(ChannelIndex chIndex); }; /// Singleton channel table diff --git a/src/mesh/generated/portnums.pb.h b/src/mesh/generated/portnums.pb.h index 758db47a6..5904a548c 100644 --- a/src/mesh/generated/portnums.pb.h +++ b/src/mesh/generated/portnums.pb.h @@ -20,10 +20,10 @@ typedef enum _PortNum { PortNum_ADMIN_APP = 6, PortNum_REPLY_APP = 32, PortNum_IP_TUNNEL_APP = 33, - PortNum_ENVIRONMENTAL_MEASUREMENT_APP = 34, PortNum_SERIAL_APP = 64, PortNum_STORE_FORWARD_APP = 65, PortNum_RANGE_TEST_APP = 66, + PortNum_ENVIRONMENTAL_MEASUREMENT_APP = 67, PortNum_PRIVATE_APP = 256, PortNum_ATAK_FORWARDER = 257, PortNum_MAX = 511