mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-18 08:12:57 +00:00
Feature: Seamless Cross-Preset Communication via UDP Multicast Bridging (#7753)
Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (rp2350) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / version (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32s3 (push) Blocked by required conditions
CI / build-esp32c3 (push) Blocked by required conditions
CI / build-esp32c6 (push) Blocked by required conditions
CI / build-nrf52840 (push) Blocked by required conditions
CI / build-rp2040 (push) Blocked by required conditions
CI / build-rp2350 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-deb-amd64 (push) Waiting to run
CI / docker-deb-amd64-tft (push) Waiting to run
CI / docker-alp-amd64 (push) Waiting to run
CI / docker-alp-amd64-tft (push) Waiting to run
CI / docker-deb-arm64 (push) Waiting to run
CI / docker-deb-armv7 (push) Waiting to run
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (rp2350) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (rp2350) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (rp2350) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / version (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32s3 (push) Blocked by required conditions
CI / build-esp32c3 (push) Blocked by required conditions
CI / build-esp32c6 (push) Blocked by required conditions
CI / build-nrf52840 (push) Blocked by required conditions
CI / build-rp2040 (push) Blocked by required conditions
CI / build-rp2350 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / build-debian-src (push) Waiting to run
CI / package-pio-deps-native-tft (push) Waiting to run
CI / test-native (push) Waiting to run
CI / docker-deb-amd64 (push) Waiting to run
CI / docker-deb-amd64-tft (push) Waiting to run
CI / docker-alp-amd64 (push) Waiting to run
CI / docker-alp-amd64-tft (push) Waiting to run
CI / docker-deb-arm64 (push) Waiting to run
CI / docker-deb-armv7 (push) Waiting to run
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (rp2350) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (rp2350) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
* Added compatibility between nodes on different Presets through `Mesh via UDP` * Optimize multicast handling and channel mapping - FloodingRouter: remove redundant UDP-encrypted rebroadcast suppression. - Router: guard multicast fallback with HAS_UDP_MULTICAST and map fallback-decoded packets to the local default channel via isDefaultChannel() - UdpMulticastHandler: set transport_mechanism only after successful decode * trunk fmt * Move setting transport mechanism. --------- Co-authored-by: GUVWAF <thijs@havinga.eu>
This commit is contained in:
parent
09de0e3edb
commit
b9d53d667e
@ -423,6 +423,32 @@ bool Channels::decryptForHash(ChannelIndex chIndex, ChannelHash channelHash)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Channels::setDefaultPresetCryptoForHash(ChannelHash channelHash)
|
||||||
|
{
|
||||||
|
// Iterate all known presets
|
||||||
|
for (int preset = _meshtastic_Config_LoRaConfig_ModemPreset_MIN; preset <= _meshtastic_Config_LoRaConfig_ModemPreset_MAX;
|
||||||
|
++preset) {
|
||||||
|
const char *name = DisplayFormatters::getModemPresetDisplayName((meshtastic_Config_LoRaConfig_ModemPreset)preset, false);
|
||||||
|
if (!name)
|
||||||
|
continue;
|
||||||
|
if (strcmp(name, "Invalid") == 0)
|
||||||
|
continue; // skip invalid placeholder
|
||||||
|
uint8_t h = xorHash((const uint8_t *)name, strlen(name));
|
||||||
|
// Expand default PSK alias 1 to actual bytes and xor into hash
|
||||||
|
uint8_t tmp = h ^ xorHash(defaultpsk, sizeof(defaultpsk));
|
||||||
|
if (tmp == channelHash) {
|
||||||
|
// Set crypto to defaultpsk and report success
|
||||||
|
CryptoKey k;
|
||||||
|
memcpy(k.bytes, defaultpsk, sizeof(defaultpsk));
|
||||||
|
k.length = sizeof(defaultpsk);
|
||||||
|
crypto->setKey(k);
|
||||||
|
LOG_INFO("Matched default preset '%s' for hash 0x%x; set default PSK", name, channelHash);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Given a channel index setup crypto for encoding that channel (or the primary channel if that channel is unsecured)
|
/** Given a channel index setup crypto for encoding that channel (or the primary channel if that channel is unsecured)
|
||||||
*
|
*
|
||||||
* This method is called before encoding outbound packets
|
* This method is called before encoding outbound packets
|
||||||
|
@ -94,6 +94,8 @@ class Channels
|
|||||||
|
|
||||||
bool ensureLicensedOperation();
|
bool ensureLicensedOperation();
|
||||||
|
|
||||||
|
bool setDefaultPresetCryptoForHash(ChannelHash channelHash);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Given a channel index, change to use the crypto key specified by that index
|
/** Given a channel index, change to use the crypto key specified by that index
|
||||||
*
|
*
|
||||||
|
@ -430,6 +430,36 @@ 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) {
|
if (decrypted) {
|
||||||
// parsing was successful
|
// parsing was successful
|
||||||
p->channel = chIndex; // change to store the index instead of the hash
|
p->channel = chIndex; // change to store the index instead of the hash
|
||||||
|
@ -50,10 +50,10 @@ class UdpMulticastHandler final
|
|||||||
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
|
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
|
||||||
#endif
|
#endif
|
||||||
meshtastic_MeshPacket mp;
|
meshtastic_MeshPacket mp;
|
||||||
mp.transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MULTICAST_UDP;
|
|
||||||
LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetLength);
|
LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetLength);
|
||||||
bool isPacketDecoded = pb_decode_from_bytes(packet.data(), packetLength, &meshtastic_MeshPacket_msg, &mp);
|
bool isPacketDecoded = pb_decode_from_bytes(packet.data(), packetLength, &meshtastic_MeshPacket_msg, &mp);
|
||||||
if (isPacketDecoded && router && mp.which_payload_variant == meshtastic_MeshPacket_encrypted_tag) {
|
if (isPacketDecoded && router && mp.which_payload_variant == meshtastic_MeshPacket_encrypted_tag) {
|
||||||
|
mp.transport_mechanism = meshtastic_MeshPacket_TransportMechanism_TRANSPORT_MULTICAST_UDP;
|
||||||
mp.pki_encrypted = false;
|
mp.pki_encrypted = false;
|
||||||
mp.public_key.size = 0;
|
mp.public_key.size = 0;
|
||||||
memset(mp.public_key.bytes, 0, sizeof(mp.public_key.bytes));
|
memset(mp.public_key.bytes, 0, sizeof(mp.public_key.bytes));
|
||||||
|
@ -100,4 +100,3 @@
|
|||||||
#define MODEM_DTR 8
|
#define MODEM_DTR 8
|
||||||
#define MODEM_RX 10
|
#define MODEM_RX 10
|
||||||
#define MODEM_TX 11
|
#define MODEM_TX 11
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user