espressif/wifi_aware

0.0.1

Latest
uploaded 2 days ago
Wi-Fi Aware (NAN) based Network Service Discovery component

Readme

# Wi-Fi Aware (`wifi_aware`)

Wi-Fi Aware (NAN - Neighbor Awareness Networking) based network service discovery component for ESP-IDF.
It enables zero-configuration service discovery and data exchange between ESP devices **without an access
point or internet connection**, using IPv6 link-local addresses over a secured NAN datapath.

Service discovery follows DNS-SD compatible patterns, so ESP devices can also interoperate with other
Wi-Fi Aware devices on the same network.

## Supported Targets

| SoC | NAN support |
| --- | :---: |
| ESP32 | ✅ |
| ESP32-S2 | ✅ |
| ESP32-C5 | ✅ |
| ESP32-C61 | ✅ |
| ESP32-S31 | ✅ |
| ESP32-C3 / S3 / C6 / C2 | ❌ |

## Security Features

Initial Wi-Fi Aware specifications did not provide a way to secure the datapath. Applications were responsible to implement their
own security mechanisms. Later, Specifications v3.0 introduced Passphrase based security - which matches WPA2-PSK level security - and
the most recent Specifications v4.0 added support for Pairing - which matches WPA3-PSK level security. Pairing also introduced
Out-of-bound methods to share the credentials, of which only specific methods are supported.

Wi-Fi Aware Secure Datapath is only available in specified ESP-IDF versions -

| ESP-IDF Version | Security Modes Available |
| --- | :---: |
| v6.1 | Open / Passphrase / PIN Code Pairing |
| v6.0 | Open |
| v5.5 | Open |
| v5.4 | Open |
| v5.3 | Open |
| v5.2 | Open |

## Mobile Platform Support

Wi-Fi Aware support in mobile platforms has changed drastically over the years. Android 8.0 introduced the initial support under the `android.net.wifi.aware` class. Later Android versions have added features incrementally, but vendor support for newer security features like Pairing is very limited. Android APIs directly map to the specifications and require applications to implement their own naming and messaging conventions.

