feat(esp_wifi): Add extended SSI support for NAN Services

1. Allow SSI in publish and subscribe, populate Peer's SSI in match events
2. Allow SSI with length higher than 255 bytes by using SDEA for all NAN services
3. Update API's to support SSI changes and other SDEA parameters
4. Fix use after free issues with NAN Beacons and SDF's

Closes https://github.com/espressif/esp-idf/issues/12473
Closes https://github.com/espressif/esp-idf/issues/13366
This commit is contained in:
Nachiket Kukade
2024-12-18 11:47:52 +05:30
committed by BOT
parent 91bfe96ced
commit 302d8e5fce
6 changed files with 262 additions and 58 deletions

View File

@@ -107,6 +107,19 @@ static esp_netif_t *g_nan_netif;
#define NAN_EXAMPLE_SERVICE_NAME "ESP_NAN-Service"
static void nan_receive_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
wifi_event_nan_receive_t *evt = (wifi_event_nan_receive_t *)event_data;
if (evt->ssi_len) {
ESP_LOGI(TAG, "Received payload from Peer "MACSTR" [Peer Service id - %d] - ", MAC2STR(evt->peer_if_mac), evt->peer_inst_id);
ESP_LOG_BUFFER_HEXDUMP(TAG, evt->ssi, evt->ssi_len, ESP_LOG_INFO);
} else {
ESP_LOGI(TAG, "Received message '%s' from Peer "MACSTR" [Peer Service id - %d]",
evt->peer_svc_info, MAC2STR(evt->peer_if_mac), evt->peer_inst_id);
}
}
static void cmd_ping_on_ping_success(esp_ping_handle_t hdl, void *args)
{
uint8_t ttl;
@@ -210,6 +223,7 @@ void initialise_wifi(void)
static int wifi_cmd_nan_disc(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **) &nan_args);
static esp_event_handler_instance_t s_instance_nan_receive;
esp_err_t ret;
if (nerrors != 0) {
@@ -245,6 +259,12 @@ static int wifi_cmd_nan_disc(int argc, char **argv)
g_nan_netif = NULL;
return 1;
}
if (!s_instance_nan_receive) {
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, WIFI_EVENT_NAN_RECEIVE,
&nan_receive_event_handler, NULL, &s_instance_nan_receive));
}
return 0;
}
@@ -255,6 +275,10 @@ static int wifi_cmd_nan_disc(int argc, char **argv)
ESP_LOGI(TAG, "Failed to stop NAN");
return 1;
}
ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, WIFI_EVENT_NAN_RECEIVE,
s_instance_nan_receive));
s_instance_nan_receive = 0;
esp_netif_destroy_default_wifi(g_nan_netif);
g_nan_netif = NULL;
}
@@ -354,38 +378,59 @@ static int wifi_cmd_nan_subscribe(int argc, char **argv)
static int wifi_cmd_nan_followup(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **) &fup_args);
uint16_t ssi_len = 0;
int ret = 0;
if (nerrors != 0) {
arg_print_errors(stderr, fup_args.end, argv[0]);
return 1;
}
wifi_nan_followup_params_t fup = {0};
if (fup_args.text->count) {
ssi_len = strlen(fup_args.text->sval[0]);
if (ssi_len >= ESP_WIFI_MAX_FUP_SSI_LEN) {
ESP_LOGE(TAG, "Length(%d) too long for Service Specific Info", ssi_len);
return 1;
}
}
wifi_nan_followup_params_t *fup = calloc(1, sizeof(wifi_nan_followup_params_t) + ssi_len);
if (!fup) {
ESP_LOGE(TAG, "Failed to allocate memory for Follow-up buffer");
return 1;
}
if (ssi_len) {
fup->ssi = (uint8_t *)(fup + 1);
memcpy(fup->ssi, fup_args.text->sval[0], ssi_len);
fup->ssi_len = ssi_len;
}
if (fup_args.own_id->count) {
fup.inst_id = fup_args.own_id->ival[0];
fup->inst_id = fup_args.own_id->ival[0];
}
if (!fup_args.peer_id->count && !fup_args.mac_addr->count) {
ESP_LOGE(TAG, "Missing peer's service instance id or peer's MAC.");
return 1;
ESP_LOGE(TAG, "Missing peer's service instance id or peer's MAC");
ret = 1;
goto exit;
}
if (fup_args.peer_id->count) {
fup.peer_inst_id = fup_args.peer_id->ival[0];
fup->peer_inst_id = fup_args.peer_id->ival[0];
}
if (fup_args.mac_addr->count &&
esp_supplicant_str_to_mac((char *)fup_args.mac_addr->sval[0], fup.peer_mac) != ESP_OK) {
return 1;
esp_supplicant_str_to_mac((char *)fup_args.mac_addr->sval[0], fup->peer_mac) != ESP_OK) {
ret = 1;
goto exit;
}
if (fup_args.text->count) {
strlcpy(fup.svc_info, fup_args.text->sval[0], ESP_WIFI_MAX_SVC_INFO_LEN);
if (esp_wifi_nan_send_message(fup) != ESP_OK) {
ESP_LOGE(TAG, "Failed to send Follow-up");
ret = 1;
}
if (esp_wifi_nan_send_message(&fup) != ESP_OK) {
return 1;
}
return 0;
exit:
free(fup);
return ret;
}
static int wifi_cmd_ndp(int argc, char **argv)

