mirror of
https://github.com/meshtastic/firmware.git
synced 2025-07-31 02:45:41 +00:00
UDP for RAK4631 Eth Gw and the t-eth-elite. Solves #7149 (#7385)
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 (stm32) (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32-s3 (push) Blocked by required conditions
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (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 (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 (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 (stm32) (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32-s3 (push) Blocked by required conditions
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (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 (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 (stm32) (push) Blocked by required conditions
CI / publish-firmware (push) Blocked by required conditions
* UDP for RAK4631 Eth Gw and the t-eth-elite. Also enable IP output on Portduino. Solves #7149 * Copilot suggestion Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix portduino build * initialize local port --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
parent
1c2a3c620f
commit
a9c9b96eb6
@ -39,7 +39,7 @@ build_flags =
|
|||||||
-Isrc/platform/portduino
|
-Isrc/platform/portduino
|
||||||
-DRADIOLIB_EEPROM_UNSUPPORTED
|
-DRADIOLIB_EEPROM_UNSUPPORTED
|
||||||
-DPORTDUINO_LINUX_HARDWARE
|
-DPORTDUINO_LINUX_HARDWARE
|
||||||
-DHAS_UDP_MULTICAST
|
-DHAS_UDP_MULTICAST=1
|
||||||
-lpthread
|
-lpthread
|
||||||
-lstdc++fs
|
-lstdc++fs
|
||||||
-lbluetooth
|
-lbluetooth
|
||||||
|
@ -68,6 +68,9 @@ static int32_t reconnectETH()
|
|||||||
initApiServer();
|
initApiServer();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||||
|
udpHandler->start();
|
||||||
|
}
|
||||||
|
|
||||||
ethStartupComplete = true;
|
ethStartupComplete = true;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
bool initEthernet();
|
bool initEthernet();
|
||||||
bool isEthernetAvailable();
|
bool isEthernetAvailable();
|
||||||
|
@ -4,8 +4,13 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mesh/Router.h"
|
#include "mesh/Router.h"
|
||||||
|
|
||||||
#include <AsyncUDP.h>
|
#if HAS_ETHERNET && defined(ARCH_NRF52)
|
||||||
|
#include "mesh/eth/ethClient.h"
|
||||||
|
#else
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <AsyncUDP.h>
|
||||||
|
|
||||||
#if HAS_ETHERNET && defined(USE_WS5500)
|
#if HAS_ETHERNET && defined(USE_WS5500)
|
||||||
#include <ETHClass2.h>
|
#include <ETHClass2.h>
|
||||||
@ -22,11 +27,11 @@ class UdpMulticastHandler final
|
|||||||
void start()
|
void start()
|
||||||
{
|
{
|
||||||
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT, 64)) {
|
if (udp.listenMulticast(udpIpAddress, UDP_MULTICAST_DEFAUL_PORT, 64)) {
|
||||||
#ifndef ARCH_PORTDUINO
|
#if defined(ARCH_NRF52) || defined(ARCH_PORTDUINO)
|
||||||
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
|
LOG_DEBUG("UDP Listening on IP: %u.%u.%u.%u:%u", udpIpAddress[0], udpIpAddress[1], udpIpAddress[2], udpIpAddress[3],
|
||||||
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
|
UDP_MULTICAST_DEFAUL_PORT);
|
||||||
#else
|
#else
|
||||||
LOG_DEBUG("UDP Listening");
|
LOG_DEBUG("UDP Listening on IP: %s", WiFi.localIP().toString().c_str());
|
||||||
#endif
|
#endif
|
||||||
udp.onPacket([this](AsyncUDPPacket packet) { onReceive(packet); });
|
udp.onPacket([this](AsyncUDPPacket packet) { onReceive(packet); });
|
||||||
} else {
|
} else {
|
||||||
@ -37,7 +42,10 @@ class UdpMulticastHandler final
|
|||||||
void onReceive(AsyncUDPPacket packet)
|
void onReceive(AsyncUDPPacket packet)
|
||||||
{
|
{
|
||||||
size_t packetLength = packet.length();
|
size_t packetLength = packet.length();
|
||||||
#ifndef ARCH_PORTDUINO
|
#if defined(ARCH_NRF52)
|
||||||
|
IPAddress ip = packet.remoteIP();
|
||||||
|
LOG_DEBUG("UDP broadcast from: %u.%u.%u.%u, len=%u", ip[0], ip[1], ip[2], ip[3], packetLength);
|
||||||
|
#elif !defined(ARCH_PORTDUINO)
|
||||||
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
|
// FIXME(PORTDUINO): arduino lacks IPAddress::toString()
|
||||||
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
|
||||||
@ -61,7 +69,11 @@ class UdpMulticastHandler final
|
|||||||
if (!mp || !udp) {
|
if (!mp || !udp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifndef ARCH_PORTDUINO
|
#if defined(ARCH_NRF52)
|
||||||
|
if (!isEthernetAvailable()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#elif !defined(ARCH_PORTDUINO)
|
||||||
if (WiFi.status() != WL_CONNECTED) {
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
69
src/platform/nrf52/AsyncUDP.cpp
Normal file
69
src/platform/nrf52/AsyncUDP.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "AsyncUDP.h"
|
||||||
|
|
||||||
|
AsyncUDP::AsyncUDP() : OSThread("AsyncUDP"), localPort(0) {}
|
||||||
|
|
||||||
|
bool AsyncUDP::listenMulticast(IPAddress multicastIP, uint16_t port, uint8_t ttl)
|
||||||
|
{
|
||||||
|
if (!isMulticast(multicastIP))
|
||||||
|
return false;
|
||||||
|
localPort = port;
|
||||||
|
udp.beginMulticast(multicastIP, port);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AsyncUDP::write(uint8_t b)
|
||||||
|
{
|
||||||
|
return udp.write(&b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AsyncUDP::write(const uint8_t *data, size_t len)
|
||||||
|
{
|
||||||
|
return udp.write(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsyncUDP::onPacket(const std::function<void(AsyncUDPPacket)> &callback)
|
||||||
|
{
|
||||||
|
_onPacket = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsyncUDP::writeTo(const uint8_t *data, size_t len, IPAddress ip, uint16_t port)
|
||||||
|
{
|
||||||
|
if (!udp.beginPacket(ip, port))
|
||||||
|
return false;
|
||||||
|
udp.write(data, len);
|
||||||
|
return udp.endPacket();
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsyncUDPPacket
|
||||||
|
AsyncUDPPacket::AsyncUDPPacket(EthernetUDP &source) : _udp(source), _remoteIP(source.remoteIP()), _remotePort(source.remotePort())
|
||||||
|
{
|
||||||
|
if (_udp.available() > 0) {
|
||||||
|
_readLength = _udp.read(_buffer, sizeof(_buffer));
|
||||||
|
} else {
|
||||||
|
_readLength = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress AsyncUDPPacket::remoteIP()
|
||||||
|
{
|
||||||
|
return _remoteIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t AsyncUDPPacket::length()
|
||||||
|
{
|
||||||
|
return _readLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *AsyncUDPPacket::data()
|
||||||
|
{
|
||||||
|
return _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t AsyncUDP::runOnce()
|
||||||
|
{
|
||||||
|
if (_onPacket && udp.parsePacket() > 0) {
|
||||||
|
AsyncUDPPacket packet(udp);
|
||||||
|
_onPacket(packet);
|
||||||
|
}
|
||||||
|
return 5; // check every 5ms
|
||||||
|
}
|
57
src/platform/nrf52/AsyncUDP.h
Normal file
57
src/platform/nrf52/AsyncUDP.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#ifndef ASYNC_UDP_H
|
||||||
|
#define ASYNC_UDP_H
|
||||||
|
|
||||||
|
#include "concurrency/OSThread.h"
|
||||||
|
#include <IPAddress.h>
|
||||||
|
#include <Print.h>
|
||||||
|
#include <RAK13800_W5100S.h>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
class AsyncUDPPacket;
|
||||||
|
|
||||||
|
class AsyncUDP : public Print, private concurrency::OSThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AsyncUDP();
|
||||||
|
explicit operator bool() const { return localPort != 0; }
|
||||||
|
|
||||||
|
bool listenMulticast(IPAddress multicastIP, uint16_t port, uint8_t ttl = 64);
|
||||||
|
bool writeTo(const uint8_t *data, size_t len, IPAddress ip, uint16_t port);
|
||||||
|
|
||||||
|
size_t write(uint8_t b) override;
|
||||||
|
size_t write(const uint8_t *data, size_t len) override;
|
||||||
|
void onPacket(const std::function<void(AsyncUDPPacket)> &callback);
|
||||||
|
|
||||||
|
private:
|
||||||
|
EthernetUDP udp;
|
||||||
|
uint16_t localPort;
|
||||||
|
std::function<void(AsyncUDPPacket)> _onPacket;
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AsyncUDPPacket
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AsyncUDPPacket(EthernetUDP &source);
|
||||||
|
|
||||||
|
IPAddress remoteIP();
|
||||||
|
uint16_t length();
|
||||||
|
const uint8_t *data();
|
||||||
|
|
||||||
|
private:
|
||||||
|
EthernetUDP &_udp;
|
||||||
|
IPAddress _remoteIP;
|
||||||
|
uint16_t _remotePort;
|
||||||
|
size_t _readLength = 0;
|
||||||
|
|
||||||
|
static constexpr size_t BUF_SIZE = 512;
|
||||||
|
uint8_t _buffer[BUF_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool isMulticast(const IPAddress &ip)
|
||||||
|
{
|
||||||
|
return (ip[0] & 0xF0) == 0xE0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASYNC_UDP_H
|
@ -5,6 +5,7 @@ board = wiscore_rak4631
|
|||||||
board_check = true
|
board_check = true
|
||||||
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631_eth_gw -D RAK_4631
|
build_flags = ${nrf52840_base.build_flags} -Ivariants/rak4631_eth_gw -D RAK_4631
|
||||||
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||||
|
-DHAS_UDP_MULTICAST=1
|
||||||
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
|
-DEINK_DISPLAY_MODEL=GxEPD2_213_BN
|
||||||
-DEINK_WIDTH=250
|
-DEINK_WIDTH=250
|
||||||
-DEINK_HEIGHT=122
|
-DEINK_HEIGHT=122
|
||||||
|
@ -6,6 +6,7 @@ board_build.partitions = default_16MB.csv
|
|||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags}
|
${esp32s3_base.build_flags}
|
||||||
-D T_ETH_ELITE
|
-D T_ETH_ELITE
|
||||||
|
-D HAS_UDP_MULTICAST=1
|
||||||
-I variants/t-eth-elite
|
-I variants/t-eth-elite
|
||||||
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user