STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
BoardNet Namespace Reference

Board networking — the ground station decides addresses, not the board. More...

Classes

struct  State

Enumerations

enum class  AddressSource : uint8_t { None , Dhcp , Recovery }
 How the board ended up with the address it is using. More...

Functions

const char * sourceName (AddressSource s)
IPAddress recoverySubnet ()
 Subnet of the recovery address: link-local, 169.254.0.0/16.
IPAddress recoveryAddress (const byte mac[6])
 The board's recovery address, from its MAC: 169.254.
void configure (State &s, const byte mac[6])
void printMac (const State &s)
 Print the MAC as aa:bb:cc:dd:ee:ff.
bool usingDhcp (const State &s)
bool hasAddress (const State &s)
uint8_t boardId (const State &s)
 The board's ID: the last octet of the address the server assigned (192.168.2.31 -> 31).
void maintainLease (State &s)
 Renew the lease as it expires.
void beginOtaHold (State &s)
 Called when an OTA transfer starts, so the address cannot move under it.
bool onServerPacket (State &s, IPAddress remote_ip, IPAddress &serverIP)
 A server packet arrived from remote_ip; adopt it as the server address.
bool serverWentSilent (const State &s)
 Server has stopped talking — forget it and resume discovery broadcasts.
void useRecoveryAddress (State &s, IPAddress dns, IPAddress gateway)
AddressSource begin (State &s, IPAddress dns, IPAddress gateway)
 Bring the interface up: ask the ground station for an address, and take the recovery address only if nothing answers.
bool retryDhcp (State &s, IPAddress dns, IPAddress gateway)
 On the recovery address, ask for a lease again every SENSOR_ETH_DHCP_RETRY_INTERVAL_MS.

Detailed Description

Board networking — the ground station decides addresses, not the board.

Enabled per board with -DSENSOR_ETH_USE_DHCP (every hotfire board today).

  1. boot: DHCP DISCOVER. The DAQ server / Test-GUI answers from its MAC -> IP reservation table, so the address a board gets is decided in one place, by people, and is the same every boot. The board takes its ID from that address (192.168.2.31 -> board 31), so every board of a type runs the same image: which board is which is the reservation table's mac = lines, not a build flag.
  2. renew the lease as it expires (suppressed during an OTA — see beginOtaHold()).
  3. the board announces itself by broadcasting BOARD_HEARTBEAT until some server talks to it, and learns the server's address from that packet.

When no DHCP server answers, the board takes its RECOVERY address, 169.254.<1 + mac[4] % 254>.<mac[5]>/16, and keeps asking for a lease every SENSOR_ETH_DHCP_RETRY_INTERVAL_MS. The recovery address exists so a board whose DHCP failed (server down, booted before the switch) can still be reflashed over Ethernet: ota_upload.py --mac <mac> computes the same address. It is never a working address — the DAQ does not talk to a board there, and the board's ID is 0 until a lease arrives.

Why not the old static 192.168.2.<BOARD_ID> fallback: it needed a per-board build, and a board that missed DHCP looked exactly like one that got it, so DHCP could be broken for weeks unnoticed. Why derive from the MAC: it is burned into the ESP32, unique, and survives any flash erase; two bytes of it give 64k addresses, so collisions are checkable in advance (the config editor refuses two boards whose recovery addresses match).

No ESP32 dependencies beyond Arduino/Ethernet, so it is unit-testable off-target — see Hotfire_Tests/test/test_board_net.

Enumeration Type Documentation

◆ AddressSource

enum class BoardNet::AddressSource : uint8_t
strong

How the board ended up with the address it is using.

Enumerator
None 

not yet brought up

Dhcp 

assigned by the ground station — the normal case

Recovery 

no DHCP answer: 169.254.x.y from the MAC, reflash-only

Definition at line 46 of file board_net.h.

Function Documentation

◆ begin()

◆ beginOtaHold()

void BoardNet::beginOtaHold ( State & s)
inline

Called when an OTA transfer starts, so the address cannot move under it.

Definition at line 144 of file board_net.h.

References BoardNet::State::otaHold.

Referenced by otaFreezeAddress(), SensorHotfire::otaFreezeAddress(), otaStart(), test_no_retry_during_an_ota(), and test_ota_suspends_renewal().

◆ boardId()

uint8_t BoardNet::boardId ( const State & s)
inline

The board's ID: the last octet of the address the server assigned (192.168.2.31 -> 31).

0 while on the recovery address, where the board has no identity the server gave it.

Definition at line 129 of file board_net.h.

References Ethernet, and usingDhcp().

