Compare commits

...

11 Commits

Author SHA1 Message Date
Ben Meadors
5f9d0bb325 Merge branch 'master' into uplink-downlink-udp-controls 2025-10-02 05:51:17 -05:00
Ben Meadors
f20ce2c29e Merge branch 'master' into uplink-downlink-udp-controls 2025-09-28 07:40:30 -05:00
Ben Meadors
24940f7735 Merge branch 'master' into uplink-downlink-udp-controls 2025-09-28 06:39:24 -05:00
Ben Meadors
87a4a6ab73 Fix isFromUs and account for channel hashes instead of indexes 2025-09-28 06:39:15 -05:00
Ben Meadors
c1e8c28128 Revert "Revert cross-preset UDP bridging"
This reverts commit 359a4dbd68.
2025-09-27 16:25:40 -05:00
Ben Meadors
b76a22996e Merge branch 'master' into uplink-downlink-udp-controls 2025-09-27 14:44:40 -05:00
Ben Meadors
6040e49b6b Merge branch 'master' into uplink-downlink-udp-controls 2025-09-27 08:05:48 -05:00
Ben Meadors
888115e0b9 Revert "Update src/mesh/udp/UdpMulticastHandler.h"
This reverts commit 2b590d2300.
2025-09-27 06:10:04 -05:00
Ben Meadors
2b590d2300 Update src/mesh/udp/UdpMulticastHandler.h
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-27 06:06:05 -05:00
Ben Meadors
42532d5b7c Size 2025-09-27 05:57:08 -05:00
Ben Meadors
683539220d Re-use Uplink / downlink controls for UDP 2025-09-27 05:55:04 -05:00
4 changed files with 110 additions and 7 deletions

View File

@@ -459,4 +459,15 @@ bool Channels::setDefaultPresetCryptoForHash(ChannelHash channelHash)
int16_t Channels::setActiveByIndex(ChannelIndex channelIndex)
{
return setCrypto(channelIndex);
}
int8_t Channels::getIndexByHash(ChannelHash channelHash)
{
// Iterate through all channels to find the one with matching hash
for (ChannelIndex i = 0; i < getNumChannels(); i++) {
if (getHash(i) == channelHash) {
return i;
}
}
return -1; // Hash not found
}

View File

