Network Provisioner

[中文]

network_provisioner is a controller-side client for espressif/network_provisioning.

Component

Role

network_provisioning

Device (server): receives Wi-Fi / Thread credentials

protocomm_ext

Controller pipe (transport + Security 0 / 1 / 2)

network_provisioner

Controller business (prov-config / prov-scan / prov-ctrl)

It encodes and decodes the provisioning protobufs. Session transport and security handshake stay in protocomm_ext.

Features

  • SoftAP + HTTP: Wi-Fi provisioning

  • BLE (NimBLE Central): Wi-Fi and Thread provisioning

  • UART Console: debug path

  • Runtime capability parsing from proto-ver (prov.cap / prov.sec_ver)

  • High-level network_provisioner_provision_wifi() / provision_thread()

Supported targets: ESP32 / ESP32-S3 / ESP32-C2 / ESP32-C3 / ESP32-C5 / ESP32-C6 / ESP32-C61 / ESP32-H2 / ESP32-P4

Typical Flow

#include "network_provisioner.h"
#include "protocomm_ext.h"

protocomm_ext_t *pc = protocomm_ext_new(&pe_cfg);
network_provisioner_t *np = network_provisioner_create(pc);

network_provisioner_fetch_capabilities(np, /* BLE: connect cfg, else NULL */ NULL);
network_provisioner_capabilities_t caps = {0};
network_provisioner_get_capabilities(np, &caps);
network_provisioner_security_t sec = {
    .sec_ver = caps.sec_ver,
    .pop = "abcd1234",
};
network_provisioner_set_security(np, &sec);
network_provisioner_establish_security(np);

network_provisioner_wifi_creds_t creds = {
    .ssid = (const uint8_t *)"myssid",
    .ssid_len = 6,
    .passphrase = (const uint8_t *)"mypass",
    .passphrase_len = 6,
};
network_provisioner_provision_wifi(np, &creds, NULL);

network_provisioner_stop_session(np);
network_provisioner_delete(np);
protocomm_ext_delete(pc);

If the peer scheme is already known, network_provisioner_start_session() still covers open → proto-ver → handshake in one call.

A BLE controller can call network_provisioner_create_ble(), then use network_provisioner_ble_scan() and network_provisioner_ble_connect_cfg(). Application endpoints use network_provisioner_add_endpoint() and network_provisioner_send().

Thread safety: APIs on one instance are not thread-safe; serialize from a single task.

Add Dependency

dependencies:
  espressif/network_provisioner: "^2.0.0"

Example

See examples/network_provisioner. Pair with the official device examples wifi_prov / thread_prov from network_provisioning.

API Reference

Header File

Functions

network_provisioner_t *network_provisioner_create(protocomm_ext_t *pc)

Wrap an existing protocomm_ext instance (session may not be open yet)

Ownership of pc remains with the caller. Call network_provisioner_delete() before protocomm_ext_delete(). For a transport this component creates, use network_provisioner_create_ble() instead.

Registers BLE endpoint UUID mappings (NETWORK_PROVISIONER_EP_*_UUID) via protocomm_ext_set_config_endpoint() (no-op for HTTP / Console).

Note

APIs on a given instance are not thread-safe. Use one task, or serialize externally. Do not call network_provisioner_delete() or network_provisioner_stop_session() while another call is in progress.

void network_provisioner_delete(network_provisioner_t *np)

Free a network_provisioner instance.

Does not delete a protocomm_ext passed to network_provisioner_create(). Does delete the transport from network_provisioner_create_ble(), then waits for the NimBLE host task to exit.

esp_err_t network_provisioner_start_session(network_provisioner_t *np, const void *transport_connect_cfg)

open_session → get_version(proto-ver) → establish_security(prov-session)

Requires the protocomm_ext instance to already use the peer’s security scheme (Sec0/1/2) and credentials.

For runtime discovery from proto-ver (recommended):

  1. network_provisioner_fetch_capabilities()

  2. network_provisioner_set_security() with peer sec_ver / PoP or Sec2 creds

  3. network_provisioner_establish_security()

