mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-21 18:22:32 +00:00
Merge branch 'develop' into multi-message-Storage
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/python:1": {
|
"ghcr.io/devcontainers/features/python:1": {
|
||||||
"installTools": true,
|
"installTools": true,
|
||||||
"version": "3.13"
|
"version": "3.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"customizations": {
|
"customizations": {
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ plugins:
|
|||||||
uri: https://github.com/trunk-io/plugins
|
uri: https://github.com/trunk-io/plugins
|
||||||
lint:
|
lint:
|
||||||
enabled:
|
enabled:
|
||||||
- checkov@3.2.486
|
- checkov@3.2.489
|
||||||
- renovate@41.157.0
|
- renovate@41.169.1
|
||||||
- prettier@3.6.2
|
- prettier@3.6.2
|
||||||
- trufflehog@3.90.11
|
- trufflehog@3.90.12
|
||||||
- yamllint@1.37.1
|
- yamllint@1.37.1
|
||||||
- bandit@1.8.6
|
- bandit@1.8.6
|
||||||
- trivy@0.67.2
|
- trivy@0.67.2
|
||||||
- taplo@0.10.0
|
- taplo@0.10.0
|
||||||
- ruff@0.14.1
|
- ruff@0.14.3
|
||||||
- isort@7.0.0
|
- isort@7.0.0
|
||||||
- markdownlint@0.45.0
|
- markdownlint@0.45.0
|
||||||
- oxipng@9.1.5
|
- oxipng@9.1.5
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
[portduino_base]
|
[portduino_base]
|
||||||
platform =
|
platform =
|
||||||
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
|
# renovate: datasource=git-refs depName=platform-native packageName=https://github.com/meshtastic/platform-native gitBranch=develop
|
||||||
https://github.com/meshtastic/platform-native/archive/d3f6e339534233c7217818867368767590ce549e.zip
|
https://github.com/meshtastic/platform-native/archive/f566d364204416cdbf298e349213f7d551f793d9.zip
|
||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ lib_deps =
|
|||||||
# renovate: datasource=custom.pio depName=Adafruit LTR390 Library packageName=adafruit/library/Adafruit LTR390 Library
|
# renovate: datasource=custom.pio depName=Adafruit LTR390 Library packageName=adafruit/library/Adafruit LTR390 Library
|
||||||
adafruit/Adafruit LTR390 Library@1.1.2
|
adafruit/Adafruit LTR390 Library@1.1.2
|
||||||
# renovate: datasource=custom.pio depName=Adafruit PCT2075 packageName=adafruit/library/Adafruit PCT2075
|
# renovate: datasource=custom.pio depName=Adafruit PCT2075 packageName=adafruit/library/Adafruit PCT2075
|
||||||
adafruit/Adafruit PCT2075@1.0.5
|
adafruit/Adafruit PCT2075@1.0.6
|
||||||
# renovate: datasource=custom.pio depName=DFRobot_BMM150 packageName=dfrobot/library/DFRobot_BMM150
|
# renovate: datasource=custom.pio depName=DFRobot_BMM150 packageName=dfrobot/library/DFRobot_BMM150
|
||||||
dfrobot/DFRobot_BMM150@1.0.0
|
dfrobot/DFRobot_BMM150@1.0.0
|
||||||
# renovate: datasource=custom.pio depName=Adafruit_TSL2561 packageName=adafruit/library/Adafruit TSL2561
|
# renovate: datasource=custom.pio depName=Adafruit_TSL2561 packageName=adafruit/library/Adafruit TSL2561
|
||||||
|
|||||||
Submodule protobufs updated: bf149bbdcc...7654db2e2d
@@ -57,7 +57,7 @@ static unsigned char TDeckProTapMap[_TCA8418_NUM_KEYS][5] = {
|
|||||||
{0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x00},
|
{0x00, 0x00, 0x00},
|
||||||
{0x20, 0x00, 0x00},
|
{0x20, 0x00, 0x00},
|
||||||
{0x00, 0x00, 0x00},
|
{0x00, 0x00, '0'},
|
||||||
{0x00, 0x00, 0x00} // R_Shift, sym, space, mic, L_Shift
|
{0x00, 0x00, 0x00} // R_Shift, sym, space, mic, L_Shift
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1638,13 +1638,32 @@ void NodeDB::addFromContact(meshtastic_SharedContact contact)
|
|||||||
// If should_ignore is set,
|
// If should_ignore is set,
|
||||||
// we need to clear the public key and other cruft, in addition to setting the node as ignored
|
// we need to clear the public key and other cruft, in addition to setting the node as ignored
|
||||||
info->is_ignored = true;
|
info->is_ignored = true;
|
||||||
|
info->is_favorite = false;
|
||||||
info->has_device_metrics = false;
|
info->has_device_metrics = false;
|
||||||
info->has_position = false;
|
info->has_position = false;
|
||||||
info->user.public_key.size = 0;
|
info->user.public_key.size = 0;
|
||||||
info->user.public_key.bytes[0] = 0;
|
info->user.public_key.bytes[0] = 0;
|
||||||
} else {
|
} else {
|
||||||
info->last_heard = getValidTime(RTCQualityNTP);
|
/* Clients are sending add_contact before every text message DM (because clients may hold a larger node database with
|
||||||
info->is_favorite = true;
|
* public keys than the radio holds). However, we don't want to update last_heard just because we sent someone a DM!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* "Boring old nodes" are the first to be evicted out of the node database when full. This includes a newly-zeroed
|
||||||
|
* nodeinfo because it has: !is_favorite && last_heard==0. To keep this from happening when we addFromContact, we set the
|
||||||
|
* new node as a favorite, and we leave last_heard alone (even if it's zero).
|
||||||
|
*/
|
||||||
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE) {
|
||||||
|
// Special case for CLIENT_BASE: is_favorite has special meaning, and we don't want to automatically set it
|
||||||
|
// without the user doing so deliberately. We don't normally expect users to use a CLIENT_BASE to send DMs or to add
|
||||||
|
// contacts, but we should make sure it doesn't auto-favorite in case they do. Instead, as a workaround, we'll set
|
||||||
|
// last_heard to now, so that the add_contact node doesn't immediately get evicted.
|
||||||
|
info->last_heard = getTime();
|
||||||
|
} else {
|
||||||
|
// Normal case: set is_favorite to prevent expiration.
|
||||||
|
// last_heard will remain as-is (or remain 0 if this entry wasn't in the nodeDB).
|
||||||
|
info->is_favorite = true;
|
||||||
|
}
|
||||||
|
|
||||||
// As the clients will begin sending the contact with DMs, we want to strictly check if the node is manually verified
|
// As the clients will begin sending the contact with DMs, we want to strictly check if the node is manually verified
|
||||||
if (contact.manually_verified) {
|
if (contact.manually_verified) {
|
||||||
info->bitfield |= NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK;
|
info->bitfield |= NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK;
|
||||||
|
|||||||
@@ -479,6 +479,11 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
|
|||||||
LOG_ERROR("Invalid protobufs in received mesh packet id=0x%08x (bad psk?)!", p->id);
|
LOG_ERROR("Invalid protobufs in received mesh packet id=0x%08x (bad psk?)!", p->id);
|
||||||
} else if (decodedtmp.portnum == meshtastic_PortNum_UNKNOWN_APP) {
|
} else if (decodedtmp.portnum == meshtastic_PortNum_UNKNOWN_APP) {
|
||||||
LOG_ERROR("Invalid portnum (bad psk?)!");
|
LOG_ERROR("Invalid portnum (bad psk?)!");
|
||||||
|
#if !(MESHTASTIC_EXCLUDE_PKI)
|
||||||
|
} else if (!owner.is_licensed && isToUs(p) && decodedtmp.portnum == meshtastic_PortNum_TEXT_MESSAGE_APP) {
|
||||||
|
LOG_WARN("Rejecting legacy DM");
|
||||||
|
return DecodeState::DECODE_FAILURE;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
p->decoded = decodedtmp;
|
p->decoded = decodedtmp;
|
||||||
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
|
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag; // change type to decoded
|
||||||
|
|||||||
@@ -272,8 +272,9 @@ typedef struct _meshtastic_AdminMessage {
|
|||||||
int32_t shutdown_seconds;
|
int32_t shutdown_seconds;
|
||||||
/* Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved. */
|
/* Tell the node to factory reset config; all device state and configuration will be returned to factory defaults; BLE bonds will be preserved. */
|
||||||
int32_t factory_reset_config;
|
int32_t factory_reset_config;
|
||||||
/* Tell the node to reset the nodedb. */
|
/* Tell the node to reset the nodedb.
|
||||||
int32_t nodedb_reset;
|
When true, favorites are preserved through reset. */
|
||||||
|
bool nodedb_reset;
|
||||||
};
|
};
|
||||||
/* The node generates this key and sends it with any get_x_response packets.
|
/* The node generates this key and sends it with any get_x_response packets.
|
||||||
The client MUST include the same key with any set_x commands. Key expires after 300 seconds.
|
The client MUST include the same key with any set_x commands. Key expires after 300 seconds.
|
||||||
@@ -459,7 +460,7 @@ X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulato
|
|||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_seconds), 97) \
|
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_seconds,reboot_seconds), 97) \
|
||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \
|
X(a, STATIC, ONEOF, INT32, (payload_variant,shutdown_seconds,shutdown_seconds), 98) \
|
||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_config,factory_reset_config), 99) \
|
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_config,factory_reset_config), 99) \
|
||||||
X(a, STATIC, ONEOF, INT32, (payload_variant,nodedb_reset,nodedb_reset), 100) \
|
X(a, STATIC, ONEOF, BOOL, (payload_variant,nodedb_reset,nodedb_reset), 100) \
|
||||||
X(a, STATIC, SINGULAR, BYTES, session_passkey, 101)
|
X(a, STATIC, SINGULAR, BYTES, session_passkey, 101)
|
||||||
#define meshtastic_AdminMessage_CALLBACK NULL
|
#define meshtastic_AdminMessage_CALLBACK NULL
|
||||||
#define meshtastic_AdminMessage_DEFAULT NULL
|
#define meshtastic_AdminMessage_DEFAULT NULL
|
||||||
|
|||||||
@@ -284,6 +284,10 @@ typedef enum _meshtastic_HardwareModel {
|
|||||||
meshtastic_HardwareModel_T_WATCH_ULTRA = 114,
|
meshtastic_HardwareModel_T_WATCH_ULTRA = 114,
|
||||||
/* Elecrow ThinkNode M3 */
|
/* Elecrow ThinkNode M3 */
|
||||||
meshtastic_HardwareModel_THINKNODE_M3 = 115,
|
meshtastic_HardwareModel_THINKNODE_M3 = 115,
|
||||||
|
/* RAK WISMESH_TAP_V2 with ESP32-S3 CPU */
|
||||||
|
meshtastic_HardwareModel_WISMESH_TAP_V2 = 116,
|
||||||
|
/* RAK3401 */
|
||||||
|
meshtastic_HardwareModel_RAK3401 = 117,
|
||||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
|||||||
@@ -104,9 +104,18 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
|||||||
(config.security.admin_key[2].size == 32 &&
|
(config.security.admin_key[2].size == 32 &&
|
||||||
memcmp(mp.public_key.bytes, config.security.admin_key[2].bytes, 32) == 0)) {
|
memcmp(mp.public_key.bytes, config.security.admin_key[2].bytes, 32) == 0)) {
|
||||||
LOG_INFO("PKC admin payload with authorized sender key");
|
LOG_INFO("PKC admin payload with authorized sender key");
|
||||||
|
|
||||||
|
// Automatically favorite the node that is using the admin key
|
||||||
auto remoteNode = nodeDB->getMeshNode(mp.from);
|
auto remoteNode = nodeDB->getMeshNode(mp.from);
|
||||||
if (remoteNode && !remoteNode->is_favorite) {
|
if (remoteNode && !remoteNode->is_favorite) {
|
||||||
remoteNode->is_favorite = true;
|
if (config.device.role == meshtastic_Config_DeviceConfig_Role_CLIENT_BASE) {
|
||||||
|
// Special case for CLIENT_BASE: is_favorite has special meaning, and we don't want to automatically set it
|
||||||
|
// without the user doing so deliberately.
|
||||||
|
LOG_INFO("PKC admin valid, but not auto-favoriting node %x because role==CLIENT_BASE", mp.from);
|
||||||
|
} else {
|
||||||
|
LOG_INFO("PKC admin valid. Auto-favoriting node %x", mp.from);
|
||||||
|
remoteNode->is_favorite = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
myReply = allocErrorResponse(meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED, &mp);
|
myReply = allocErrorResponse(meshtastic_Routing_Error_ADMIN_PUBLIC_KEY_UNAUTHORIZED, &mp);
|
||||||
|
|||||||
@@ -204,6 +204,10 @@ void StoreForwardModule::historyAdd(const meshtastic_MeshPacket &mp)
|
|||||||
this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
|
this->packetHistory[this->packetHistoryTotalCount].payload_size = p.payload.size;
|
||||||
this->packetHistory[this->packetHistoryTotalCount].rx_rssi = mp.rx_rssi;
|
this->packetHistory[this->packetHistoryTotalCount].rx_rssi = mp.rx_rssi;
|
||||||
this->packetHistory[this->packetHistoryTotalCount].rx_snr = mp.rx_snr;
|
this->packetHistory[this->packetHistoryTotalCount].rx_snr = mp.rx_snr;
|
||||||
|
this->packetHistory[this->packetHistoryTotalCount].hop_start = mp.hop_start;
|
||||||
|
this->packetHistory[this->packetHistoryTotalCount].hop_limit = mp.hop_limit;
|
||||||
|
this->packetHistory[this->packetHistoryTotalCount].via_mqtt = mp.via_mqtt;
|
||||||
|
this->packetHistory[this->packetHistoryTotalCount].transport_mechanism = mp.transport_mechanism;
|
||||||
memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
memcpy(this->packetHistory[this->packetHistoryTotalCount].payload, p.payload.bytes, meshtastic_Constants_DATA_PAYLOAD_LEN);
|
||||||
|
|
||||||
this->packetHistoryTotalCount++;
|
this->packetHistoryTotalCount++;
|
||||||
@@ -256,6 +260,10 @@ meshtastic_MeshPacket *StoreForwardModule::preparePayload(NodeNum dest, uint32_t
|
|||||||
p->decoded.emoji = (uint32_t)this->packetHistory[i].emoji;
|
p->decoded.emoji = (uint32_t)this->packetHistory[i].emoji;
|
||||||
p->rx_rssi = this->packetHistory[i].rx_rssi;
|
p->rx_rssi = this->packetHistory[i].rx_rssi;
|
||||||
p->rx_snr = this->packetHistory[i].rx_snr;
|
p->rx_snr = this->packetHistory[i].rx_snr;
|
||||||
|
p->hop_start = this->packetHistory[i].hop_start;
|
||||||
|
p->hop_limit = this->packetHistory[i].hop_limit;
|
||||||
|
p->via_mqtt = this->packetHistory[i].via_mqtt;
|
||||||
|
p->transport_mechanism = (meshtastic_MeshPacket_TransportMechanism)this->packetHistory[i].transport_mechanism;
|
||||||
|
|
||||||
// Let's assume that if the server received the S&F request that the client is in range.
|
// Let's assume that if the server received the S&F request that the client is in range.
|
||||||
// TODO: Make this configurable.
|
// TODO: Make this configurable.
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ struct PacketHistoryStruct {
|
|||||||
pb_size_t payload_size;
|
pb_size_t payload_size;
|
||||||
int32_t rx_rssi;
|
int32_t rx_rssi;
|
||||||
float rx_snr;
|
float rx_snr;
|
||||||
|
uint8_t hop_start;
|
||||||
|
uint8_t hop_limit;
|
||||||
|
bool via_mqtt;
|
||||||
|
uint8_t transport_mechanism;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<meshtastic_StoreAndForward>
|
class StoreForwardModule : private concurrency::OSThread, public ProtobufModule<meshtastic_StoreAndForward>
|
||||||
|
|||||||
Reference in New Issue
Block a user