diff options
-rw-r--r-- | src/Config/Pins.h | 4 | ||||
-rw-r--r-- | src/Config/Pins_Duet3_MB6HC.h | 6 | ||||
-rw-r--r-- | src/Config/Pins_Duet3_MB6XD.h | 6 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/Lwip/lwipopts.h | 2 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/LwipEthernetInterface.cpp | 36 | ||||
-rw-r--r-- | src/Networking/LwipEthernet/LwipEthernetInterface.h | 2 | ||||
-rw-r--r-- | src/Networking/MulticastResponder.cpp | 109 | ||||
-rw-r--r-- | src/Networking/MulticastResponder.h | 27 | ||||
-rw-r--r-- | src/Networking/Network.cpp | 33 | ||||
-rw-r--r-- | src/Networking/NetworkDefs.h | 31 | ||||
-rw-r--r-- | src/Networking/NetworkResponder.h | 4 |
11 files changed, 238 insertions, 22 deletions
diff --git a/src/Config/Pins.h b/src/Config/Pins.h index efa86e7f..69d7f45d 100644 --- a/src/Config/Pins.h +++ b/src/Config/Pins.h @@ -179,6 +179,10 @@ # define SUPPORT_TELNET HAS_NETWORKING #endif +#ifndef SUPPORT_MULTICAST_DISCOVERY +# define SUPPORT_MULTICAST_DISCOVERY 0 +#endif + #ifndef HAS_SBC_INTERFACE # define HAS_SBC_INTERFACE 0 #endif diff --git a/src/Config/Pins_Duet3_MB6HC.h b/src/Config/Pins_Duet3_MB6HC.h index 5574ff1e..d9076bed 100644 --- a/src/Config/Pins_Duet3_MB6HC.h +++ b/src/Config/Pins_Duet3_MB6HC.h @@ -14,12 +14,15 @@ constexpr uint32_t IAP_IMAGE_START = 0x20458000; // last 32kb of RAM // Features definition +// Networking support #define HAS_LWIP_NETWORKING 1 #define HAS_WIFI_NETWORKING 0 -#define HAS_SBC_INTERFACE 1 +// Storage support +#define HAS_SBC_INTERFACE 1 #define HAS_MASS_STORAGE 1 #define HAS_HIGH_SPEED_SD 1 + #define HAS_CPU_TEMP_SENSOR 1 #define SUPPORT_TMC51xx 1 @@ -45,6 +48,7 @@ constexpr uint32_t IAP_IMAGE_START = 0x20458000; // last 32kb of RAM #define SUPPORT_OBJECT_MODEL 1 #define SUPPORT_FTP 1 #define SUPPORT_TELNET 1 +#define SUPPORT_MULTICAST_DISCOVERY 1 #define SUPPORT_ASYNC_MOVES 1 #define ALLOCATE_DEFAULT_PORTS 0 #define TRACK_OBJECT_NAMES 1 diff --git a/src/Config/Pins_Duet3_MB6XD.h b/src/Config/Pins_Duet3_MB6XD.h index 514cb4ed..ac87e4dd 100644 --- a/src/Config/Pins_Duet3_MB6XD.h +++ b/src/Config/Pins_Duet3_MB6XD.h @@ -14,12 +14,15 @@ constexpr uint32_t IAP_IMAGE_START = 0x20458000; // last 32kb of RAM // Features definition +// Networking support #define HAS_LWIP_NETWORKING 1 #define HAS_WIFI_NETWORKING 0 -#define HAS_SBC_INTERFACE 1 +// Storage support +#define HAS_SBC_INTERFACE 1 #define HAS_MASS_STORAGE 1 #define HAS_HIGH_SPEED_SD 1 + #define HAS_CPU_TEMP_SENSOR 1 #define SUPPORT_TMC51xx 0 @@ -44,6 +47,7 @@ constexpr uint32_t IAP_IMAGE_START = 0x20458000; // last 32kb of RAM #define SUPPORT_OBJECT_MODEL 1 #define SUPPORT_FTP 1 #define SUPPORT_TELNET 1 +#define SUPPORT_MULTICAST_DISCOVERY 1 #define SUPPORT_ASYNC_MOVES 1 #define ALLOCATE_DEFAULT_PORTS 0 #define TRACK_OBJECT_NAMES 1 diff --git a/src/Networking/LwipEthernet/Lwip/lwipopts.h b/src/Networking/LwipEthernet/Lwip/lwipopts.h index dc747e95..ec45aee7 100644 --- a/src/Networking/LwipEthernet/Lwip/lwipopts.h +++ b/src/Networking/LwipEthernet/Lwip/lwipopts.h @@ -267,7 +267,7 @@ extern uint32_t random32(void) noexcept; #define LWIP_NETIF_HOSTNAME 1 /** The maximum number of services per netif */ -#define MDNS_MAX_SERVICES 4 +#define MDNS_MAX_SERVICES 5 // increased from 4 to 5 to include _duet_discovery service /* diff --git a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp index 9f35a201..027c4daa 100644 --- a/src/Networking/LwipEthernet/LwipEthernetInterface.cpp +++ b/src/Networking/LwipEthernet/LwipEthernetInterface.cpp @@ -20,6 +20,10 @@ #include <Networking/HttpResponder.h> #include <Networking/FtpResponder.h> #include <Networking/TelnetResponder.h> +#if SUPPORT_MULTICAST_DISCOVERY +# include <Networking/MulticastResponder.h> +#endif + #include <General/IP4String.h> #include <Version.h> // version is reported by MDNS #include "GMAC/ethernet_sam.h" @@ -46,7 +50,14 @@ extern "C" extern struct netif gs_net_if; } -const char * const MdnsServiceStrings[NumProtocols] = { "_http", "_ftp", "_telnet" }; +const char * const MdnsServiceStrings[NumProtocols] = +{ + "_http", "_ftp", "_telnet", +#if SUPPORT_MULTICAST_DISCOVERY + "_duet_discovery" +#endif +}; + const char * const MdnsTxtRecords[2] = { "product=" FIRMWARE_NAME, "version=" VERSION }; const unsigned int MdnsTtl = 10 * 60; // same value as on the Duet 0.6/0.8.5 @@ -142,9 +153,9 @@ void LwipEthernetInterface::Init() noexcept lwipMutex.Create("LwipCore"); // Clear the PCBs - for (size_t i = 0; i < NumTcpPorts; ++i) + for (tcp_pcb*& pcb : listeningPcbs) { - listeningPcbs[i] = nullptr; + pcb = nullptr; } macAddress = platform.GetDefaultMacAddress(); @@ -178,6 +189,7 @@ GCodeResult LwipEthernetInterface::EnableProtocol(NetworkProtocol protocol, int RebuildMdnsServices(); } } + ReportOneProtocol(protocol, reply); return GCodeResult::ok; } @@ -205,7 +217,11 @@ GCodeResult LwipEthernetInterface::DisableProtocol(NetworkProtocol protocol, con void LwipEthernetInterface::StartProtocol(NetworkProtocol protocol) noexcept { - if (listeningPcbs[protocol] == nullptr) + if ( listeningPcbs[protocol] == nullptr +#if SUPPORT_MULTICAST_DISCOVERY + && protocol != MulticastDiscoveryProtocol +#endif + ) { tcp_pcb *pcb = tcp_new(); if (pcb == nullptr) @@ -245,6 +261,12 @@ void LwipEthernetInterface::StartProtocol(NetworkProtocol protocol) noexcept sockets[TelnetSocketNumber]->Init(TelnetSocketNumber, portNumbers[protocol], protocol); break; +#if SUPPORT_MULTICAST_DISCOVERY + case MulticastDiscoveryProtocol: + MulticastResponder::Start(portNumbers[protocol]); + break; +#endif + default: break; } @@ -270,6 +292,12 @@ void LwipEthernetInterface::ShutdownProtocol(NetworkProtocol protocol) noexcept sockets[TelnetSocketNumber]->TerminateAndDisable(); break; +#if SUPPORT_MULTICAST_DISCOVERY + case MulticastDiscoveryProtocol: + MulticastResponder::Stop(); + break; +#endif + default: break; } diff --git a/src/Networking/LwipEthernet/LwipEthernetInterface.h b/src/Networking/LwipEthernet/LwipEthernetInterface.h index 01fa0f03..12c2bc08 100644 --- a/src/Networking/LwipEthernet/LwipEthernetInterface.h +++ b/src/Networking/LwipEthernet/LwipEthernetInterface.h @@ -87,7 +87,7 @@ private: TcpPort portNumbers[NumProtocols]; // port number used for each protocol bool protocolEnabled[NumProtocols]; // whether each protocol is enabled bool closeDataPort; - tcp_pcb *listeningPcbs[NumTcpPorts]; + tcp_pcb *listeningPcbs[NumProtocols + 1]; bool activated; bool initialised; diff --git a/src/Networking/MulticastResponder.cpp b/src/Networking/MulticastResponder.cpp new file mode 100644 index 00000000..f39d120a --- /dev/null +++ b/src/Networking/MulticastResponder.cpp @@ -0,0 +1,109 @@ +/* + * MulricastResponder.cpp + * + * Created on: 12 Jul 2022 + * Author: David + */ + +#include "MulticastResponder.h" +#include <Platform/RepRap.h> +#include <Platform/Platform.h> + +extern "C" { +#include "LwipEthernet/Lwip/src/include/lwip/udp.h" +} + +#if SUPPORT_MULTICAST_DISCOVERY + +static udp_pcb *ourPcb = nullptr; +static pbuf * volatile receivedPbuf = nullptr; +static volatile uint32_t receivedIpAddr; +static volatile uint16_t receivedPort; +static unsigned int messagesProcessed = 0; + +static bool active = false; + +// Receive callback function +extern "C" void rcvFunc(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) noexcept +{ + if (active && receivedPbuf == nullptr) + { + receivedIpAddr = addr->addr; + receivedPort = port; + receivedPbuf = p; + } + else + { + pbuf_free(p); + } +} + +void MulticastResponder::Init() noexcept +{ + // Nothing needed here yet +} + +// Do some work, returning true if we did anything significant +void MulticastResponder::Spin() noexcept +{ + pbuf *rxPbuf = receivedPbuf; + if (rxPbuf != nullptr) + { + debugPrintf("Rx UDP: addr %u.%u.%u.%u port %u data", + (unsigned int)((receivedIpAddr >> 24) & 0xFF), (unsigned int)((receivedIpAddr >> 16) & 0xFF), (unsigned int)((receivedIpAddr >> 8) & 0xFF), (unsigned int)(receivedIpAddr & 0xFF), receivedPort); + for (size_t i = 0; i < rxPbuf->len; ++i) + { + debugPrintf(" %02x", ((const uint8_t*)(rxPbuf->payload))[i]); + } + debugPrintf("\n"); + pbuf_free(rxPbuf); + receivedPbuf = nullptr; + ++messagesProcessed; + } +} + +void MulticastResponder::Diagnostics(MessageType mtype) noexcept +{ + reprap.GetPlatform().MessageF(mtype, "=== Multicast handler ===\nResponder is %s, messages processed %u\n", (active) ? "active" : "inactive", messagesProcessed); +} + +void MulticastResponder::Start(TcpPort port) noexcept +{ + if (ourPcb == nullptr) + { + ourPcb = udp_new_ip_type(IPADDR_TYPE_ANY); + if (ourPcb == nullptr) + { + reprap.GetPlatform().Message(ErrorMessage, "unable to allocate a pcb\n"); + } + else + { + udp_set_multicast_ttl(ourPcb, 255); + if (udp_bind(ourPcb, IP_ADDR_ANY, port) != ERR_OK) + { + reprap.GetPlatform().Message(ErrorMessage, "udp_bind call failed\n"); + } + else + { + debugPrintf("udp_bind call succeeded\n"); + udp_recv(ourPcb, rcvFunc, nullptr); + } + } + } + active = true; + messagesProcessed = 0; +} + +void MulticastResponder::Stop() noexcept +{ + if (ourPcb != nullptr) + { + udp_remove(ourPcb); + ourPcb = nullptr; + } + active = false; +} + +#endif + +// End diff --git a/src/Networking/MulticastResponder.h b/src/Networking/MulticastResponder.h new file mode 100644 index 00000000..2d57581e --- /dev/null +++ b/src/Networking/MulticastResponder.h @@ -0,0 +1,27 @@ +/* + * MulricastResponder.h + * + * Created on: 12 Jul 2022 + * Author: David + */ + +#ifndef SRC_NETWORKING_MULTICASTRESPONDER_H_ +#define SRC_NETWORKING_MULTICASTRESPONDER_H_ + +#include <RepRapFirmware.h> +#include <NetworkDefs.h> + +#if SUPPORT_MULTICAST_DISCOVERY + +namespace MulticastResponder +{ + void Init() noexcept; + void Spin() noexcept; + void Start(TcpPort port) noexcept; + void Stop() noexcept; + void Diagnostics(MessageType mtype) noexcept; +} + +#endif + +#endif /* SRC_NETWORKING_MULTICASTRESPONDER_H_ */ diff --git a/src/Networking/Network.cpp b/src/Networking/Network.cpp index f80f18bf..0b6f60fe 100644 --- a/src/Networking/Network.cpp +++ b/src/Networking/Network.cpp @@ -21,29 +21,32 @@ #include "NetworkInterface.h" #if HAS_LWIP_NETWORKING -#include "LwipEthernet/LwipEthernetInterface.h" +# include "LwipEthernet/LwipEthernetInterface.h" #endif #if HAS_W5500_NETWORKING -#include "W5500Ethernet/W5500Interface.h" +# include "W5500Ethernet/W5500Interface.h" #endif #if HAS_WIFI_NETWORKING -#include "ESP8266WiFi/WiFiInterface.h" +# include "ESP8266WiFi/WiFiInterface.h" #endif #if HAS_RTOSPLUSTCP_NETWORKING -#include "RTOSPlusTCPEthernet/RTOSPlusTCPEthernetInterface.h" +# include "RTOSPlusTCPEthernet/RTOSPlusTCPEthernetInterface.h" #endif #if SUPPORT_HTTP -#include "HttpResponder.h" +# include "HttpResponder.h" #endif #if SUPPORT_FTP -#include "FtpResponder.h" +# include "FtpResponder.h" #endif #if SUPPORT_TELNET -#include "TelnetResponder.h" +# include "TelnetResponder.h" +#endif +#if SUPPORT_MULTICAST_DISCOVERY +# include "MulticastResponder.h" #endif #ifdef __LPC17xx__ @@ -250,6 +253,11 @@ GCodeResult Network::DisableProtocol(unsigned int interface, NetworkProtocol pro break; #endif +#if SUPPORT_MULTICAST_DISCOVERY + case MulticastDiscoveryProtocol: + break; +#endif + default: break; } @@ -435,6 +443,10 @@ void Network::Activate() noexcept } # endif +#if SUPPORT_MULTICAST_DISCOVERY + MulticastResponder::Init(); +#endif + // Finally, create the network task networkTask.Create(NetworkLoop, "NETWORK", nullptr, TaskPriority::SpinPriority); #endif @@ -519,6 +531,9 @@ void Network::Spin() noexcept if (nr == nullptr) { nr = responders; // 'responders' can't be null at this point +#if SUPPORT_MULTICAST_DISCOVERY + MulticastResponder::Spin(); +#endif } doneSomething = nr->Spin(); nr = nr->GetNext(); @@ -572,6 +587,10 @@ void Network::Diagnostics(MessageType mtype) noexcept iface->Diagnostics(mtype); } #endif + +#if SUPPORT_MULTICAST_DISCOVERY + MulticastResponder::Diagnostics(mtype); +#endif } int Network::EnableState(unsigned int interface) const noexcept diff --git a/src/Networking/NetworkDefs.h b/src/Networking/NetworkDefs.h index 116a97ea..d1f17b9e 100644 --- a/src/Networking/NetworkDefs.h +++ b/src/Networking/NetworkDefs.h @@ -36,16 +36,37 @@ constexpr IPAddress DefaultIpAddress; // will be initialised to 0 by construc constexpr IPAddress DefaultNetMask(0x00FFFFFF); // equivalent to 255.255.255.0. Use constexpr constructor to avoid it being allocated in RAM. constexpr IPAddress DefaultGateway; // will be initialised to 0 by constructor -constexpr size_t NumProtocols = 3; // number of network protocols we support, not counting FtpDataProtocol, MdnsProtocol or AnyProtocol -constexpr NetworkProtocol HttpProtocol = 0, FtpProtocol = 1, TelnetProtocol = 2, FtpDataProtocol = 3, MdnsProtocol = 4, AnyProtocol = 255; +constexpr size_t NumTcpProtocols = 3; + +#if SUPPORT_MULTICAST_DISCOVERY +constexpr size_t NumProtocols = NumTcpProtocols + 1; // number of network protocols we support, not counting FtpDataProtocol, MdnsProtocol or AnyProtocol +#else +constexpr size_t NumProtocols = NumTcpProtocols; // number of network protocols we support, not counting FtpDataProtocol, MdnsProtocol or AnyProtocol +#endif + +constexpr NetworkProtocol HttpProtocol = 0, FtpProtocol = 1, TelnetProtocol = 2, MulticastDiscoveryProtocol = 3, FtpDataProtocol = 3, MdnsProtocol = 4, AnyProtocol = 255; -constexpr size_t NumTcpPorts = NumProtocols + 1; constexpr TcpPort DefaultHttpPort = 80; constexpr TcpPort DefaultFtpPort = 21; constexpr TcpPort DefaultTelnetPort = 23; +#if SUPPORT_MULTICAST_DISCOVERY +constexpr TcpPort DefaultMulticastDiscoveryPort = 10002; // this is actually a UDP port +#endif -constexpr TcpPort DefaultPortNumbers[NumProtocols] = { DefaultHttpPort, DefaultFtpPort, DefaultTelnetPort }; -constexpr const char *_ecv_array ProtocolNames[NumProtocols] = { "HTTP", "FTP", "TELNET" }; +constexpr TcpPort DefaultPortNumbers[NumProtocols] = +{ + DefaultHttpPort, DefaultFtpPort, DefaultTelnetPort, +#if SUPPORT_MULTICAST_DISCOVERY + DefaultMulticastDiscoveryPort +#endif +}; +constexpr const char *_ecv_array ProtocolNames[NumProtocols] = +{ + "HTTP", "FTP", "TELNET", +#if SUPPORT_MULTICAST_DISCOVERY + "Multicast Discovery" +#endif +}; constexpr uint8_t MdnsMacAddress[6] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFB }; constexpr uint8_t MdnsIPAddress[4] = { 224, 0, 0, 251 }; diff --git a/src/Networking/NetworkResponder.h b/src/Networking/NetworkResponder.h index 2bf3976d..2cfb3c97 100644 --- a/src/Networking/NetworkResponder.h +++ b/src/Networking/NetworkResponder.h @@ -27,8 +27,8 @@ public: NetworkResponder(const NetworkResponder&) = delete; NetworkResponder *GetNext() const noexcept { return next; } - virtual bool Spin() noexcept = 0; // do some work, returning true if we did anything significant - virtual bool Accept(Socket *s, NetworkProtocol protocol) noexcept = 0; // ask the responder to accept this connection, returns true if it did + virtual bool Spin() noexcept = 0; // do some work, returning true if we did anything significant + virtual bool Accept(Socket *s, NetworkProtocol protocol) noexcept = 0; // ask the responder to accept this connection, returns true if it did virtual void Terminate(NetworkProtocol protocol, NetworkInterface *interface) noexcept = 0; // terminate the responder if it is serving the specified protocol on the specified interface virtual void Diagnostics(MessageType mtype) const noexcept = 0; |