From 78c1511c458a4a87c7cca3a4c78a85a681b2ee57 Mon Sep 17 00:00:00 2001
From: Channel59 <caspar@meshnex.nl>
Date: Wed, 10 Jul 2024 00:17:11 +0200
Subject: [PATCH 1/4] patches: add dhcp hostname support

---
 ...241-Add-methods-for-setting-hostname.patch | 196 ++++++++++++++++++
 .../0242-Request-hostname-through-DHCP.patch  |  53 +++++
 2 files changed, 249 insertions(+)
 create mode 100644 patches/0241-Add-methods-for-setting-hostname.patch
 create mode 100644 patches/0242-Request-hostname-through-DHCP.patch

diff --git a/patches/0241-Add-methods-for-setting-hostname.patch b/patches/0241-Add-methods-for-setting-hostname.patch
new file mode 100644
index 000000000..21c301771
--- /dev/null
+++ b/patches/0241-Add-methods-for-setting-hostname.patch
@@ -0,0 +1,196 @@
+From 75b34cc20a33c05cbc01b3fbdabbfc40ae034bef Mon Sep 17 00:00:00 2001
+From: Guilherme Ricioli <guilherme.riciolic@gmail.com>
+Date: Mon, 15 Apr 2024 17:40:59 -0300
+Subject: [PATCH] Add methods for setting hostname
+
+In the same way it is done for setting MAC address, add methods for
+setting hostname. The underlying network stack can then request this
+to the local DNS through DHCP.
+---
+ .../include/netsocket/EMACInterface.h         |  8 ++++++
+ .../include/netsocket/NetworkInterface.h      | 16 ++++++++++++
+ .../netsocket/include/netsocket/nsapi_types.h | 10 +++++++
+ .../netsocket/source/EMACInterface.cpp        | 26 +++++++++++++++++++
+ .../netsocket/source/NetworkInterface.cpp     | 10 +++++++
+ .../doubles/NetworkInterface_stub.cpp         | 10 +++++++
+ .../test_NetworkInterface.cpp                 | 11 ++++++++
+ 7 files changed, 91 insertions(+)
+
+diff --git a/connectivity/netsocket/include/netsocket/EMACInterface.h b/connectivity/netsocket/include/netsocket/EMACInterface.h
+index 8cf47cb703..c06aeb850e 100644
+--- a/connectivity/netsocket/include/netsocket/EMACInterface.h
++++ b/connectivity/netsocket/include/netsocket/EMACInterface.h
+@@ -83,6 +83,12 @@ public:
+     /** @copydoc NetworkInterface::disconnect */
+     nsapi_error_t disconnect() override;
+ 
++    /** @copydoc NetworkInterface::get_hostname */
++    const char *get_hostname() override;
++
++    /** @copydoc NetworkInterface::set_hostname */
++    nsapi_error_t set_hostname(const char *hostname) override;
++
+     /** @copydoc NetworkInterface::get_mac_address */
+     const char *get_mac_address() override;
+ 
+@@ -146,6 +152,8 @@ protected:
+     OnboardNetworkStack::Interface *_interface = nullptr;
+     bool _dhcp = true;
+     bool _blocking = true;
++    bool _hostname_set = false;
++    char _hostname[NSAPI_HOSTNAME_SIZE];
+     bool _hw_mac_addr_set = false;
+     char _mac_address[NSAPI_MAC_SIZE];
+     char _ip_address[NSAPI_IPv6_SIZE] {};
+diff --git a/connectivity/netsocket/include/netsocket/NetworkInterface.h b/connectivity/netsocket/include/netsocket/NetworkInterface.h
+index 9071a1e40b..81f6011950 100644
+--- a/connectivity/netsocket/include/netsocket/NetworkInterface.h
++++ b/connectivity/netsocket/include/netsocket/NetworkInterface.h
+@@ -90,6 +90,22 @@ public:
+      */
+     virtual void set_as_default();
+ 
++    /** Get hostname.
++     *
++     *  @return         Hostname if configured, null otherwise
++     */
++    virtual const char *get_hostname();
++
++    /** Set hostname.
++     *
++     *  @param          hostname Hostname string
++     *  @retval         NSAPI_ERROR_OK on success
++     *  @retval         NSAPI_ERROR_UNSUPPORTED if this feature is not supported
++     *  @retval         NSAPI_ERROR_PARAMETER if hostname is not valid
++     *  @retval         NSAPI_ERROR_BUSY if hostname couldn't be set
++     */
++    virtual nsapi_error_t set_hostname(const char *hostname);
++
+     /** Get the local MAC address.
+      *
+      *  Provided MAC address is intended for info or debug purposes and
+diff --git a/connectivity/netsocket/include/netsocket/nsapi_types.h b/connectivity/netsocket/include/netsocket/nsapi_types.h
+index 3b496d5087..28dbcc9a38 100644
+--- a/connectivity/netsocket/include/netsocket/nsapi_types.h
++++ b/connectivity/netsocket/include/netsocket/nsapi_types.h
+@@ -196,6 +196,16 @@ typedef enum nsapi_security {
+  */
+ #define NSAPI_IP_BYTES NSAPI_IPv6_BYTES
+ 
++/** Maximum size of hostname
++ *
++ *  According to RFC 1034 [1], Section 3.1 "Name space specifications and
++ *  terminology", 63 is the maximum size of a hostname. +1 for the string
++ *  terminator.
++ *
++ *  [1] https://www.rfc-editor.org/rfc/rfc1034
++ */
++#define NSAPI_HOSTNAME_SIZE 64
++
+ /** Maximum size of MAC address representation
+  */
+ #define NSAPI_MAC_SIZE 18
+diff --git a/connectivity/netsocket/source/EMACInterface.cpp b/connectivity/netsocket/source/EMACInterface.cpp
+index f48bc0a185..de8d9753d7 100644
+--- a/connectivity/netsocket/source/EMACInterface.cpp
++++ b/connectivity/netsocket/source/EMACInterface.cpp
+@@ -88,6 +88,32 @@ nsapi_error_t EMACInterface::disconnect()
+     return NSAPI_ERROR_NO_CONNECTION;
+ }
+ 
++const char *EMACInterface::get_hostname()
++{
++    if (_hostname_set) {
++        return _hostname;
++    }
++    return nullptr;
++}
++
++nsapi_error_t EMACInterface::set_hostname(const char *hostname)
++{
++    if (!hostname || strlen(hostname) > NSAPI_HOSTNAME_SIZE - 1) {
++        return NSAPI_ERROR_PARAMETER;
++    }
++
++    if (_interface) {
++        // can't set hostname once initialized
++        return NSAPI_ERROR_BUSY;
++    }
++
++    memset(_hostname, 0, NSAPI_HOSTNAME_SIZE);
++    strncpy(_hostname, hostname, NSAPI_HOSTNAME_SIZE - 1);
++    _hostname_set = true;
++
++    return NSAPI_ERROR_OK;
++}
++
+ const char *EMACInterface::get_mac_address()
+ {
+     if (_interface && _interface->get_mac_address(_mac_address, sizeof(_mac_address))) {
+diff --git a/connectivity/netsocket/source/NetworkInterface.cpp b/connectivity/netsocket/source/NetworkInterface.cpp
+index 0f237f0e19..649df0f9b3 100644
+--- a/connectivity/netsocket/source/NetworkInterface.cpp
++++ b/connectivity/netsocket/source/NetworkInterface.cpp
+@@ -29,6 +29,16 @@ void NetworkInterface::set_as_default()
+ 
+ }
+ 
++const char *NetworkInterface::get_hostname()
++{
++    return 0;
++}
++
++nsapi_error_t NetworkInterface::set_hostname(const char *hostname)
++{
++    return NSAPI_ERROR_UNSUPPORTED;
++}
++
+ const char *NetworkInterface::get_mac_address()
+ {
+     return 0;
+diff --git a/connectivity/netsocket/tests/UNITTESTS/doubles/NetworkInterface_stub.cpp b/connectivity/netsocket/tests/UNITTESTS/doubles/NetworkInterface_stub.cpp
+index 020a551ba9..c849704a35 100644
+--- a/connectivity/netsocket/tests/UNITTESTS/doubles/NetworkInterface_stub.cpp
++++ b/connectivity/netsocket/tests/UNITTESTS/doubles/NetworkInterface_stub.cpp
+@@ -21,6 +21,16 @@
+ 
+ 
+ // Default network-interface state
++const char *NetworkInterface::get_hostname()
++{
++    return 0;
++}
++
++nsapi_error_t NetworkInterface::set_hostname(const char *hostname)
++{
++    return NSAPI_ERROR_UNSUPPORTED;
++}
++
+ const char *NetworkInterface::get_mac_address()
+ {
+     return 0;
+diff --git a/connectivity/netsocket/tests/UNITTESTS/netsocket/NetworkInterface/test_NetworkInterface.cpp b/connectivity/netsocket/tests/UNITTESTS/netsocket/NetworkInterface/test_NetworkInterface.cpp
+index 1a928c36ee..27433ffaa1 100644
+--- a/connectivity/netsocket/tests/UNITTESTS/netsocket/NetworkInterface/test_NetworkInterface.cpp
++++ b/connectivity/netsocket/tests/UNITTESTS/netsocket/NetworkInterface/test_NetworkInterface.cpp
+@@ -68,6 +68,17 @@ TEST_F(TestNetworkInterface, constructor)
+ }
+ 
+ // get_default_instance is tested along with the implementations of NetworkInterface.
++TEST_F(TestNetworkInterface, get_hostname)
++{
++    char *n = 0;
++    EXPECT_EQ(iface->get_hostname(), n);
++}
++
++TEST_F(TestNetworkInterface, set_hostname)
++{
++    char *hostname;
++    EXPECT_EQ(iface->set_hostname(hostname), NSAPI_ERROR_UNSUPPORTED);
++}
+ 
+ TEST_F(TestNetworkInterface, get_mac_address)
+ {
+-- 
+2.45.2
+
diff --git a/patches/0242-Request-hostname-through-DHCP.patch b/patches/0242-Request-hostname-through-DHCP.patch
new file mode 100644
index 000000000..e2a383900
--- /dev/null
+++ b/patches/0242-Request-hostname-through-DHCP.patch
@@ -0,0 +1,53 @@
+From 091ea74d6956d6684bcd88ed842a73218a7b8bd3 Mon Sep 17 00:00:00 2001
+From: Guilherme Ricioli <guilherme.riciolic@gmail.com>
+Date: Tue, 16 Apr 2024 10:50:48 -0300
+Subject: [PATCH] Request hostname through DHCP
+
+If hostname is provided, request it to local DNS through DHCP.
+---
+ connectivity/lwipstack/source/LWIPInterface.cpp             | 6 ++++++
+ connectivity/netsocket/include/netsocket/NetworkInterface.h | 4 +++-
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/connectivity/lwipstack/source/LWIPInterface.cpp b/connectivity/lwipstack/source/LWIPInterface.cpp
+index dfefebcb8b..64869a3538 100644
+--- a/connectivity/lwipstack/source/LWIPInterface.cpp
++++ b/connectivity/lwipstack/source/LWIPInterface.cpp
+@@ -437,6 +437,7 @@ LWIP::Interface::Interface() :
+ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, NetworkInterface *user_network_interface)
+ {
+ #if LWIP_ETHERNET
++    const char *hostname;
+     Interface *interface = new (std::nothrow) Interface();
+     if (!interface) {
+         return NSAPI_ERROR_NO_MEMORY;
+@@ -445,6 +446,11 @@ nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardN
+     interface->memory_manager = &memory_manager;
+     interface->ppp_enabled = false;
+ 
++    hostname = user_network_interface->get_hostname();
++    if (hostname) {
++        netif_set_hostname(&interface->netif, hostname);
++    }
++
+ #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE)
+     netif->interface.hwaddr[0] = MBED_MAC_ADDR_0;
+     netif->interface.hwaddr[1] = MBED_MAC_ADDR_1;
+diff --git a/connectivity/netsocket/include/netsocket/NetworkInterface.h b/connectivity/netsocket/include/netsocket/NetworkInterface.h
+index 81f6011950..22355767ce 100644
+--- a/connectivity/netsocket/include/netsocket/NetworkInterface.h
++++ b/connectivity/netsocket/include/netsocket/NetworkInterface.h
+@@ -102,7 +102,9 @@ public:
+      *  @retval         NSAPI_ERROR_OK on success
+      *  @retval         NSAPI_ERROR_UNSUPPORTED if this feature is not supported
+      *  @retval         NSAPI_ERROR_PARAMETER if hostname is not valid
+-     *  @retval         NSAPI_ERROR_BUSY if hostname couldn't be set
++     *  @retval         NSAPI_ERROR_BUSY if hostname couldn't be set (e.g. for
++     *                  LwIP stack, hostname can only be set before calling
++     *                  \c EthernetInterface::connect method)
+      */
+     virtual nsapi_error_t set_hostname(const char *hostname);
+ 
+-- 
+2.45.2
+

From 66209a4399318a7c7fbe439841ef11622bab4a5d Mon Sep 17 00:00:00 2001
From: Channel59 <caspar@meshnex.nl>
Date: Wed, 10 Jul 2024 00:37:47 +0200
Subject: [PATCH 2/4] Add setHostname() method to Ethernet.cpp

---
 libraries/Ethernet/src/Ethernet.cpp | 5 +++++
 libraries/Ethernet/src/Ethernet.h   | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/libraries/Ethernet/src/Ethernet.cpp b/libraries/Ethernet/src/Ethernet.cpp
index ab720fcaf..05d4061fb 100644
--- a/libraries/Ethernet/src/Ethernet.cpp
+++ b/libraries/Ethernet/src/Ethernet.cpp
@@ -24,6 +24,11 @@ int arduino::EthernetClass::_begin(uint8_t *mac, unsigned long timeout, unsigned
   return (linkStatus() == LinkON ? 1 : 0);
 }
 
+int arduino::EthernetClass::setHostname(const char* hostname) {
+  eth_if->set_hostname(hostname);
+  return 1;
+}
+
 int arduino::EthernetClass::begin(uint8_t *mac, IPAddress ip) {
   IPAddress dns = ip;
   dns[3] = 1;
diff --git a/libraries/Ethernet/src/Ethernet.h b/libraries/Ethernet/src/Ethernet.h
index 8783d651c..b554b3ef2 100644
--- a/libraries/Ethernet/src/Ethernet.h
+++ b/libraries/Ethernet/src/Ethernet.h
@@ -56,6 +56,9 @@ class EthernetClass : public MbedSocketClass {
   EthernetClass(EthernetInterface *_if)
     : eth_if(_if){};
 
+  // When using DHCP the hostname provided will be used.
+  int setHostname(const char* hostname);
+
   // Initialise the Ethernet shield to use the provided MAC address and
   // gain the rest of the configuration through DHCP.
   // Returns 0 if the DHCP configuration failed, and 1 if it succeeded

From 68268e8fd4741313c60f7d95fe03114d6aac2f9d Mon Sep 17 00:00:00 2001
From: pennam <m.pennasilico@arduino.cc>
Date: Thu, 3 Oct 2024 12:27:19 +0200
Subject: [PATCH 3/4] Add setHostname() method to WiFi

---
 libraries/WiFi/src/WiFi.cpp | 5 +++++
 libraries/WiFi/src/WiFi.h   | 5 ++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/libraries/WiFi/src/WiFi.cpp b/libraries/WiFi/src/WiFi.cpp
index 6ad89d619..957a2966b 100644
--- a/libraries/WiFi/src/WiFi.cpp
+++ b/libraries/WiFi/src/WiFi.cpp
@@ -96,6 +96,11 @@ int arduino::WiFiClass::begin(const char* ssid) {
   return begin(ssid, NULL, ENC_TYPE_NONE);
 }
 
+int arduino::WiFiClass::setHostname(const char* hostname) {
+  wifi_if->set_hostname(hostname);
+  return 1;
+}
+
 //Config Wifi to set Static IP && Disable DHCP
 void arduino::WiFiClass::config(const char* localip, const char* netmask, const char* gateway){
   SocketHelpers::config(IPAddress(localip), dnsIP(0), IPAddress(gateway), IPAddress(netmask));
diff --git a/libraries/WiFi/src/WiFi.h b/libraries/WiFi/src/WiFi.h
index 9fae11c40..dd01192a2 100644
--- a/libraries/WiFi/src/WiFi.h
+++ b/libraries/WiFi/src/WiFi.h
@@ -75,7 +75,10 @@ class WiFiClass : public MbedSocketClass {
      *        must be between ASCII 32-126 (decimal).
      */
   int begin(const char* ssid, const char* passphrase, wl_enc_type security = ENC_TYPE_UNKNOWN);
-	
+
+  // When using DHCP the hostname provided will be used.
+  int setHostname(const char* hostname);
+
   // Inherit config methods from the parent class
   using MbedSocketClass::config;
 

From da99e8b40aa48f9b68354bf1b45f51d81a67c66a Mon Sep 17 00:00:00 2001
From: pennam <m.pennasilico@arduino.cc>
Date: Thu, 3 Oct 2024 18:13:13 +0200
Subject: [PATCH 4/4] patches: allow hostname configuration for whdSTA

---
 ...-WhdSTA-allow-hostname-configuration.patch | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 patches/0243-WhdSTA-allow-hostname-configuration.patch

diff --git a/patches/0243-WhdSTA-allow-hostname-configuration.patch b/patches/0243-WhdSTA-allow-hostname-configuration.patch
new file mode 100644
index 000000000..9fea05c90
--- /dev/null
+++ b/patches/0243-WhdSTA-allow-hostname-configuration.patch
@@ -0,0 +1,25 @@
+From b6c62d169e750de6e5af3a47bc6c0c2a1fc81c88 Mon Sep 17 00:00:00 2001
+From: pennam <m.pennasilico@arduino.cc>
+Date: Thu, 3 Oct 2024 18:05:26 +0200
+Subject: [PATCH] WhdSTA allow hostname configuration
+
+---
+ .../drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp    | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp
+index 509a2c0981..ba1fa7900a 100644
+--- a/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp
++++ b/connectivity/drivers/emac/COMPONENT_WHD/interface/WhdSTAInterface.cpp
+@@ -280,7 +280,7 @@ nsapi_error_t WhdSTAInterface::connect()
+     _iface_shared.if_status_flags |= IF_STATUS_STA_UP;
+     _iface_shared.default_if_cfg = DEFAULT_IF_STA;
+     if (!_interface) {
+-        nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface);
++        nsapi_error_t err = _stack.add_ethernet_interface(_emac, true, &_interface, this);
+         if (err != NSAPI_ERROR_OK) {
+             _interface = NULL;
+             return err;
+-- 
+2.45.2
+