Skip to content

Commit 17c4e9c

Browse files
committed
espressif: fix returning ping time and pinging too often
1 parent ecb399a commit 17c4e9c

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

ports/espressif/common-hal/wifi/Radio.c

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -532,32 +532,59 @@ void common_hal_wifi_radio_set_ipv4_address_ap(wifi_radio_obj_t *self, mp_obj_t
532532
common_hal_wifi_radio_start_dhcp_server(self); // restart access point DHCP
533533
}
534534

535+
static void ping_success_cb(esp_ping_handle_t hdl, void *args) {
536+
wifi_radio_obj_t *self = (wifi_radio_obj_t *)args;
537+
esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &self->ping_elapsed_time, sizeof(self->ping_elapsed_time));
538+
}
539+
535540
mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, mp_float_t timeout) {
536541
esp_ping_config_t ping_config = ESP_PING_DEFAULT_CONFIG();
537542
ipaddress_ipaddress_to_esp_idf(ip_address, &ping_config.target_addr);
538543
ping_config.count = 1;
539544

545+
// We must fetch ping information using the callback mechanism, because the session storage is freed when
546+
// the ping session is done, even before esp_ping_delete_session().
547+
esp_ping_callbacks_t ping_callbacks = {
548+
.on_ping_success = ping_success_cb,
549+
.cb_args = (void *)self,
550+
};
551+
540552
size_t timeout_ms = timeout * 1000;
541553

554+
// ESP-IDF creates a task to do the ping session. It shuts down when done, but only after a one second delay.
555+
// Calling common_hal_wifi_radio_ping() too fast will cause resource exhaustion.
542556
esp_ping_handle_t ping;
543-
CHECK_ESP_RESULT(esp_ping_new_session(&ping_config, NULL, &ping));
557+
esp_err_t ret;
558+
for (size_t tries = 1; tries <= 5; tries++) {
559+
ret = esp_ping_new_session(&ping_config, &ping_callbacks, &ping);
560+
if (ret == ESP_OK) {
561+
break;
562+
}
563+
// Wait for old task to go away and then try again.
564+
// Empirical testing shows we have to wait at least two seconds, despite the task
565+
// having a one-second timeout.
566+
common_hal_time_delay_ms(2000);
567+
if (mp_hal_is_interrupted()) {
568+
return -1;
569+
}
570+
}
571+
CHECK_ESP_RESULT(ret);
572+
544573
esp_ping_start(ping);
545574

546-
uint32_t received = 0;
547-
uint32_t total_time_ms = 0;
575+
// Use all ones as a flag that the elapsed time was not set (ping failed or timed out).
576+
self->ping_elapsed_time = (uint32_t)(-1);
577+
548578
uint32_t start_time = common_hal_time_monotonic_ms();
549-
while (received == 0 && (common_hal_time_monotonic_ms() - start_time < timeout_ms) && !mp_hal_is_interrupted()) {
579+
while ((self->ping_elapsed_time == (uint32_t)(-1)) &&
580+
(common_hal_time_monotonic_ms() - start_time < timeout_ms) &&
581+
!mp_hal_is_interrupted()) {
550582
RUN_BACKGROUND_TASKS;
551-
esp_ping_get_profile(ping, ESP_PING_PROF_DURATION, &total_time_ms, sizeof(total_time_ms));
552-
esp_ping_get_profile(ping, ESP_PING_PROF_REPLY, &received, sizeof(received));
553-
}
554-
uint32_t elapsed_time = 0xffffffff;
555-
if (received > 0) {
556-
esp_ping_get_profile(ping, ESP_PING_PROF_TIMEGAP, &elapsed_time, sizeof(elapsed_time));
557583
}
584+
esp_ping_stop(ping);
558585
esp_ping_delete_session(ping);
559586

560-
return elapsed_time;
587+
return (mp_int_t)self->ping_elapsed_time;
561588
}
562589

563590
void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self) {

ports/espressif/common-hal/wifi/Radio.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ typedef struct {
3232
esp_netif_ip_info_t ip_info;
3333
esp_netif_dns_info_t dns_info;
3434
esp_netif_t *netif;
35+
uint32_t ping_elapsed_time;
36+
wifi_config_t ap_config;
37+
esp_netif_ip_info_t ap_ip_info;
38+
esp_netif_t *ap_netif;
3539
bool started;
3640
bool ap_mode;
3741
bool sta_mode;
3842
uint8_t retries_left;
3943
uint8_t starting_retries;
4044
uint8_t last_disconnect_reason;
41-
wifi_config_t ap_config;
42-
esp_netif_ip_info_t ap_ip_info;
43-
esp_netif_t *ap_netif;
4445
} wifi_radio_obj_t;
4546

4647
extern void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self);

0 commit comments

Comments
 (0)