#include "ping.h" #include "device_list.h" #include #include #include "ping/ping_sock.h" #include "esp_netif.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" static const char *TAG = "ping"; typedef struct { bool reply_received; SemaphoreHandle_t finished; } ping_context_t; static bool parse_mac_address(const char *text, struct eth_addr * mac); static void ping_device(device_info_t *device); void ping_selected_devices(const char *query); static void ping_success_callback(esp_ping_handle_t handle, void *arguments); static void ping_end_callback(esp_ping_handle_t handle, void *arguments); static bool parse_mac_address(const char *text, struct eth_addr *mac) { if ((text == NULL) || (mac == NULL)) return false; return (sscanf(text, "%2hhX:%2hhX:%2hhX:%2hhX:%2hhX:%2hhX", &mac->addr[0], &mac->addr[1], &mac->addr[2], &mac->addr[3], &mac->addr[4], &mac->addr[5]) == 6); } void ping_selected_devices(const char *query) { const char *current = query; while ((current = strstr(current, "mac=")) != NULL) { struct eth_addr mac; device_info_t *device; char mac_string[18]; size_t length; current += 4; const char *end = strchr(current, '&'); if (end != NULL) length = end - current; else length = strlen(current); if (length >= sizeof(mac_string)) break; memcpy(mac_string, current, length); mac_string[length] = '\0'; if (parse_mac_address(mac_string, &mac)) { device = device_list_find_by_mac(&mac); if (device != NULL) { ping_device(device); } } if (end == NULL) break; current = end + 1; } } static void ping_device(device_info_t *device) { ping_context_t context = { .reply_received = false, .finished = xSemaphoreCreateBinary() }; if (context.finished == NULL) return; esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG(); config.target_addr.type = ESP_IPADDR_TYPE_V4; config.target_addr.u_addr.ip4.addr = device->ip.addr; config.count = 1; config.interval_ms = 1000; config.timeout_ms = 1000; esp_ping_callbacks_t callbacks = { .on_ping_success = ping_success_callback, .on_ping_end = ping_end_callback, .cb_args = &context }; esp_ping_handle_t ping; if (esp_ping_new_session(&config, &callbacks, &ping) != ESP_OK) { vSemaphoreDelete(context.finished); return; } esp_ping_start(ping); xSemaphoreTake(context.finished, portMAX_DELAY); esp_ping_stop(ping); esp_ping_delete_session(ping); device->active = context.reply_received; vSemaphoreDelete(context.finished); } static void ping_success_callback(esp_ping_handle_t handle, void *args) { ping_context_t *context = (ping_context_t *)args; context->reply_received = true; } static void ping_end_callback(esp_ping_handle_t handle, void *args) { ping_context_t *context = (ping_context_t *)args; xSemaphoreGive(context->finished); }