Skip to content

Commit

Permalink
Refactor Network localDeviceId to be const
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidSchinazi committed Jan 10, 2025
1 parent d7c5a90 commit 68de46b
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 83 deletions.
5 changes: 3 additions & 2 deletions src/jazzlights/network/arduino_esp_wifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,15 @@ std::string WiFiReasonToString(uint8_t reason) {
}
} // namespace

ArduinoEspWiFiNetwork::ArduinoEspWiFiNetwork() {
// static
NetworkDeviceId ArduinoEspWiFiNetwork::QueryLocalDeviceId() {
uint8_t macAddress[6] = {};
if (WiFi.macAddress(&macAddress[0]) == nullptr) {
uint64_t efuseMac64 = ESP.getEfuseMac();
if (efuseMac64 == 0) { jll_fatal("%u Wi-Fi failed to read MAC address from both Wi-Fi and EFUSE", timeMillis()); }
memcpy(macAddress, &efuseMac64, sizeof(macAddress));
}
localDeviceId_ = NetworkDeviceId(macAddress);
return NetworkDeviceId(macAddress);
}

void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info) {
Expand Down
9 changes: 6 additions & 3 deletions src/jazzlights/network/arduino_esp_wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class ArduinoEspWiFiNetwork : public UdpNetwork {
NetworkStatus update(NetworkStatus status, Milliseconds currentTime) override;
int recv(void* buf, size_t bufsize, std::string* details) override;
void send(void* buf, size_t bufsize) override;
NetworkDeviceId getLocalDeviceId() override { return localDeviceId_; }
NetworkDeviceId getLocalDeviceId() const override { return localDeviceId_; }
NetworkType type() const override { return NetworkType::kWiFi; }
std::string getStatusStr(Milliseconds currentTime) override;

Expand All @@ -36,14 +36,17 @@ class ArduinoEspWiFiNetwork : public UdpNetwork {
};

private:
ArduinoEspWiFiNetwork();
explicit ArduinoEspWiFiNetwork() {}

static constexpr wl_status_t kUninitialized = static_cast<wl_status_t>(123);
static std::string WiFiStatusToString(wl_status_t status);
static NetworkDeviceId QueryLocalDeviceId();

uint16_t port_ = DefaultUdpPort();
const char* mcastAddr_ = DefaultMulticastAddress();
WiFiUDP udp_;
StaticConf* staticConf_ = nullptr;
NetworkDeviceId localDeviceId_;
const NetworkDeviceId localDeviceId_ = QueryLocalDeviceId();
wl_status_t currentWiFiStatus_ = kUninitialized;
Milliseconds timeOfLastWiFiStatusTransition_ = -1;
bool attemptingDhcp_ = true;
Expand Down
12 changes: 9 additions & 3 deletions src/jazzlights/network/arduino_ethernet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,16 @@ std::string EthernetHardwareStatusToString(EthernetHardwareStatus hwStatus) {

} // namespace

ArduinoEthernetNetwork::ArduinoEthernetNetwork() {
// static
NetworkDeviceId ArduinoEthernetNetwork::QueryLocalDeviceId() {
uint8_t wifiMacAddress[6] = {};
uint64_t efuseMac64 = ESP.getEfuseMac();
if (efuseMac64 == 0) { jll_fatal("%u Wi-Fi failed to read MAC address from EFUSE", timeMillis()); }
memcpy(wifiMacAddress, &efuseMac64, sizeof(wifiMacAddress));
localDeviceId_ = NetworkDeviceId(wifiMacAddress).PlusOne();
return NetworkDeviceId(wifiMacAddress).PlusOne();
}

ArduinoEthernetNetwork::ArduinoEthernetNetwork() {
jll_info("%u Starting Ethernet with MAC address " DEVICE_ID_FMT, timeMillis(), DEVICE_ID_HEX(localDeviceId_));
#if JL_CORE2AWS_ETHERNET
// These pins work with the M5Stack Core2AWS connected to the Ethernet W5500 module.
Expand Down Expand Up @@ -100,7 +104,9 @@ NetworkStatus ArduinoEthernetNetwork::update(NetworkStatus status, Milliseconds
constexpr unsigned long kResponseTimeoutMs = 1000;
// TODO move Ethernet.begin() call to its own thread because it performs DHCP synchronously
// and currently blocks our main thread while waiting for a DHCP response.
int beginRes = Ethernet.begin(localDeviceId_.data(), kDhcpTimeoutMs, kResponseTimeoutMs);
uint8_t macAddress[6];
localDeviceId_.writeTo(macAddress);
int beginRes = Ethernet.begin(macAddress, kDhcpTimeoutMs, kResponseTimeoutMs);
if (beginRes == 0) {
jll_error("%u Ethernet DHCP failed", currentTime);
// TODO add support for IPv4 link-local addresses.
Expand Down
7 changes: 5 additions & 2 deletions src/jazzlights/network/arduino_ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ class ArduinoEthernetNetwork : public UdpNetwork {
NetworkStatus update(NetworkStatus status, Milliseconds currentTime) override;
int recv(void* buf, size_t bufsize, std::string* details) override;
void send(void* buf, size_t bufsize) override;
NetworkDeviceId getLocalDeviceId() override { return localDeviceId_; }
NetworkDeviceId getLocalDeviceId() const override { return localDeviceId_; }
NetworkType type() const override { return NetworkType::kEthernet; }
std::string getStatusStr(Milliseconds currentTime) override;

private:
explicit ArduinoEthernetNetwork();
NetworkDeviceId localDeviceId_;

static NetworkDeviceId QueryLocalDeviceId();

const NetworkDeviceId localDeviceId_ = QueryLocalDeviceId();
uint16_t port_ = DefaultUdpPort();
const char* mcastAddr_ = DefaultMulticastAddress();
EthernetUDP udp_;
Expand Down
21 changes: 11 additions & 10 deletions src/jazzlights/network/esp32_ble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,8 @@ NetworkStatus Esp32BleNetwork::update(NetworkStatus status, Milliseconds current
}
}

Esp32BleNetwork::Esp32BleNetwork() {
// static
NetworkDeviceId Esp32BleNetwork::InitBluetoothStackAndQueryLocalDeviceId() {
// Initialize ESP Bluetooth stack.
ESP_ERROR_CHECK(esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT));
esp_bt_controller_config_t cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
Expand All @@ -430,15 +431,6 @@ Esp32BleNetwork::Esp32BleNetwork() {
if (esp_random() == 0xdeadbeef) { (void)btStarted(); }
#endif // JL_BLE4

// Initialize localDeviceId_.
uint8_t addressType;
esp_bd_addr_t localAddress;
memset(localAddress, 0, sizeof(localAddress));
ESP_ERROR_CHECK(esp_ble_gap_get_local_used_addr(localAddress, &addressType));
jll_info("%u Initialized BLE with local MAC address " ESP_BD_ADDR_STR " (type %u)", timeMillis(),
ESP_BD_ADDR_HEX(localAddress), addressType);
localDeviceId_ = NetworkDeviceId(localAddress);
lastReceiveTime_ = -1;
// Override callbacks away from BLEDevice back to us.
ESP_ERROR_CHECK(esp_ble_gap_register_callback(&Esp32BleNetwork::GapCallback));
// Configure scanning parameters.
Expand All @@ -450,6 +442,15 @@ Esp32BleNetwork::Esp32BleNetwork() {
scanParams.scan_window = 16000; // 10s (unit is 625us).
scanParams.scan_duplicate = BLE_SCAN_DUPLICATE_DISABLE;
ESP_ERROR_CHECK(esp_ble_gap_set_scan_params(&scanParams));

// Initialize localDeviceId_.
uint8_t addressType;
esp_bd_addr_t localAddress;
memset(localAddress, 0, sizeof(localAddress));
ESP_ERROR_CHECK(esp_ble_gap_get_local_used_addr(localAddress, &addressType));
jll_info("%u Initialized BLE with local MAC address " ESP_BD_ADDR_STR " (type %u)", timeMillis(),
ESP_BD_ADDR_HEX(localAddress), addressType);
return NetworkDeviceId(localAddress);
}

void Esp32BleNetwork::runLoopImpl(Milliseconds currentTime) { MaybeUpdateAdvertisingState(currentTime); }
Expand Down
12 changes: 7 additions & 5 deletions src/jazzlights/network/esp32_ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Esp32BleNetwork : public Network {
void triggerSendAsap(Milliseconds currentTime) override;

// Get this device's BLE MAC address.
NetworkDeviceId getLocalDeviceId() override { return localDeviceId_; }
NetworkDeviceId getLocalDeviceId() const override { return localDeviceId_; }
NetworkType type() const override { return NetworkType::kBLE; }
bool shouldEcho() const override { return true; }
Milliseconds getLastReceiveTime() const override { return lastReceiveTime_; }
Expand Down Expand Up @@ -61,7 +61,7 @@ class Esp32BleNetwork : public Network {
// 29 is dictated by the BLE standard.
static constexpr size_t kMaxInnerPayloadLength = 29;

explicit Esp32BleNetwork();
explicit Esp32BleNetwork() {}
void StartScanning(Milliseconds currentTime);
void StopScanning(Milliseconds currentTime);
void StartAdvertising(Milliseconds currentTime);
Expand All @@ -79,8 +79,10 @@ class Esp32BleNetwork : public Network {

static void GapCallback(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t* param);

NetworkDeviceId localDeviceId_;
std::atomic<Milliseconds> lastReceiveTime_;
static NetworkDeviceId InitBluetoothStackAndQueryLocalDeviceId();

const NetworkDeviceId localDeviceId_ = InitBluetoothStackAndQueryLocalDeviceId();
std::atomic<Milliseconds> lastReceiveTime_{-1};
std::mutex mutex_;
// All the variables below are protected by mutex_.
State state_ = State::kIdle;
Expand All @@ -106,7 +108,7 @@ class Esp32BleNetwork : public Network {
void setMessageToSend(const NetworkMessage& /*messageToSend*/, Milliseconds /*currentTime*/) override {}
void disableSending(Milliseconds /*currentTime*/) override {}
void triggerSendAsap(Milliseconds /*currentTime*/) override {}
NetworkDeviceId getLocalDeviceId() override { return NetworkDeviceId(); }
NetworkDeviceId getLocalDeviceId() const override { return NetworkDeviceId(); }
NetworkType type() const override { return NetworkType::kBLE; }
bool shouldEcho() const override { return false; }
Milliseconds getLastReceiveTime() const override { return -1; }
Expand Down
22 changes: 15 additions & 7 deletions src/jazzlights/network/esp32_ethernet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,18 @@ void Esp32EthernetNetwork::RunTask() {
}
}

// static
NetworkDeviceId Esp32EthernetNetwork::QueryLocalDeviceId() {
// W5500 SPI Ethernet modules do not have a MAC address, so we instead add one to the Wi-Fi MAC.
uint8_t wifi_mac_addr[6];
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
ESP_ERROR_CHECK(esp_read_mac(wifi_mac_addr, ESP_MAC_EFUSE_FACTORY));
#else
ESP_ERROR_CHECK(esp_efuse_mac_get_default(wifi_mac_addr));
#endif
return NetworkDeviceId(wifi_mac_addr).PlusOne();
}

Esp32EthernetNetwork::Esp32EthernetNetwork()
: eventQueue_(xQueueCreate(/*num_queue_items=*/1, /*queue_item_size=*/sizeof(Esp32EthernetNetworkEvent))) {
if (eventQueue_ == nullptr) { jll_fatal("Failed to create Esp32EthernetNetwork queue"); }
Expand Down Expand Up @@ -366,12 +378,6 @@ Esp32EthernetNetwork::Esp32EthernetNetwork()
}
ESP_ERROR_CHECK(spiInitErr);

// The SPI Ethernet module(s) do not have a MAC address, so we instead add one to the Wi-Fi MAC.
uint8_t wifi_mac_addr[6];
ESP_ERROR_CHECK(esp_read_mac(wifi_mac_addr, ESP_MAC_EFUSE_FACTORY));
NetworkDeviceId wifi_mac(wifi_mac_addr);
localDeviceId_ = wifi_mac.PlusOne();

eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
phy_config.phy_addr = host_id;
Expand Down Expand Up @@ -400,7 +406,9 @@ Esp32EthernetNetwork::Esp32EthernetNetwork()
esp_eth_config_t eth_config_spi = ETH_DEFAULT_CONFIG(mac, phy);
ESP_ERROR_CHECK(esp_eth_driver_install(&eth_config_spi, &eth_handle));

ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, localDeviceId_.data()));
uint8_t mac_address[6];
localDeviceId_.writeTo(mac_address);
ESP_ERROR_CHECK(esp_eth_ioctl(eth_handle, ETH_CMD_S_MAC_ADDR, mac_address));

InitializeNetStack();

Expand Down
6 changes: 4 additions & 2 deletions src/jazzlights/network/esp32_ethernet.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Esp32EthernetNetwork : public Network {
~Esp32EthernetNetwork();

NetworkStatus update(NetworkStatus status, Milliseconds currentTime) override;
NetworkDeviceId getLocalDeviceId() override { return localDeviceId_; }
NetworkDeviceId getLocalDeviceId() const override { return localDeviceId_; }
NetworkType type() const override { return NetworkType::kEthernet; }
std::string getStatusStr(Milliseconds currentTime) override;
void setMessageToSend(const NetworkMessage& messageToSend, Milliseconds currentTime) override;
Expand Down Expand Up @@ -63,8 +63,10 @@ class Esp32EthernetNetwork : public Network {
void CreateSocket();
void CloseSocket();

static NetworkDeviceId QueryLocalDeviceId();

QueueHandle_t eventQueue_;
NetworkDeviceId localDeviceId_; // Only modified in constructor.
const NetworkDeviceId localDeviceId_ = QueryLocalDeviceId();
TaskHandle_t taskHandle_ = nullptr; // Only modified in constructor.
struct in_addr multicastAddress_ = {}; // Only modified in constructor.
int socket_ = -1; // Only used on our task.
Expand Down
19 changes: 11 additions & 8 deletions src/jazzlights/network/esp32_wifi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,13 +385,7 @@ void Esp32WiFiNetwork::RunTask() {
}
}

Esp32WiFiNetwork::Esp32WiFiNetwork()
: eventQueue_(xQueueCreate(/*num_queue_items=*/1, /*queue_item_size=*/sizeof(Esp32WiFiNetworkEvent))) {
if (eventQueue_ == nullptr) { jll_fatal("Failed to create Esp32WiFiNetwork queue"); }
udpPayload_ = reinterpret_cast<uint8_t*>(malloc(kReceiveBufferLength));
if (udpPayload_ == nullptr) {
jll_fatal("Esp32WiFiNetwork failed to allocate receive buffer of length %zu", kReceiveBufferLength);
}
NetworkDeviceId Esp32WiFiNetwork::InitWiFiStackAndQueryLocalDeviceId() {
InitializeNetStack();
esp_netif_create_default_wifi_sta();

Expand Down Expand Up @@ -420,7 +414,16 @@ Esp32WiFiNetwork::Esp32WiFiNetwork()

uint8_t macAddress[6];
ESP_ERROR_CHECK(esp_wifi_get_mac(WIFI_IF_STA, macAddress));
localDeviceId_ = NetworkDeviceId(macAddress);
return NetworkDeviceId(macAddress);
}

Esp32WiFiNetwork::Esp32WiFiNetwork()
: eventQueue_(xQueueCreate(/*num_queue_items=*/1, /*queue_item_size=*/sizeof(Esp32WiFiNetworkEvent))) {
if (eventQueue_ == nullptr) { jll_fatal("Failed to create Esp32WiFiNetwork queue"); }
udpPayload_ = reinterpret_cast<uint8_t*>(malloc(kReceiveBufferLength));
if (udpPayload_ == nullptr) {
jll_fatal("Esp32WiFiNetwork failed to allocate receive buffer of length %zu", kReceiveBufferLength);
}

if (inet_pton(AF_INET, DefaultMulticastAddress(), &multicastAddress_) != 1) {
jll_fatal("Esp32WiFiNetwork failed to parse multicast address");
Expand Down
6 changes: 4 additions & 2 deletions src/jazzlights/network/esp32_wifi.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Esp32WiFiNetwork : public Network {
~Esp32WiFiNetwork();

NetworkStatus update(NetworkStatus status, Milliseconds currentTime) override;
NetworkDeviceId getLocalDeviceId() override { return localDeviceId_; }
NetworkDeviceId getLocalDeviceId() const override { return localDeviceId_; }
NetworkType type() const override { return NetworkType::kWiFi; }
std::string getStatusStr(Milliseconds currentTime) override;
void setMessageToSend(const NetworkMessage& messageToSend, Milliseconds currentTime) override;
Expand Down Expand Up @@ -66,8 +66,10 @@ class Esp32WiFiNetwork : public Network {
void CreateSocket();
void CloseSocket();

NetworkDeviceId InitWiFiStackAndQueryLocalDeviceId();

QueueHandle_t eventQueue_;
NetworkDeviceId localDeviceId_; // Only modified in constructor.
const NetworkDeviceId localDeviceId_ = InitWiFiStackAndQueryLocalDeviceId();
TaskHandle_t taskHandle_ = nullptr; // Only modified in constructor.
struct in_addr multicastAddress_ = {}; // Only modified in constructor.
int socket_ = -1; // Only used on our task.
Expand Down
4 changes: 2 additions & 2 deletions src/jazzlights/network/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ class Network {
// Request an immediate send.
virtual void triggerSendAsap(Milliseconds currentTime) = 0;

// Returns this device's unique ID, often using its MAC address. Not const to allow taking locks.
virtual NetworkDeviceId getLocalDeviceId() = 0;
// Returns this device's unique ID, often using its MAC address.
virtual NetworkDeviceId getLocalDeviceId() const = 0;

// The type of this network.
virtual NetworkType type() const = 0;
Expand Down
Loading

0 comments on commit 68de46b

Please sign in to comment.