mirror of
https://github.com/meshtastic/firmware.git
synced 2025-08-13 00:35:16 +00:00
Merge branch 'master' into tft-gui-work
This commit is contained in:
commit
39e67aec8f
@ -290,7 +290,7 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
if (strcmp(logLevel, MESHTASTIC_LOG_LEVEL_TRACE) == 0) {
|
||||||
if (settingsStrings[traceFilename] != "") {
|
if (settingsStrings[traceFilename] != "") {
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, newFormat);
|
va_start(arg, format);
|
||||||
try {
|
try {
|
||||||
traceFile << va_arg(arg, char *) << std::endl;
|
traceFile << va_arg(arg, char *) << std::endl;
|
||||||
} catch (const std::ios_base::failure &e) {
|
} catch (const std::ios_base::failure &e) {
|
||||||
@ -326,7 +326,7 @@ void RedirectablePrint::log(const char *logLevel, const char *format, ...)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, newFormat);
|
va_start(arg, format);
|
||||||
|
|
||||||
log_to_serial(logLevel, newFormat, arg);
|
log_to_serial(logLevel, newFormat, arg);
|
||||||
log_to_syslog(logLevel, newFormat, arg);
|
log_to_syslog(logLevel, newFormat, arg);
|
||||||
|
@ -564,7 +564,8 @@ void NodeDB::installDefaultChannels()
|
|||||||
|
|
||||||
void NodeDB::resetNodes()
|
void NodeDB::resetNodes()
|
||||||
{
|
{
|
||||||
clearLocalPosition();
|
if (!config.position.fixed_position)
|
||||||
|
clearLocalPosition();
|
||||||
numMeshNodes = 1;
|
numMeshNodes = 1;
|
||||||
std::fill(devicestate.node_db_lite.begin() + 1, devicestate.node_db_lite.end(), meshtastic_NodeInfoLite());
|
std::fill(devicestate.node_db_lite.begin() + 1, devicestate.node_db_lite.end(), meshtastic_NodeInfoLite());
|
||||||
devicestate.has_rx_text_message = false;
|
devicestate.has_rx_text_message = false;
|
||||||
@ -1222,4 +1223,4 @@ void recordCriticalError(meshtastic_CriticalErrorCode code, uint32_t address, co
|
|||||||
LOG_ERROR("A critical failure occurred, portduino is exiting...");
|
LOG_ERROR("A critical failure occurred, portduino is exiting...");
|
||||||
exit(2);
|
exit(2);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -252,7 +252,12 @@ void SerialModule::sendTelemetry(meshtastic_Telemetry m)
|
|||||||
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_Telemetry_msg, &m);
|
pb_encode_to_bytes(p->decoded.payload.bytes, sizeof(p->decoded.payload.bytes), &meshtastic_Telemetry_msg, &m);
|
||||||
p->to = NODENUM_BROADCAST;
|
p->to = NODENUM_BROADCAST;
|
||||||
p->decoded.want_response = false;
|
p->decoded.want_response = false;
|
||||||
p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
|
||||||
|
p->want_ack = true;
|
||||||
|
p->priority = meshtastic_MeshPacket_Priority_HIGH;
|
||||||
|
} else {
|
||||||
|
p->priority = meshtastic_MeshPacket_Priority_RELIABLE;
|
||||||
|
}
|
||||||
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,8 +429,10 @@ void SerialModule::processWXSerial()
|
|||||||
static char windGust[5] = "xx.x"; // Assuming windGust is 4 characters long + null terminator
|
static char windGust[5] = "xx.x"; // Assuming windGust is 4 characters long + null terminator
|
||||||
static char batVoltage[5] = "0.0V";
|
static char batVoltage[5] = "0.0V";
|
||||||
static char capVoltage[5] = "0.0V";
|
static char capVoltage[5] = "0.0V";
|
||||||
|
static char temperature[5] = "00.0";
|
||||||
static float batVoltageF = 0;
|
static float batVoltageF = 0;
|
||||||
static float capVoltageF = 0;
|
static float capVoltageF = 0;
|
||||||
|
static float temperatureF = 0;
|
||||||
bool gotwind = false;
|
bool gotwind = false;
|
||||||
|
|
||||||
while (Serial2.available()) {
|
while (Serial2.available()) {
|
||||||
@ -499,6 +506,13 @@ void SerialModule::processWXSerial()
|
|||||||
strcpy(capVoltage, capVoltagePos + 17); // 18 for ws 80, 17 for ws85
|
strcpy(capVoltage, capVoltagePos + 17); // 18 for ws 80, 17 for ws85
|
||||||
capVoltageF = strtof(capVoltage, nullptr);
|
capVoltageF = strtof(capVoltage, nullptr);
|
||||||
}
|
}
|
||||||
|
// GXTS04Temp = 24.4
|
||||||
|
} else if (strstr(line, "GXTS04Temp") != NULL) { // we have a temperature line
|
||||||
|
char *tempPos = strstr(line, "GXTS04Temp = ");
|
||||||
|
if (tempPos != NULL) {
|
||||||
|
strcpy(temperature, tempPos + 15); // 15 spaces for ws85
|
||||||
|
temperatureF = strtof(temperature, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update lineStart for the next line
|
// Update lineStart for the next line
|
||||||
@ -514,8 +528,8 @@ void SerialModule::processWXSerial()
|
|||||||
}
|
}
|
||||||
if (gotwind) {
|
if (gotwind) {
|
||||||
|
|
||||||
LOG_INFO("WS85 : %i %.1fg%.1f %.1fv %.1fv", atoi(windDir), strtof(windVel, nullptr), strtof(windGust, nullptr),
|
LOG_INFO("WS85 : %i %.1fg%.1f %.1fv %.1fv %.1fC", atoi(windDir), strtof(windVel, nullptr), strtof(windGust, nullptr),
|
||||||
batVoltageF, capVoltageF);
|
batVoltageF, capVoltageF, temperatureF);
|
||||||
}
|
}
|
||||||
if (gotwind && !Throttle::isWithinTimespanMs(lastAveraged, averageIntervalMillis)) {
|
if (gotwind && !Throttle::isWithinTimespanMs(lastAveraged, averageIntervalMillis)) {
|
||||||
// calulate averages and send to the mesh
|
// calulate averages and send to the mesh
|
||||||
@ -535,17 +549,32 @@ void SerialModule::processWXSerial()
|
|||||||
// make a telemetry packet with the data
|
// make a telemetry packet with the data
|
||||||
meshtastic_Telemetry m = meshtastic_Telemetry_init_zero;
|
meshtastic_Telemetry m = meshtastic_Telemetry_init_zero;
|
||||||
m.which_variant = meshtastic_Telemetry_environment_metrics_tag;
|
m.which_variant = meshtastic_Telemetry_environment_metrics_tag;
|
||||||
|
|
||||||
m.variant.environment_metrics.wind_speed = velAvg;
|
m.variant.environment_metrics.wind_speed = velAvg;
|
||||||
|
m.variant.environment_metrics.has_wind_speed = true;
|
||||||
|
|
||||||
m.variant.environment_metrics.wind_direction = dirAvg;
|
m.variant.environment_metrics.wind_direction = dirAvg;
|
||||||
m.variant.environment_metrics.wind_gust = gust;
|
m.variant.environment_metrics.has_wind_direction = true;
|
||||||
m.variant.environment_metrics.wind_lull = lull;
|
|
||||||
|
m.variant.environment_metrics.temperature = temperatureF;
|
||||||
|
m.variant.environment_metrics.has_temperature = true;
|
||||||
|
|
||||||
m.variant.environment_metrics.voltage =
|
m.variant.environment_metrics.voltage =
|
||||||
capVoltageF > batVoltageF ? capVoltageF : batVoltageF; // send the larger of the two voltage values.
|
capVoltageF > batVoltageF ? capVoltageF : batVoltageF; // send the larger of the two voltage values.
|
||||||
|
m.variant.environment_metrics.has_voltage = true;
|
||||||
|
|
||||||
LOG_INFO("WS85 Transmit speed=%fm/s, direction=%d , lull=%f, gust=%f, voltage=%f",
|
m.variant.environment_metrics.wind_gust = gust;
|
||||||
|
m.variant.environment_metrics.has_wind_gust = true;
|
||||||
|
|
||||||
|
if (lull == -1)
|
||||||
|
lull = 0;
|
||||||
|
m.variant.environment_metrics.wind_lull = lull;
|
||||||
|
m.variant.environment_metrics.has_wind_lull = true;
|
||||||
|
|
||||||
|
LOG_INFO("WS85 Transmit speed=%fm/s, direction=%d , lull=%f, gust=%f, voltage=%f temperature=%f",
|
||||||
m.variant.environment_metrics.wind_speed, m.variant.environment_metrics.wind_direction,
|
m.variant.environment_metrics.wind_speed, m.variant.environment_metrics.wind_direction,
|
||||||
m.variant.environment_metrics.wind_lull, m.variant.environment_metrics.wind_gust,
|
m.variant.environment_metrics.wind_lull, m.variant.environment_metrics.wind_gust,
|
||||||
m.variant.environment_metrics.voltage);
|
m.variant.environment_metrics.voltage, m.variant.environment_metrics.temperature);
|
||||||
|
|
||||||
sendTelemetry(m);
|
sendTelemetry(m);
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ Allocator<meshtastic_ServiceEnvelope> &mqttPool = staticMqttPool;
|
|||||||
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
|
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
|
||||||
static uint8_t bytes[meshtastic_MqttClientProxyMessage_size + 30]; // 12 for channel name and 16 for nodeid
|
static uint8_t bytes[meshtastic_MqttClientProxyMessage_size + 30]; // 12 for channel name and 16 for nodeid
|
||||||
|
|
||||||
|
static bool isMqttServerAddressPrivate = false;
|
||||||
|
|
||||||
void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length)
|
void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||||
{
|
{
|
||||||
mqtt->onReceive(topic, payload, length);
|
mqtt->onReceive(topic, payload, length);
|
||||||
@ -238,6 +240,11 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE)
|
|||||||
moduleConfig.mqtt.map_report_settings.publish_interval_secs, default_map_publish_interval_secs);
|
moduleConfig.mqtt.map_report_settings.publish_interval_secs, default_map_publish_interval_secs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isMqttServerAddressPrivate = isPrivateIpAddress(moduleConfig.mqtt.address);
|
||||||
|
if (isMqttServerAddressPrivate) {
|
||||||
|
LOG_INFO("MQTT server is a private IP address.");
|
||||||
|
}
|
||||||
|
|
||||||
#if HAS_NETWORKING
|
#if HAS_NETWORKING
|
||||||
if (!moduleConfig.mqtt.proxy_to_client_enabled)
|
if (!moduleConfig.mqtt.proxy_to_client_enabled)
|
||||||
pubSub.setCallback(mqttCallback);
|
pubSub.setCallback(mqttCallback);
|
||||||
@ -538,9 +545,8 @@ void MQTT::onSend(const meshtastic_MeshPacket &mp_encrypted, const meshtastic_Me
|
|||||||
|
|
||||||
// mp_decoded will not be decoded when it's PKI encrypted and not directed to us
|
// mp_decoded will not be decoded when it's PKI encrypted and not directed to us
|
||||||
if (mp_decoded.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
if (mp_decoded.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
|
||||||
|
|
||||||
// check for the lowest bit of the data bitfield set false, and the use of one of the default keys.
|
// check for the lowest bit of the data bitfield set false, and the use of one of the default keys.
|
||||||
if (!isFromUs(&mp_decoded) && strcmp(moduleConfig.mqtt.address, "127.0.0.1") != 0 && mp_decoded.decoded.has_bitfield &&
|
if (!isFromUs(&mp_decoded) && !isMqttServerAddressPrivate && mp_decoded.decoded.has_bitfield &&
|
||||||
!(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK) &&
|
!(mp_decoded.decoded.bitfield & BITFIELD_OK_TO_MQTT_MASK) &&
|
||||||
(ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) ||
|
(ch.settings.psk.size < 2 || (ch.settings.psk.size == 16 && memcmp(ch.settings.psk.bytes, defaultpsk, 16)) ||
|
||||||
(ch.settings.psk.size == 32 && memcmp(ch.settings.psk.bytes, eventpsk, 32)))) {
|
(ch.settings.psk.size == 32 && memcmp(ch.settings.psk.bytes, eventpsk, 32)))) {
|
||||||
@ -696,4 +702,44 @@ bool MQTT::isValidJsonEnvelope(JSONObject &json)
|
|||||||
(json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us
|
(json["from"]->AsNumber() == nodeDB->getNodeNum()) && // only accept message if the "from" is us
|
||||||
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type
|
(json.find("type") != json.end()) && json["type"]->IsString() && // should specify a type
|
||||||
(json.find("payload") != json.end()); // should have a payload
|
(json.find("payload") != json.end()); // should have a payload
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MQTT::isPrivateIpAddress(const char address[])
|
||||||
|
{
|
||||||
|
// Min. length like 10.0.0.0, max like 192.168.255.255
|
||||||
|
size_t length = strlen(address);
|
||||||
|
if (length < 8 || length > 15) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the address contains only digits and dots.
|
||||||
|
// Even if it's not a valid IP address, we will know it's not a domain.
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
if (!isdigit(address[i]) && address[i] != '.') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the easy ones first.
|
||||||
|
if (strcmp(address, "127.0.0.1") == 0 || strncmp(address, "10.", 3) == 0 || strncmp(address, "192.168", 7) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if it's definitely not a 172 address.
|
||||||
|
if (strncmp(address, "172", 3) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We know it's a 172 address, now see if the second octet is 2 digits.
|
||||||
|
if (address[6] != '.') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the second octet into a secondary buffer we can null-terminate and parse.
|
||||||
|
char octet2[3];
|
||||||
|
strncpy(octet2, address + 4, 2);
|
||||||
|
octet2[2] = 0;
|
||||||
|
|
||||||
|
int octet2Num = atoi(octet2);
|
||||||
|
return octet2Num >= 16 && octet2Num <= 31;
|
||||||
}
|
}
|
@ -120,6 +120,10 @@ class MQTT : private concurrency::OSThread
|
|||||||
// returns true if this is a valid JSON envelope which we accept on downlink
|
// returns true if this is a valid JSON envelope which we accept on downlink
|
||||||
bool isValidJsonEnvelope(JSONObject &json);
|
bool isValidJsonEnvelope(JSONObject &json);
|
||||||
|
|
||||||
|
/// Determines if the given address is a private IPv4 address, i.e. not routable on the public internet.
|
||||||
|
/// These are the ranges: 127.0.0.1, 10.0.0.0-10.255.255.255, 172.16.0.0-172.31.255.255, 192.168.0.0-192.168.255.255.
|
||||||
|
bool isPrivateIpAddress(const char address[]);
|
||||||
|
|
||||||
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
|
/// Return 0 if sleep is okay, veto sleep if we are connected to pubsub server
|
||||||
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }
|
// int preflightSleepCb(void *unused = NULL) { return pubSub.connected() ? 1 : 0; }
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
[env:heltec-v2_1]
|
[env:heltec-v2_1]
|
||||||
|
board_level = extra
|
||||||
;build_type = debug ; to make it possible to step through our jtag debugger
|
;build_type = debug ; to make it possible to step through our jtag debugger
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = heltec_wifi_lora_32_V2
|
board = heltec_wifi_lora_32_V2
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
[env:heltec-v2_0]
|
[env:heltec-v2_0]
|
||||||
;build_type = debug ; to make it possible to step through our jtag debugger
|
;build_type = debug ; to make it possible to step through our jtag debugger
|
||||||
|
board_level = extra
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = heltec_wifi_lora_32_V2
|
board = heltec_wifi_lora_32_V2
|
||||||
build_flags =
|
build_flags =
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
[env:tlora-v1]
|
[env:tlora-v1]
|
||||||
|
board_level = extra
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-lora32-v1
|
board = ttgo-lora32-v1
|
||||||
build_flags =
|
build_flags =
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
[env:tlora_v1_3]
|
[env:tlora_v1_3]
|
||||||
|
board_level = extra
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-lora32-v1
|
board = ttgo-lora32-v1
|
||||||
build_flags =
|
build_flags =
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
[env:tlora-v2]
|
[env:tlora-v2]
|
||||||
|
board_level = extra
|
||||||
extends = esp32_base
|
extends = esp32_base
|
||||||
board = ttgo-lora32-v1
|
board = ttgo-lora32-v1
|
||||||
build_flags =
|
build_flags =
|
||||||
|
Loading…
Reference in New Issue
Block a user