diff --git a/.github/ISSUE_TEMPLATE/New Board.yml b/.github/ISSUE_TEMPLATE/New Board.yml index ad706f3c0..c71ed4ba2 100644 --- a/.github/ISSUE_TEMPLATE/New Board.yml +++ b/.github/ISSUE_TEMPLATE/New Board.yml @@ -28,7 +28,7 @@ body: description: What LoRa IC does the board have? validations: required: true - + - type: input id: link attributes: diff --git a/.github/actions/setup-base/action.yml b/.github/actions/setup-base/action.yml index 1791f80ae..45930a94f 100644 --- a/.github/actions/setup-base/action.yml +++ b/.github/actions/setup-base/action.yml @@ -1,5 +1,5 @@ -name: 'Setup Build Base Composite Action' -description: 'Base build actions for Meshtastic Platform IO steps' +name: "Setup Build Base Composite Action" +description: "Base build actions for Meshtastic Platform IO steps" runs: using: "composite" @@ -10,7 +10,7 @@ runs: submodules: "recursive" ref: ${{github.event.pull_request.head.ref}} repository: ${{github.event.pull_request.head.repo.full_name}} - + - name: Install cppcheck shell: bash run: | @@ -38,4 +38,4 @@ runs: - name: Upgrade platformio shell: bash run: | - pio upgrade \ No newline at end of file + pio upgrade diff --git a/.github/workflows/build_esp32.yml b/.github/workflows/build_esp32.yml index 74b71db50..7996a9b1b 100644 --- a/.github/workflows/build_esp32.yml +++ b/.github/workflows/build_esp32.yml @@ -7,7 +7,7 @@ on: required: true type: string -jobs: +jobs: build-esp32: runs-on: ubuntu-latest steps: @@ -31,7 +31,7 @@ jobs: - name: Remove debug flags for release if: ${{ github.event_name == 'workflow_dispatch' }} - run: | + run: | sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini @@ -46,7 +46,7 @@ jobs: file: "firmware.bin" target: "release/bleota.bin" token: ${{ secrets.GITHUB_TOKEN }} - + - name: Get release version string shell: bash run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT diff --git a/.github/workflows/build_nrf52.yml b/.github/workflows/build_nrf52.yml index cdf43c22e..33ee4d00c 100644 --- a/.github/workflows/build_nrf52.yml +++ b/.github/workflows/build_nrf52.yml @@ -7,7 +7,7 @@ on: required: true type: string -jobs: +jobs: build-nrf52: runs-on: ubuntu-latest steps: @@ -30,4 +30,4 @@ jobs: path: | release/*.uf2 release/*.elf - release/*.zip \ No newline at end of file + release/*.zip diff --git a/.github/workflows/build_rpi2040.yml b/.github/workflows/build_rpi2040.yml index fb7e3db5b..76ca2c20e 100644 --- a/.github/workflows/build_rpi2040.yml +++ b/.github/workflows/build_rpi2040.yml @@ -7,7 +7,7 @@ on: required: true type: string -jobs: +jobs: build-rpi2040: runs-on: ubuntu-latest steps: @@ -29,4 +29,4 @@ jobs: name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip path: | release/*.uf2 - release/*.elf \ No newline at end of file + release/*.elf diff --git a/.github/workflows/sec_sast_flawfinder.yml b/.github/workflows/sec_sast_flawfinder.yml index e2ba44090..2c7e751af 100644 --- a/.github/workflows/sec_sast_flawfinder.yml +++ b/.github/workflows/sec_sast_flawfinder.yml @@ -10,31 +10,31 @@ on: jobs: flawfinder: - runs-on: ubuntu-latest - name: Flawfinder + runs-on: ubuntu-latest + name: Flawfinder - steps: - # step 1 - - name: clone application source code - uses: actions/checkout@v3 + steps: + # step 1 + - name: clone application source code + uses: actions/checkout@v3 - # step 2 - - name: flawfinder_scan - uses: david-a-wheeler/flawfinder@2.0.19 - with: - arguments: '--sarif ./' - output: 'flawfinder_report.sarif' + # step 2 + - name: flawfinder_scan + uses: david-a-wheeler/flawfinder@2.0.19 + with: + arguments: "--sarif ./" + output: "flawfinder_report.sarif" - # step 3 - - name: save report as pipeline artifact - uses: actions/upload-artifact@v3 - with: - name: flawfinder_report.sarif - path: flawfinder_report.sarif + # step 3 + - name: save report as pipeline artifact + uses: actions/upload-artifact@v3 + with: + name: flawfinder_report.sarif + path: flawfinder_report.sarif - # step 4 - - name: publish code scanning alerts - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: flawfinder_report.sarif - category: flawfinder + # step 4 + - name: publish code scanning alerts + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: flawfinder_report.sarif + category: flawfinder diff --git a/.github/workflows/sec_sast_semgrep_cron.yml b/.github/workflows/sec_sast_semgrep_cron.yml index 426250280..cdd2c3c37 100644 --- a/.github/workflows/sec_sast_semgrep_cron.yml +++ b/.github/workflows/sec_sast_semgrep_cron.yml @@ -6,39 +6,37 @@ on: branches: - master schedule: - - cron: '0 1 * * 6' + - cron: "0 1 * * 6" jobs: - semgrep-full: - runs-on: ubuntu-latest - container: - image: returntocorp/semgrep + runs-on: ubuntu-latest + container: + image: returntocorp/semgrep - steps: + steps: + # step 1 + - name: clone application source code + uses: actions/checkout@v3 - # step 1 - - name: clone application source code - uses: actions/checkout@v3 + # step 2 + - name: full scan + run: | + semgrep \ + --sarif --output report.sarif \ + --metrics=off \ + --config="p/default" - # step 2 - - name: full scan - run: | - semgrep \ - --sarif --output report.sarif \ - --metrics=off \ - --config="p/default" + # step 3 + - name: save report as pipeline artifact + uses: actions/upload-artifact@v3 + with: + name: report.sarif + path: report.sarif - # step 3 - - name: save report as pipeline artifact - uses: actions/upload-artifact@v3 - with: - name: report.sarif - path: report.sarif - - # step 4 - - name: publish code scanning alerts - uses: github/codeql-action/upload-sarif@v2 - with: - sarif_file: report.sarif - category: semgrep + # step 4 + - name: publish code scanning alerts + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: report.sarif + category: semgrep diff --git a/.github/workflows/sec_sast_semgrep_pull.yml b/.github/workflows/sec_sast_semgrep_pull.yml index 8fe3632b4..1697ffb1b 100644 --- a/.github/workflows/sec_sast_semgrep_pull.yml +++ b/.github/workflows/sec_sast_semgrep_pull.yml @@ -1,17 +1,14 @@ --- name: Semgrep Differential Scan -on: - pull_request +on: pull_request jobs: - semgrep-diff: runs-on: ubuntu-latest container: image: returntocorp/semgrep steps: - # step 1 - name: clone application source code uses: actions/checkout@v3 diff --git a/.vscode/tasks.json b/.vscode/tasks.json index b2340005e..cdb8f5114 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,17 +1,15 @@ { - "version": "2.0.0", - "tasks": [ - { - "type": "PlatformIO", - "task": "Build", - "problemMatcher": [ - "$platformio" - ], - "group": { - "kind": "build", - "isDefault": true - }, - "label": "PlatformIO: Build" - } - ] -} \ No newline at end of file + "version": "2.0.0", + "tasks": [ + { + "type": "PlatformIO", + "task": "Build", + "problemMatcher": ["$platformio"], + "group": { + "kind": "build", + "isDefault": true + }, + "label": "PlatformIO: Build" + } + ] +} diff --git a/bin/readprops.py b/bin/readprops.py index c23092e41..ffa361541 100644 --- a/bin/readprops.py +++ b/bin/readprops.py @@ -22,9 +22,9 @@ def readProps(prefsLoc): isDirty = subprocess.check_output( ['git', 'diff', 'HEAD']).decode("utf-8").strip() suffix = sha - if isDirty: - # short for 'dirty', we want to keep our verstrings source for protobuf reasons - suffix = sha + "-d" + # if isDirty: + # # short for 'dirty', we want to keep our verstrings source for protobuf reasons + # suffix = sha + "-d" verObj['long'] = "{}.{}.{}.{}".format( version["major"], version["minor"], version["build"], suffix) except: diff --git a/protobufs b/protobufs index 8cb6ed3c9..22ffb71c3 160000 --- a/protobufs +++ b/protobufs @@ -1 +1 @@ -Subproject commit 8cb6ed3c91e23062cf0a4b8e50e4f98ef36170d3 +Subproject commit 22ffb71c35ee7f097b9fb54d282f9c1d3f3d953f diff --git a/src/concurrency/OSThread.cpp b/src/concurrency/OSThread.cpp index c52efd626..af50d28f5 100644 --- a/src/concurrency/OSThread.cpp +++ b/src/concurrency/OSThread.cpp @@ -1,9 +1,5 @@ #include "OSThread.h" #include "configuration.h" -#ifdef HAS_SCREEN -#include "graphics/Screen.h" -#endif -#include "main.h" #include namespace concurrency @@ -83,21 +79,12 @@ void OSThread::run() #endif currentThread = this; auto newDelay = runOnce(); -#ifdef ARCH_ESP32 - auto newHeap = ESP.getFreeHeap(); - if (newHeap < 10000) { - LOG_DEBUG("\n\n====== heap too low [10000] -> reboot in 5s ======\n\n"); -#ifdef HAS_SCREEN - screen->startRebootScreen(); -#endif - rebootAtMsec = millis() + 5000; - } #ifdef DEBUG_HEAP + auto newHeap = ESP.getFreeHeap(); if (newHeap < heap) LOG_DEBUG("------ Thread %s leaked heap %d -> %d (%d) ------\n", ThreadName.c_str(), heap, newHeap, newHeap - heap); if (heap < newHeap) LOG_DEBUG("++++++ Thread %s freed heap %d -> %d (%d) ++++++\n", ThreadName.c_str(), heap, newHeap, newHeap - heap); -#endif #endif runned(); diff --git a/src/gps/GPS.cpp b/src/gps/GPS.cpp index 4368bc3a7..1b7c8511f 100644 --- a/src/gps/GPS.cpp +++ b/src/gps/GPS.cpp @@ -190,7 +190,6 @@ bool GPS::setupGPS() // Switch to Vehicle Mode, since SoftRF enables Aviation < 2g _serial_gps->write("$PCAS11,3*1E\r\n"); delay(250); - } else if (gnssModel == GNSS_MODEL_UBLOX) { /* @@ -429,6 +428,10 @@ void GPS::publishUpdate() int32_t GPS::runOnce() { + // Repeaters have no need for GPS + if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) + disable(); + if (whileIdle()) { // if we have received valid NMEA claim we are connected setConnected(); diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 1c56244bf..5ce2a5152 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -618,7 +618,6 @@ static void drawGPScoordinates(OLEDDisplay *display, int16_t x, int16_t y, const } else { display->drawString(x + (SCREEN_WIDTH - (display->getStringWidth(coordinateLine))) / 2, y, coordinateLine); } - } else { char latLine[22]; char lonLine[22]; @@ -1703,6 +1702,9 @@ void DebugInfo::drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *stat case meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST: mode = "LongF"; break; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: + mode = "LongM"; + break; case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW: mode = "VeryL"; break; diff --git a/src/main.cpp b/src/main.cpp index 4f72be7da..4f65ff51b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -128,6 +128,17 @@ static int32_t ledBlinker() setLed(ledOn); +#ifdef ARCH_ESP32 + auto newHeap = ESP.getFreeHeap(); + if (newHeap < 11000) { + LOG_DEBUG("\n\n====== heap too low [11000] -> reboot in 1s ======\n\n"); +#ifdef HAS_SCREEN + screen->startRebootScreen(); +#endif + rebootAtMsec = millis() + 900; + } +#endif + // have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that return powerStatus->getIsCharging() ? 1000 : (ledOn ? 1 : 1000); } @@ -299,6 +310,10 @@ void setup() // but we need to do this after main cpu iniot (esp32setup), because we need the random seed set nodeDB.init(); + // If we're taking on the repeater role, use flood router + if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) + router = new FloodingRouter(); + playStartMelody(); // fixed screen override? diff --git a/src/mesh/FloodingRouter.cpp b/src/mesh/FloodingRouter.cpp index 6fd4d0401..16c20d7a2 100644 --- a/src/mesh/FloodingRouter.cpp +++ b/src/mesh/FloodingRouter.cpp @@ -48,15 +48,13 @@ void FloodingRouter::sniffReceived(const meshtastic_MeshPacket *p, const meshtas traceRouteModule->updateRoute(tosend); } - LOG_INFO("Rebroadcasting received floodmsg to neighbors", p); + LOG_INFO("Rebroadcasting received floodmsg to neighbors\n"); // Note: we are careful to resend using the original senders node id // We are careful not to call our hooked version of send() - because we don't want to check this again Router::send(tosend); - } else { LOG_DEBUG("Not rebroadcasting. Role = Role_ClientMute\n"); } - } else { LOG_DEBUG("Ignoring a simple (0 id) broadcast\n"); } diff --git a/src/mesh/NodeDB.cpp b/src/mesh/NodeDB.cpp index cfb815d1e..3961c4ae2 100644 --- a/src/mesh/NodeDB.cpp +++ b/src/mesh/NodeDB.cpp @@ -225,6 +225,25 @@ void NodeDB::installDefaultModuleConfig() initModuleConfigIntervals(); } +void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role) +{ + if (role == meshtastic_Config_DeviceConfig_Role_ROUTER) { + initConfigIntervals(); + initModuleConfigIntervals(); + } else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) { + config.display.screen_on_secs = 1; + meshtastic_Channel &ch = channels.getByIndex(channels.getPrimaryIndex()); + meshtastic_ChannelSettings &channelSettings = ch.settings; + uint8_t defaultpskIndex = 1; + channelSettings.psk.bytes[0] = defaultpskIndex; + channelSettings.psk.size = 1; + } else if (role == meshtastic_Config_DeviceConfig_Role_TRACKER) { + config.position.position_broadcast_smart_enabled = false; + config.position.position_broadcast_secs = 120; + config.position.gps_update_interval = 60; + } +} + void NodeDB::initModuleConfigIntervals() { moduleConfig.telemetry.device_update_interval = default_broadcast_interval_secs; @@ -609,13 +628,11 @@ void NodeDB::updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSou LOG_INFO("updatePosition LOCAL pos@%x, time=%u, latI=%d, lonI=%d, alt=%d\n", p.timestamp, p.time, p.latitude_i, p.longitude_i, p.altitude); info->position = p; - } else if ((p.time > 0) && !p.latitude_i && !p.longitude_i && !p.timestamp && !p.location_source) { // FIXME SPECIAL TIME SETTING PACKET FROM EUD TO RADIO // (stop-gap fix for issue #900) LOG_DEBUG("updatePosition SPECIAL time setting time=%u\n", p.time); info->position.time = p.time; - } else { // Be careful to only update fields that have been set by the REMOTE sender // A lot of position reports don't have time populated. In that case, be careful to not blow away the time we diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index c169a85cd..106d35402 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -129,6 +129,8 @@ class NodeDB bool loadProto(const char *filename, size_t protoSize, size_t objSize, const pb_msgdesc_t *fields, void *dest_struct); bool saveProto(const char *filename, size_t protoSize, const pb_msgdesc_t *fields, const void *dest_struct); + void installRoleDefaults(meshtastic_Config_DeviceConfig_Role role); + private: /// Find a node in our DB, create an empty NodeInfo if missing meshtastic_NodeInfo *getOrCreateNode(NodeNum n); diff --git a/src/mesh/RadioInterface.cpp b/src/mesh/RadioInterface.cpp index 3c59867f6..d7c1e1aec 100644 --- a/src/mesh/RadioInterface.cpp +++ b/src/mesh/RadioInterface.cpp @@ -401,13 +401,18 @@ void RadioInterface::applyModemConfig() cr = 8; sf = 11; break; + case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE: + bw = (myRegion->wideLora) ? 406.25 : 125; + cr = 8; + sf = 11; + break; case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW: bw = (myRegion->wideLora) ? 406.25 : 125; cr = 8; sf = 12; break; case meshtastic_Config_LoRaConfig_ModemPreset_VERY_LONG_SLOW: - bw = (myRegion->wideLora) ? 203.125 : 31.25; + bw = (myRegion->wideLora) ? 203.125 : 62.5; cr = 8; sf = 12; break; diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 0cb7ee8be..15bcc1d2a 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -301,8 +301,6 @@ void Router::sniffReceived(const meshtastic_MeshPacket *p, const meshtastic_Rout bool perhapsDecode(meshtastic_MeshPacket *p) { - // LOG_DEBUG("\n\n** perhapsDecode payloadVariant - %d\n\n", p->which_payloadVariant); - if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) return true; // If packet was already decoded just return @@ -367,7 +365,6 @@ meshtastic_Routing_Error perhapsEncode(meshtastic_MeshPacket *p) { // If the packet is not yet encrypted, do so now if (p->which_payload_variant == meshtastic_MeshPacket_decoded_tag) { - size_t numbytes = pb_encode_to_bytes(bytes, sizeof(bytes), &meshtastic_Data_msg, &p->decoded); // Only allow encryption on the text message app. @@ -454,7 +451,7 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src) else printPacket("handleReceived(REMOTE)", p); } else { - printPacket("packet decoding failed (no PSK?)", p); + printPacket("packet decoding failed or skipped (no PSK?)", p); } // call modules here diff --git a/src/mesh/Router.h b/src/mesh/Router.h index 8e116dca0..f43f92158 100644 --- a/src/mesh/Router.h +++ b/src/mesh/Router.h @@ -73,9 +73,6 @@ class Router : protected concurrency::OSThread */ void enqueueReceivedMessage(meshtastic_MeshPacket *p); - protected: - friend class RoutingModule; - /** * Send a packet on a suitable interface. This routine will * later free() the packet to pool. This routine is not allowed to stall. @@ -85,6 +82,9 @@ class Router : protected concurrency::OSThread */ virtual ErrorCode send(meshtastic_MeshPacket *p); + protected: + friend class RoutingModule; + /** * Should this incoming filter be dropped? * diff --git a/src/mesh/generated/meshtastic/admin.pb.h b/src/mesh/generated/meshtastic/admin.pb.h index 5caa22bb7..c47fb886f 100644 --- a/src/mesh/generated/meshtastic/admin.pb.h +++ b/src/mesh/generated/meshtastic/admin.pb.h @@ -112,13 +112,6 @@ typedef struct _meshtastic_AdminMessage { bool begin_edit_settings; /* Commits an open transaction for any edits made to config, module config, owner, and channel settings */ bool commit_edit_settings; - /* Setting channels/radio config remotely carries the risk that you might send an invalid config and the radio never talks to your mesh again. - Therefore if setting either of these properties remotely, you must send a confirm_xxx message within 10 minutes. - If you fail to do so, the radio will assume loss of comms and revert your changes. - These messages are optional when changing the local node. */ - bool confirm_set_channel; - /* TODO: REPLACE */ - bool confirm_set_radio; /* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot) Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. */ int32_t reboot_ota_seconds; @@ -181,8 +174,6 @@ extern "C" { #define meshtastic_AdminMessage_set_ringtone_message_tag 37 #define meshtastic_AdminMessage_begin_edit_settings_tag 64 #define meshtastic_AdminMessage_commit_edit_settings_tag 65 -#define meshtastic_AdminMessage_confirm_set_channel_tag 66 -#define meshtastic_AdminMessage_confirm_set_radio_tag 67 #define meshtastic_AdminMessage_reboot_ota_seconds_tag 95 #define meshtastic_AdminMessage_exit_simulator_tag 96 #define meshtastic_AdminMessage_reboot_seconds_tag 97 @@ -214,8 +205,6 @@ X(a, STATIC, ONEOF, STRING, (payload_variant,set_canned_message_module_me X(a, STATIC, ONEOF, STRING, (payload_variant,set_ringtone_message,set_ringtone_message), 37) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_channel,confirm_set_channel), 66) \ -X(a, STATIC, ONEOF, BOOL, (payload_variant,confirm_set_radio,confirm_set_radio), 67) \ X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \ X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \ X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_seconds), 97) \ diff --git a/src/mesh/generated/meshtastic/config.pb.h b/src/mesh/generated/meshtastic/config.pb.h index 907824fb2..ff602b668 100644 --- a/src/mesh/generated/meshtastic/config.pb.h +++ b/src/mesh/generated/meshtastic/config.pb.h @@ -19,11 +19,19 @@ typedef enum _meshtastic_Config_DeviceConfig_Role { meshtastic_Config_DeviceConfig_Role_CLIENT_MUTE = 1, /* Router device role. Mesh packets will prefer to be routed over this node. This node will not be used by client apps. - The wifi/ble radios and the oled screen will be put to sleep. */ + The wifi/ble radios and the oled screen will be put to sleep. + This mode may still potentially have higher power usage due to it's preference in message rebroadcasting on the mesh. */ meshtastic_Config_DeviceConfig_Role_ROUTER = 2, /* Router Client device role Mesh packets will prefer to be routed over this node. The Router Client can be used as both a Router and an app connected Client. */ - meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT = 3 + meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT = 3, + /* Repeater device role + Mesh packets will simply be rebroadcasted over this node. Nodes under this role node will not originate NodeInfo, Position, Telemetry + or any other packet type. They will simply rebroadcast any mesh packets on the same frequency, channel num, spread factory, and coding rate. */ + meshtastic_Config_DeviceConfig_Role_REPEATER = 4, + /* Tracker device role + Position Mesh packets for will be higher priority and sent more frequently by default. */ + meshtastic_Config_DeviceConfig_Role_TRACKER = 5 } meshtastic_Config_DeviceConfig_Role; /* Bit field of boolean configuration options, indicating which optional @@ -172,7 +180,9 @@ typedef enum _meshtastic_Config_LoRaConfig_ModemPreset { /* Short Range - Slow */ meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW = 5, /* Short Range - Fast */ - meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST = 6 + meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST = 6, + /* Long Range - Moderately Fast */ + meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE = 7 } meshtastic_Config_LoRaConfig_ModemPreset; typedef enum _meshtastic_Config_BluetoothConfig_PairingMode { @@ -419,8 +429,8 @@ extern "C" { /* Helper constants for enums */ #define _meshtastic_Config_DeviceConfig_Role_MIN meshtastic_Config_DeviceConfig_Role_CLIENT -#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT -#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_ROUTER_CLIENT+1)) +#define _meshtastic_Config_DeviceConfig_Role_MAX meshtastic_Config_DeviceConfig_Role_TRACKER +#define _meshtastic_Config_DeviceConfig_Role_ARRAYSIZE ((meshtastic_Config_DeviceConfig_Role)(meshtastic_Config_DeviceConfig_Role_TRACKER+1)) #define _meshtastic_Config_PositionConfig_PositionFlags_MIN meshtastic_Config_PositionConfig_PositionFlags_UNSET #define _meshtastic_Config_PositionConfig_PositionFlags_MAX meshtastic_Config_PositionConfig_PositionFlags_SPEED @@ -451,8 +461,8 @@ extern "C" { #define _meshtastic_Config_LoRaConfig_RegionCode_ARRAYSIZE ((meshtastic_Config_LoRaConfig_RegionCode)(meshtastic_Config_LoRaConfig_RegionCode_UA_868+1)) #define _meshtastic_Config_LoRaConfig_ModemPreset_MIN meshtastic_Config_LoRaConfig_ModemPreset_LONG_FAST -#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST -#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST+1)) +#define _meshtastic_Config_LoRaConfig_ModemPreset_MAX meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE +#define _meshtastic_Config_LoRaConfig_ModemPreset_ARRAYSIZE ((meshtastic_Config_LoRaConfig_ModemPreset)(meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE+1)) #define _meshtastic_Config_BluetoothConfig_PairingMode_MIN meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN #define _meshtastic_Config_BluetoothConfig_PairingMode_MAX meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index b67751bf2..18557f0b3 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -225,7 +225,7 @@ void AdminModule::handleSetOwner(const meshtastic_User &o) void AdminModule::handleSetConfig(const meshtastic_Config &c) { - bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER); + auto existingRole = config.device.role; bool isRegionUnset = (config.lora.region == meshtastic_Config_LoRaConfig_RegionCode_UNSET); switch (c.which_payload_variant) { @@ -234,10 +234,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) config.has_device = true; config.device = c.payload_variant.device; // If we're setting router role for the first time, install its intervals - if (!isRouter && c.payload_variant.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER) { - nodeDB.initConfigIntervals(); - nodeDB.initModuleConfigIntervals(); - } + if (existingRole != c.payload_variant.device.role) + nodeDB.installRoleDefaults(c.payload_variant.device.role); break; case meshtastic_Config_position_tag: LOG_INFO("Setting config: Position\n"); diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index aacb77151..e8481356b 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -33,51 +33,56 @@ */ void setupModules() { + if (config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER) { #if HAS_BUTTON - inputBroker = new InputBroker(); + inputBroker = new InputBroker(); #endif - adminModule = new AdminModule(); - nodeInfoModule = new NodeInfoModule(); - positionModule = new PositionModule(); - waypointModule = new WaypointModule(); - textMessageModule = new TextMessageModule(); - traceRouteModule = new TraceRouteModule(); + adminModule = new AdminModule(); + nodeInfoModule = new NodeInfoModule(); + positionModule = new PositionModule(); + waypointModule = new WaypointModule(); + textMessageModule = new TextMessageModule(); + traceRouteModule = new TraceRouteModule(); - // Note: if the rest of meshtastic doesn't need to explicitly use your module, you do not need to assign the instance - // to a global variable. + // Note: if the rest of meshtastic doesn't need to explicitly use your module, you do not need to assign the instance + // to a global variable. - new RemoteHardwareModule(); - new ReplyModule(); + new RemoteHardwareModule(); + new ReplyModule(); #if HAS_BUTTON - rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1(); - rotaryEncoderInterruptImpl1->init(); - upDownInterruptImpl1 = new UpDownInterruptImpl1(); - upDownInterruptImpl1->init(); - cardKbI2cImpl = new CardKbI2cImpl(); - cardKbI2cImpl->init(); + rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1(); + rotaryEncoderInterruptImpl1->init(); + upDownInterruptImpl1 = new UpDownInterruptImpl1(); + upDownInterruptImpl1->init(); + cardKbI2cImpl = new CardKbI2cImpl(); + cardKbI2cImpl->init(); #endif #if HAS_SCREEN - cannedMessageModule = new CannedMessageModule(); + cannedMessageModule = new CannedMessageModule(); #endif #if HAS_TELEMETRY - new DeviceTelemetryModule(); - new EnvironmentTelemetryModule(); + new DeviceTelemetryModule(); + new EnvironmentTelemetryModule(); #endif #if (defined(ARCH_ESP32) || defined(ARCH_NRF52)) && !defined(TTGO_T_ECHO) && !defined(CONFIG_IDF_TARGET_ESP32S2) - new SerialModule(); + new SerialModule(); #endif #ifdef ARCH_ESP32 - // Only run on an esp32 based device. - audioModule = new AudioModule(); - externalNotificationModule = new ExternalNotificationModule(); + // Only run on an esp32 based device. + audioModule = new AudioModule(); + externalNotificationModule = new ExternalNotificationModule(); - storeForwardModule = new StoreForwardModule(); + storeForwardModule = new StoreForwardModule(); - new RangeTestModule(); + new RangeTestModule(); #elif defined(ARCH_NRF52) - externalNotificationModule = new ExternalNotificationModule(); + externalNotificationModule = new ExternalNotificationModule(); #endif - - // NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra acks + } else { + adminModule = new AdminModule(); + traceRouteModule = new TraceRouteModule(); + } + // NOTE! This module must be added LAST because it likes to check for replies from other modules and avoid sending extra + // acks routingModule = new RoutingModule(); } diff --git a/src/modules/PositionModule.cpp b/src/modules/PositionModule.cpp index ee3ba493f..d923dad8a 100644 --- a/src/modules/PositionModule.cpp +++ b/src/modules/PositionModule.cpp @@ -129,7 +129,10 @@ void PositionModule::sendOurPosition(NodeNum dest, bool wantReplies) meshtastic_MeshPacket *p = allocReply(); p->to = dest; p->decoded.want_response = wantReplies; - p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; + if (config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER) + p->priority = meshtastic_MeshPacket_Priority_RELIABLE; + else + p->priority = meshtastic_MeshPacket_Priority_BACKGROUND; prevPacketId = p->id; service.sendToMesh(p, RX_SRC_LOCAL, true); @@ -161,7 +164,6 @@ int32_t PositionModule::runOnce() sendOurPosition(NODENUM_BROADCAST, requestReplies); } } - } else if (config.position.position_broadcast_smart_enabled) { // Only send packets if the channel is less than 25% utilized. diff --git a/src/modules/RoutingModule.cpp b/src/modules/RoutingModule.cpp index bf3739f2c..f91d32a20 100644 --- a/src/modules/RoutingModule.cpp +++ b/src/modules/RoutingModule.cpp @@ -24,6 +24,8 @@ bool RoutingModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mesh meshtastic_MeshPacket *RoutingModule::allocReply() { + if (config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER) + return NULL; assert(currentRequest); // We only consider making replies if the request was a legit routing packet (not just something we were sniffing) diff --git a/version.properties b/version.properties index 7cf773466..8ad7a80c8 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ [VERSION] major = 2 minor = 0 -build = 14 +build = 16