From e124d2094f91aa039bec808a126f40eb01fdfbad Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 6 Jun 2020 13:16:36 -0700 Subject: [PATCH 1/4] PROTOCOL CHANGE! activate 32 bit nodenums/packetids --- docs/software/crypto.md | 3 --- docs/software/nrf52-TODO.md | 2 +- proto | 2 +- src/mesh/MeshService.cpp | 8 +++++--- src/mesh/MeshTypes.h | 4 ++-- src/mesh/Router.cpp | 7 +++++-- src/mesh/mesh.pb.c | 2 +- src/mesh/mesh.pb.h | 14 +++++++------- 8 files changed, 22 insertions(+), 20 deletions(-) diff --git a/docs/software/crypto.md b/docs/software/crypto.md index 7f5709c48..755cb3369 100644 --- a/docs/software/crypto.md +++ b/docs/software/crypto.md @@ -34,7 +34,4 @@ Note that for both stategies, sizes are measured in blocks and that an AES block ## Remaining todo -- Make the packet numbers 32 bit -- Confirm the packet #s are stored in flash across deep sleep (and otherwise in in RAM) - Have the app change the crypto key when the user generates a new channel -- Implement for NRF52 [NRF52](https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.0.0/lib_crypto_aes.html#sub_aes_ctr) diff --git a/docs/software/nrf52-TODO.md b/docs/software/nrf52-TODO.md index 137bcb04e..500180d03 100644 --- a/docs/software/nrf52-TODO.md +++ b/docs/software/nrf52-TODO.md @@ -40,7 +40,6 @@ Needed to be fully functional at least at the same level of the ESP32 boards. At ## Items to be 'feature complete' -- change packet numbers to be 32 bits - check datasheet about sx1262 temperature compensation - enable brownout detection and watchdog - stop polling for GPS characters, instead stay blocked on read in a thread @@ -128,6 +127,7 @@ Nice ideas worth considering someday... - scheduleOSCallback doesn't work yet - it is way too fast (causes rapid polling of busyTx, high power draw etc...) - find out why we reboot while debugging - it was bluetooth/softdevice - make a file system implementation (preferably one that can see the files the bootloader also sees) - preferably https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/libraries/InternalFileSytem/examples/Internal_ReadWrite/Internal_ReadWrite.ino else use https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.3.0/lib_fds_usage.html?cp=7_5_0_3_55_3 +- change packet numbers to be 32 bits ``` diff --git a/proto b/proto index 9d083d5d4..3ba76bbe4 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 9d083d5d4ff4ef095135b18468004eaba77cb691 +Subproject commit 3ba76bbe4c98ee9c9e422d8dc10844cc9fb5272a diff --git a/src/mesh/MeshService.cpp b/src/mesh/MeshService.cpp index 5060851c3..49cd0fe79 100644 --- a/src/mesh/MeshService.cpp +++ b/src/mesh/MeshService.cpp @@ -86,12 +86,14 @@ void MeshService::sendOurOwner(NodeNum dest, bool wantReplies) const MeshPacket *MeshService::handleFromRadioUser(const MeshPacket *mp) { bool wasBroadcast = mp->to == NODENUM_BROADCAST; - bool isCollision = mp->from == myNodeInfo.my_node_num; - // we win if we have a lower macaddr - bool weWin = memcmp(&owner.macaddr, &mp->decoded.user.macaddr, sizeof(owner.macaddr)) < 0; + // Disable this collision testing if we use 32 bit nodenums + bool isCollision = (sizeof(NodeNum) == 1) && (mp->from == myNodeInfo.my_node_num); if (isCollision) { + // we win if we have a lower macaddr + bool weWin = memcmp(&owner.macaddr, &mp->decoded.user.macaddr, sizeof(owner.macaddr)) < 0; + if (weWin) { DEBUG_MSG("NOTE! Received a nodenum collision and we are vetoing\n"); diff --git a/src/mesh/MeshTypes.h b/src/mesh/MeshTypes.h index adba78415..32ec2b08d 100644 --- a/src/mesh/MeshTypes.h +++ b/src/mesh/MeshTypes.h @@ -6,8 +6,8 @@ #include "mesh.pb.h" #include -typedef uint8_t NodeNum; -typedef uint8_t PacketId; // A packet sequence number +typedef uint32_t NodeNum; +typedef uint32_t PacketId; // A packet sequence number #define NODENUM_BROADCAST (sizeof(NodeNum) == 4 ? UINT32_MAX : UINT8_MAX) #define ERRNO_OK 0 diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index eb8a1ab32..2f8dd5e28 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -56,8 +56,11 @@ PacketId generatePacketId() if (!didInit) { didInit = true; - i = random(0, numPacketId + - 1); // pick a random initial sequence number at boot (to prevent repeated reboots always starting at 0) + + // pick a random initial sequence number at boot (to prevent repeated reboots always starting at 0) + // Note: we mask the high order bit to ensure that we never pass a 'negative' number to random + i = random(numPacketId & 0x7fffffff); + DEBUG_MSG("Initial packet id %u, numPacketId %u\n", i, numPacketId); } i++; diff --git a/src/mesh/mesh.pb.c b/src/mesh/mesh.pb.c index 4eb53e1ba..88db1a219 100644 --- a/src/mesh/mesh.pb.c +++ b/src/mesh/mesh.pb.c @@ -9,7 +9,7 @@ PB_BIND(Position, Position, AUTO) -PB_BIND(Data, Data, 2) +PB_BIND(Data, Data, AUTO) PB_BIND(User, User, AUTO) diff --git a/src/mesh/mesh.pb.h b/src/mesh/mesh.pb.h index 0eae7ecad..8e4ba34bb 100644 --- a/src/mesh/mesh.pb.h +++ b/src/mesh/mesh.pb.h @@ -47,7 +47,7 @@ typedef struct _ChannelSettings { char name[12]; } ChannelSettings; -typedef PB_BYTES_ARRAY_T(251) Data_payload_t; +typedef PB_BYTES_ARRAY_T(240) Data_payload_t; typedef struct _Data { Data_Type typ; Data_payload_t payload; @@ -586,20 +586,20 @@ extern const pb_msgdesc_t ManufacturingData_msg; /* Maximum encoded size of messages (where known) */ #define Position_size 39 -#define Data_size 256 +#define Data_size 245 #define User_size 72 #define RouteDiscovery_size 88 -#define SubPacket_size 285 -#define MeshPacket_size 324 +#define SubPacket_size 274 +#define MeshPacket_size 313 #define ChannelSettings_size 60 #define RadioConfig_size 157 #define RadioConfig_UserPreferences_size 93 #define NodeInfo_size 132 #define MyNodeInfo_size 110 -#define DeviceState_size 15463 +#define DeviceState_size 15100 #define DebugString_size 258 -#define FromRadio_size 333 -#define ToRadio_size 327 +#define FromRadio_size 322 +#define ToRadio_size 316 /* ManufacturingData_size depends on runtime parameters */ #ifdef __cplusplus From a5f05019db3059f3e61dc5eedfc05c39f95340a9 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sat, 6 Jun 2020 14:30:15 -0700 Subject: [PATCH 2/4] fix build instructions --- docs/software/build-instructions.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/software/build-instructions.md b/docs/software/build-instructions.md index 073ce4e8e..c4ac9b8e1 100644 --- a/docs/software/build-instructions.md +++ b/docs/software/build-instructions.md @@ -6,10 +6,11 @@ in these instructions I describe use of their command line tool. 1. Purchase a suitable radio (see above) 2. Install [PlatformIO](https://platformio.org/platformio-ide) 3. Download this git repo and cd into it -4. If you are outside the USA, edit [platformio.ini](/platformio.ini) to set the correct frequency range for your country. The line you need to change starts with "hw_version" and instructions are provided above that line. Options are provided for EU433, EU835, CN, JP and US. Pull-requests eagerly accepted for other countries. -5. Plug the radio into your USB port -6. Type "pio run --environment XXX -t upload" (This command will fetch dependencies, build the project and install it on the board via USB). For XXX, use the board type you have (either tbeam, heltec, ttgo-lora32-v1, ttgo-lora32-v2). -7. Platform IO also installs a very nice VisualStudio Code based IDE, see their [tutorial](https://docs.platformio.org/en/latest/tutorials/espressif32/arduino_debugging_unit_testing.html) if you'd like to use it. +4. Run "git submodule update --init --recursive" to pull in dependencies this project needs. +5. If you are outside the USA, edit [platformio.ini](/platformio.ini) to set the correct frequency range for your country. The line you need to change starts with "hw_version" and instructions are provided above that line. Options are provided for EU433, EU835, CN, JP and US. Pull-requests eagerly accepted for other countries. +6. Plug the radio into your USB port +7. Type "pio run --environment XXX -t upload" (This command will fetch dependencies, build the project and install it on the board via USB). For XXX, use the board type you have (either tbeam, heltec, ttgo-lora32-v1, ttgo-lora32-v2). +8. Platform IO also installs a very nice VisualStudio Code based IDE, see their [tutorial](https://docs.platformio.org/en/latest/tutorials/espressif32/arduino_debugging_unit_testing.html) if you'd like to use it. ## Decoding stack traces From 871a85d6888573f66c82a4f3acad25f7752e9638 Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 7 Jun 2020 17:22:07 -0700 Subject: [PATCH 3/4] force all devices to discard old settings --- src/mesh/NodeDB.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 334e178f6..108fa0562 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -30,7 +30,7 @@ DeviceState versions used to be defined in the .proto file but really only this #define here. */ -#define DEVICESTATE_CUR_VER 8 +#define DEVICESTATE_CUR_VER 9 #define DEVICESTATE_MIN_VER DEVICESTATE_CUR_VER #ifndef NO_ESP32 @@ -134,8 +134,11 @@ void NodeDB::init() sprintf(owner.id, "!%02x%02x%02x%02x%02x%02x", ourMacAddr[0], ourMacAddr[1], ourMacAddr[2], ourMacAddr[3], ourMacAddr[4], ourMacAddr[5]); memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr)); - sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]); + // Set default owner name + pickNewNodeNum(); // Note: we will repick later, just in case the settings are corrupted, but we need a valid + // owner.short_name now + sprintf(owner.long_name, "Unknown %02x%02x", ourMacAddr[4], ourMacAddr[5]); sprintf(owner.short_name, "?%02X", myNodeInfo.my_node_num & 0xff); if (!FSBegin()) // FIXME - do this in main? From 2d2ed591e9704881494d1f73ee2c56381e9f1eeb Mon Sep 17 00:00:00 2001 From: geeksville Date: Sun, 7 Jun 2020 22:12:06 -0700 Subject: [PATCH 4/4] set num_bits for nodenum and packet id after loading save file --- src/mesh/NodeDB.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index 334e178f6..428639e92 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -123,8 +123,6 @@ void NodeDB::init() // default to no GPS, until one has been found by probing myNodeInfo.has_gps = false; - myNodeInfo.node_num_bits = sizeof(NodeNum) * 8; - myNodeInfo.packet_id_bits = sizeof(PacketId) * 8; myNodeInfo.message_timeout_msec = FLOOD_EXPIRE_TIME; myNodeInfo.min_app_version = 167; generatePacketId(); // FIXME - ugly way to init current_packet_id; @@ -148,6 +146,11 @@ 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; + // 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) pickNewNodeNum();