Parameters
  • np – Network provisioner instance

  • transport_connect_cfg – HTTP: NULL; BLE: ble_addr_t *; Console: NULL

esp_err_t network_provisioner_fetch_capabilities(network_provisioner_t *np, const void *transport_connect_cfg)

open_session + read proto-ver (plaintext); does not run the security handshake

Stores capabilities for network_provisioner_get_capabilities().

esp_err_t network_provisioner_establish_security(network_provisioner_t *np)

security_init + establish_security after credentials are configured

esp_err_t network_provisioner_stop_session(network_provisioner_t *np)

Close the transport session.

esp_err_t network_provisioner_get_capabilities(network_provisioner_t *np, network_provisioner_capabilities_t *caps)

Copy capabilities stored by fetch_capabilities()

esp_err_t network_provisioner_wifi_set_config(network_provisioner_t *np, const uint8_t *ssid, size_t ssid_len, const uint8_t *passphrase, size_t passphrase_len, const uint8_t *bssid, int32_t channel)

Send Wi-Fi SetConfig on prov-config

esp_err_t network_provisioner_wifi_apply_config(network_provisioner_t *np)

Send Wi-Fi ApplyConfig on prov-config

esp_err_t network_provisioner_wifi_get_status(network_provisioner_t *np, network_provisioner_wifi_status_t *status)

Query Wi-Fi STA status from the peer.

esp_err_t network_provisioner_thread_set_config(network_provisioner_t *np, const uint8_t *dataset, size_t dataset_len)

Send Thread SetConfig (Active Operational Dataset)

esp_err_t network_provisioner_thread_apply_config(network_provisioner_t *np)

Send Thread ApplyConfig.

esp_err_t network_provisioner_thread_get_status(network_provisioner_t *np, network_provisioner_thread_status_t *status)

Query Thread attach status from the peer.

esp_err_t network_provisioner_wifi_scan_start(network_provisioner_t *np, bool blocking, bool passive, uint32_t group_channels, uint32_t period_ms)

Start a Wi-Fi scan on the peer.

esp_err_t network_provisioner_wifi_scan_status(network_provisioner_t *np, bool *finished, uint32_t *result_count)

Query whether the peer Wi-Fi scan has finished.

esp_err_t network_provisioner_wifi_scan_result(network_provisioner_t *np, uint32_t start_index, uint32_t count, network_provisioner_wifi_ap_t *out, uint32_t *out_count)

Fetch Wi-Fi scan results from the peer.

esp_err_t network_provisioner_thread_scan_start(network_provisioner_t *np, bool blocking, uint32_t channel_mask)

Start a Thread scan on the peer.

esp_err_t network_provisioner_thread_scan_status(network_provisioner_t *np, bool *finished, uint32_t *result_count)

Query whether the peer Thread scan has finished.

esp_err_t network_provisioner_thread_scan_result(network_provisioner_t *np, uint32_t start_index, uint32_t count, network_provisioner_thread_network_t *out, uint32_t *out_count)

Fetch Thread scan results from the peer.

esp_err_t network_provisioner_wifi_reset(network_provisioner_t *np)

Reset Wi-Fi provisioning state on the peer.

esp_err_t network_provisioner_wifi_reprov(network_provisioner_t *np)

Re-enable Wi-Fi provisioning on the peer.

esp_err_t network_provisioner_thread_reset(network_provisioner_t *np)

Reset Thread provisioning state on the peer.

esp_err_t network_provisioner_thread_reprov(network_provisioner_t *np)

Re-enable Thread provisioning on the peer.

esp_err_t network_provisioner_provision_wifi(network_provisioner_t *np, const network_provisioner_wifi_creds_t *creds, network_provisioner_wifi_status_t *out_status)

Set + Apply + poll until Connected or fail/timeout.

