SensESP 3.3.0
Universal Signal K sensor toolkit ESP32
Loading...
Searching...
No Matches
ethernet_provisioner.cpp
Go to the documentation of this file.
1#include "sensesp.h"
2
4
5#if defined(CONFIG_IDF_TARGET_ESP32P4)
6
7#include <Network.h>
8
9namespace sensesp {
10
11EthernetProvisioner::EthernetProvisioner(const EthernetConfig& config)
12 : config_(config) {
13 ESP_LOGI(__FILENAME__,
14 "Bringing up Ethernet (PHY type=%d addr=%d MDC=%d MDIO=%d "
15 "PWR=%d clk_mode=%d)",
16 (int)config_.phy_type, (int)config_.phy_addr, config_.mdc_pin,
17 config_.mdio_pin, config_.power_pin, (int)config_.clock_mode);
18
19 // Register an ARDUINO_EVENT_ETH_START listener that applies the
20 // SensESP hostname to the ETH interface right after the netif has
21 // been created but before DHCP DISCOVER goes out. This is the only
22 // guaranteed-correct moment:
23 //
24 // - Before ETH.begin(): _esp_netif is still NULL so
25 // ETH.setHostname() returns false and the hostname is dropped
26 // (this is what the previous implementation did, causing the
27 // DHCP client to advertise "espressif" — the Arduino ESP32
28 // variant's compile-time default — instead of the SensESP
29 // hostname).
30 //
31 // - After ETH.begin(): the netif exists, but esp_eth_start()
32 // already ran and the DHCP client may have already sent its
33 // DISCOVER, so setting the hostname here would land after the
34 // server has recorded the wrong one.
35 //
36 // - In the ETH_START event: fires synchronously from the
37 // network event loop after the netif is created and before
38 // the DHCP client starts. This is the canonical pattern used
39 // by the Arduino-ESP32 ETH_LAN8720 example.
40 //
41 // Network.onEvent() callbacks run on a separate FreeRTOS task
42 // (the LwIP / system event task), so the capture must be plain
43 // value-captured — no reference to `this`.
44 String hostname = SensESPBaseApp::get_hostname();
45 Network.onEvent(
46 [hostname](arduino_event_id_t, arduino_event_info_t) {
47 if (!ETH.setHostname(hostname.c_str())) {
48 ESP_LOGW("eth_prov",
49 "ETH.setHostname(\"%s\") failed in ETH_START handler",
50 hostname.c_str());
51 } else {
52 ESP_LOGI("eth_prov",
53 "Ethernet hostname set to \"%s\" before DHCP DISCOVER",
54 hostname.c_str());
55 }
56 },
57 ARDUINO_EVENT_ETH_START);
58
59 // Use the explicit RMII begin() so SensESP doesn't depend on the
60 // variant supplying compile-time ETH_PHY_* macros — although on the
61 // current Waveshare ESP32-P4 board the variant happens to match.
62 bool started = ETH.begin(config_.phy_type, config_.phy_addr, config_.mdc_pin,
63 config_.mdio_pin, config_.power_pin,
64 config_.clock_mode);
65 if (!started) {
66 ESP_LOGE(__FILENAME__,
67 "ETH.begin() failed — check pin mapping and PHY power.");
68 return;
69 }
70
71 ESP_LOGI(__FILENAME__,
72 "Ethernet driver started; waiting for PHY link + DHCP lease.");
73}
74
75EthernetProvisioner::~EthernetProvisioner() {
76 // Arduino's ETH does not provide a clean shutdown that re-initialises
77 // cleanly afterwards, so we deliberately do nothing here. The
78 // NetworkStateProducer in SensESPApp owns the event subscriptions.
79}
80
81IPAddress EthernetProvisioner::local_ip() const { return ETH.localIP(); }
82
83IPAddress EthernetProvisioner::gateway_ip() const { return ETH.gatewayIP(); }
84
85String EthernetProvisioner::mac_address() const { return ETH.macAddress(); }
86
87bool EthernetProvisioner::is_connected() const {
88 // Considered connected once the PHY link is up *and* the IP stack
89 // has obtained an address. The Arduino ETH wrapper exposes both
90 // through its NetworkInterface base class.
91 return ETH.linkUp() && ETH.hasIP();
92}
93
94int EthernetProvisioner::link_speed_mbps() const {
95 return ETH.linkUp() ? ETH.linkSpeed() : 0;
96}
97
98bool EthernetProvisioner::is_full_duplex() const {
99 return ETH.linkUp() && ETH.fullDuplex();
100}
101
102} // namespace sensesp
103
104#endif // CONFIG_IDF_TARGET_ESP32P4