Wi-Fi AwareTM (NAN)

[中文]

Wi-Fi AwareTM or NAN (Neighbor Awareness Networking) is a protocol that allows Wi-Fi devices to discover services in their proximity. Typically, location-based services are based on querying servers for information about the environment and the location knowledge is based on GPS or other location reckoning techniques. However, NAN does not require real-time connection to servers, GPS or other geo-location, but instead uses direct device-to-device Wi-Fi to discover and exchange information. NAN scales effectively in dense Wi-Fi environments and complements the connectivity of Wi-Fi by providing information about people and services in the proximity.

Multiple NAN devices which are in the vicinity form a NAN cluster which allows them to communicate with each other. Devices within a NAN cluster can advertise (Publish method) or look for (Subscribe method) services using NAN Service Discovery protocols. Matching of services is done by service name, once a match is found, a device can either send a message or establish an IPv6 Datapath with the peer.

ESP32 supports Wi-Fi Aware in standalone mode with support for both Service Discovery and Datapath. Wi-Fi Aware is still an evolving protocol. Please refer to Wi-Fi Alliance's official page on Wi-Fi Aware for more information. Many Android smartphones with Android 8 or higher support Wi-Fi Aware. Refer to Android's developer guide on Wi-Fi Aware Wi-Fi Aware for more information.

Application Example

A pair of examples for a Publisher-Subscriber use case: wifi/wifi_aware/nan_publisher and wifi/wifi_aware/nan_subscriber. A user interactive console example to explore full functionality of Wi-Fi Aware: wifi/wifi_aware/nan_console. Please check the README for more details in respective example directories.

API Reference

Header File

  • components/esp_wifi/wifi_apps/include/esp_nan.h

  • This header file can be included with:

    #include "esp_nan.h"
    
  • This header file is a part of the API provided by the esp_wifi component. To declare that your component depends on esp_wifi, add the following to your CMakeLists.txt:

    REQUIRES esp_wifi
    

    or

    PRIV_REQUIRES esp_wifi
    

Functions

esp_err_t esp_wifi_nan_start(const wifi_nan_config_t *nan_cfg)

Start NAN Discovery with provided configuration.

Attention

This API should be called after esp_wifi_init().

Parameters

nan_cfg -- NAN related parameters to be configured.

Returns

  • ESP_OK: succeed

  • others: failed

esp_err_t esp_wifi_nan_stop(void)

Stop NAN Discovery, end NAN Services and Datapaths.

Returns

  • ESP_OK: succeed

  • others: failed

uint8_t esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t *publish_cfg, bool ndp_resp_needed)

Start Publishing a service to the NAN Peers in vicinity.

Attention

This API should be called after esp_wifi_nan_start().

Parameters
  • publish_cfg -- Configuration parameters for publishing a service.

  • ndp_resp_needed -- Setting this true will require user response for every NDP Req using esp_wifi_nan_datapath_resp API.

Returns

  • non-zero: Publish service identifier

  • zero: failed

uint8_t esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t *subscribe_cfg)

Subscribe for a service within the NAN cluster.

Attention

This API should be called after esp_wifi_nan_start().

Parameters

subscribe_cfg -- Configuration parameters for subscribing for a service.

Returns

  • non-zero: Subscribe service identifier

  • zero: failed

esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params)

Send a follow-up message to the NAN Peer with matched service.

Attention

This API should be called after a NAN service is discovered due to a match.

Parameters

fup_params -- Configuration parameters for sending a Follow-up message.

Returns

  • ESP_OK: succeed

  • others: failed

esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id)

Cancel a NAN service.

Parameters

service_id -- Publish/Subscribe service id to be cancelled.

Returns

  • ESP_OK: succeed

  • others: failed

uint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req)

Send NAN Datapath Request to a NAN Publisher with matched service.

Attention

This API should be called by the Subscriber after a match occurs with a Publisher.

Parameters

req -- NAN Datapath Request parameters.

Returns

  • 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

esp_err_t esp_wifi_nan_datapath_resp(wifi_nan_datapath_resp_t *resp)

Respond to a NAN Datapath request with Accept or Reject.

Attention

This API should be called if ndp_resp_needed is set True by the Publisher and a WIFI_EVENT_NDP_INDICATION event is received due to an incoming NDP request.

Parameters

resp -- NAN Datapath Response parameters.

Returns

  • ESP_OK: succeed

  • others: failed

esp_err_t esp_wifi_nan_datapath_end(wifi_nan_datapath_end_req_t *req)

Terminate a NAN Datapath.

Parameters

req -- NAN Datapath end request parameters.

Returns

  • ESP_OK: succeed

  • others: failed

void esp_wifi_nan_get_ipv6_linklocal_from_mac(ip6_addr_t *ip6, uint8_t *mac_addr)

Get IPv6 Link Local address using MAC address.

Parameters
  • ip6 -- [out] Derived IPv6 Link Local address.

  • mac_addr -- [in] Input MAC Address.

esp_err_t esp_wifi_nan_get_own_svc_info(uint8_t *own_svc_id, char *svc_name, int *num_peer_records)

brief Get own Service information from Service ID OR Name.

Attention

If service information is to be fetched from service name, set own_svc_id as zero.

Parameters
  • own_svc_id -- [inout] As input, it indicates Service ID to search for. As output, it indicates Service ID of the service found using Service Name.

  • svc_name -- [inout] As input, it indicates Service Name to search for. As output, it indicates Service Name of the service found using Service ID.

  • num_peer_records -- [out] Number of peers discovered by corresponding service.

Returns

  • ESP_OK: succeed

  • ESP_FAIL: failed

esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_id, struct nan_peer_record *peer_record)

brief Get a list of Peers discovered by the given Service.

Parameters
  • num_peer_records -- [inout] As input param, it stores max peers peer_record can hold. As output param, it specifies the actual number of peers this API returns.

  • own_svc_id -- Service ID of own service.

  • peer_record -- [out] Pointer to first peer record.

Returns

  • ESP_OK: succeed

  • ESP_FAIL: failed

esp_err_t esp_wifi_nan_get_peer_info(char *svc_name, uint8_t *peer_mac, struct nan_peer_record *peer_info)

brief Find Peer's Service information using Peer MAC and optionally Service Name.

Parameters
  • svc_name -- Service Name of the published/subscribed service.

  • peer_mac -- Peer's NAN Management Interface MAC address.

  • peer_info -- [out] Peer's service information structure.

Returns

  • ESP_OK: succeed

  • ESP_FAIL: failed

Structures

struct nan_peer_record

Parameters of a peer service record

Public Members

uint8_t peer_svc_id

Identifier of Peer's service

uint8_t own_svc_id

Identifier of own service associated with Peer

uint8_t peer_nmi[6]

Peer's NAN Management Interface address

uint8_t peer_svc_type

Peer's service type (Publish/Subscribe)

uint8_t ndp_id

Specifies if the peer has any active datapath

uint8_t peer_ndi[6]

Peer's NAN Data Interface address, only valid when ndp_id is non-zero

Macros

WIFI_NAN_CONFIG_DEFAULT()
NDP_STATUS_ACCEPTED
NDP_STATUS_REJECTED
NAN_MAX_PEERS_RECORD
ESP_NAN_PUBLISH
ESP_NAN_SUBSCRIBE