138 lines
3.3 KiB
C
138 lines
3.3 KiB
C
#include "ping.h"
|
|
#include "device_list.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#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);
|
|
} |