esp_err_t network_provisioner_provision_thread(network_provisioner_t *np, const network_provisioner_thread_creds_t *creds, network_provisioner_thread_status_t *out_status)

Set + Apply Thread dataset and poll until attached or fail/timeout.

protocomm_ext_t *network_provisioner_get_protocomm(network_provisioner_t *np)

Return the wrapped protocomm_ext instance.

The caller owns it only when the instance came from network_provisioner_create(). network_provisioner_create_ble() owns the transport; network_provisioner_delete() releases it.

network_provisioner_t *network_provisioner_create_ble(void)

Create a BLE (NimBLE central) transport and wrap it.

Starts the NimBLE central transport with whichever security version is enabled (Sec0, otherwise Sec1, otherwise a Sec2 placeholder). Call network_provisioner_set_security() with the peer scheme before the handshake. network_provisioner_delete() also deletes this transport and waits for the NimBLE host task to exit.

Returns

Instance, or NULL on allocation / transport failure

esp_err_t network_provisioner_set_security(network_provisioner_t *np, const network_provisioner_security_t *sec)

Apply Sec0 / Sec1 / Sec2 before network_provisioner_establish_security()

Sec1 with no_pop, or an empty PoP, uses Security 1 with no PoP. Sec2 requires a non-empty username. pop / username longer than 64 bytes are rejected.

esp_err_t network_provisioner_add_endpoint(network_provisioner_t *np, const char *name, uint16_t uuid)

Register one extra logical endpoint (BLE characteristic UUID16)

Built-in prov-* endpoints are registered by network_provisioner_create(). Use this for application endpoints after the standard 0xFF4F..0xFF53 range. HTTP / Console ignore uuid and return ESP_OK.

esp_err_t network_provisioner_send(network_provisioner_t *np, const char *ep_name, const uint8_t *req, size_t req_len, uint8_t **resp, size_t *resp_len)

Send one application payload on a named endpoint.

Pipe only: the caller encodes and decodes the protobuf. Requires an established session. Caller frees *resp on success.

esp_err_t network_provisioner_get_version(network_provisioner_t *np, const char **version_json)

proto-ver JSON stored by fetch_capabilities() / start_session()

*version_json points at internal storage. It stays valid until the next fetch/start on this instance, or network_provisioner_delete().

esp_err_t network_provisioner_ble_scan(network_provisioner_t *np, uint32_t timeout_ms, const char *name, bool name_exact, const uint8_t *addr, network_provisioner_ble_device_t *out, size_t capacity, size_t *out_count)

Active-scan nearby BLE peripherals.

Waits until the NimBLE host is synced. Does not connect. The instance must use a BLE transport (network_provisioner_create_ble() or network_provisioner_create() on a BLE protocomm_ext). HTTP and Console return ESP_ERR_NOT_SUPPORTED. name NULL or empty matches every advertised name; otherwise it is a prefix, or an exact name when name_exact is true. Matching uses the full advertised name. The name copied into the result is truncated and NUL-terminated. addr is 6 bytes, MSB first, or NULL to ignore the address. Only matches are stored. Devices beyond capacity are dropped. out_count is the number written. Returns ESP_ERR_NOT_SUPPORTED when NimBLE is disabled.

esp_err_t network_provisioner_ble_connect_cfg(const uint8_t addr[6], uint8_t addr_type, void *out, size_t out_size)

Pack a scan-result address into the blob fetch_capabilities() expects.

out must be at least NETWORK_PROVISIONER_BLE_CONNECT_CFG_MAX bytes. Pass it as transport_connect_cfg. addr[] is MSB first.

esp_err_t network_provisioner_ble_has_char(network_provisioner_t *np, const uint8_t svc_uuid128[16], uint16_t chr_uuid16)

True when the connected peer exposes this 16-bit characteristic.

Requires a BLE transport, same as network_provisioner_ble_scan(). Other transports return ESP_ERR_NOT_SUPPORTED.

