|
|
|
@@ -21,6 +21,9 @@ internal esp_err_t get_ip_info(esp_netif_ip_info_t *ip_info);
|
|
|
|
internal void led_blink_number(int n, uint8_t r, uint8_t g, uint8_t b);
|
|
|
|
internal void led_blink_number(int n, uint8_t r, uint8_t g, uint8_t b);
|
|
|
|
internal void blink_last_ip_octet();
|
|
|
|
internal void blink_last_ip_octet();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Internal states
|
|
|
|
|
|
|
|
internal esp_netif_ip_info_t s_current_ip_info = {};
|
|
|
|
|
|
|
|
|
|
|
|
// === Ethernet ===
|
|
|
|
// === Ethernet ===
|
|
|
|
|
|
|
|
|
|
|
|
internal constexpr char kLogEthernet[] = "ETH";
|
|
|
|
internal constexpr char kLogEthernet[] = "ETH";
|
|
|
|
@@ -31,26 +34,43 @@ internal uint8_t s_eth_count = 0;
|
|
|
|
internal esp_eth_netif_glue_handle_t s_eth_glue = nullptr;
|
|
|
|
internal esp_eth_netif_glue_handle_t s_eth_glue = nullptr;
|
|
|
|
internal esp_netif_t *s_eth_netif = nullptr;
|
|
|
|
internal esp_netif_t *s_eth_netif = nullptr;
|
|
|
|
internal SemaphoreHandle_t s_semph_get_ip_addrs = nullptr;
|
|
|
|
internal SemaphoreHandle_t s_semph_get_ip_addrs = nullptr;
|
|
|
|
|
|
|
|
internal SemaphoreHandle_t s_semph_eth_link = nullptr;
|
|
|
|
|
|
|
|
internal volatile bool s_eth_link_up = false;
|
|
|
|
#ifndef NDEBUG
|
|
|
|
#ifndef NDEBUG
|
|
|
|
internal bool s_ethernet_connected = false;
|
|
|
|
internal bool s_ethernet_connected = false;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
void eth_on_got_ip(void *arg, esp_event_base_t event_base, int32_t event_id,
|
|
|
|
void ethernet_event_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
void *event_data) {
|
|
|
|
int32_t event_id, void *event_data) {
|
|
|
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
|
|
|
if (event_base == IP_EVENT && event_id == IP_EVENT_ETH_GOT_IP) {
|
|
|
|
bool isEthernetNetif =
|
|
|
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
|
|
|
strncmp(kNetifDescEth, esp_netif_get_desc(event->esp_netif),
|
|
|
|
if (event->esp_netif != s_eth_netif) {
|
|
|
|
strlen(kNetifDescEth) - 1) == 0;
|
|
|
|
return;
|
|
|
|
if (!isEthernetNetif) {
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
ESP_LOGI(kLogEthernet, "Got IPv4 event: Interface \"%s\" address: " IPSTR,
|
|
|
|
}
|
|
|
|
esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
|
|
|
|
ESP_LOGI(kLogEthernet, "Got IPv4 event: Interface \"%s\" address: " IPSTR,
|
|
|
|
|
|
|
|
esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xSemaphoreGive(s_semph_get_ip_addrs);
|
|
|
|
s_current_ip_info = event->ip_info;
|
|
|
|
|
|
|
|
xSemaphoreGive(s_semph_get_ip_addrs);
|
|
|
|
|
|
|
|
} else if (event_base == ETH_EVENT && event_id == ETHERNET_EVENT_CONNECTED) {
|
|
|
|
|
|
|
|
ESP_LOGI(kLogEthernet, "Ethernet Link Up");
|
|
|
|
|
|
|
|
s_eth_link_up = true;
|
|
|
|
|
|
|
|
if (s_semph_eth_link) {
|
|
|
|
|
|
|
|
xSemaphoreGive(s_semph_eth_link);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (event_base == ETH_EVENT &&
|
|
|
|
|
|
|
|
event_id == ETHERNET_EVENT_DISCONNECTED) {
|
|
|
|
|
|
|
|
ESP_LOGI(kLogEthernet, "Ethernet Link Down");
|
|
|
|
|
|
|
|
s_eth_link_up = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void teardown_ethernet() {
|
|
|
|
void teardown_ethernet() {
|
|
|
|
|
|
|
|
if (s_semph_eth_link != nullptr) {
|
|
|
|
|
|
|
|
vSemaphoreDelete(s_semph_eth_link);
|
|
|
|
|
|
|
|
s_semph_eth_link = nullptr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (s_semph_get_ip_addrs != nullptr) {
|
|
|
|
if (s_semph_get_ip_addrs != nullptr) {
|
|
|
|
vSemaphoreDelete(s_semph_get_ip_addrs);
|
|
|
|
vSemaphoreDelete(s_semph_get_ip_addrs);
|
|
|
|
s_semph_get_ip_addrs = nullptr;
|
|
|
|
s_semph_get_ip_addrs = nullptr;
|
|
|
|
@@ -59,7 +79,9 @@ void teardown_ethernet() {
|
|
|
|
if (s_eth_netif) {
|
|
|
|
if (s_eth_netif) {
|
|
|
|
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP,
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP,
|
|
|
|
ð_on_got_ip));
|
|
|
|
ðernet_event_handler));
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID,
|
|
|
|
|
|
|
|
ðernet_event_handler));
|
|
|
|
ESP_ERROR_CHECK(esp_eth_stop(s_eth_handles[0]));
|
|
|
|
ESP_ERROR_CHECK(esp_eth_stop(s_eth_handles[0]));
|
|
|
|
ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue));
|
|
|
|
ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue));
|
|
|
|
esp_netif_destroy(s_eth_netif);
|
|
|
|
esp_netif_destroy(s_eth_netif);
|
|
|
|
@@ -82,7 +104,8 @@ internal esp_err_t connect_ethernet(bool blockUntilIPAcquired) {
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
s_semph_get_ip_addrs = xSemaphoreCreateBinary();
|
|
|
|
s_semph_get_ip_addrs = xSemaphoreCreateBinary();
|
|
|
|
if (s_semph_get_ip_addrs == NULL) {
|
|
|
|
s_semph_eth_link = xSemaphoreCreateBinary();
|
|
|
|
|
|
|
|
if (s_semph_get_ip_addrs == NULL || s_semph_eth_link == NULL) {
|
|
|
|
return ESP_ERR_NO_MEM;
|
|
|
|
return ESP_ERR_NO_MEM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Connection is split in two steps. First we open the connection and ask for
|
|
|
|
// Connection is split in two steps. First we open the connection and ask for
|
|
|
|
@@ -107,7 +130,9 @@ internal esp_err_t connect_ethernet(bool blockUntilIPAcquired) {
|
|
|
|
|
|
|
|
|
|
|
|
// Register user defined event handlers
|
|
|
|
// Register user defined event handlers
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP,
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP,
|
|
|
|
ð_on_got_ip, NULL));
|
|
|
|
ðernet_event_handler, NULL));
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID,
|
|
|
|
|
|
|
|
ðernet_event_handler, NULL));
|
|
|
|
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_eth_start(s_eth_handles[0]));
|
|
|
|
ESP_ERROR_CHECK(esp_eth_start(s_eth_handles[0]));
|
|
|
|
|
|
|
|
|
|
|
|
@@ -135,6 +160,15 @@ void disconnect_ethernet() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal esp_err_t check_ethernet_connection(uint32_t timeoutSeconds) {
|
|
|
|
internal esp_err_t check_ethernet_connection(uint32_t timeoutSeconds) {
|
|
|
|
|
|
|
|
// Wait up to 5000ms for the physical link to negotiate
|
|
|
|
|
|
|
|
if (!s_eth_link_up) {
|
|
|
|
|
|
|
|
if (!xSemaphoreTake(s_semph_eth_link, pdMS_TO_TICKS(5000))) {
|
|
|
|
|
|
|
|
ESP_LOGE(kLogEthernet,
|
|
|
|
|
|
|
|
"No physical Ethernet link detected. Skipping DHCP wait.");
|
|
|
|
|
|
|
|
return ESP_ERR_INVALID_STATE; // Special error to skip retries
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(kLogEthernet, "Waiting for IP address for %d seconds.",
|
|
|
|
ESP_LOGI(kLogEthernet, "Waiting for IP address for %d seconds.",
|
|
|
|
timeoutSeconds);
|
|
|
|
timeoutSeconds);
|
|
|
|
if (xSemaphoreTake(s_semph_get_ip_addrs,
|
|
|
|
if (xSemaphoreTake(s_semph_get_ip_addrs,
|
|
|
|
@@ -151,30 +185,50 @@ internal esp_err_t check_ethernet_connection(uint32_t timeoutSeconds) {
|
|
|
|
internal constexpr char kLogWifi[] = "WIFI";
|
|
|
|
internal constexpr char kLogWifi[] = "WIFI";
|
|
|
|
internal esp_netif_t *s_wifi_netif = nullptr;
|
|
|
|
internal esp_netif_t *s_wifi_netif = nullptr;
|
|
|
|
internal SemaphoreHandle_t s_semph_get_wifi_ip_addrs = nullptr;
|
|
|
|
internal SemaphoreHandle_t s_semph_get_wifi_ip_addrs = nullptr;
|
|
|
|
|
|
|
|
internal SemaphoreHandle_t s_semph_wifi_link = nullptr;
|
|
|
|
|
|
|
|
internal volatile bool s_wifi_link_up = false;
|
|
|
|
#ifndef NDEBUG
|
|
|
|
#ifndef NDEBUG
|
|
|
|
internal bool s_wifi_connected = false;
|
|
|
|
internal bool s_wifi_connected = false;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
void wifi_event_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
void wifi_event_handler(void *arg, esp_event_base_t event_base,
|
|
|
|
int32_t event_id, void *event_data) {
|
|
|
|
int32_t event_id, void *event_data) {
|
|
|
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
|
|
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
|
|
|
|
ESP_LOGI(kLogWifi, "WiFi disconnected, retrying...");
|
|
|
|
ESP_LOGI(kLogWifi, "WiFi associated with AP.");
|
|
|
|
esp_wifi_connect();
|
|
|
|
s_wifi_link_up = true;
|
|
|
|
|
|
|
|
if (s_semph_wifi_link) {
|
|
|
|
|
|
|
|
xSemaphoreGive(s_semph_wifi_link);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (event_base == WIFI_EVENT &&
|
|
|
|
|
|
|
|
event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
|
|
|
|
|
|
|
ESP_LOGI(kLogWifi, "WiFi disconnected.");
|
|
|
|
|
|
|
|
s_wifi_link_up = false;
|
|
|
|
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
|
|
|
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
|
|
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
|
|
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
|
|
|
|
|
|
|
|
if (event->esp_netif != s_wifi_netif) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
ESP_LOGI(kLogWifi, "Got IPv4 event: Interface \"%s\" address: " IPSTR,
|
|
|
|
ESP_LOGI(kLogWifi, "Got IPv4 event: Interface \"%s\" address: " IPSTR,
|
|
|
|
esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
|
|
|
|
esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s_current_ip_info = event->ip_info;
|
|
|
|
xSemaphoreGive(s_semph_get_wifi_ip_addrs);
|
|
|
|
xSemaphoreGive(s_semph_get_wifi_ip_addrs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void teardown_wifi() {
|
|
|
|
void teardown_wifi() {
|
|
|
|
|
|
|
|
if (s_semph_wifi_link != nullptr) {
|
|
|
|
|
|
|
|
vSemaphoreDelete(s_semph_wifi_link);
|
|
|
|
|
|
|
|
s_semph_wifi_link = nullptr;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (s_semph_get_wifi_ip_addrs != nullptr) {
|
|
|
|
if (s_semph_get_wifi_ip_addrs != nullptr) {
|
|
|
|
vSemaphoreDelete(s_semph_get_wifi_ip_addrs);
|
|
|
|
vSemaphoreDelete(s_semph_get_wifi_ip_addrs);
|
|
|
|
s_semph_get_wifi_ip_addrs = nullptr;
|
|
|
|
s_semph_get_wifi_ip_addrs = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED,
|
|
|
|
|
|
|
|
&wifi_event_handler);
|
|
|
|
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
|
|
|
|
esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED,
|
|
|
|
&wifi_event_handler);
|
|
|
|
&wifi_event_handler);
|
|
|
|
esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP,
|
|
|
|
esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP,
|
|
|
|
@@ -197,7 +251,8 @@ internal esp_err_t connect_wifi(const char *ssid, const char *password,
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
s_semph_get_wifi_ip_addrs = xSemaphoreCreateBinary();
|
|
|
|
s_semph_get_wifi_ip_addrs = xSemaphoreCreateBinary();
|
|
|
|
if (s_semph_get_wifi_ip_addrs == NULL) {
|
|
|
|
s_semph_wifi_link = xSemaphoreCreateBinary();
|
|
|
|
|
|
|
|
if (s_semph_get_wifi_ip_addrs == NULL || s_semph_wifi_link == NULL) {
|
|
|
|
return ESP_ERR_NO_MEM;
|
|
|
|
return ESP_ERR_NO_MEM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -208,6 +263,8 @@ internal esp_err_t connect_wifi(const char *ssid, const char *password,
|
|
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(
|
|
|
|
|
|
|
|
WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &wifi_event_handler, NULL));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(
|
|
|
|
WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &wifi_event_handler, NULL));
|
|
|
|
WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &wifi_event_handler, NULL));
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP,
|
|
|
|
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP,
|
|
|
|
@@ -248,6 +305,15 @@ void disconnect_wifi() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal esp_err_t check_wifi_connection(uint32_t timeoutSeconds) {
|
|
|
|
internal esp_err_t check_wifi_connection(uint32_t timeoutSeconds) {
|
|
|
|
|
|
|
|
// Wait up to 10000ms for the physical link to associate with the AP
|
|
|
|
|
|
|
|
if (!s_wifi_link_up) {
|
|
|
|
|
|
|
|
if (!xSemaphoreTake(s_semph_wifi_link, pdMS_TO_TICKS(10000))) {
|
|
|
|
|
|
|
|
ESP_LOGE(kLogWifi,
|
|
|
|
|
|
|
|
"Failed to associate with WiFi AP. Skipping DHCP wait.");
|
|
|
|
|
|
|
|
return ESP_ERR_INVALID_STATE; // Special error to skip retries
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ESP_LOGI(kLogWifi, "Waiting for IP address for %d seconds.", timeoutSeconds);
|
|
|
|
ESP_LOGI(kLogWifi, "Waiting for IP address for %d seconds.", timeoutSeconds);
|
|
|
|
if (xSemaphoreTake(s_semph_get_wifi_ip_addrs,
|
|
|
|
if (xSemaphoreTake(s_semph_get_wifi_ip_addrs,
|
|
|
|
pdMS_TO_TICKS(timeoutSeconds * 1000))) {
|
|
|
|
pdMS_TO_TICKS(timeoutSeconds * 1000))) {
|
|
|
|
@@ -259,12 +325,8 @@ internal esp_err_t check_wifi_connection(uint32_t timeoutSeconds) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal esp_err_t get_ip_info(esp_netif_ip_info_t *ip_info) {
|
|
|
|
internal esp_err_t get_ip_info(esp_netif_ip_info_t *ip_info) {
|
|
|
|
if (s_eth_netif) {
|
|
|
|
*ip_info = s_current_ip_info;
|
|
|
|
return esp_netif_get_ip_info(s_eth_netif, ip_info);
|
|
|
|
return ESP_OK;
|
|
|
|
} else if (s_wifi_netif) {
|
|
|
|
|
|
|
|
return esp_netif_get_ip_info(s_wifi_netif, ip_info);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return ESP_FAIL;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
internal void led_blink_number(int n, uint8_t r, uint8_t g, uint8_t b);
|
|
|
|
internal void led_blink_number(int n, uint8_t r, uint8_t g, uint8_t b);
|
|
|
|
@@ -280,8 +342,12 @@ internal void blink_last_ip_octet() {
|
|
|
|
int t = (last_octet / 10) % 10;
|
|
|
|
int t = (last_octet / 10) % 10;
|
|
|
|
int u = last_octet % 10;
|
|
|
|
int u = last_octet % 10;
|
|
|
|
|
|
|
|
|
|
|
|
led_blink_number(h, 255, 255, 255);
|
|
|
|
if (h > 0) {
|
|
|
|
led_blink_number(t, 255, 255, 255);
|
|
|
|
led_blink_number(h, 255, 255, 255);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (h > 0 || t > 0) {
|
|
|
|
|
|
|
|
led_blink_number(t, 255, 255, 255);
|
|
|
|
|
|
|
|
}
|
|
|
|
led_blink_number(u, 255, 255, 255);
|
|
|
|
led_blink_number(u, 255, 255, 255);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|