mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-05 19:19:18 +00:00
UDP local area network meshing on ESP32
This commit is contained in:
parent
9421eba027
commit
5faeb45651
@ -37,6 +37,7 @@ build_flags =
|
|||||||
-DLIBPAX_ARDUINO
|
-DLIBPAX_ARDUINO
|
||||||
-DLIBPAX_WIFI
|
-DLIBPAX_WIFI
|
||||||
-DLIBPAX_BLE
|
-DLIBPAX_BLE
|
||||||
|
-DHAS_UDP_MULTICAST=1
|
||||||
;-DDEBUG_HEAP
|
;-DDEBUG_HEAP
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
|
10
src/main.cpp
10
src/main.cpp
@ -114,6 +114,11 @@ AccelerometerThread *accelerometerThread = nullptr;
|
|||||||
AudioThread *audioThread = nullptr;
|
AudioThread *audioThread = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_UDP_MULTICAST
|
||||||
|
#include "mesh/udp/UdpMulticastThread.h"
|
||||||
|
UdpMulticastThread *udpThread = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(TCXO_OPTIONAL)
|
#if defined(TCXO_OPTIONAL)
|
||||||
float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if TCXO is optional, put this here so it can be changed further down.
|
float tcxoVoltage = SX126X_DIO3_TCXO_VOLTAGE; // if TCXO is optional, put this here so it can be changed further down.
|
||||||
#endif
|
#endif
|
||||||
@ -783,6 +788,11 @@ void setup()
|
|||||||
LOG_DEBUG("Start audio thread");
|
LOG_DEBUG("Start audio thread");
|
||||||
audioThread = new AudioThread();
|
audioThread = new AudioThread();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_UDP_MULTICAST
|
||||||
|
LOG_DEBUG("Start multicast thread");
|
||||||
|
udpThread = new UdpMulticastThread();
|
||||||
|
#endif
|
||||||
service = new MeshService();
|
service = new MeshService();
|
||||||
service->init();
|
service->init();
|
||||||
|
|
||||||
|
@ -49,6 +49,11 @@ extern Adafruit_DRV2605 drv;
|
|||||||
extern AudioThread *audioThread;
|
extern AudioThread *audioThread;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_UDP_MULTICAST
|
||||||
|
#include "mesh/udp/UdpMulticastThread.h"
|
||||||
|
extern UdpMulticastThread *udpThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Global Screen singleton.
|
// Global Screen singleton.
|
||||||
extern graphics::Screen *screen;
|
extern graphics::Screen *screen;
|
||||||
|
|
||||||
|
@ -299,6 +299,8 @@ NodeDB::NodeDB()
|
|||||||
resetRadioConfig(); // If bogus settings got saved, then fix them
|
resetRadioConfig(); // If bogus settings got saved, then fix them
|
||||||
// nodeDB->LOG_DEBUG("region=%d, NODENUM=0x%x, dbsize=%d", config.lora.region, myNodeInfo.my_node_num, numMeshNodes);
|
// nodeDB->LOG_DEBUG("region=%d, NODENUM=0x%x, dbsize=%d", config.lora.region, myNodeInfo.my_node_num, numMeshNodes);
|
||||||
|
|
||||||
|
config.network.enabled_protocols = meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST;
|
||||||
|
|
||||||
// If we are setup to broadcast on the default channel, ensure that the telemetry intervals are coerced to the minimum value
|
// If we are setup to broadcast on the default channel, ensure that the telemetry intervals are coerced to the minimum value
|
||||||
// of 30 minutes or more
|
// of 30 minutes or more
|
||||||
if (channels.isDefaultChannel(channels.getPrimaryIndex())) {
|
if (channels.isDefaultChannel(channels.getPrimaryIndex())) {
|
||||||
|
@ -274,6 +274,12 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
|||||||
abortSendAndNak(encodeResult, p);
|
abortSendAndNak(encodeResult, p);
|
||||||
return encodeResult; // FIXME - this isn't a valid ErrorCode
|
return encodeResult; // FIXME - this isn't a valid ErrorCode
|
||||||
}
|
}
|
||||||
|
#if HAS_UDP_MULTICAST
|
||||||
|
if (udpThread && isFromUs(p) &&
|
||||||
|
config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||||
|
udpThread->onSend(const_cast<meshtastic_MeshPacket *>(p));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||||
// Only publish to MQTT if we're the original transmitter of the packet
|
// Only publish to MQTT if we're the original transmitter of the packet
|
||||||
if (moduleConfig.mqtt.enabled && isFromUs(p) && mqtt) {
|
if (moduleConfig.mqtt.enabled && isFromUs(p) && mqtt) {
|
||||||
@ -624,6 +630,12 @@ void Router::handleReceived(meshtastic_MeshPacket *p, RxSource src)
|
|||||||
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
|
// After potentially altering it, publish received message to MQTT if we're not the original transmitter of the packet
|
||||||
if ((decoded || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled && !isFromUs(p) && mqtt)
|
if ((decoded || p_encrypted->pki_encrypted) && moduleConfig.mqtt.enabled && !isFromUs(p) && mqtt)
|
||||||
mqtt->onSend(*p_encrypted, *p, p->channel);
|
mqtt->onSend(*p_encrypted, *p, p->channel);
|
||||||
|
#endif
|
||||||
|
#if HAS_UDP_MULTICAST
|
||||||
|
if ((decoded || p_encrypted->pki_encrypted) && !isFromUs(p) && udpThread &&
|
||||||
|
config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||||
|
udpThread->onSend(const_cast<meshtastic_MeshPacket *>(p_encrypted));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
71
src/mesh/udp/UdpMulticastThread.h
Normal file
71
src/mesh/udp/UdpMulticastThread.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#pragma once
|
||||||
|
#if HAS_UDP_MULTICAST
|
||||||
|
#include "configuration.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "mesh/Router.h"
|
||||||
|
|
||||||
|
#include <AsyncUDP.h>
|
||||||
|
#include <WiFi.h>
|
||||||
|
|
||||||
|
#define UDP_MULTICAST_DEFAUL_PORT 4403 // Default port for UDP multicast is same as TCP api server
|
||||||
|
#define UDP_MULTICAST_THREAD_INTERVAL_MS 15000
|
||||||
|
|
||||||
|
class UdpMulticastThread : public concurrency::OSThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UdpMulticastThread() : OSThread("UdpMulticast") { udpIpAddress = IPAddress(224, 0, 0, 69); }
|
||||||
|
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT)) {
|
||||||
|
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
|
||||||
|
udp.onPacket([this](AsyncUDPPacket packet) { onReceive(packet); });
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("Failed to listen on UDP");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onReceive(AsyncUDPPacket packet)
|
||||||
|
{
|
||||||
|
size_t packetLength = packet.length();
|
||||||
|
LOG_DEBUG("UDP broadcast from: %s, len=%u", packet.remoteIP().toString().c_str(), packetLength);
|
||||||
|
meshtastic_MeshPacket mp;
|
||||||
|
uint8_t bytes[meshtastic_MeshPacket_size]; // Allocate buffer for the data
|
||||||
|
size_t packetSize = packet.readBytes(bytes, packet.length());
|
||||||
|
LOG_DEBUG("Decoding MeshPacket from UDP len=%u", packetSize);
|
||||||
|
bool isPacketDecoded = pb_decode_from_bytes(bytes, packetLength, &meshtastic_MeshPacket_msg, &mp);
|
||||||
|
if (isPacketDecoded && router) {
|
||||||
|
UniquePacketPoolPacket p = packetPool.allocUniqueCopy(mp);
|
||||||
|
// Unset received SNR/RSSI which might have been added by the MQTT gateway
|
||||||
|
p->rx_snr = 0;
|
||||||
|
p->rx_rssi = 0;
|
||||||
|
router->enqueueReceivedMessage(p.release());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onSend(const meshtastic_MeshPacket *mp)
|
||||||
|
{
|
||||||
|
if (!mp || WiFi.status() != WL_CONNECTED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG_DEBUG("Broadcasting MeshPacket (id=%u)", mp->id);
|
||||||
|
uint8_t buffer[meshtastic_MeshPacket_size];
|
||||||
|
size_t encodedLength = pb_encode_to_bytes(buffer, sizeof(buffer), &meshtastic_MeshPacket_msg, mp);
|
||||||
|
LOG_DEBUG("Encoded MeshPacket size: %u", encodedLength);
|
||||||
|
udp.broadcastTo(buffer, encodedLength, UDP_MULTICAST_DEFAUL_PORT);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int32_t runOnce() override
|
||||||
|
{
|
||||||
|
canSleep = true;
|
||||||
|
// TODO: Might consider a heartbeat for discovery or keep alive?
|
||||||
|
return UDP_MULTICAST_THREAD_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
IPAddress udpIpAddress;
|
||||||
|
AsyncUDP udp;
|
||||||
|
};
|
||||||
|
#endif // ARCH_ESP32
|
@ -112,6 +112,12 @@ static void onNetworkConnected()
|
|||||||
APStartupComplete = true;
|
APStartupComplete = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if HAS_UDP_MULTICAST
|
||||||
|
if (udpThread) {
|
||||||
|
udpThread->start();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
// FIXME this is kinda yucky, instead we should just have an observable for 'wifireconnected'
|
||||||
#ifndef MESHTASTIC_EXCLUDE_MQTT
|
#ifndef MESHTASTIC_EXCLUDE_MQTT
|
||||||
if (mqtt)
|
if (mqtt)
|
||||||
|
Loading…
Reference in New Issue
Block a user