View File

@@ -30,17 +30,30 @@
#else
#define EXAMPLE_NAN_SVC_MSG "Welcome"
#endif
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
static EventGroupHandle_t nan_event_group;
static const char *TAG = "publisher";
static int NAN_RECEIVE = BIT0;
uint8_t g_peer_inst_id;
static uint8_t g_peer_mac[ETH_ALEN];
static void nan_receive_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
wifi_event_nan_receive_t *evt = (wifi_event_nan_receive_t *)event_data;
g_peer_inst_id = evt->peer_inst_id;
memcpy(g_peer_mac, evt->peer_if_mac, ETH_ALEN);
if (evt->ssi_len) {
ESP_LOGI(TAG, "Received payload from Peer "MACSTR" [Peer Service id - %d] - ", MAC2STR(evt->peer_if_mac), evt->peer_inst_id);
ESP_LOG_BUFFER_HEXDUMP(TAG, evt->ssi, evt->ssi_len, ESP_LOG_INFO);
} else {
ESP_LOGI(TAG, "Received message '%s' from Peer "MACSTR" [Peer Service id - %d]",
evt->peer_svc_info, MAC2STR(evt->peer_if_mac), evt->peer_inst_id);
}
xEventGroupSetBits(nan_event_group, NAN_RECEIVE);
}
@@ -55,7 +68,7 @@ static void nan_ndp_indication_event_handler(void *arg, esp_event_base_t event_b
wifi_nan_datapath_resp_t ndp_resp = {0};
ndp_resp.accept = true; /* Accept incoming datapath request */
ndp_resp.ndp_id = evt->ndp_id;
memcpy(ndp_resp.peer_mac, evt->peer_nmi, 6);
memcpy(ndp_resp.peer_mac, evt->peer_nmi, ETH_ALEN);
esp_wifi_nan_datapath_resp(&ndp_resp);
@@ -106,20 +119,27 @@ void wifi_nan_publish(void)
return;
}
wifi_nan_followup_params_t fup = {0};
fup.ssi_len = (strlen(EXAMPLE_NAN_SVC_MSG) < ESP_WIFI_MAX_FUP_SSI_LEN) ? strlen(EXAMPLE_NAN_SVC_MSG) : ESP_WIFI_MAX_FUP_SSI_LEN;
fup.ssi = calloc(1, fup.ssi_len);
if (!fup.ssi) {
ESP_LOGE(TAG, "Failed to allocate for Follow-up");
return;
}
memcpy((char *)fup.ssi, EXAMPLE_NAN_SVC_MSG, fup.ssi_len);
fup.inst_id = pub_id;
while (1) {
EventBits_t bits = xEventGroupWaitBits(nan_event_group, NAN_RECEIVE, pdFALSE, pdFALSE, portMAX_DELAY);
if (bits & NAN_RECEIVE) {
xEventGroupClearBits(nan_event_group, NAN_RECEIVE);
wifi_nan_followup_params_t fup = {0};
fup.inst_id = pub_id,
fup.peer_inst_id = g_peer_inst_id,
strlcpy(fup.svc_info, EXAMPLE_NAN_SVC_MSG, ESP_WIFI_MAX_SVC_INFO_LEN);
fup.peer_inst_id = g_peer_inst_id;
memcpy(fup.peer_mac, g_peer_mac, sizeof(fup.peer_mac));
/* Reply to the message from a subscriber */
esp_wifi_nan_send_message(&fup);
}
vTaskDelay(10);
}
free(fup.ssi);
}
void initialise_wifi(void)