Referenced by loop(), SensorHotfire::loop(), pollNetwork(), SensorHotfire::setup(), setup(), test_board_id_is_the_assigned_address(), test_no_answer_puts_the_board_on_its_recovery_address(), and test_retry_that_gets_a_lease_moves_the_board().

◆ configure()

void BoardNet::configure ( State & s,
const byte mac[6] )
inline

Definition at line 93 of file board_net.h.

References BoardNet::State::mac, and mac.

Referenced by makeState(), SensorHotfire::setup(), and setup().

◆ hasAddress()

bool BoardNet::hasAddress ( const State & s)
inline

Definition at line 120 of file board_net.h.

References None, and BoardNet::State::source.

Referenced by test_source_is_reported_honestly().

◆ maintainLease()

void BoardNet::maintainLease ( State & s)
inline

Renew the lease as it expires.

No-op when we are not on a lease, and deliberately a no-op during an OTA: a renewal that moved our address mid-flash would drop the transfer.

Definition at line 138 of file board_net.h.

References Ethernet, BoardNet::State::otaHold, and usingDhcp().

Referenced by loop(), SensorHotfire::loop(), pollNetwork(), test_lease_is_renewed_only_on_a_lease(), and test_ota_suspends_renewal().

◆ onServerPacket()

bool BoardNet::onServerPacket ( State & s,
IPAddress remote_ip,
IPAddress & serverIP )
inline

◆ printMac()

void BoardNet::printMac ( const State & s)
inline

Print the MAC as aa:bb:cc:dd:ee:ff.

The ground station keys its reservation table on this, so it has to be readable off the serial log — otherwise registering a new board means guessing, or sniffing its DHCP request.

Definition at line 103 of file board_net.h.

References HEX, BoardNet::State::mac, and Serial.

Referenced by SensorHotfire::setup(), setup(), and test_mac_is_stored_for_reporting().

◆ recoveryAddress()

IPAddress BoardNet::recoveryAddress ( const byte mac[6])
inline

The board's recovery address, from its MAC: 169.254.

<1 + mac[4] % 254>.<mac[5]>.

The third octet stays in 1..254, the range RFC 3927 lets a host use. firmware/tools/ota_upload.py and daq-server's config validation compute the same thing; test_board_net pins the formula with the vectors they test.

Definition at line 77 of file board_net.h.

References IPAddress, and mac.

Referenced by begin(), test_recovery_address_formula(), and useRecoveryAddress().

◆ recoverySubnet()

IPAddress BoardNet::recoverySubnet ( )
inline

Subnet of the recovery address: link-local, 169.254.0.0/16.

Definition at line 65 of file board_net.h.

References IPAddress.

Referenced by useRecoveryAddress().

◆ retryDhcp()

bool BoardNet::retryDhcp ( State & s,
IPAddress dns,
IPAddress gateway )
inline

On the recovery address, ask for a lease again every SENSOR_ETH_DHCP_RETRY_INTERVAL_MS.

Call every loop(); a no-op on a lease and during an OTA. Returns true when a lease arrived: the address and boardId() changed, so the caller should re-announce itself.

Each attempt blocks for up to SENSOR_ETH_DHCP_RETRY_TIMEOUT_MS. That is only ever spent on the recovery address, where the DAQ cannot reach the board, so it can never stall a session. Open sockets survive: a new address does not close them, and the W5500 is not reset.

Definition at line 213 of file board_net.h.

References Dhcp, dns, Ethernet, gateway, BoardNet::State::lastDhcpAttemptMillis, BoardNet::State::mac, millis(), BoardNet::State::otaHold, Recovery, SENSOR_ETH_DHCP_RESPONSE_TIMEOUT_MS, SENSOR_ETH_DHCP_RETRY_INTERVAL_MS, SENSOR_ETH_DHCP_RETRY_TIMEOUT_MS, Serial, BoardNet::State::source, and useRecoveryAddress().

Referenced by loop(), SensorHotfire::loop(), pollNetwork(), test_failed_retry_stays_reflashable(), test_no_retry_during_an_ota(), test_retry_that_gets_a_lease_moves_the_board(), and test_retry_waits_for_the_interval().

◆ serverWentSilent()

bool BoardNet::serverWentSilent ( const State & s)
inline

◆ sourceName()

const char * BoardNet::sourceName ( AddressSource s)
inline

Definition at line 52 of file board_net.h.

References Dhcp, None, and Recovery.

Referenced by SensorHotfire::setup(), setup(), and test_source_is_reported_honestly().

◆ useRecoveryAddress()

void BoardNet::useRecoveryAddress ( State & s,
IPAddress dns,
IPAddress gateway )
inline

◆ usingDhcp()