Merge upstream/dev into develop

Bu işleme şunda yer alıyor:
Jared Dohrman
2026-04-17 17:54:47 +10:00
işleme e05c9bc09c
37 değiştirilmiş dosya ile 2059 ekleme ve 629 silme
+29 -7
Dosyayı Görüntüle
@@ -230,17 +230,37 @@ void DataStore::loadPrefsInt(const char *filename, NodePrefs& _prefs, double& no
file.read((uint8_t *)&_prefs.gps_interval, sizeof(_prefs.gps_interval)); // 86
file.read((uint8_t *)&_prefs.autoadd_config, sizeof(_prefs.autoadd_config)); // 87
file.read((uint8_t *)&_prefs.autoadd_max_hops, sizeof(_prefs.autoadd_max_hops)); // 88
file.read((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89
if (file.available() >= (int)sizeof(_prefs.wifi_powersave)) {
file.read((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89
const int wifi_bytes = sizeof(_prefs.wifi_powersave) + sizeof(_prefs.wifi_ssid) + sizeof(_prefs.wifi_pwd);
const int scope_bytes = sizeof(_prefs.default_scope_name) + sizeof(_prefs.default_scope_key);
const int remaining = file.available();
if (remaining >= wifi_bytes + scope_bytes) {
file.read((uint8_t *)&_prefs.wifi_powersave, sizeof(_prefs.wifi_powersave)); // 90
}
if (file.available() >= (int)sizeof(_prefs.wifi_ssid)) {
file.read((uint8_t *)_prefs.wifi_ssid, sizeof(_prefs.wifi_ssid)); // 91
_prefs.wifi_ssid[sizeof(_prefs.wifi_ssid) - 1] = 0;
}
if (file.available() >= (int)sizeof(_prefs.wifi_pwd)) {
file.read((uint8_t *)_prefs.wifi_pwd, sizeof(_prefs.wifi_pwd)); // 124
_prefs.wifi_pwd[sizeof(_prefs.wifi_pwd) - 1] = 0;
file.read((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)); // 189
_prefs.default_scope_name[sizeof(_prefs.default_scope_name) - 1] = 0;
file.read((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)); // 220
} else if (remaining >= scope_bytes) {
file.read((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)); // 90
_prefs.default_scope_name[sizeof(_prefs.default_scope_name) - 1] = 0;
file.read((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)); // 121
} else {
if (file.available() >= (int)sizeof(_prefs.wifi_powersave)) {
file.read((uint8_t *)&_prefs.wifi_powersave, sizeof(_prefs.wifi_powersave)); // 90
}
if (file.available() >= (int)sizeof(_prefs.wifi_ssid)) {
file.read((uint8_t *)_prefs.wifi_ssid, sizeof(_prefs.wifi_ssid)); // 91
_prefs.wifi_ssid[sizeof(_prefs.wifi_ssid) - 1] = 0;
}
if (file.available() >= (int)sizeof(_prefs.wifi_pwd)) {
file.read((uint8_t *)_prefs.wifi_pwd, sizeof(_prefs.wifi_pwd)); // 124
_prefs.wifi_pwd[sizeof(_prefs.wifi_pwd) - 1] = 0;
}
}
file.close();
@@ -279,10 +299,12 @@ void DataStore::savePrefs(const NodePrefs& _prefs, double node_lat, double node_
file.write((uint8_t *)&_prefs.gps_interval, sizeof(_prefs.gps_interval)); // 86
file.write((uint8_t *)&_prefs.autoadd_config, sizeof(_prefs.autoadd_config)); // 87
file.write((uint8_t *)&_prefs.autoadd_max_hops, sizeof(_prefs.autoadd_max_hops)); // 88
file.write((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89
file.write((uint8_t *)&_prefs.rx_boosted_gain, sizeof(_prefs.rx_boosted_gain)); // 89
file.write((uint8_t *)&_prefs.wifi_powersave, sizeof(_prefs.wifi_powersave)); // 90
file.write((uint8_t *)_prefs.wifi_ssid, sizeof(_prefs.wifi_ssid)); // 91
file.write((uint8_t *)_prefs.wifi_pwd, sizeof(_prefs.wifi_pwd)); // 124
file.write((uint8_t *)_prefs.default_scope_name, sizeof(_prefs.default_scope_name)); // 189
file.write((uint8_t *)_prefs.default_scope_key, sizeof(_prefs.default_scope_key)); // 220
file.close();
}
+62 -15
Dosyayı Görüntüle
@@ -53,7 +53,7 @@
#define CMD_SEND_BINARY_REQ 50
#define CMD_FACTORY_RESET 51
#define CMD_SEND_PATH_DISCOVERY_REQ 52
#define CMD_SET_FLOOD_SCOPE 54 // v8+
#define CMD_SET_FLOOD_SCOPE_KEY 54 // v8+
#define CMD_SEND_CONTROL_DATA 55 // v8+
#define CMD_GET_STATS 56 // v8+, second byte is stats type
#define CMD_SEND_ANON_REQ 57
@@ -62,6 +62,8 @@
#define CMD_GET_ALLOWED_REPEAT_FREQ 60
#define CMD_SET_PATH_HASH_MODE 61
#define CMD_SEND_CHANNEL_DATA 62
#define CMD_SET_DEFAULT_FLOOD_SCOPE 63
#define CMD_GET_DEFAULT_FLOOD_SCOPE 64
// Stats sub-types for CMD_GET_STATS
#define STATS_TYPE_CORE 0
@@ -96,6 +98,7 @@
#define RESP_CODE_AUTOADD_CONFIG 25
#define RESP_ALLOWED_REPEAT_FREQ 26
#define RESP_CODE_CHANNEL_DATA_RECV 27
#define RESP_CODE_DEFAULT_FLOOD_SCOPE 28
#define MAX_CHANNEL_DATA_LENGTH (MAX_FRAME_SIZE - 9)
@@ -548,27 +551,32 @@ bool MyMesh::allowPacketForward(const mesh::Packet* packet) {
return _prefs.client_repeat != 0;
}
void MyMesh::sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis) {
// TODO: dynamic send_scope, depending on recipient and current 'home' Region
if (send_scope.isNull()) {
void MyMesh::sendFloodScoped(const TransportKey& scope, mesh::Packet* pkt, uint32_t delay_millis) {
if (scope.isNull()) {
sendFlood(pkt, delay_millis, _prefs.path_hash_mode + 1);
} else {
uint16_t codes[2];
codes[0] = send_scope.calcTransportCode(pkt);
codes[0] = scope.calcTransportCode(pkt);
codes[1] = 0; // REVISIT: set to 'home' Region, for sender/return region?
sendFlood(pkt, codes, delay_millis, _prefs.path_hash_mode + 1);
}
}
void MyMesh::sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis) {
// TODO: dynamic send_scope, depending on recipient and current 'home' Region
TransportKey default_scope;
memcpy(&default_scope.key, _prefs.default_scope_key, sizeof(default_scope.key));
auto scope = send_scope.isNull() ? &default_scope : &send_scope;
sendFloodScoped(*scope, pkt, delay_millis);
}
void MyMesh::sendFloodScoped(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t delay_millis) {
// TODO: have per-channel send_scope
if (send_scope.isNull()) {
sendFlood(pkt, delay_millis, _prefs.path_hash_mode + 1);
} else {
uint16_t codes[2];
codes[0] = send_scope.calcTransportCode(pkt);
codes[1] = 0; // REVISIT: set to 'home' Region, for sender/return region?
sendFlood(pkt, codes, delay_millis, _prefs.path_hash_mode + 1);
}
TransportKey default_scope;
memcpy(&default_scope.key, _prefs.default_scope_key, sizeof(default_scope.key));
auto scope = send_scope.isNull() ? &default_scope : &send_scope;
sendFloodScoped(*scope, pkt, delay_millis);
}
void MyMesh::onMessageRecv(const ContactInfo &from, mesh::Packet *pkt, uint32_t sender_timestamp,
@@ -973,6 +981,17 @@ void MyMesh::begin(bool has_display) {
strcpy(_prefs.node_name, pub_key_hex);
#endif
// if build provides default-scope, init with that
#ifdef DEFAULT_FLOOD_SCOPE_NAME
strcpy(_prefs.default_scope_name, DEFAULT_FLOOD_SCOPE_NAME);
{
TransportKeyStore temp;
TransportKey key;
temp.getAutoKeyFor(0, "#" DEFAULT_FLOOD_SCOPE_NAME, key);
memcpy(_prefs.default_scope_key, key.key, sizeof(key.key));
}
#endif
// load persisted prefs
_store->loadPrefs(_prefs, sensors.node_lat, sensors.node_lon);
@@ -1290,7 +1309,9 @@ void MyMesh::handleCmdFrame(size_t len) {
if (pkt) {
if (len >= 2 && cmd_frame[1] == 1) { // optional param (1 = flood, 0 = zero hop)
unsigned long delay_millis = 0;
sendFlood(pkt, delay_millis, _prefs.path_hash_mode + 1);
TransportKey default_scope;
memcpy(&default_scope.key, _prefs.default_scope_key, sizeof(default_scope.key));
sendFloodScoped(default_scope, pkt, delay_millis);
} else {
sendZeroHop(pkt);
}
@@ -1942,13 +1963,39 @@ void MyMesh::handleCmdFrame(size_t len) {
} else {
writeErrFrame(ERR_CODE_FILE_IO_ERROR);
}
} else if (cmd_frame[0] == CMD_SET_FLOOD_SCOPE && len >= 2 && cmd_frame[1] == 0) {
} else if (cmd_frame[0] == CMD_SET_FLOOD_SCOPE_KEY && len >= 2 && cmd_frame[1] == 0) {
if (len >= 2 + 16) {
memcpy(send_scope.key, &cmd_frame[2], sizeof(send_scope.key)); // set curr scope TransportKey
} else {
memset(send_scope.key, 0, sizeof(send_scope.key)); // set scope to null
}
writeOKFrame();
} else if (cmd_frame[0] == CMD_SET_DEFAULT_FLOOD_SCOPE && len >= 1) {
if (len >= 1+31+16) {
int n = strlen((char *) &cmd_frame[1]);
if (n > 0 && n < 31) {
strcpy(_prefs.default_scope_name, (char *) &cmd_frame[1]);
memcpy(_prefs.default_scope_key, &cmd_frame[1+31], 16);
savePrefs();
writeOKFrame();
} else {
writeErrFrame(ERR_CODE_ILLEGAL_ARG);
}
} else {
memset(_prefs.default_scope_name, 0, sizeof(_prefs.default_scope_name)); // set default scope to null
memset(_prefs.default_scope_key, 0, sizeof(_prefs.default_scope_key));
savePrefs();
writeOKFrame();
}
} else if (cmd_frame[0] == CMD_GET_DEFAULT_FLOOD_SCOPE) {
out_frame[0] = RESP_CODE_DEFAULT_FLOOD_SCOPE;
if (strlen(_prefs.default_scope_name) > 0) {
memcpy(&out_frame[1], _prefs.default_scope_name, 31);
memcpy(&out_frame[1+31], _prefs.default_scope_key, 16);
_serial->writeFrame(out_frame, 1+31+16);
} else {
_serial->writeFrame(out_frame, 1); // no name or key means null
}
} else if (cmd_frame[0] == CMD_SEND_CONTROL_DATA && len >= 2 && (cmd_frame[1] & 0x80) != 0) {
auto resp = createControlData(&cmd_frame[1], len - 1);
if (resp) {
+2 -1
Dosyayı Görüntüle
@@ -5,7 +5,7 @@
#include "AbstractUITask.h"
/*------------ Frame Protocol --------------*/
#define FIRMWARE_VER_CODE 10
#define FIRMWARE_VER_CODE 11
#ifndef FIRMWARE_BUILD_DATE
#define FIRMWARE_BUILD_DATE "20 Mar 2026"
@@ -117,6 +117,7 @@ protected:
bool filterRecvFloodPacket(mesh::Packet* packet) override;
bool allowPacketForward(const mesh::Packet* packet) override;
void sendFloodScoped(const TransportKey& scope, mesh::Packet* pkt, uint32_t delay_millis);
void sendFloodScoped(const ContactInfo& recipient, mesh::Packet* pkt, uint32_t delay_millis=0) override;
void sendFloodScoped(const mesh::GroupChannel& channel, mesh::Packet* pkt, uint32_t delay_millis=0) override;
+2
Dosyayı Görüntüle
@@ -35,4 +35,6 @@ struct NodePrefs { // persisted to file
uint8_t wifi_powersave; // 0 = none, 1 = min, 2 = max
char wifi_ssid[33];
char wifi_pwd[65];
char default_scope_name[31];
uint8_t default_scope_key[16];
};