diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8b7b4592c..9ef8f77c6 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -7,7 +7,7 @@ is appreciated." This will allow other devs to potentially save you time by not accidentially duplicating work etc... - Please do not check in files that don't have real changes - Please do not reformat lines that you didn't have to change the code on -- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor, +- We recommend using the [Visual Studio Code](https://platformio.org/install/ide?install=vscode) editor and the 'clang-format' extension, because automatically follows our indentation rules and it's auto reformatting will not cause spurious changes to lines. - If your PR fixes a bug, mention "fixes #bugnum" somewhere in your pull request description. - If your other co-developers have comments on your PR please tweak as needed. diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 585775e48..b01111fd9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,10 +15,10 @@ jobs: uses: actions/setup-python@v2 with: python-version: 3.x - - name: Install Platform IO + - name: Install Platform IO and meshtastic-python run: | python -m pip install --upgrade pip - pip install -U platformio + pip install -U platformio meshtastic - name: Install extra python tools run: | pip install -U adafruit-nrfutil @@ -31,6 +31,11 @@ jobs: run: platformio run -e heltec - name: Build for lora-relay-v1 run: platformio run -e lora-relay-v1 - # Turn off linux for now - name: Build for native + - name: Build for native run: platformio run -e native + - name: Integration test + run: | + .pio/build/native/program & + sleep 1 + python3 -c 'from meshtastic.test import testSimulator; testSimulator()' + diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 0f0d7401d..27bdd05a2 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,6 +2,7 @@ // See http://go.microsoft.com/fwlink/?LinkId=827846 // for the documentation about the extensions.json format "recommendations": [ - "platformio.platformio-ide" + "platformio.platformio-ide", + "xaver.clang-format" ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index b89870c5b..5ce21fa35 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -77,5 +77,6 @@ "--java_out=/tmp", "-I=/home/kevinh/development/meshtastic/meshtastic-esp32/proto" ] - } + }, + "editor.formatOnSave": true } \ No newline at end of file diff --git a/bin/program-1.0-tbeam.sh b/bin/program-1.0-tbeam.sh new file mode 100755 index 000000000..b2b37756b --- /dev/null +++ b/bin/program-1.0-tbeam.sh @@ -0,0 +1,3 @@ +esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-EU865-1.0.0.bin +echo "Erasing the otadata partition, which will turn off flash flippy-flop and force the first image to be used" +esptool.py --baud 921600 erase_region 0xe000 0x2000 diff --git a/bin/program-1.1-tbeam.sh b/bin/program-1.1-tbeam.sh index 9b95c3380..98ba5c682 100755 --- a/bin/program-1.1-tbeam.sh +++ b/bin/program-1.1-tbeam.sh @@ -1 +1 @@ -esptool.py --baud 921600 write_flash 0x10000 release/archive/firmware-tbeam-1.1.50.bin +esptool.py --baud 921600 write_flash 0x10000 release/archive/old/firmware-tbeam-1.1.50.bin diff --git a/docs/software/TODO.md b/docs/software/TODO.md index c65a53658..7ffe9361f 100644 --- a/docs/software/TODO.md +++ b/docs/software/TODO.md @@ -2,16 +2,26 @@ You probably don't care about this section - skip to the next one. +## before next release + +* DONE timestamps on oled screen are wrong - don't seem to be updating based on message rx (actually: this is expected behavior when no node on the mesh has GPS time) +* DONE add ch-del +* DONE channel hash suffixes are wrong on android +* DONE before next relase: test empty channel sets on android +* DONE channel sharing in android +* DONE test 1.0 firmware update on android +* DONE test 1.1 firmware update on android +* test 1.2.10 firmware update on android +* DONE test link sharing on android +* luxon bug report - seeing rx acks for nodes that are not on the network +* document how to do remote admin +* release py, android, device + ## 1.2 cleanup & multichannel support: -* before next relase: test empty channel sets on android -* test link sharing on android - * DONE cleanup the external notification and serial plugins * non ack version of stress test fails sometimes! -* timestamps on oled screen are wrong - don't seem to be updating based on message rx -* luxon bug report - seeing rx acks for nodes that are not on the network -* channel hash suffixes are wrong on android + * tx fault test has a bug #734 * DONE move device types into an enum in nodeinfo * fix android to use new device types for firmware update diff --git a/platformio.ini b/platformio.ini index 946b8bcbc..f2142b8e4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -;default_envs = tbeam +default_envs = tbeam ;default_envs = tbeam0.7 ;default_envs = heltec ;default_envs = tlora-v1 @@ -17,7 +17,7 @@ ;default_envs = lora-relay-v1 # nrf board ;default_envs = eink ;default_envs = nrf52840dk-geeksville -default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here +;default_envs = native # lora-relay-v1 # nrf52840dk-geeksville # linux # or if you'd like to change the default to something like lora-relay-v1 put that here [common] ; common is not currently used diff --git a/proto b/proto index 39bb8b26b..b8c0499f2 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 39bb8b26bbc107aae3586d5a5e11a06ea12680bc +Subproject commit b8c0499f28f9673d1df17d04da562e30703f01cb diff --git a/src/configuration.h b/src/configuration.h index 627b6aae4..3d4fb652d 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -338,7 +338,7 @@ along with this program. If not, see . #elif defined(TLORA_V2_1_16) // This string must exactly match the case used in release file names or the android updater won't work -#define HW_VENDOR HardwareModel_TLORA_V2_1p6_ +#define HW_VENDOR HardwareModel_TLORA_V2_1_1p6 #undef GPS_RX_PIN #undef GPS_TX_PIN @@ -382,8 +382,8 @@ along with this program. If not, see . #define LED_PIN 12 // If defined we will blink this LED //#define BUTTON_PIN 36 // If defined, this will be used for user button presses (ToDo problem on that line on debug screen --> -//Long press start!) #define BUTTON_NEED_PULLUP //GPIOs 34 to 39 are GPIs – input only pins. These pins don’t have internal -//pull-ups or pull-down resistors. +// Long press start!) #define BUTTON_NEED_PULLUP //GPIOs 34 to 39 are GPIs – input only pins. These pins don’t have internal +// pull-ups or pull-down resistors. #define USE_RF95 #define LORA_DIO0 38 // a No connect on the SX1262 module diff --git a/src/mesh/generated/admin.pb.h b/src/mesh/generated/admin.pb.h index d68103cea..cf71a9cb2 100644 --- a/src/mesh/generated/admin.pb.h +++ b/src/mesh/generated/admin.pb.h @@ -25,6 +25,7 @@ typedef struct _AdminMessage { Channel get_channel_response; bool confirm_set_channel; bool confirm_set_radio; + bool exit_simulator; }; } AdminMessage; @@ -47,6 +48,7 @@ extern "C" { #define AdminMessage_get_channel_response_tag 7 #define AdminMessage_confirm_set_channel_tag 32 #define AdminMessage_confirm_set_radio_tag 33 +#define AdminMessage_exit_simulator_tag 34 /* Struct field encoding specification for nanopb */ #define AdminMessage_FIELDLIST(X, a) \ @@ -58,7 +60,8 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,get_radio_response,get_radio_respons X(a, STATIC, ONEOF, UINT32, (variant,get_channel_request,get_channel_request), 6) \ X(a, STATIC, ONEOF, MESSAGE, (variant,get_channel_response,get_channel_response), 7) \ X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_channel,confirm_set_channel), 32) \ -X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) +X(a, STATIC, ONEOF, BOOL, (variant,confirm_set_radio,confirm_set_radio), 33) \ +X(a, STATIC, ONEOF, BOOL, (variant,exit_simulator,exit_simulator), 34) #define AdminMessage_CALLBACK NULL #define AdminMessage_DEFAULT NULL #define AdminMessage_variant_set_radio_MSGTYPE RadioConfig diff --git a/src/plugins/AdminPlugin.cpp b/src/plugins/AdminPlugin.cpp index 96b5c51a0..65c901121 100644 --- a/src/plugins/AdminPlugin.cpp +++ b/src/plugins/AdminPlugin.cpp @@ -6,6 +6,10 @@ #include "configuration.h" #include "main.h" +#ifdef PORTDUINO +#include "unistd.h" +#endif + AdminPlugin *adminPlugin; void AdminPlugin::handleGetChannel(const MeshPacket &req, uint32_t channelIndex) @@ -51,7 +55,7 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, const AdminMessag break; case AdminMessage_set_channel_tag: - DEBUG_MSG("Client is setting channel\n"); + DEBUG_MSG("Client is setting channel %d\n", r->set_channel.index); handleSetChannel(r->set_channel); break; @@ -65,6 +69,13 @@ bool AdminPlugin::handleReceivedProtobuf(const MeshPacket &mp, const AdminMessag handleGetRadio(mp); break; +#ifdef PORTDUINO + case AdminMessage_exit_simulator_tag: + DEBUG_MSG("Exiting simulator\n"); + _exit(0); + break; +#endif + default: // Probably a message sent by us or sent to our local node. FIXME, we should avoid scanning these messages DEBUG_MSG("Ignoring nonrelevant admin %d\n", r->which_variant); @@ -102,8 +113,7 @@ void AdminPlugin::handleSetChannel(const Channel &cc) if (cc.index == 0) { // FIXME, this updates the user preferences also, which isn't needed - we really just want to notify on configChanged service.reloadConfig(); - } - else { + } else { channels.onConfigChanged(); // tell the radios about this change nodeDB.saveChannelsToDisk(); } diff --git a/src/plugins/esp32/StoreForwardPlugin.cpp b/src/plugins/esp32/StoreForwardPlugin.cpp index 28f1c6738..1726a0b27 100644 --- a/src/plugins/esp32/StoreForwardPlugin.cpp +++ b/src/plugins/esp32/StoreForwardPlugin.cpp @@ -8,89 +8,36 @@ #include #include -#define STOREFORWARD_MAX_PACKETS 7500 +#define STOREFORWARD_MAX_PACKETS 0 #define STOREFORWARD_SEND_HISTORY_SHORT 600 StoreForwardPlugin *storeForwardPlugin; -StoreForwardPluginRadio *storeForwardPluginRadio; - -StoreForwardPlugin::StoreForwardPlugin() : concurrency::OSThread("StoreForwardPlugin") {} int32_t StoreForwardPlugin::runOnce() { #ifndef NO_ESP32 - /* - Uncomment the preferences below if you want to use the plugin - without having to configure it from the PythonAPI or WebUI. - - attn @mc-hamster I moved this back inside the comment because I don't think it was intended to checkin. It was forcing all - nodes to be running this and turning off is_router. - - radioConfig.preferences.store_forward_plugin_enabled = 1; - radioConfig.preferences.is_router = 0; - */ - if (radioConfig.preferences.store_forward_plugin_enabled) { - if (firstTime) { - - firstTime = 0; - - if (radioConfig.preferences.is_router) { - DEBUG_MSG("Initializing Store & Forward Plugin - Enabled as Router\n"); - // Router - if (ESP.getPsramSize()) { - if (ESP.getFreePsram() >= 2048 * 1024) { - // Do the startup here - storeForwardPluginRadio = new StoreForwardPluginRadio(); - - this->populatePSRAM(); - - // packetHistory[0].bytes; - return (10 * 1000); - - } else { - DEBUG_MSG("Device has less than 2M of PSRAM free. Aborting startup.\n"); - DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); - - return (INT32_MAX); - } - - } else { - DEBUG_MSG("Device doesn't have PSRAM.\n"); - DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); - - return (INT32_MAX); - } - - } else { - DEBUG_MSG("Initializing Store & Forward Plugin - Enabled as Client\n"); - return (5 * 1000); - } - + if (radioConfig.preferences.is_router) { + // Maybe some cleanup functions? + this->sawNodeReport(); + this->historyReport(); + return (10 * 1000); } else { + /* + * If the plugin is turned on and is_router is not enabled, then we'll send a heartbeat every + * few minutes. + * + * This behavior is expected to change. It's only here until we come up with something better. + */ - if (radioConfig.preferences.is_router) { - // Maybe some cleanup functions? - this->sawNodeReport(); - this->historyReport(); - return (10 * 1000); - } else { - /* - * If the plugin is turned on and is_router is not enabled, then we'll send a heartbeat every - * few minutes. - */ + DEBUG_MSG("Store & Forward Plugin - Sending heartbeat\n"); - DEBUG_MSG("Store & Forward Plugin - Sending heartbeat\n"); + storeForwardPlugin->sendPayload(); - // storeForwardPluginRadio->sendPayloadHeartbeat(); - if(storeForwardPluginRadio) - storeForwardPluginRadio->sendPayload(); - - return (1 * 60 * 1000); - } + return (4 * 60 * 1000); } } else { @@ -110,24 +57,29 @@ void StoreForwardPlugin::populatePSRAM() https://learn.upesy.com/en/programmation/psram.html#psram-tab */ - DEBUG_MSG("Before PSRAM initilization\n"); + DEBUG_MSG("Before PSRAM initilization:\n"); - DEBUG_MSG("Total heap: %d\n", ESP.getHeapSize()); - DEBUG_MSG("Free heap: %d\n", ESP.getFreeHeap()); - DEBUG_MSG("Total PSRAM: %d\n", ESP.getPsramSize()); - DEBUG_MSG("Free PSRAM: %d\n", ESP.getFreePsram()); + DEBUG_MSG(" Total heap: %d\n", ESP.getHeapSize()); + DEBUG_MSG(" Free heap: %d\n", ESP.getFreeHeap()); + DEBUG_MSG(" Total PSRAM: %d\n", ESP.getPsramSize()); + DEBUG_MSG(" Free PSRAM: %d\n", ESP.getFreePsram()); // PacketHistoryStruct *packetHistory = (PacketHistoryStruct *)ps_calloc(STOREFORWARD_MAX_PACKETS, // sizeof(PacketHistoryStruct)); - this->packetHistory = (PacketHistoryStruct *)ps_calloc(STOREFORWARD_MAX_PACKETS, sizeof(PacketHistoryStruct)); - DEBUG_MSG("After PSRAM initilization\n"); - DEBUG_MSG("Total heap: %d\n", ESP.getHeapSize()); - DEBUG_MSG("Free heap: %d\n", ESP.getFreeHeap()); - DEBUG_MSG("Total PSRAM: %d\n", ESP.getPsramSize()); - DEBUG_MSG("Free PSRAM: %d\n", ESP.getFreePsram()); + // Use a maximum of half the available PSRAM unless otherwise specified. + uint32_t numberOfPackets = + STOREFORWARD_MAX_PACKETS ? STOREFORWARD_MAX_PACKETS : ((ESP.getPsramSize() / 2) / sizeof(PacketHistoryStruct)); - DEBUG_MSG("packetHistory Size - %u", sizeof(packetHistory)); + this->packetHistory = (PacketHistoryStruct *)ps_calloc(numberOfPackets, sizeof(PacketHistoryStruct)); + DEBUG_MSG("After PSRAM initilization:\n"); + + DEBUG_MSG(" Total heap: %d\n", ESP.getHeapSize()); + DEBUG_MSG(" Free heap: %d\n", ESP.getFreeHeap()); + DEBUG_MSG(" Total PSRAM: %d\n", ESP.getPsramSize()); + DEBUG_MSG(" Free PSRAM: %d\n", ESP.getFreePsram()); + DEBUG_MSG("Store and Forward Stats:\n"); + DEBUG_MSG(" numberOfPackets - %u\n", numberOfPackets); } // We saw a node. @@ -228,41 +180,32 @@ void StoreForwardPlugin::sawNodeReport() } } -MeshPacket *StoreForwardPluginRadio::allocReply() +MeshPacket *StoreForwardPlugin::allocReply() { auto reply = allocDataPacket(); // Allocate a packet for sending - return reply; // attn @mc-hamster this code was commented out and was causing memory corruption + return reply; } -void StoreForwardPluginRadio::sendPayload(NodeNum dest, bool wantReplies) +void StoreForwardPlugin::sendPayload(NodeNum dest, bool wantReplies) { - /* - MeshPacket *p = this->allocReply(); // attn @mc-hamster, I moved inside the commented block to prevent leaking memory + DEBUG_MSG("Sending S&F Payload\n"); + MeshPacket *p = allocReply(); p->to = dest; p->decoded.want_response = wantReplies; p->want_ack = true; -*/ - // static char heartbeatString[20]; - // snprintf(heartbeatString, sizeof(heartbeatString), "1"); + /* + */ + static char heartbeatString[20]; + snprintf(heartbeatString, sizeof(heartbeatString), "1"); - // p->decoded.data.payload.size = strlen(heartbeatString); // You must specify how many bytes are in the reply - // memcpy(p->decoded.data.payload.bytes, "1", 1); - - // service.sendToMesh(p); -} - -void StoreForwardPluginRadio::sendPayloadHeartbeat(NodeNum dest, bool wantReplies) -{ - DEBUG_MSG("Sending S&F Heartbeat\n"); - MeshPacket *p = this->allocReply(); - p->to = dest; - p->decoded.want_response = wantReplies; + p->decoded.payload.size = strlen(heartbeatString); // You must specify how many bytes are in the reply + memcpy(p->decoded.payload.bytes, "1", 1); service.sendToMesh(p); } -bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) +bool StoreForwardPlugin::handleReceived(const MeshPacket &mp) { #ifndef NO_ESP32 if (radioConfig.preferences.store_forward_plugin_enabled) { @@ -274,7 +217,7 @@ bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) printPacket("----- PACKET FROM RADIO -----", &mp); uint32_t sawTime = storeForwardPlugin->sawNode(getFrom(&mp) & 0xffffffff); DEBUG_MSG("We last saw this node (%u), %u sec ago\n", mp.from & 0xffffffff, (millis() - sawTime) / 1000); - + DEBUG_MSG(" -------------- "); if (mp.decoded.portnum == PortNum_UNKNOWN_APP) { DEBUG_MSG("Packet came from - PortNum_UNKNOWN_APP\n"); } else if (mp.decoded.portnum == PortNum_TEXT_MESSAGE_APP) { @@ -322,3 +265,52 @@ bool StoreForwardPluginRadio::handleReceived(const MeshPacket &mp) return true; // Let others look at this message also if they want } + +StoreForwardPlugin::StoreForwardPlugin() + : SinglePortPlugin("StoreForwardPlugin", PortNum_STORE_FORWARD_APP), concurrency::OSThread("StoreForwardPlugin") +{ + +#ifndef NO_ESP32 + + /* + Uncomment the preferences below if you want to use the plugin + without having to configure it from the PythonAPI or WebUI. + + radioConfig.preferences.store_forward_plugin_enabled = 1; + radioConfig.preferences.is_router = 1; + */ + + if (radioConfig.preferences.store_forward_plugin_enabled) { + if (radioConfig.preferences.is_router) { + DEBUG_MSG("Initializing Store & Forward Plugin - Enabled as Router\n"); + // Router + if (ESP.getPsramSize()) { + if (ESP.getFreePsram() >= 2048 * 1024) { + // Do the startup here + + this->populatePSRAM(); + + // packetHistory[0].bytes; + // return (10 * 1000); + + } else { + DEBUG_MSG("Device has less than 2M of PSRAM free. Aborting startup.\n"); + DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); + + // return (INT32_MAX); + } + + } else { + DEBUG_MSG("Device doesn't have PSRAM.\n"); + DEBUG_MSG("Store & Forward Plugin - Aborting Startup.\n"); + + // return (INT32_MAX); + } + + } else { + DEBUG_MSG("Initializing Store & Forward Plugin - Enabled as Client\n"); + // return (5 * 1000); + } + } +#endif +} \ No newline at end of file diff --git a/src/plugins/esp32/StoreForwardPlugin.h b/src/plugins/esp32/StoreForwardPlugin.h index d2a2879c8..f8df48926 100644 --- a/src/plugins/esp32/StoreForwardPlugin.h +++ b/src/plugins/esp32/StoreForwardPlugin.h @@ -6,7 +6,6 @@ #include #include - struct PacketHistoryStruct { uint32_t time; uint32_t to; @@ -14,7 +13,7 @@ struct PacketHistoryStruct { uint8_t bytes[MAX_RHPACKETLEN]; }; -class StoreForwardPlugin : private concurrency::OSThread +class StoreForwardPlugin : public SinglePortPlugin, private concurrency::OSThread { bool firstTime = 1; @@ -37,41 +36,18 @@ class StoreForwardPlugin : private concurrency::OSThread void historySend(uint32_t msAgo, uint32_t to); void populatePSRAM(); + /** + * Send our payload into the mesh + */ + void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); + virtual MeshPacket *allocReply(); + virtual bool wantPortnum(PortNum p) { return true; }; + private: // Nothing here protected: virtual int32_t runOnce(); -}; - -extern StoreForwardPlugin *storeForwardPlugin; - -/* - * Radio interface for StoreForwardPlugin - * - */ -class StoreForwardPluginRadio : public SinglePortPlugin -{ - // uint32_t lastRxID; - - public: - StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_STORE_FORWARD_APP) {} - // StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} - - /** - * Send our payload into the mesh - */ - void sendPayload(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); - - /** - * Send our payload into the mesh - */ - void sendPayloadHeartbeat(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); - - protected: - virtual MeshPacket *allocReply(); - - virtual bool wantPortnum(PortNum p) { return true; }; /** Called to handle a particular incoming message @@ -80,4 +56,28 @@ class StoreForwardPluginRadio : public SinglePortPlugin virtual bool handleReceived(const MeshPacket &mp); }; +extern StoreForwardPlugin *storeForwardPlugin; + +/* + * Radio interface for StoreForwardPlugin + * + */ + +/* +class StoreForwardPluginRadio : public SinglePortPlugin +{ + // uint32_t lastRxID; + + public: + StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_STORE_FORWARD_APP) {} + // StoreForwardPluginRadio() : SinglePortPlugin("StoreForwardPluginRadio", PortNum_TEXT_MESSAGE_APP) {} + + void sendPayloadHeartbeat(NodeNum dest = NODENUM_BROADCAST, bool wantReplies = false); + + protected: + virtual MeshPacket *allocReply2(); +}; + extern StoreForwardPluginRadio *storeForwardPluginRadio; +*/ + diff --git a/version.properties b/version.properties index e615e8b4b..565c90526 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 1 minor = 2 -build = 10 +build = 11