svc_uuid128 is the 128-bit service UUID in NimBLE byte order (LSB at [0]). The characteristic UUID is that same base with bytes 12–13 replaced by chr_uuid16 (little-endian), which is how network_provisioning embeds UUID16.

Structures

struct network_provisioner_capabilities_t

Capabilities parsed from the peer proto-ver JSON.

Public Members

bool wifi_prov

Peer supports Wi-Fi provisioning

bool wifi_scan

Peer supports Wi-Fi scan

bool thread_prov

Peer supports Thread provisioning

bool thread_scan

Peer supports Thread scan

bool no_sec

Peer advertises no-security (Sec0)

bool no_pop

Peer does not require Proof-of-Possession

int sec_ver

Security scheme from proto-ver JSON (prov.sec_ver, 0 / 1 / 2). Required when a prov object is present; bare version strings fall back to 1.

struct network_provisioner_wifi_status_t

Wi-Fi STA status reported by the peer.

Public Members

network_provisioner_wifi_state_t state

Connection state

network_provisioner_wifi_fail_reason_t fail_reason

Failure reason when disconnected/failed

char ip4_addr[16]

IPv4 address string, or empty

char ssid[33]

Connected SSID

int32_t channel

Channel, or 0 if unknown

struct network_provisioner_thread_status_t

Thread network status reported by the peer.

Public Members

network_provisioner_thread_state_t state

Attach state

network_provisioner_thread_fail_reason_t fail_reason

Failure reason when attach failed

uint32_t pan_id

PAN ID

uint32_t channel

Channel

char name[33]

Network name

struct network_provisioner_wifi_ap_t

One Wi-Fi AP entry from a peer scan.

Public Members

uint8_t ssid[33]

SSID bytes

uint8_t ssid_len

SSID length

uint8_t bssid[6]

BSSID

uint32_t channel

Channel

int32_t rssi

RSSI in dBm

int auth_mode

Wi-Fi auth mode (wifi_auth_mode_t)

struct network_provisioner_thread_network_t

One Thread network entry from a peer scan.

Public Members

uint32_t pan_id

PAN ID

uint32_t channel

Channel

int32_t rssi

RSSI in dBm

uint32_t lqi

Link quality indicator

char network_name[33]

Network name

uint8_t ext_pan_id[8]

Extended PAN ID

uint8_t ext_addr[8]

Extended address

struct network_provisioner_wifi_creds_t

Wi-Fi credentials for network_provisioner_provision_wifi()

Public Members

const uint8_t *ssid

SSID bytes

size_t ssid_len

SSID length

const uint8_t *passphrase

Passphrase bytes; may be NULL for open AP

size_t passphrase_len

Passphrase length

const uint8_t *bssid

Optional BSSID, 6 bytes or NULL

int32_t channel

0 = any channel

uint32_t poll_timeout_ms

Status poll timeout; 0 uses the default

uint32_t poll_interval_ms

Status poll interval; 0 uses the default

struct network_provisioner_thread_creds_t

Thread credentials for network_provisioner_provision_thread()

Public Members

const uint8_t *dataset

Active Operational Dataset bytes

size_t dataset_len

Dataset length

uint32_t poll_timeout_ms

Status poll timeout; 0 uses the default

uint32_t poll_interval_ms

Status poll interval; 0 uses the default

struct network_provisioner_security_t

Credentials for network_provisioner_set_security()

Strings are copied during the call and need not outlive it.

Public Members

int sec_ver

0, 1, or 2 (from capabilities.sec_ver)

bool no_pop

Sec1: peer advertises no Proof-of-Possession

const char *pop

Sec1 PoP, or Sec2 password. NULL / empty Sec1 PoP is allowed

const char *username

Sec2 username. Ignored for Sec0 / Sec1

struct network_provisioner_ble_device_t

One controller-side BLE scan result.

Public Members

uint8_t addr[6]

Peer address, MSB first, the same order as “AA:BB:CC:DD:EE:FF”

uint8_t addr_type

