diff --git a/.github/workflows/main_matrix.yml b/.github/workflows/main_matrix.yml index 6d509bd7d..6b48e8128 100644 --- a/.github/workflows/main_matrix.yml +++ b/.github/workflows/main_matrix.yml @@ -201,6 +201,7 @@ jobs: ./device-*.bat ./littlefs-*.bin ./bleota*bin + ./mt-*-ota.bin ./Meshtastic_nRF52_factory_erase*.uf2 retention-days: 30 diff --git a/.gitignore b/.gitignore index 06e8c472f..769603202 100644 --- a/.gitignore +++ b/.gitignore @@ -48,5 +48,5 @@ arduino-lib-builder* dependencies.lock idf_component.yml CMakeLists.txt -sdkconfig.* +/sdkconfig.* .dummy/* diff --git a/bin/config-dist.yaml b/bin/config-dist.yaml index adf804ba9..3c996051e 100644 --- a/bin/config-dist.yaml +++ b/bin/config-dist.yaml @@ -105,6 +105,8 @@ Lora: GPS: # SerialPath: /dev/ttyS0 +# ExtraPins: +# - 22 ### Specify I2C device, or leave blank for none diff --git a/platformio.ini b/platformio.ini index 546de2df3..6923c65b9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -114,8 +114,7 @@ lib_deps = [radiolib_base] lib_deps = # renovate: datasource=custom.pio depName=RadioLib packageName=jgromes/library/RadioLib - # jgromes/RadioLib@7.4.0 - https://github.com/jgromes/RadioLib/archive/536c7267362e2c1345be7054ba45e503252975ff.zip + jgromes/RadioLib@7.5.0 [device-ui_base] lib_deps = diff --git a/src/DebugConfiguration.cpp b/src/DebugConfiguration.cpp index d65c4f1e8..08c7abc04 100644 --- a/src/DebugConfiguration.cpp +++ b/src/DebugConfiguration.cpp @@ -41,7 +41,8 @@ extern "C" void logLegacy(const char *level, const char *fmt, ...) } #if HAS_NETWORKING - +namespace meshtastic +{ Syslog::Syslog(UDP &client) { this->_client = &client; @@ -195,4 +196,6 @@ inline bool Syslog::_sendLog(uint16_t pri, const char *appName, const char *mess return true; } +}; // namespace meshtastic + #endif diff --git a/src/DebugConfiguration.h b/src/DebugConfiguration.h index 98bbe0f72..eac6260fc 100644 --- a/src/DebugConfiguration.h +++ b/src/DebugConfiguration.h @@ -162,6 +162,8 @@ extern "C" void logLegacy(const char *level, const char *fmt, ...); #if HAS_NETWORKING +namespace meshtastic +{ class Syslog { private: @@ -195,4 +197,6 @@ class Syslog bool vlogf(uint16_t pri, const char *appName, const char *fmt, va_list args) __attribute__((format(printf, 3, 0))); }; -#endif // HAS_NETWORKING \ No newline at end of file +}; // namespace meshtastic + +#endif // HAS_NETWORKING diff --git a/src/RedirectablePrint.cpp b/src/RedirectablePrint.cpp index 895dcb147..e15d56912 100644 --- a/src/RedirectablePrint.cpp +++ b/src/RedirectablePrint.cpp @@ -18,7 +18,7 @@ #endif #if HAS_NETWORKING -extern Syslog syslog; +extern meshtastic::Syslog syslog; #endif void RedirectablePrint::rpInit() { diff --git a/src/mesh/NodeDB.h b/src/mesh/NodeDB.h index 817e31617..adf2b42ea 100644 --- a/src/mesh/NodeDB.h +++ b/src/mesh/NodeDB.h @@ -378,6 +378,8 @@ extern meshtastic_CriticalErrorCode error_code; extern uint32_t error_address; #define NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_SHIFT 0 #define NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK (1 << NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_SHIFT) +#define NODEINFO_BITFIELD_IS_MUTED_SHIFT 1 +#define NODEINFO_BITFIELD_IS_MUTED_MASK (1 << NODEINFO_BITFIELD_IS_MUTED_SHIFT) #define Module_Config_size \ (ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \ diff --git a/src/mesh/TypeConversions.cpp b/src/mesh/TypeConversions.cpp index 17cd92851..75195bd42 100644 --- a/src/mesh/TypeConversions.cpp +++ b/src/mesh/TypeConversions.cpp @@ -14,6 +14,7 @@ meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfo info.is_favorite = lite->is_favorite; info.is_ignored = lite->is_ignored; info.is_key_manually_verified = lite->bitfield & NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK; + info.is_muted = lite->bitfield & NODEINFO_BITFIELD_IS_MUTED_MASK; if (lite->has_hops_away) { info.has_hops_away = true; diff --git a/src/mesh/eth/ethClient.cpp b/src/mesh/eth/ethClient.cpp index 2b4f63512..a811ec16c 100644 --- a/src/mesh/eth/ethClient.cpp +++ b/src/mesh/eth/ethClient.cpp @@ -21,7 +21,7 @@ uint32_t ntp_renew = 0; #endif EthernetUDP syslogClient; -Syslog syslog(syslogClient); +meshtastic::Syslog syslog(syslogClient); bool ethStartupComplete = 0; diff --git a/src/mesh/wifi/WiFiAPClient.cpp b/src/mesh/wifi/WiFiAPClient.cpp index 45944872e..a95dfa58f 100644 --- a/src/mesh/wifi/WiFiAPClient.cpp +++ b/src/mesh/wifi/WiFiAPClient.cpp @@ -58,7 +58,7 @@ bool needReconnect = true; // If we create our reconnector, run it once at the bool isReconnecting = false; // If we are currently reconnecting WiFiUDP syslogClient; -Syslog syslog(syslogClient); +meshtastic::Syslog syslog(syslogClient); Periodic *wifiReconnect; diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index 5f0c27fff..5eac64a62 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -383,6 +383,16 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta } break; } + case meshtastic_AdminMessage_toggle_muted_node_tag: { + LOG_INFO("Client received toggle_muted_node command"); + meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(r->toggle_muted_node); + if (node != NULL) { + node->bitfield ^= (1 << NODEINFO_BITFIELD_IS_MUTED_SHIFT); + saveChanges(SEGMENT_NODEDATABASE, false); + } + break; + } + case meshtastic_AdminMessage_set_fixed_position_tag: { LOG_INFO("Client received set_fixed_position command"); meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeDB->getNodeNum()); diff --git a/src/modules/ExternalNotificationModule.cpp b/src/modules/ExternalNotificationModule.cpp index 3f6375a65..04fcd8e73 100644 --- a/src/modules/ExternalNotificationModule.cpp +++ b/src/modules/ExternalNotificationModule.cpp @@ -459,7 +459,13 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP } } + meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(mp.from); + bool mutedNode = false; + if (sender) { + mutedNode = (sender->bitfield & NODEINFO_BITFIELD_IS_MUTED_MASK); + } meshtastic_Channel ch = channels.getByIndex(mp.channel ? mp.channel : channels.getPrimaryIndex()); + if (moduleConfig.external_notification.alert_bell) { if (containsBell) { LOG_INFO("externalNotificationModule - Notification Bell"); @@ -510,7 +516,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP } } - if (moduleConfig.external_notification.alert_message && + if (moduleConfig.external_notification.alert_message && !mutedNode && (!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) { LOG_INFO("externalNotificationModule - Notification Module"); isNagging = true; @@ -522,7 +528,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP } } - if (moduleConfig.external_notification.alert_message_vibra && + if (moduleConfig.external_notification.alert_message_vibra && !mutedNode && (!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) { LOG_INFO("externalNotificationModule - Notification Module (Vibra)"); isNagging = true; @@ -534,7 +540,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP } } - if (moduleConfig.external_notification.alert_message_buzzer && + if (moduleConfig.external_notification.alert_message_buzzer && !mutedNode && (!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) { LOG_INFO("externalNotificationModule - Notification Module (Buzzer)"); if (config.device.buzzer_mode != meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY || diff --git a/src/modules/esp32/PaxcounterModule.h b/src/modules/esp32/PaxcounterModule.h index ebd6e7191..50656e32e 100644 --- a/src/modules/esp32/PaxcounterModule.h +++ b/src/modules/esp32/PaxcounterModule.h @@ -2,7 +2,7 @@ #include "ProtobufModule.h" #include "configuration.h" -#if defined(ARCH_ESP32) +#if defined(ARCH_ESP32) && !MESHTASTIC_EXCLUDE_PAXCOUNTER #include "../mesh/generated/meshtastic/paxcount.pb.h" #include "NodeDB.h" #include @@ -35,4 +35,4 @@ class PaxcounterModule : private concurrency::OSThread, public ProtobufModulepin; } + for (auto i : portduino_config.extra_pins) { + if (i.enabled && i.pin > max_GPIO) + max_GPIO = i.pin; + } + gpioInit(max_GPIO + 1); // Done here so we can inform Portduino how many GPIOs we need. // Need to bind all the configured GPIO pins so they're not simulated @@ -504,6 +509,19 @@ void portduinoSetup() } } } + for (auto i : portduino_config.extra_pins) { + // In the case of a ch341 Lora device, we don't want to touch the system GPIO lines for Lora + // Those GPIO are handled in our usermode driver instead. + if (i.config_section == "Lora" && portduino_config.lora_spi_dev == "ch341") { + continue; + } + if (i.enabled) { + if (initGPIOPin(i.pin, gpioChipName + std::to_string(i.gpiochip), i.line) != ERRNO_OK) { + printf("Error setting pin number %d. It may not exist, or may already be in use.\n", i.line); + exit(EXIT_FAILURE); + } + } + } // Only initialize the radio pins when dealing with real, kernel controlled SPI hardware if (portduino_config.lora_spi_dev != "" && portduino_config.lora_spi_dev != "ch341") { @@ -717,6 +735,16 @@ bool loadConfig(const char *configPath) portduino_config.has_gps = 1; } } + if (yamlConfig["GPIO"]["ExtraPins"]) { + for (auto extra_pin : yamlConfig["GPIO"]["ExtraPins"]) { + portduino_config.extra_pins.push_back(pinMapping()); + portduino_config.extra_pins.back().config_section = "GPIO"; + portduino_config.extra_pins.back().config_name = "ExtraPins"; + portduino_config.extra_pins.back().enabled = true; + readGPIOFromYaml(extra_pin, portduino_config.extra_pins.back()); + } + } + if (yamlConfig["I2C"]) { portduino_config.i2cdev = yamlConfig["I2C"]["I2CDevice"].as(""); } diff --git a/src/platform/portduino/PortduinoGlue.h b/src/platform/portduino/PortduinoGlue.h index 9335be90a..8992f5f1a 100644 --- a/src/platform/portduino/PortduinoGlue.h +++ b/src/platform/portduino/PortduinoGlue.h @@ -2,6 +2,7 @@ #include #include #include +#include #include "LR11x0Interface.h" #include "Module.h" @@ -97,6 +98,7 @@ extern struct portduino_config_struct { pinMapping lora_txen_pin = {"Lora", "TXen"}; pinMapping lora_rxen_pin = {"Lora", "RXen"}; pinMapping lora_sx126x_ant_sw_pin = {"Lora", "SX126X_ANT_SW"}; + std::vector extra_pins = {}; // GPS bool has_gps = false; @@ -300,6 +302,20 @@ extern struct portduino_config_struct { } out << YAML::EndMap; // Lora + if (!extra_pins.empty()) { + out << YAML::Key << "GPIO" << YAML::Value << YAML::BeginMap; + out << YAML::Key << "ExtraPins" << YAML::Value << YAML::BeginSeq; + for (auto extra : extra_pins) { + out << YAML::BeginMap; + out << YAML::Key << "pin" << YAML::Value << extra.pin; + out << YAML::Key << "line" << YAML::Value << extra.line; + out << YAML::Key << "gpiochip" << YAML::Value << extra.gpiochip; + out << YAML::EndMap; + } + out << YAML::EndSeq; + out << YAML::EndMap; // GPIO + } + if (i2cdev != "") { out << YAML::Key << "I2C" << YAML::Value << YAML::BeginMap; out << YAML::Key << "I2CDevice" << YAML::Value << i2cdev; diff --git a/variants/esp32/esp32-common.ini b/variants/esp32/esp32-common.ini index e582b6880..81a49223b 100644 --- a/variants/esp32/esp32-common.ini +++ b/variants/esp32/esp32-common.ini @@ -65,8 +65,6 @@ lib_deps = https://github.com/dbinfrago/libpax/archive/3cdc0371c375676a97967547f4065607d4c53fd1.zip # renovate: datasource=github-tags depName=XPowersLib packageName=lewisxhe/XPowersLib https://github.com/lewisxhe/XPowersLib/archive/v0.3.2.zip - # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master - https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip # renovate: datasource=custom.pio depName=rweather/Crypto packageName=rweather/library/Crypto rweather/Crypto@0.4.0 diff --git a/variants/esp32/esp32.ini b/variants/esp32/esp32.ini index d1a8a63b0..5999bc098 100644 --- a/variants/esp32/esp32.ini +++ b/variants/esp32/esp32.ini @@ -5,4 +5,5 @@ extends = esp32_common custom_esp32_kind = esp32 build_flags = - ${esp32_common.build_flags} \ No newline at end of file + ${esp32_common.build_flags} + -DMESHTASTIC_EXCLUDE_AUDIO=1 diff --git a/variants/esp32c3/esp32c3.ini b/variants/esp32c3/esp32c3.ini index 2d7ae71bc..e5f117ad7 100644 --- a/variants/esp32c3/esp32c3.ini +++ b/variants/esp32c3/esp32c3.ini @@ -4,3 +4,8 @@ custom_esp32_kind = esp32c3 monitor_speed = 115200 monitor_filters = esp32_c3_exception_decoder + +lib_deps = + ${esp32_common.lib_deps} + # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master + https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip diff --git a/variants/esp32s2/esp32s2.ini b/variants/esp32s2/esp32s2.ini index c806943ee..836e31d8d 100644 --- a/variants/esp32s2/esp32s2.ini +++ b/variants/esp32s2/esp32s2.ini @@ -12,7 +12,12 @@ build_flags = -DHAS_BLUETOOTH=0 -DMESHTASTIC_EXCLUDE_PAXCOUNTER -DMESHTASTIC_EXCLUDE_BLUETOOTH - + +lib_deps = + ${esp32_common.lib_deps} + # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master + https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip + lib_ignore = ${esp32_common.lib_ignore} NimBLE-Arduino diff --git a/variants/esp32s3/esp32s3.ini b/variants/esp32s3/esp32s3.ini index 5e333f3ce..299415442 100644 --- a/variants/esp32s3/esp32s3.ini +++ b/variants/esp32s3/esp32s3.ini @@ -3,3 +3,8 @@ extends = esp32_common custom_esp32_kind = esp32s3 monitor_speed = 115200 + +lib_deps = + ${esp32_common.lib_deps} + # renovate: datasource=git-refs depName=meshtastic-ESP32_Codec2 packageName=https://github.com/meshtastic/ESP32_Codec2 gitBranch=master + https://github.com/meshtastic/ESP32_Codec2/archive/633326c78ac251c059ab3a8c430fcdf25b41672f.zip