| Supported Targets | ESP32 | ESP32-C5 | ESP32-C61 | ESP32-S2 | ESP32-S31 |
| ----------------- | ----- | -------- | --------- | -------- | --------- |
# Wi-Fi Aware UDP Client Example
Discoverer side of the [`wifi_aware`](../../) UDP demo. This example looks for a
Wi-Fi Aware service advertised by [`udp_server`](../udp_server/), connects to it,
and periodically sends a UDP message that the server echoes back.
## Introduction
Wi-Fi Aware (also referred to as NAN - Neighbor Awareness Networking) is a protocol that allows Wi-Fi devices to discover services in their proximity. NAN uses direct device-to-device communication and does not require any Internet or AP connection.
Multiple NAN devices which are in the vicinity will form a cluster which allows them to communicate with each other. Devices within the cluster can advertise or look for services and establish a peer-to-peer datapath with or without security.
In this example, Wi-Fi Aware Service Discovery and Datapath establishment are implemented in `example_wifi_aware.c`, while `udp_client.c` creates the UDP socket and operates over the TCP/IP stack. When Pairing is selected as the security mode, `pair_button.c` implements push button triggers to restart and erase previous pairing credentials.
## How to use the example
This example is meant to run together with another ESP device flashing [`udp_server`](../udp_server/). The simplest way is to run the following command for both this and the [`udp_server`](../udp_server/) example.
```bash
idf.py set-target esp32c5 build flash monitor
```
Service-specific and security parameters can be changed using the Example project configuration. A Publisher (Advertiser) running the [`udp_server`](../udp_server/) needs to have identical parameters for a successful discovery and connection.
The `wifi_aware` component uses service names in compliance with [RFC 6763](https://www.rfc-editor.org/rfc/rfc6763). Option `Service Type` - which defaults to `ESP-Demo` - is used to identify a service.
ESP-IDF v6.1 introduces Wi-Fi Aware Pairing and Datapath security protocols as experimental features. Enable `Make experimental features visible` first, then navigate to `Component config -> Wi-Fi` and enable the following features:
1. `Enable Wi-Fi Aware: Encrypted Pairwise Datapath (NDP Security)` for:
- WPA2-PSK level passphrase based security
- that uses `NAN Datapath Passphrase` from `Example Configuration`
2. In addition enable `Enable NAN Pairing` for:
- WPA3-PSK level security using PIN Code based pairing
- that uses `Static Pairing PIN (6 digits)` from `Example Configuration`
- and retains credentials if `Persist NAN Pairing Credentials to NVS` is enabled
For Wi-Fi Aware Pairing, configuring a PIN is a one-time activity (also called bootstrapping). An ESP device can be paired with only one peer at a time. If `Persist NAN Pairing Credentials to NVS` is enabled, that pairing survives a reset.
To pair with a new device, the previous credentials must be erased. On ESP-DevKitC boards, the BOOT button does this: after pairing, long-press BOOT for 5 seconds to erase the stored credentials. Repeat this if you need to pair with the same device again.
## API Flow between `udp_client` and `udp_server`
```mermaid
sequenceDiagram
autonumber
participant App as app_main (udp_client)
participant WA as example_wifi_aware_connect
participant EV as WA_EVENT handlers
participant Pub as Publisher (udp_server)
participant UDP as udp_client_run
App->>App: nvs_flash_init / esp_netif_init / event_loop
App->>App: esp_wifi_init()
App->>App: pair_button_init() (optional)
loop connect / rediscover loop
App->>WA: example_wifi_aware_connect(&addr, &port, &netif_index, erase)
WA->>WA: wifi_aware_init(trigger=WA_TRIGGER_NONE)
WA->>WA: register WA_EVENT_BOOTSTRAP_COMPLETED / _PAIRING_CONFIRMED
WA->>WA: register WA_EVENT_PEER_LOST / _DATAPATH_DISCONNECTED
WA->>Pub: wifi_aware_discover(&sub_cfg, &session)
Pub-->>EV: discovery callback(session, peer, info)
Note over EV: latch peer handle, never block here
alt PIN-pairing security enabled
EV->>EV: wifi_aware_peer_get_info(peer, &info)
alt info.already_paired (NIRA-recognised)
EV->>Pub: wifi_aware_pairing_verify(peer)
else first encounter
EV->>Pub: wifi_aware_pairing_bootstrap_request(peer, info.selected_method)
Pub-->>EV: WA_EVENT_BOOTSTRAP_COMPLETED (peer, accepted)
EV->>Pub: wifi_aware_pairing_start(peer, &cred)
end
Pub-->>EV: WA_EVENT_PAIRING_CONFIRMED (peer, status)
end
EV-->>WA: xSemaphoreGive(connect_sem) — hand off to the caller task
WA->>Pub: wifi_aware_connect(peer, 0, &endpoint)
Pub-->>WA: wa_endpoint_t: addr + port + netif + netif_index
WA-->>App: ESP_OK, peer endpoint
App->>UDP: udp_client_run(addr, port, netif_index)
loop every 2 s
UDP->>Pub: sendto() — "Message from ESP32"
Pub-->>UDP: recvfrom() — "OK: Message from ESP32"
end
Note over App: on socket error: rediscover & reconnect
end
```
## Example console output
```
I (480) wifi_init: WiFi IRAM OP enabled
I (480) wifi_init: WiFi RX IRAM OP enabled
I (480) wifi_init: WiFi SLP IRAM OP enabled
I (490) udp_client: Starting Wi-Fi Aware discovery
I (490) wifi_aware: Initializing Wi-Fi Aware service
I (500) phy_init: phy_version 282,a2b3f88,Apr 22 2026,17:01:12
I (570) wifi:11ax coex: WDEVAX_PTI0(0x040000a0), WDEVAX_PTI1(0x0000820c).
I (580) wifi:mode : NAN (da:85:ac:77:c2:6e)
I (3580) NAN: Join Cluster with Id 50:6f:9a:01:76:3f
I (3580) nan_app: NAN Discovery started.
I (3580) wifi_aware: Wi-Fi Aware service initialized successfully
I (3580) wifi:(2.4G)set country: cc=IN schan=1 nchan=13 policy=1
I (3590) wa_service: Starting service discovery for _ESP-Demo._udp
I (3590) wifi_aware: Discovering services: ESP._udp (timeout: 10 s)
I (3600) nan_app: Started Subscribing to _ESP-Demo._udp [Service ID - 5]
I (3600) wifi_aware: NAN service subscription started successfully (subscribe_id: 5, service: _ESP-Demo._udp)
I (3610) wifi_aware: Live discovery active for 10 s (stop on first match)
I (4500) nan_app: Service matched with da:85:ac:5b:ec:39 [Peer Publish id - 5]
I (4500) wifi_aware: NAN Service Match: Peer da:85:ac:5b:ec:39 [Subscribe ID: 5, Publish ID: 5], Datapath 0, NDPE 0, selected=0
I (4510) wifi_aware: 0x4082a6d4 50 6f 9a 02 02 0e 00 5f 45 53 50 2d 44 65 6d 6f |Po....._ESP-Demo|
I (4510) wifi_aware: 0x4082a6e4 2e 5f 75 64 70 |._udp|
I (4520) wifi_aware: Found Service Name (len=14)
I (4530) wifi_aware: Added PTR record: service=_ESP-Demo._udp, instance=NULL, publish_id=5, subscribe_id=5, ndpe=0, already_paired=0
I (4540) wa_service: Matched peer 0x00000101:
I (4540) wa_service: Service matched, ready to resolve
I (4550) wifi_aware: Publisher doesn't support NDPE, sending Follow-up to request SRV record
I (4550) wifi_aware: Connecting to peer da:85:ac:5b:ec:39 (instance=(none), pairing_name=(none), publish_id=5)
I (5090) wifi_aware: Sent empty GSP Follow-up to da:85:ac:5b:ec:39 for SRV record
I (5600) wifi_aware: Received follow-up from Peer da:85:ac:5b:ec:39 [Our ID: 5, Peer ID: 5], SSI len: 25
I (5600) wifi_aware: Found Transport Port: 3333
I (5600) wifi_aware: Received SRV record via Follow-up: port=3333
I (6090) wifi:(trc)phytype:CBW20-LGI, snr:0, maxRate:0, highestRateIdx:1
W (6090) wifi:(trc)band:2G, phymode:0, highestRateIdx:1, lowestRateIdx:11, dataSchedTableSize:14
I (6100) wifi:(trc)band:2G, rate(LP-1Mbps, rateIdx:11), ampdu(rate:L-MCS0, schedIdx(8, stop:8)), snr:0, ampduState:wait operational
I (6110) wifi:Committed slots 0x3fff0000 for Peer da:85:ac:5b:ec:39 on Channel 6
I (6120) nan_app: NDP confirmed with Peer da:85:ac:5b:ec:39 [NDP ID - 1, Peer IPv6 - FE80::D885:ACFF:FE5B:EC39]
I (6130) wifi_aware: NDP Confirmed: Peer da:85:ac:5b:ec:39 [NDP ID: 1]
I (6130) wifi_aware: Datapath established successfully
I (6140) wifi_aware: Derived IPv6 address from peer NDI: FE80::D885:ACFF:FE5B:EC39
I (6140) wifi_aware: SRV record already received via Follow-up: port=3333
I (7390) wifi_aware: Got IPv6 address on NAN interface (index: 0): fe80:0000:0000:0000:d885:acff:fe77:c26e
I (7390) wifi_aware: Datapath ready
I (7390) wifi_aware: Resolved port: 3333
I (7390) wa_service: Datapath established, peer service port 3333
I (7400) udp_client: NAN interface index: 2
I (7400) udp_client: Socket created, sending to [FE80::D885:ACFF:FE5B:EC39]:3333
I (7410) udp_client: Message sent
I (7770) udp_client: Received 23 bytes from FE80::D885:ACFF:FE5B:EC39:
I (7770) udp_client: OK: Message from ESP32
I (7770) udp_client: Received expected ack from server
I (9770) udp_client: Message sent
I (9820) udp_client: Received 23 bytes from FE80::D885:ACFF:FE5B:EC39:
I (9820) udp_client: OK: Message from ESP32
I (9820) udp_client: Received expected ack from server
```
To create a project from this example, run:
idf.py create-project-from-example "espressif/wifi_aware=0.1.0:udp_client"