NimBLE address type. NETWORK_PROVISIONER_BLE_ADDR_PUBLIC is 0

char name[NETWORK_PROVISIONER_BLE_NAME_MAX]

Advertised Local Name, NUL-terminated. Longer names are truncated

uint8_t mfg_data[NETWORK_PROVISIONER_BLE_MFG_MAX]

Manufacturer data. Longer payloads are truncated

uint8_t mfg_data_len

Number of valid bytes in mfg_data

Macros

NETWORK_PROVISIONER_EP_PROTO_VER

Endpoint names matching espressif/network_provisioning (device side).

NETWORK_PROVISIONER_EP_SESSION
NETWORK_PROVISIONER_EP_CONFIG
NETWORK_PROVISIONER_EP_SCAN
NETWORK_PROVISIONER_EP_CTRL
NETWORK_PROVISIONER_EP_CTRL_UUID

BLE characteristic UUID16 values used by network_provisioning / wifi_provisioning (see wifi_prov manager set_config_endpoint). Register via protocomm_ext_set_config_endpoint() before BLE sessions.

NETWORK_PROVISIONER_EP_SCAN_UUID
NETWORK_PROVISIONER_EP_SESSION_UUID
NETWORK_PROVISIONER_EP_CONFIG_UUID
NETWORK_PROVISIONER_EP_PROTO_VER_UUID
NETWORK_PROVISIONER_MAX_SCAN_RESULTS

Upper bound on Wi-Fi / Thread scan result entries accepted from a peer (request count and reported result_count).

NETWORK_PROVISIONER_BLE_NAME_MAX

Advertised name copied into network_provisioner_ble_device_t::name, including NUL.

NETWORK_PROVISIONER_BLE_MFG_MAX

Manufacturer data copied into one scan result. Longer payloads are truncated.

NETWORK_PROVISIONER_BLE_CONNECT_CFG_MAX

Bytes required by network_provisioner_ble_connect_cfg().

NETWORK_PROVISIONER_BLE_ADDR_PUBLIC

Address type for a public BLE address (NimBLE BLE_ADDR_PUBLIC).

Type Definitions

typedef struct network_provisioner network_provisioner_t

Opaque network provisioner instance returned by network_provisioner_create()

Enumerations

enum network_provisioner_wifi_state_t

Values:

enumerator NETWORK_PROVISIONER_WIFI_STATE_CONNECTED

STA connected

enumerator NETWORK_PROVISIONER_WIFI_STATE_CONNECTING

STA connecting

enumerator NETWORK_PROVISIONER_WIFI_STATE_DISCONNECTED

STA disconnected

enumerator NETWORK_PROVISIONER_WIFI_STATE_CONNECTION_FAILED

STA connection failed

enum network_provisioner_wifi_fail_reason_t

Values:

enumerator NETWORK_PROVISIONER_WIFI_FAIL_AUTH_ERROR

Authentication failed

enumerator NETWORK_PROVISIONER_WIFI_FAIL_NETWORK_NOT_FOUND

AP not found

enumerator NETWORK_PROVISIONER_WIFI_FAIL_UNKNOWN

Unspecified failure

enum network_provisioner_thread_state_t

Values:

enumerator NETWORK_PROVISIONER_THREAD_STATE_ATTACHED

Attached to Thread network

enumerator NETWORK_PROVISIONER_THREAD_STATE_ATTACHING

Attaching

enumerator NETWORK_PROVISIONER_THREAD_STATE_DETACHED

Detached

enumerator NETWORK_PROVISIONER_THREAD_STATE_ATTACHING_FAILED

Attach failed

enum network_provisioner_thread_fail_reason_t

Values:

enumerator NETWORK_PROVISIONER_THREAD_FAIL_DATASET_INVALID

Dataset invalid

enumerator NETWORK_PROVISIONER_THREAD_FAIL_NETWORK_NOT_FOUND

Network not found

enumerator NETWORK_PROVISIONER_THREAD_FAIL_UNKNOWN

Unspecified failure