diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 4efffa6896..3dc380d586 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -660,10 +660,10 @@ esp_err_t esp_wifi_get_country(wifi_country_t *country); /** - * @brief Set MAC address of WiFi station or the soft-AP interface. + * @brief Set MAC address of WiFi station, soft-AP or NAN interface. * * @attention 1. This API can only be called when the interface is disabled - * @attention 2. Soft-AP and station have different MAC addresses, do not set them to be the same. + * @attention 2. Above mentioned interfaces have different MAC addresses, do not set them to be the same. * @attention 3. The bit 0 of the first byte of MAC address can not be 1. For example, the MAC address * can set to be "1a:XX:XX:XX:XX:XX", but can not be "15:XX:XX:XX:XX:XX". * diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index ee0a65c85d..2394f28812 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit ee0a65c85dc848ea67c1bc55f080c71b4e02226c +Subproject commit 2394f288120349d894b074bf47057eb389ce1053 diff --git a/components/esp_wifi/wifi_apps/include/esp_nan.h b/components/esp_wifi/wifi_apps/include/esp_nan.h index 0fba2bf5f5..9be6bbb665 100644 --- a/components/esp_wifi/wifi_apps/include/esp_nan.h +++ b/components/esp_wifi/wifi_apps/include/esp_nan.h @@ -120,8 +120,8 @@ esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id); * @param req NAN Datapath Request parameters. * * @return - * - non-zero: NAN Datapath Identifier - * - zero: failed + * - non-zero NAN Datapath identifier: If NAN datapath req was accepted by publisher + * - zero: If NAN datapath req was rejected by publisher or a timeout occurs */ uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req); diff --git a/components/esp_wifi/wifi_apps/src/nan_app.c b/components/esp_wifi/wifi_apps/src/nan_app.c index 9290cb0f87..f1e40b82ab 100644 --- a/components/esp_wifi/wifi_apps/src/nan_app.c +++ b/components/esp_wifi/wifi_apps/src/nan_app.c @@ -23,13 +23,15 @@ /* NAN Events */ #define NDP_INDICATION BIT2 -#define NDP_CONFIRMED BIT3 +#define NDP_ACCEPTED BIT3 #define NDP_TERMINATED BIT4 +#define NDP_REJECTED BIT5 /* Macros */ #define MACADDR_LEN 6 #define MACADDR_EQUAL(a1, a2) (memcmp(a1, a2, MACADDR_LEN)) #define MACADDR_COPY(dst, src) (memcpy(dst, src, MACADDR_LEN)) +#define NAN_DW_INTVL_MS 524 /* NAN DW interval (512 TU's ~= 524 mSec) */ /* Global Variables */ static const char *TAG = "nan_app"; @@ -477,13 +479,19 @@ static void nan_app_action_ndp_confirm(void *arg, esp_event_base_t event_base, i ESP_LOGE(TAG, "%s: NAN netif is NULL", __func__); return; } + + if (nan_find_ndl(evt->ndp_id, NULL) == NULL) { + /* As ndl isn't found, timeout has occured for NDP response and datapath request is rejected */ + return; + } if (evt->status == NDP_STATUS_REJECTED) { ESP_LOGE(TAG, "NDP request to Peer "MACSTR" rejected [NDP ID - %d]", MAC2STR(evt->peer_nmi), evt->ndp_id); nan_reset_ndl(evt->ndp_id, false); + os_event_group_set_bits(nan_event_group, NDP_REJECTED); return; } - // if interface not ready when started, rxcb to be registered on connection + /* If interface not ready when started, rxcb to be registered on connection */ if (esp_wifi_register_if_rxcb(driver, esp_netif_receive, s_nan_ctx.nan_netif) != ESP_OK) { ESP_LOGE(TAG, "%s: esp_wifi_register_if_rxcb failed", __func__); return; @@ -494,11 +502,11 @@ static void nan_app_action_ndp_confirm(void *arg, esp_event_base_t event_base, i esp_netif_action_connected(s_nan_ctx.nan_netif, event_base, event_id, data); esp_netif_create_ip6_linklocal(s_nan_ctx.nan_netif); - s_nan_ctx.state |= NDP_CONFIRMED; esp_wifi_nan_get_ipv6_linklocal_from_mac(&target_addr.u_addr.ip6, evt->peer_ndi); target_addr.type = IPADDR_TYPE_V6; ESP_LOGI(TAG, "NDP confirmed with Peer "MACSTR" [NDP ID - %d, Peer IPv6 - %s]", MAC2STR(evt->peer_nmi), evt->ndp_id, inet6_ntoa(*ip_2_ip6(&target_addr))); + os_event_group_set_bits(nan_event_group, NDP_ACCEPTED); } static void nan_app_action_ndp_terminated(void *arg, esp_event_base_t event_base, int32_t event_id, void *data) @@ -514,7 +522,6 @@ static void nan_app_action_ndp_terminated(void *arg, esp_event_base_t event_base ESP_LOGI(TAG, "NDP terminated with Peer "MACSTR" [NDP ID - %d]", MAC2STR(evt->init_ndi), evt->ndp_id); nan_reset_ndl(evt->ndp_id, false); - s_nan_ctx.state &= ~(NDP_CONFIRMED); s_nan_ctx.event &= ~(NDP_INDICATION); os_event_group_set_bits(nan_event_group, NDP_TERMINATED); } @@ -629,7 +636,7 @@ void esp_nan_action_stop(void) { nan_clear_app_default_handlers(); - if (s_nan_ctx.state & NDP_CONFIRMED) { + if (nan_is_datapath_active()) { nan_reset_ndl(0, true); esp_wifi_internal_reg_rxcb(WIFI_IF_NAN, NULL); } @@ -685,7 +692,7 @@ esp_err_t esp_wifi_nan_stop(void) return ESP_FAIL; } - if (s_nan_ctx.state & NDP_CONFIRMED) { + if (nan_is_datapath_active()) { /* Terminate all NDP's */ wifi_nan_datapath_end_req_t ndp_end = {0}; for (int i=0; i < ESP_WIFI_NAN_DATAPATH_MAX_PEERS; i++) { @@ -701,7 +708,7 @@ esp_err_t esp_wifi_nan_stop(void) os_event_group_wait_bits(nan_event_group, NDP_TERMINATED, pdFALSE, pdFALSE, portMAX_DELAY); os_event_group_clear_bits(nan_event_group, NDP_TERMINATED); /* Wait for 1 NAN DW interval (512 TU's ~= 524 mSec) for successful termination */ - g_wifi_osi_funcs._task_delay(524/portTICK_PERIOD_MS); + g_wifi_osi_funcs._task_delay(NAN_DW_INTVL_MS/portTICK_PERIOD_MS); } ESP_RETURN_ON_ERROR(esp_wifi_stop(), TAG, "Stopping NAN failed"); @@ -860,7 +867,17 @@ uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req) nan_record_new_ndl(ndp_id, req->pub_id, req->peer_mac, ESP_WIFI_NDP_ROLE_INITIATOR); ESP_LOGD(TAG, "Requested NDP with "MACSTR" [NDP ID - %d]", MAC2STR(req->peer_mac), ndp_id); - return ndp_id; + EventBits_t bits = os_event_group_wait_bits(nan_event_group, NDP_ACCEPTED | NDP_REJECTED, pdFALSE, pdFALSE, pdMS_TO_TICKS(2*NAN_DW_INTVL_MS)); + if (bits & NDP_ACCEPTED) { + os_event_group_clear_bits(nan_event_group, NDP_ACCEPTED); + return ndp_id; + } else if (bits & NDP_REJECTED) { + os_event_group_clear_bits(nan_event_group, NDP_REJECTED); + return 0; + } else { + nan_reset_ndl(ndp_id, false); + return 0; + } } esp_err_t esp_wifi_nan_datapath_resp(wifi_nan_datapath_resp_t *resp) @@ -892,7 +909,7 @@ esp_err_t esp_wifi_nan_datapath_end(wifi_nan_datapath_end_req_t *req) { struct ndl_info *ndl = NULL; - if (!(s_nan_ctx.state & NDP_CONFIRMED)) { + if (!nan_is_datapath_active()) { ESP_LOGE(TAG, "No Datapath active"); return ESP_FAIL; } diff --git a/examples/wifi/wifi_aware/nan_console/main/nan_main.c b/examples/wifi/wifi_aware/nan_console/main/nan_main.c index ad353148e1..a2734340ce 100644 --- a/examples/wifi/wifi_aware/nan_console/main/nan_main.c +++ b/examples/wifi/wifi_aware/nan_console/main/nan_main.c @@ -54,7 +54,6 @@ typedef struct { struct arg_str *name; struct arg_int *type; struct arg_str *filter; - struct arg_lit *ndp_ask; struct arg_lit *cancel; struct arg_int *id; struct arg_end *end; @@ -90,9 +89,6 @@ typedef struct { struct arg_lit *init; struct arg_int *peer_pub_id; struct arg_str *mac_addr; - /* NDP Accept/Reject parameters */ - struct arg_lit *accept; - struct arg_lit *reject; /* NDP Terminate parameters */ struct arg_lit *terminate; struct arg_int *ndp_id; @@ -299,11 +295,6 @@ static int wifi_cmd_nan_publish(int argc, char **argv) strlcpy(publish.matching_filter, pub_args.filter->sval[0], ESP_WIFI_MAX_SVC_NAME_LEN); } - if (pub_args.ndp_ask->count) { - ndp_resp_needed = true; - ESP_LOGI(TAG, "Issue 'ndp -A -d [id]' to Accept OR 'ndp -R -d [id]' to Reject incoming NDP requests"); - } - if (!esp_wifi_nan_publish_service(&publish, ndp_resp_needed)) { return 1; } @@ -401,8 +392,7 @@ static int wifi_cmd_ndp(int argc, char **argv) return 1; } - if ((ndp_args.init->count == 0) && (ndp_args.terminate->count == 0) && - (ndp_args.accept->count == 0) && (ndp_args.reject->count == 0)) { + if ((ndp_args.init->count == 0) && (ndp_args.terminate->count == 0)) { ESP_LOGE(TAG, "Invalid NDP command"); return 1; } @@ -424,25 +414,11 @@ static int wifi_cmd_ndp(int argc, char **argv) } if (!esp_wifi_nan_datapath_req(&ndp_req)) { - return 1; + ESP_LOGE(TAG, "Invalid configuration or NDP Request was rejected"); } goto out; } - if (ndp_args.accept->count || ndp_args.reject->count) { - wifi_nan_datapath_resp_t ndp_resp = {0}; - ndp_resp.accept = ndp_args.accept->count ? true : false; - if (ndp_args.ndp_id->count) { - ndp_resp.ndp_id = ndp_args.ndp_id->ival[0]; - } else { - ESP_LOGE(TAG, "Missing own NDP id, add using '-d' parameter"); - return 1; - } - - esp_wifi_nan_datapath_resp(&ndp_resp); - goto out; - } - if (ndp_args.terminate->count) { wifi_nan_datapath_end_req_t ndp_end = {0}; if (ndp_args.ndp_id->count) { @@ -485,7 +461,6 @@ void register_nan(void) pub_args.name = arg_str0("n", "name", "", "Name for the service"); pub_args.type = arg_int0("t", "type", "<0/1>", "0 - Unsolicited(Default), 1 - Solicited"); pub_args.filter = arg_str0("f", "filter", "", "Comma separated Matching Filter"); - pub_args.ndp_ask = arg_lit0("a", "ndp_ask", "Explicitly Accept OR Reject incoming NDP Requests"); /* NAN Publish cancel parameters */ pub_args.cancel = arg_lit0("C", "cancel", "Cancel a service"); pub_args.id = arg_int0("i", "id", "<0-255>", "Publish service id"); @@ -541,9 +516,7 @@ void register_nan(void) ndp_args.init = arg_lit0("I", "initiate", "NDP Initiate"); ndp_args.peer_pub_id = arg_int0("p", "peer_pub_id", "<1-254>", "Peer's Publish Id"); ndp_args.mac_addr = arg_str0("m", "mac", "", "Peer's MAC Address"); - /* NDP Accept/Reject/Terminate parameters */ - ndp_args.accept = arg_lit0("A", "accept", "Accept NDP Request"); - ndp_args.reject = arg_lit0("R", "reject", "Reject NDP Request"); + /* NDP Terminate parameters */ ndp_args.terminate = arg_lit0("T", "terminate", "NDP Terminate"); ndp_args.ndp_id = arg_int0("d", "ndp_id", "<1-254>", "NDP ID"); ndp_args.end = arg_end(1); diff --git a/examples/wifi/wifi_aware/nan_publisher/main/publisher_main.c b/examples/wifi/wifi_aware/nan_publisher/main/publisher_main.c index fb30028864..027b784b8e 100644 --- a/examples/wifi/wifi_aware/nan_publisher/main/publisher_main.c +++ b/examples/wifi/wifi_aware/nan_publisher/main/publisher_main.c @@ -44,6 +44,22 @@ static void nan_receive_event_handler(void *arg, esp_event_base_t event_base, xEventGroupSetBits(nan_event_group, NAN_RECEIVE); } +static void nan_ndp_indication_event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + if (event_data == NULL) { + return; + } + wifi_event_ndp_indication_t *evt = (wifi_event_ndp_indication_t *)event_data; + + 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); + + esp_wifi_nan_datapath_resp(&ndp_resp); + +} void wifi_nan_publish(void) { nan_event_group = xEventGroupCreate(); @@ -54,12 +70,24 @@ void wifi_nan_publish(void) NULL, &instance_any_id)); + /* ndp_require_consent + * If set to false - All incoming NDP requests will be internally accepted if valid. + * If set to true - All incoming NDP requests raise NDP_INDICATION event, upon which application can either accept or reject them. + */ + bool ndp_require_consent = true; + /* Start NAN Discovery */ wifi_nan_config_t nan_cfg = WIFI_NAN_CONFIG_DEFAULT(); esp_netif_create_default_wifi_nan(); esp_wifi_nan_start(&nan_cfg); + ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, + WIFI_EVENT_NDP_INDICATION, + &nan_ndp_indication_event_handler, + NULL, + &instance_any_id)); + /* Publish a service */ uint8_t pub_id; wifi_nan_publish_cfg_t publish_cfg = { @@ -73,7 +101,7 @@ void wifi_nan_publish(void) .single_replied_event = 1, }; - pub_id = esp_wifi_nan_publish_service(&publish_cfg, false); + pub_id = esp_wifi_nan_publish_service(&publish_cfg, ndp_require_consent); if (pub_id == 0) { return; } diff --git a/examples/wifi/wifi_aware/nan_subscriber/main/subscriber_main.c b/examples/wifi/wifi_aware/nan_subscriber/main/subscriber_main.c index f5fe8cc274..c6096516ef 100644 --- a/examples/wifi/wifi_aware/nan_subscriber/main/subscriber_main.c +++ b/examples/wifi/wifi_aware/nan_subscriber/main/subscriber_main.c @@ -94,7 +94,7 @@ static void nan_ndp_confirmed_event_handler(void *arg, esp_event_base_t event_ba wifi_event_ndp_confirm_t *evt = (wifi_event_ndp_confirm_t *)event_data; if (evt->status == NDP_STATUS_REJECTED) { - ESP_LOGI(TAG, "NDP request to Peer "MACSTR" rejected [NDP ID - %d]", MAC2STR(evt->peer_nmi), evt->ndp_id); + ESP_LOGE(TAG, "NDP request to Peer "MACSTR" rejected [NDP ID - %d]", MAC2STR(evt->peer_nmi), evt->ndp_id); xEventGroupSetBits(nan_event_group, NDP_FAILED); } else { memcpy(g_peer_ndi, evt->peer_ndi, sizeof(g_peer_ndi));