@@ -96,6 +96,9 @@ class Channels
bool setDefaultPresetCryptoForHash(ChannelHash channelHash);
/** Return the channel index for the specified channel hash, or -1 for not found */
int8_t getIndexByHash(ChannelHash channelHash);
private:
/** Given a channel index, change to use the crypto key specified by that index
*
@@ -103,9 +106,6 @@ class Channels
*/
int16_t setCrypto(ChannelIndex chIndex);
/** Return the channel index for the specified channel hash, or -1 for not found */
int8_t getIndexByHash(ChannelHash channelHash);
/** Given a channel number, return the (0 to 255) hash for that channel
* If no suitable channel could be found, return -1
*

View File

@@ -356,13 +356,55 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
if (moduleConfig.mqtt.enabled && isFromUs(p) && mqtt) {
mqtt->onSend(*p, *p_decoded, chIndex);
}
#endif
#if HAS_UDP_MULTICAST
if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
// We must have at least one channel setup for with uplink_enabled
bool uplinkEnabled = false;
for (int i = 0; i <= 7; i++) {
if (channels.getByIndex(i).settings.uplink_enabled)
uplinkEnabled = true;
}
if (uplinkEnabled) {
udpHandler->onSend(const_cast<meshtastic_MeshPacket *>(p), chIndex);
}
}
#endif
packetPool.release(p_decoded);
}
#if HAS_UDP_MULTICAST
if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
udpHandler->onSend(const_cast<meshtastic_MeshPacket *>(p));
// For packets that are already encrypted, we need to determine the channel from packet info
else if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST &&
isFromUs(p)) {
// Check if any channel has uplink enabled (for PKI support)
bool uplinkEnabled = false;
for (int i = 0; i <= 7; i++) {
if (channels.getByIndex(i).settings.uplink_enabled) {
uplinkEnabled = true;
break;
}
}
if (uplinkEnabled) {
ChannelIndex chIndex = 0; // Default to primary channel
// For PKI encrypted packets, use default channel if at least one channel has uplink
if (p->pki_encrypted) {
for (int i = 0; i <= 7; i++) {
if (channels.getByIndex(i).settings.uplink_enabled) {
chIndex = i;
break;
}
}
udpHandler->onSend(const_cast<meshtastic_MeshPacket *>(p), chIndex);
} else {
// For regular channel PSK encrypted packets, try to find the channel by hash
int8_t foundIndex = channels.getIndexByHash(p->channel);
if (foundIndex >= 0) {
chIndex = foundIndex;
udpHandler->onSend(const_cast<meshtastic_MeshPacket *>(p), chIndex);
}
}
}
}
#endif
@@ -480,6 +522,35 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
}
}
#if HAS_UDP_MULTICAST
// Fallback: for UDP multicast, try default preset names with default PSK if normal channel match failed
if (!decrypted && p->transport_mechanism == meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MULTICAST_UDP) {
if (channels.setDefaultPresetCryptoForHash(p->channel)) {
memcpy(bytes, p->encrypted.bytes, rawSize);
crypto->decrypt(p->from, p->id, rawSize, bytes);
meshtastic_Data decodedtmp;
memset(&decodedtmp, 0, sizeof(decodedtmp));
if (pb_decode_from_bytes(bytes, rawSize, &meshtastic_Data_msg, &decodedtmp) &&
decodedtmp.portnum != meshtastic_PortNum_UNKNOWN_APP) {
p->decoded = decodedtmp;
p->which_payload_variant = meshtastic_MeshPacket_decoded_tag;
// Map to our local default channel index (name+PSK default), not necessarily primary
ChannelIndex defaultIndex = channels.getPrimaryIndex();
for (ChannelIndex i = 0; i < channels.getNumChannels(); ++i) {
if (channels.isDefaultChannel(i)) {
defaultIndex = i;
break;
}
}
chIndex = defaultIndex;
decrypted = true;
} else {
LOG_WARN("UDP fallback decode attempted but failed for hash 0x%x", p->channel);
}
}
}
#endif
if (decrypted) {
// parsing was successful
p->channel = chIndex; // change to store the index instead of the hash

View File

@@ -2,6 +2,7 @@
#if HAS_UDP_MULTICAST
#include "configuration.h"
#include "main.h"
#include "mesh/Channels.h"
#include "mesh/Router.h"
#if HAS_ETHERNET && defined(ARCH_NRF52)
@@ -53,6 +54,20 @@ class UdpMulticastHandler final
LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetLength);
bool isPacketDecoded = pb_decode_from_bytes(packet.data(), packetLength, &meshtastic_MeshPacket_msg, &mp);
if (isPacketDecoded && router && mp.which_payload_variant == meshtastic_MeshPacket_encrypted_tag) {
// Convert channel hash to index for downlink check
int8_t chIndex = channels.getIndexByHash(mp.channel);
if (chIndex < 0) {
LOG_DEBUG("UDP received packet with unknown channel hash 0x%x", mp.channel);
return;
}
// Check if downlink is enabled for this channel
auto &ch = channels.getByIndex(chIndex);
if (!ch.settings.downlink_enabled) {
LOG_DEBUG("UDP downlink disabled for channel %d", chIndex);
return;
}
mp.transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MULTICAST_UDP;
mp.pki_encrypted = false;
mp.public_key.size = 0;
@@ -65,11 +80,17 @@ class UdpMulticastHandler final
}
}
bool onSend(const meshtastic_MeshPacket *mp)
bool onSend(const meshtastic_MeshPacket *mp, ChannelIndex chIndex)
{
if (!mp || !udp) {
return false;
}
// Check if uplink is enabled for this specific channel
auto &ch = channels.getByIndex(chIndex);
if (!ch.settings.uplink_enabled) {
LOG_DEBUG("UDP uplink disabled for channel %d", chIndex);
return false;
}
#if defined(ARCH_NRF52)
if (!isEthernetAvailable()) {
return false;