View File

@@ -32,7 +32,7 @@
#define EXAMPLE_NAN_SVC_MSG "Hello"
#endif
static const char *TAG = "nan_sub";
static const char *TAG = "subscriber";
static EventGroupHandle_t nan_event_group;
@@ -42,8 +42,21 @@ const int NDP_FAILED = BIT2;
static wifi_event_nan_svc_match_t g_svc_match_evt;
static void nan_receive_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
wifi_event_nan_receive_t *evt = (wifi_event_nan_receive_t *)event_data;
if (evt->ssi_len) {
ESP_LOGI(TAG, "Received payload from Peer "MACSTR" [Peer Service id - %d] - ", MAC2STR(evt->peer_if_mac), evt->peer_inst_id);
ESP_LOG_BUFFER_HEXDUMP(TAG, evt->ssi, evt->ssi_len, ESP_LOG_INFO);
} else {
ESP_LOGI(TAG, "Received message '%s' from Peer "MACSTR" [Peer Service id - %d]",
evt->peer_svc_info, MAC2STR(evt->peer_if_mac), evt->peer_inst_id);
}
}
#ifdef CONFIG_EXAMPLE_NAN_SEND_PING
static uint8_t g_peer_ndi[6];
static uint8_t g_peer_ndi[ETH_ALEN];
static void cmd_ping_on_ping_success(esp_ping_handle_t hdl, void *args)
{
@@ -149,6 +162,11 @@ void wifi_nan_subscribe(void)
&nan_svc_match_event_handler,
NULL,
&instance_any_id));
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
WIFI_EVENT_NAN_RECEIVE,
&nan_receive_event_handler,
NULL,
&instance_any_id));
#ifdef CONFIG_EXAMPLE_NAN_SEND_PING
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
@@ -189,13 +207,20 @@ void wifi_nan_subscribe(void)
wifi_nan_followup_params_t fup = {
.inst_id = sub_id,
.peer_inst_id = g_svc_match_evt.publish_id,
.svc_info = EXAMPLE_NAN_SVC_MSG,
};
memcpy(fup.peer_mac, g_svc_match_evt.pub_if_mac, sizeof(fup.peer_mac));
fup.ssi_len = (strlen(EXAMPLE_NAN_SVC_MSG) < ESP_WIFI_MAX_FUP_SSI_LEN) ? strlen(EXAMPLE_NAN_SVC_MSG) : ESP_WIFI_MAX_FUP_SSI_LEN;
fup.ssi = calloc(1, fup.ssi_len);
if (!fup.ssi) {
ESP_LOGE(TAG, "Failed to allocate for Follow-up");
return;
}
memcpy((char *)fup.ssi, EXAMPLE_NAN_SVC_MSG, fup.ssi_len);
if (esp_wifi_nan_send_message(&fup) == ESP_OK)
ESP_LOGI(TAG, "Sending message '%s' to Publisher "MACSTR" ...",
EXAMPLE_NAN_SVC_MSG, MAC2STR(g_svc_match_evt.pub_if_mac));
free(fup.ssi);
#endif
#ifdef CONFIG_EXAMPLE_NAN_SEND_PING
wifi_nan_datapath_req_t ndp_req = {0};