Merge branch 'master' of https://github.com/meshtastic/firmware into add-meshtiny

This commit is contained in:
whywilson 2025-07-26 19:55:42 +08:00
commit 90e3820616
5 changed files with 42 additions and 19 deletions

View File

@ -146,7 +146,7 @@ class MeshService
virtual void sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m); virtual void sendMqttMessageToClientProxy(meshtastic_MqttClientProxyMessage *m);
/// Send a ClientNotification to the phone /// Send a ClientNotification to the phone
void sendClientNotification(meshtastic_ClientNotification *cn); virtual void sendClientNotification(meshtastic_ClientNotification *cn);
/// Send an error response to the phone /// Send an error response to the phone
void sendRoutingErrorResponse(meshtastic_Routing_Error error, const meshtastic_MeshPacket *mp); void sendRoutingErrorResponse(meshtastic_Routing_Error error, const meshtastic_MeshPacket *mp);

View File

@ -798,8 +798,11 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
bool AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c) bool AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
{ {
if (!hasOpenEditTransaction) // If we are in an open transaction or configuring MQTT, defer disabling Bluetooth
// Otherwise, disable Bluetooth to prevent the phone from interfering with the config
if (!hasOpenEditTransaction && c.which_payload_variant != meshtastic_ModuleConfig_mqtt_tag)
disableBluetooth(); disableBluetooth();
switch (c.which_payload_variant) { switch (c.which_payload_variant) {
case meshtastic_ModuleConfig_mqtt_tag: case meshtastic_ModuleConfig_mqtt_tag:
#if MESHTASTIC_EXCLUDE_MQTT #if MESHTASTIC_EXCLUDE_MQTT
@ -810,6 +813,8 @@ bool AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
if (!MQTT::isValidConfig(c.payload_variant.mqtt)) { if (!MQTT::isValidConfig(c.payload_variant.mqtt)) {
return false; return false;
} }
// Disable Bluetooth to prevent interference during MQTT configuration
disableBluetooth();
moduleConfig.has_mqtt = true; moduleConfig.has_mqtt = true;
moduleConfig.mqtt = c.payload_variant.mqtt; moduleConfig.mqtt = c.payload_variant.mqtt;
#endif #endif

View File

@ -39,6 +39,7 @@
#include <machine/endian.h> #include <machine/endian.h>
#define ntohl __ntohl #define ntohl __ntohl
#endif #endif
#include <RTC.h>
MQTT *mqtt; MQTT *mqtt;
@ -624,18 +625,32 @@ bool MQTT::isValidConfig(const meshtastic_ModuleConfig_MQTTConfig &config, MQTTC
return connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection); return connectPubSub(parsed, *pubSub, (client != nullptr) ? *client : *clientConnection);
} }
#else #else
LOG_ERROR("Invalid MQTT config: proxy_to_client_enabled must be enabled on nodes that do not have a network"); const char *warning = "Invalid MQTT config: proxy_to_client_enabled must be enabled on nodes that do not have a network";
LOG_ERROR(warning);
#if !IS_RUNNING_TESTS
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->level = meshtastic_LogRecord_Level_ERROR;
cn->time = getValidTime(RTCQualityFromNet);
strncpy(cn->message, warning, sizeof(cn->message) - 1);
cn->message[sizeof(cn->message) - 1] = '\0'; // Ensure null termination
service->sendClientNotification(cn);
#endif
return false; return false;
#endif #endif
} }
const bool defaultServer = isDefaultServer(parsed.serverAddr); const bool defaultServer = isDefaultServer(parsed.serverAddr);
if (defaultServer && config.tls_enabled) {
LOG_ERROR("Invalid MQTT config: TLS was enabled, but the default server does not support TLS");
return false;
}
if (defaultServer && parsed.serverPort != PubSubConfig::defaultPort) { if (defaultServer && parsed.serverPort != PubSubConfig::defaultPort) {
LOG_ERROR("Invalid MQTT config: Unsupported port '%d' for the default MQTT server", parsed.serverPort); const char *warning = "Invalid MQTT config: default server address must not have a port specified";
LOG_ERROR(warning);
#if !IS_RUNNING_TESTS
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->level = meshtastic_LogRecord_Level_ERROR;
cn->time = getValidTime(RTCQualityFromNet);
strncpy(cn->message, warning, sizeof(cn->message) - 1);
cn->message[sizeof(cn->message) - 1] = '\0'; // Ensure null termination
service->sendClientNotification(cn);
#endif
return false; return false;
} }
return true; return true;

View File

@ -27,6 +27,12 @@
#include <utility> #include <utility>
#include <variant> #include <variant>
#if defined(UNIT_TEST)
#define IS_RUNNING_TESTS 1
#else
#define IS_RUNNING_TESTS 0
#endif
namespace namespace
{ {
// Minimal router needed to receive messages from MQTT. // Minimal router needed to receive messages from MQTT.
@ -56,7 +62,13 @@ class MockMeshService : public MeshService
messages_.emplace_back(*m); messages_.emplace_back(*m);
releaseMqttClientProxyMessageToPool(m); releaseMqttClientProxyMessageToPool(m);
} }
std::list<meshtastic_MqttClientProxyMessage> messages_; // Messages received from the MeshService. void sendClientNotification(meshtastic_ClientNotification *n) override
{
notifications_.emplace_back(*n);
releaseClientNotificationToPool(n);
}
std::list<meshtastic_MqttClientProxyMessage> messages_; // Messages received from the MeshService.
std::list<meshtastic_ClientNotification> notifications_; // Notifications received from the MeshService.
}; };
// Minimal NodeDB needed to return values from getMeshNode. // Minimal NodeDB needed to return values from getMeshNode.
@ -823,14 +835,6 @@ void test_configWithDefaultServerAndInvalidPort(void)
TEST_ASSERT_FALSE(MQTT::isValidConfig(config)); TEST_ASSERT_FALSE(MQTT::isValidConfig(config));
} }
// Configuration with the default server and tls_enabled = true is invalid.
void test_configWithDefaultServerAndInvalidTLSEnabled(void)
{
meshtastic_ModuleConfig_MQTTConfig config = {.tls_enabled = true};
TEST_ASSERT_FALSE(MQTT::isValidConfig(config));
}
// isValidConfig connects to a custom host and port. // isValidConfig connects to a custom host and port.
void test_configCustomHostAndPort(void) void test_configCustomHostAndPort(void)
{ {
@ -911,7 +915,6 @@ void setup()
RUN_TEST(test_configEnabledEmptyIsValid); RUN_TEST(test_configEnabledEmptyIsValid);
RUN_TEST(test_configWithDefaultServer); RUN_TEST(test_configWithDefaultServer);
RUN_TEST(test_configWithDefaultServerAndInvalidPort); RUN_TEST(test_configWithDefaultServerAndInvalidPort);
RUN_TEST(test_configWithDefaultServerAndInvalidTLSEnabled);
RUN_TEST(test_configCustomHostAndPort); RUN_TEST(test_configCustomHostAndPort);
RUN_TEST(test_configWithConnectionFailure); RUN_TEST(test_configWithConnectionFailure);
RUN_TEST(test_configWithTLSEnabled); RUN_TEST(test_configWithTLSEnabled);

View File

@ -10,4 +10,4 @@ build_flags = ${nrf52840_base.build_flags}
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/diy/nrf52_promicro_diy_tcxo> build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/diy/nrf52_promicro_diy_tcxo>
lib_deps = lib_deps =
${nrf52840_base.lib_deps} ${nrf52840_base.lib_deps}
debug_tool = jlink debug_tool = jlink