diff --git a/src/mesh/Channels.cpp b/src/mesh/Channels.cpp index 4dcd94e3b..f3dfae88e 100644 --- a/src/mesh/Channels.cpp +++ b/src/mesh/Channels.cpp @@ -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 } \ No newline at end of file diff --git a/src/mesh/Channels.h b/src/mesh/Channels.h index b53f552fa..499401c5c 100644 --- a/src/mesh/Channels.h +++ b/src/mesh/Channels.h @@ -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 * diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 828f70018..fa15a7c1f 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -357,10 +357,16 @@ ErrorCode Router::send(meshtastic_MeshPacket *p) } #endif #if HAS_UDP_MULTICAST - // Only publish to UDP if we're the original transmitter of the packet - if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST && - isFromUs(p)) { - udpHandler->onSend(const_cast(p), chIndex); + 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(p), chIndex); + } } #endif packetPool.release(p_decoded); @@ -369,7 +375,35 @@ ErrorCode Router::send(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)) { - udpHandler->onSend(const_cast(p), p->channel); + // 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(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(p), chIndex); + } + } + } } #endif diff --git a/src/mesh/udp/UdpMulticastHandler.h b/src/mesh/udp/UdpMulticastHandler.h index 0a27a316e..b04785f30 100644 --- a/src/mesh/udp/UdpMulticastHandler.h +++ b/src/mesh/udp/UdpMulticastHandler.h @@ -54,10 +54,17 @@ 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(mp.channel); + auto &ch = channels.getByIndex(chIndex); if (!ch.settings.downlink_enabled) { - LOG_DEBUG("UDP downlink disabled for channel %d", mp.channel); + LOG_DEBUG("UDP downlink disabled for channel %d", chIndex); return; }