Apple announced Wi-Fi Aware support in WWDC 2025 and introduced it in iOS 26. Apple internally implements a DNS-SD-style mechanism
and [RFC 6763](https://www.rfc-editor.org/rfc/rfc6763) compliant naming conventions. Only way to connect using Wi-Fi Aware is using a
PIN-code based pairing method.

| Platform | Devices | Supported security mode | Notes |
| --- | --- | --- | --- |
| Android | Pixel series, Samsung Galaxy S series | Open or Passphrase (WPA2-level) | Use `WA_SEC_OPEN` or `WA_SEC_PWD` (`wa_dp_security_cfg_t`). |
| iOS / iPadOS | iPhone 12+, iPad 10+ (iOS 26+) | PIN-code Pairing only (WPA3-level) | Use `WA_SEC_PIN_PAIRING` with `WA_BOOTSTRAP_PINCODE`. |

### Platform API references

- Apple —
    - Overview & API reference: <https://developer.apple.com/documentation/wifiaware>
- Android —
    - Overview: <https://source.android.com/docs/core/connect/wifi-aware>
    - API reference: <https://developer.android.com/develop/connectivity/wifi/wifi-aware>

## Architecture Overview

For ease of use and compatibility with Mobile platforms, Espressif's Wi-Fi Aware component implements [RFC 6763](https://www.rfc-editor.org/rfc/rfc6763)
style discovery mechanism and service naming conventions.
A DNS-SD service instance name has the form:

```
<Instance>._<Service>._<Protocol>.<Domain>
```

- **Instance** (`<Instance>`): a user-friendly, human-readable label, up to 63 bytes, unique within the
  service type. Spaces and punctuation are allowed (e.g. `"Office Printer"`).
- **Service** (`<Service>`): the registered service name from the
  [IANA Service Name registry](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml),
  without the leading underscore (e.g. `ipp`, `printer`, `http`). The stack prepends the underscore.
- **Protocol** (`_tcp` or `_udp`): the transport, selected via `wa_proto_t` (`WA_PROTO_TCP` / `WA_PROTO_UDP`).
- **Domain**: typically `local.` for link-local discovery.

For example, an IPP printer advertised on the local network is:

```
Office Printer._ipp._tcp.local.
```

In this component you configure Advertiser with **instance** (`instance_name`), the **service** (`service_type`, no
leading underscore), and the **protocol** (`proto`). The Discoverer that is configured to seek the **service** and
the **protocol** (`proto`) will find the Advertiser and establish a connection if their security requirements match.
Using IANA registered **service** is recommended to stay interoperable with third-party clients.

## Protocol Flow

The diagram below shows the API-level interaction between a server and a client using the
`wifi_aware` API. The server advertises a service; the client discovers it, optionally runs
PIN-code bootstrap + pairing, then brings up the NAN datapath and resolves the peer's IPv6 endpoint.
Security is optional — pass `NULL` for an open datapath, or a `wa_dp_security_cfg_t` for passphrase or
PIN-pairing mode.

```mermaid
sequenceDiagram
    autonumber
    participant P as Server
    participant S as Client

    P->>P: esp_wifi_init
    P->>P: wifi_aware_init
    P->>P: wifi_aware_service_advertise

    S->>S: esp_wifi_init
    S->>S: wifi_aware_init
    S->>P: wifi_aware_service_discover
    P-->>S: discovery callback: wa_matched_peer_t

    alt Pairing for mode WA_SEC_PIN_PAIRING (Optional)
        S->>P: wifi_aware_bootstrap_request(method = PIN Code)
        P->>S: wifi_aware_bootstrap_response(method = PIN Code)
        S->>P: wifi_aware_pairing_start(PIN obtained OOB)
    end

    S->>P: wifi_aware_request_connection(device_name, &addr, &port)

    alt Secured datapath for modes WA_SEC_PWD & WA_SEC_PIN_PAIRING (Optional)
        S->>P: Secured handshake
        P-->>S: Secured handshake
    end

    P-->>S: IPv6 link-local address + port
    Note over S,P: NAN datapath established
```

## How to Use

### As an ESP-IDF Component

Add the component dependency to your project's `main/idf_component.yml`:

```yaml
dependencies:
  espressif/wifi_aware:
    version: "^0.0.1"
```

Or clone this repository and add the `components` directory to your `EXTRA_COMPONENT_DIRS`.

## API Usage

### Server (Advertising) — e.g. an IPP printer

```c
#include "wifi_aware.h"

// Initialize Wi-Fi Aware
wa_init_config_t config = { .trigger = WA_TRIGGER_NONE, .hostname = "ESP-HOST-123" };
wifi_aware_init(&config);

// Advertise this device as an IPP printer (RFC 6763: "_ipp._tcp").
// service_type uses the IANA-registered name without the leading underscore;
// the stack prepends it.
wa_service_cfg_t svc = {
    .instance_name   = "Office Printer",   // up to 63 chars, unique per service type
    .service_type    = "ipp",              // IANA service name -> "_ipp._tcp"
    .service_subtype = NULL,               // optional DNS-SD subtype; NULL if unused
    .proto           = WA_PROTO_TCP,
};
wifi_aware_service_advertise(&svc, 631, NULL, 0);  // IPP port 631, no security, no timeout
```

### Client (Discovery)

```c
#include "esp_wifi.h"
#include "wifi_aware.h"

void discovery_callback(wa_matched_peer_t *records) {
    // Handle discovered services
}

// Wi-Fi is owned by the application: initialize it before wifi_aware_init()
wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_cfg);

// Initialize Wi-Fi Aware
wa_init_config_t config = { .trigger = WA_TRIGGER_NONE};
wifi_aware_init(&config);

// Discover IPP printers on the local network
wa_service_info_t desc = { .service_type = "ipp", .proto = WA_PROTO_TCP };
wa_match_cfg_t match = {
    .timeout            = 10,   // seconds
    .callback           = discovery_callback,
    .stop_on_first_match = true,
};
wifi_aware_service_discover(&desc, NULL, &match);

// Resolve a discovered printer and connect to its IPP endpoint
ip6_addr_t addr;
uint16_t   port;
wifi_aware_request_connection("Office Printer", &addr, &port);
```

## Requirements

- ESP-IDF `>=5.2`
- Wi-Fi NAN enabled (`CONFIG_ESP_WIFI_NAN_ENABLE=y`, `CONFIG_ESP_WIFI_NAN_SYNC_ENABLE=y`)
- NAN security/pairing enabled for secured datapath (`CONFIG_ESP_WIFI_NAN_SECURITY=y`,
  `CONFIG_ESP_WIFI_NAN_PAIRING=y`)
- IPv6 enabled (`CONFIG_LWIP_IPV6=y`)

Links

Supports all targets

To add this component to your project, run:

idf.py add-dependency "espressif/wifi_aware^0.0.1"

download archive

Stats

  • Archive size
    Archive size ~ 62.63 KB
  • Downloaded in total
    Downloaded in total 1 time
  • Weekly Downloads Weekly Downloads (All Versions)
  • Downloaded this version
    This version: 1 time

Badge

espressif/wifi_aware version: 0.0.1
|