ESP-IDF 中的 Wi-Fi Aware™ (NAN) 协议:邻近感知组网与设备间服务发现实战指南 ESP-IDF 中的 Wi-Fi Aware™ (NAN) 协议邻近感知组网与设备间服务发现实战指南【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idfWi-Fi Aware™又称 NANNeighbor Awareness Networking邻居感知组网是一种让 Wi-Fi 设备在彼此邻近时直接发现服务的无线协议。本文以 ESP-IDF 官方文档 esp_nan.rst 为核心骨架结合仓库中的 NAN 应用源码、类型定义、Kconfig 配置与五个官方示例系统讲解 NAN 集群、Publish/Subscribe 服务发现、Follow-up 消息、NDP 数据通道Datapath以及轻量级 NAN-USD 模式的完整技术栈。读完本文你将掌握在 ESP32 系列芯片上从零搭建无 Internet、无 AP、无 GPS的近场服务发现与设备直连通信方案并理解其背后的 API 调用链与事件模型。一、什么是 Wi-Fi Aware (NAN)根据官方文档传统的基于位置的服务LBS通常依赖 GPS 或其他定位技术并向服务器查询周边环境信息而NAN 不要求实时连接服务器、GPS 或其他地理位置服务它直接使用设备到设备device-to-device的 Wi-Fi 来完成信息发现与交换。NAN 在密集 Wi-Fi 环境中依然能够高效扩展并通过提供邻近人员与服务的信息来补充传统 Wi-Fi 连接的能力。NAN 协议的核心工作模式如下NAN Cluster位于同一邻近区域的多个 NAN 设备会自动组成一个 NAN 集群cluster集群内的设备可以互相通信。集群依靠定期的同步帧Discovery Beacon / Synchronization Beacon维持时间同步设备在称为 Discovery WindowDW的时隙内交换服务发现帧。Publish / Subscribe集群内设备可以通过Publish发布方式通告自己的服务或通过Subscribe订阅方式查找服务这一过程由 NAN Service Discovery 协议完成。服务匹配服务匹配依据服务名service name进行并可附加匹配过滤器matching filter进一步精确匹配。匹配后的通信一旦匹配成功设备可以选择向对端发送 Follow-up 消息或通过 NDPNAN Datapath协商建立 IPv6 数据通道之后双方各自获得 IPv6 地址即可进行后续通信。在 ESP-IDF 中Wi-Fi Aware 以standalone独立模式提供支持同时覆盖 Service Discovery服务发现与 Datapath数据通道两大能力。需要说明的是Wi-Fi Aware 仍是演进中的协议其行为细节以 Wi-Fi Alliance 规范为准Android 8 及以上版本的多数智能手机支持 Wi-Fi Aware可与其进行互操作测试。二、两种发现模式NAN-Sync 集群发现与 NAN-USD 非同步发现ESP-IDF 的 NAN 实现实际包含两套可独立启用的引擎均通过 menuconfig 开关控制见 components/esp_wifi/KconfigKconfig 选项说明依赖ESP_WIFI_NAN_SYNC_ENABLE启用 Wi-Fi Aware 同步发现NAN-Sync即标准集群模式会自动选中LWIP_IPV6以支持数据通道的 IPv6 寻址SOC_WIFI_NAN_SUPPORTESP_WIFI_NAN_SECURITY启用加密成对数据通道NDP Security引入 PBKDF2 密钥派生、M1–M4 四次握手、PTK 派生与 CCMP 密钥安装ESP_WIFI_NAN_SYNC_ENABLEIDF_EXPERIMENTAL_FEATURESESP_WIFI_MBEDTLS_CRYPTOESP_WIFI_NAN_USD_ENABLE启用 NAN 非同步服务发现NAN-USD无需组建集群开销更轻IDF_EXPERIMENTAL_FEATURESESP_WIFI_NAN_PAIRING启用 NAN Pairing支持基于 PIN 等引导方式的配对需 PASN 支持ESP_WIFI_NAN_SECURITY两种模式的区别从 esp_nan.h 的 API 注释中可以清晰读出NAN-Sync集群模式调用esp_wifi_nan_sync_start()启动同步发现设备会扫描/加入/创建 NAN 集群随后通过esp_wifi_nan_publish_service()/esp_wifi_nan_subscribe_service()进行服务发现。NAN-USD非同步模式调用esp_wifi_nan_usd_start()启动不形成 NAN 集群以更轻量的方式广播/侦听服务目前 USD 运行在 Station 接口之上官方注释明确说明该设计在后续版本中可能变化。USD 的 Publish 与 Subscribe 默认配置分别通过esp_wifi_usd_get_default_publish_cfg()与esp_wifi_usd_get_default_subscribe_cfg()获取默认工作信道为 2.4 GHz 的 6 号信道2.437 GHzdwell 周期按 Wi-Fi Aware 规范取 Nmin5、Nmax10、Mmin5、Mmax10。同一份 publish/subscribe 调用在两种模式下自动路由当 USD 发现激活时请求由 USD 引擎处理否则走 NAN 同步路径见 esp_nan.h 中esp_wifi_nan_publish_service()的 attention 注释。另外同一时刻最多同时支持 2 个服务例如一个 publish 加一个 subscribe或两个 publish/subscribe该上限由ESP_WIFI_NAN_MAX_SVC_SUPPORTED定义值为 2见 esp_wifi_types_generic.h。三、核心 API从启动到数据通道的完整调用链NAN 应用编程接口集中在 components/esp_wifi/wifi_apps/nan_app/include/esp_nan.h按功能可分为四组3.1 同步发现NAN-Sync生命周期esp_err_t esp_wifi_nan_sync_start(const wifi_nan_sync_config_t *nan_cfg); esp_err_t esp_wifi_nan_sync_stop(void);esp_wifi_nan_sync_start()使用给定参数启动 NAN 同步。注意必须在esp_wifi_init()之后调用且 Discovery 流量只有在启动 publish/subscribe 服务后才会产生。esp_wifi_nan_sync_stop()停止同步发现同时结束所有 publish/subscribe 服务官方注释特别强调该调用会一并终止所有正在进行的 NAN 数据通道。3.2 服务发布、订阅与消息uint8_t esp_wifi_nan_publish_service(const wifi_nan_publish_cfg_t *publish_cfg); uint8_t esp_wifi_nan_subscribe_service(const wifi_nan_subscribe_cfg_t *subscribe_cfg); esp_err_t esp_wifi_nan_send_message(wifi_nan_followup_params_t *fup_params); esp_err_t esp_wifi_nan_cancel_service(uint8_t service_id);publish/subscribe 返回非零值表示服务实例 IDservice id返回 0 表示失败。后续的 Follow-up 发送、NDP 发起、服务取消都要以该 ID 为参数。esp_wifi_nan_send_message()在服务匹配成功后向对端发送 Follow-up 消息。esp_wifi_nan_cancel_service()按服务 ID 取消已发布的 Publish/Subscribe 服务。3.3 NAN 数据通道NDP / Datapathuint8_t esp_wifi_nan_datapath_req(wifi_nan_datapath_req_t *req); esp_err_t esp_wifi_nan_datapath_resp(wifi_nan_datapath_resp_t *resp); esp_err_t esp_wifi_nan_datapath_end(wifi_nan_datapath_end_req_t *req); void esp_wifi_nan_get_ipv6_linklocal_from_mac(ip6_addr_t *ip6, uint8_t *mac_addr);esp_wifi_nan_datapath_req()由 Subscriber 在匹配成功后调用向匹配到的 Publisher 发起 NDP 请求。返回非零 NDP ID 表示请求被接受返回 0 表示被拒绝或超时。esp_wifi_nan_datapath_resp()当 publish 配置中ndp_resp_needed 1且收到WIFI_EVENT_NDP_INDICATION事件时调用用于显式接受/拒绝入站 NDP 请求若ndp_resp_needed 0则为自动接受。esp_wifi_nan_datapath_end()终止已建立的 NDP。esp_wifi_nan_get_ipv6_linklocal_from_mac()由对端 MAC 推导其 IPv6 链路本地地址——NAN 数据通道建立后双方获得的正是基于 MAC 生成的链路本地 IPv6 地址。3.4 信息查询与 USD 辅助esp_err_t esp_wifi_nan_get_own_svc_info(uint8_t *own_svc_id, char *svc_name, int *num_peer_records); esp_err_t esp_wifi_nan_get_peer_records(int *num_peer_records, uint8_t own_svc_id, struct nan_peer_record *peer_record); esp_err_t esp_wifi_nan_get_peer_info(char *svc_name, uint8_t *peer_mac, struct nan_peer_record *peer_info); esp_err_t esp_wifi_nan_usd_start(void); esp_err_t esp_wifi_nan_usd_stop(void);其中esp_wifi_nan_get_own_svc_info()支持按服务 ID 查名字、或按名字查 ID按名字查询时将own_svc_id置 0struct nan_peer_record描述了单个对端服务记录包含对端服务 ID、本端关联服务 ID、对端 NMINAN 管理接口地址、对端服务类型以及 NDP 状态等信息定义见 esp_nan.hNAN_MAX_PEERS_RECORD为 15。3.5 事件模型NAN 的运行是事件驱动的所有状态变化通过 Wi-Fi 事件上报事件定义见 esp_wifi_types_generic.h事件含义WIFI_EVENT_NAN_SYNC_STARTED/WIFI_EVENT_NAN_SYNC_STOPPED同步发现启动/停止WIFI_EVENT_NAN_CLUSTER_JOIN加入、创建或合并进入 NAN 集群WIFI_EVENT_NAN_SVC_MATCH服务发现匹配成功WIFI_EVENT_NAN_REPLIED已回复对端的服务发现匹配WIFI_EVENT_NAN_RECEIVE收到 Follow-up 消息WIFI_EVENT_NDP_INDICATION收到对端 NDP 请求WIFI_EVENT_NDP_CONFIRMNDP 建立确认WIFI_EVENT_NDP_TERMINATED数据通道终止WIFI_EVENT_NAN_PAIRING_INDICATION/WIFI_EVENT_NAN_PAIRING_CONFIRMNAN 配对指示/完成四、配置结构体深度解析所有 NAN 配置结构体均定义于 components/esp_wifi/include/esp_wifi_types_generic.h本节逐字段说明其作用与取值。4.1wifi_nan_sync_config_t同步启动参数定义于 esp_wifi_types_generic.h#L606-L615默认值由WIFI_NAN_SYNC_CONFIG_DEFAULT()宏提供op_channel 6、master_pref 2、scan_time 3、warm_up_sec 5字段类型说明op_channeluint8_tNAN 发现工作信道master_prefuint8_t设备作为 NAN Master 的偏好值scan_timeuint8_t搜寻 NAN 集群的扫描时间秒warm_up_secuint16_t担任 Anchor Master 角色前的预热时间disable_random_macbool是否禁用 NAN 中的 MAC 随机化reset_current_nvs_credsbool启动前擦除 NVS 中保存的本端 NIK 与缓存的对端 NIK/NPK 凭据use_nvs_for_cachingbool将新学到的对端凭据持久化到 NVS使其跨重启保留group_mgmt_protbool设备级组管理保护对 Beacon 与组播 SDF 施加 BIP 保护会强制所有安全服务开启 GTKSACSIA 能力无法在没有 GTKSA 的情况下编码 IGTK/BIGTK该结构体同时也是wifi_config_t联合体的成员之一wifi_config_t.nan说明 NAN 配置通过esp_wifi_set_config()的标准路径下发。4.2wifi_nan_publish_cfg_t/wifi_nan_subscribe_cfg_t服务配置两者结构几乎对称见 esp_wifi_types_generic.h#L1047-L1096关键字段如下字段说明service_name服务名最大长度ESP_WIFI_MAX_SVC_NAME_LEN256 字节匹配时大小写不敏感type服务类型取值wifi_nan_service_type_t见 L926matching_filter逗号分隔的匹配过滤器最大ESP_WIFI_MAX_FILTER_LEN256 字节过滤器匹配大小写敏感single_replied_event/single_match_eventPublish 侧只上报一次 Replied 事件还是每次Subscribe 侧单次 Match 事件按 SSI 更新还是每次都上报datapath_reqd该服务是否需要 NAN 数据通道fsd_reqd/fsd_gas是否需要进一步服务发现FSD以及 FSD 使用 Follow-up0还是 GAS1ndp_resp_needed仅 Publish0 自动接受 NDP 请求1 需调用esp_wifi_nan_datapath_resp()显式响应usd_discovery_flag0 使用 NAN 同步发现1 使用 USD 发现对应规范中的 NAN Discovery flagsecurity_reqd0 开放Open1 需要加密NDP Securityssi_len/ssi服务特定信息Service Specific Info最大ESP_WIFI_MAX_SVC_SSI_LEN512 字节WFA 定义协议使用wifi_nan_wfa_ssi_t类型其余为应用自定义ttl服务运行时长秒在 USD 模式下若 ttl0Publish 只发送一条消息Subscribe 则侦听至首次匹配上报usd_publish_config/usd_subscribe_configUSD 配置wifi_nan_usd_config_t仅当usd_discovery_flag置位时有效security_cfg安全配置security_reqd置位时使用驱动会在调用期间私有复制调用返回后调用方即可释放vendor_ie附加到 Publish/Subscribe 帧中的厂商自定义 IEpairingNAN 配对配置参数需启用ESP_WIFI_NAN_PAIRING4.3wifi_nan_followup_params_t与 NDP 请求/响应wifi_nan_followup_params_tL1102-L1109包含本端服务实例 IDinst_id、对端服务实例 IDpeer_inst_id、对端 MACpeer_mac、消息内容ssi/ssi_len上限ESP_WIFI_MAX_FUP_SSI_LEN以及可选的vendor_ie。wifi_nan_datapath_req_tL1126-L1130包含pub_idPublisher 的服务实例 ID、peer_mac、confirm_required安全 NDP 握手始终需要 NDP Confirm 帧。头文件注释明确指出数据通道安全完全由 subscribe 时传入的security_cfg决定NAN 库内部自动派生 ND-PMK、ND-PMKID 并选择密码套件调用方不会接触原始密钥材料。wifi_nan_datapath_resp_tL1150-L1156accept为 true 接受 / false 拒绝入站 NDP另含ndp_id、peer_mac与可选的ssi。五、官方示例五种玩法逐个数ESP-IDF 在 examples/wifi/wifi_aware/ 目录下提供了 5 个官方示例与文档一一对应5.1 nan_console交互式控制台全流程演示examples/wifi/wifi_aware/nan_console 将 NAN 的全部能力做成 console 命令支持运行时动态配置 NAN 与服务无需改代码即可验证完整流程。其 README 给出了清晰的基础操作步骤# NAN Discovery服务发现 nan -S # 启动 NAN-p 主偏好 -c 工作信道 -w 预热时间 nan -T # 停止 NAN publish # 发布服务-n 服务名 -t 类型 -f 匹配过滤器 subscribe # 订阅服务-n 服务名 -t 类型 -f 匹配过滤器 send -p 5 -t Hello # 向服务实例 id 5 的对端发送 Follow-up 消息 publish -C -i 5 # 取消 id 为 5 的发布服务 # NAN Datapath数据通道 ndp -I -p 5 # 向匹配到的 Publisherpublish id 5发起 NDP ping FE80::E2E2:E6FF:FE7B:C132 # 对端 IPv6 链路本地地址 ndp -T -d 1 # 终止 NDP id 1其中 publish 类型可选 Unsolicited主动广播0或 Solicited响应主动订阅者1subscribe 类型可选 Passive被动侦听0或 Active主动广播 Action 帧1——这正是文档所描述的匹配机制在命令行层面的映射。README 还给出了端到端的实测日志节选设备 1 启动 NAN 后创建集群Start own Cluster, Id 50:6f:9a:01:0e:76随后State Scanning AnchorMaster设备 2 扫描加入同一集群Join Cluster with Id 50:6f:9a:01:0e:76订阅匹配Service matched with e0:e2:e6:7b:c1:32 [Peer Publish id - 5]NDP 建立NDP confirmed with NDP id 1 [Peer IPv6 - FE80::E2E2:E6FF:FE7B:C132]数据接口就绪NAN Data Interface ready [IPv6 - fe80:...:e2e2:e6ff:fe7b:c132, type - LINK_LOCAL]IPv6 ping 统计5 packets transmitted, 5 received, 0% packet loss。日志印证了前文的调用链服务匹配 → Follow-up/NDP → 双方获得基于 MAC 派生的链路本地 IPv6 地址正是esp_wifi_nan_get_ipv6_linklocal_from_mac()的原理→ 直接通信。5.2 nan_publisher / nan_subscriber最小发布/订阅对examples/wifi/wifi_aware/nan_publisher 与 examples/wifi/wifi_aware/nan_subscriber 展示最小化的 Publish/Subscribe 编程模型。Publisher 通过menuconfig配置见 Kconfig.projbuild设定ESP_WIFI_NAN_SVC_NAME服务名默认testPublish TypeUnsolicited / SolicitedESP_WIFI_NAN_MATCHING_FILTER匹配过滤器默认空ESP_WIFI_NAN_SERVICE_MESSAGE收到 Subscriber Follow-up 后的回复消息默认WelcomeSecurity Configuration子菜单可启用 NAN Security加密数据通道、ND-GTK 组数据保护等。匹配规则在 README 中明确服务名匹配大小写不敏感匹配过滤器匹配大小写敏感。匹配后 Subscriber 可发送 Follow-up 或发起 DatapathPublisher 收到 Follow-up 后自动回复并在资源充足时接受 Datapath 请求。示例日志展示了 Publisher 收到Received message Hello from Peer ...后回复Replied Welcome to the Subscriber...以及接受 NDP 后获得fe80:0000:0000:0000:1afe:34ff:fe72:50ca链路本地地址的完整过程。5.3 usd_publisher / usd_subscriber轻量级非同步发现examples/wifi/wifi_aware/usd_publisher 与 examples/wifi/wifi_aware/usd_subscriber 演示NAN-USD模式无需组建 NAN 集群即可向附近设备广播/发现服务。Publisher 侧流程为启动 USD → 发布服务 → 响应订阅者的 Follow-up → 发现完成回到空闲态Subscriber 侧为启用 USD 发现 → 订阅服务 → 处理 Follow-up 交互 → 会话结束终止发现。这一模式尤其适合只做一次性发现、不想维护集群同步的轻量场景。六、支持芯片与使用前提从各示例 README 的 Supported Targets 表可以确认NAN-Sync 示例nan_console / nan_publisher / nan_subscriber支持 ESP32、ESP32-C5、ESP32-C61、ESP32-S2、ESP32-S31NAN-USD 示例usd_publisher / usd_subscriber在上述基础上额外支持 ESP32-C2、ESP32-C3、ESP32-C6、ESP32-S3。使用 NAN 前需在 menuconfig 中开启对应功能idf.py menuconfig # Component config - Wi-Fi - Enable Wi-Fi Aware: Synchronization (NAN-Sync) # Component config - Wi-Fi - Enable Wi-Fi Aware: Unsynchronized service discovery (NAN-USD) # 可选Enable Wi-Fi Aware: Encrypted Pairwise Datapath (NDP Security) # 可选Enable NAN Pairing编译与烧录流程与其他 ESP-IDF 示例一致idf.py set-target target、idf.py build、idf.py flash monitor。NAN-Sync 模式需要至少两台支持 NAN 的设备才能观察到集群组建与服务匹配如需与手机互测可选用支持 Wi-Fi Aware 的 Android 8 设备。七、小结本文以官方文档 esp_nan.rst 为纲串起了 ESP-IDF Wi-Fi Aware 的完整技术图景从 NAN 集群与 Publish/Subscribe 的协议本质到 NAN-Sync 与 NAN-USD 两种模式的选择从 esp_nan.h 提供的同步、服务、消息、NDP、查询五组 API到 esp_wifi_types_generic.h 中每一份配置结构体的字段语义最后落到 examples/wifi/wifi_aware/ 下五个可直接运行的示例。无论是想快速用nan_console体验完整流程还是基于nan_publisher/nan_subscriber搭建自己的近场服务或是用usd_publisher/usd_subscriber实现轻量发现这套 API 与事件模型都足以支撑起不依赖 Internet、AP 与 GPS 的设备直连应用。【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考