Wi-Fi Aware (NAN)

支持的芯片[ RTL8730E ][ RTL8721Dx ][ RTL8721F ]

备注

Realtek Wi-Fi NAN 功能只支持带有 wpa_supplicant 的 Linux Host, 包括 Wi-Fi 网卡模式中的 Fat Host (WHC Wi-Fi 配置选项及典型模式) 和 RTL8730E Linux 架构。

Wi-Fi NAN 概述

Wi-Fi Aware,也称为 NAN (Neighbor Awareness Networking) 协议,是一项由 Wi-Fi 联盟认证的技术标准。 它允许支持该功能的设备在不依赖于传统的网络基础设施、互联网连接或 GPS 信号的情况下,快速发现、连接并与其他 Wi-Fi 设备交换数据。 与传统的 Wi-Fi 直连(Wi-Fi Direct)相比,NAN 在设备发现阶段功耗更低、效率更高,适合需要持续感知周围环境的应用场景。 这使得一系列创新的点对点(P2P)应用成为可能,例如:

  • 社交应用:查找附近有共同兴趣的朋友或加入一个本地游戏。

  • 信息共享:在会议室里快速分享文件给所有与会者。

  • 本地服务:在商场里接收附近商家的优惠券,或在博物馆里获取关于展品的详细介绍。

Wi-Fi NAN 的高效与低功耗特性,得益于其独特的工作机制,主要包括 NAN 集群、服务发布/订阅模型以及数据链路的建立。

NAN 集群

多个邻近的 NAN 设备可以自动组成一个 NAN 集群 (NAN Cluster) ,集群中的设备能够相互通信。在集群内部,设备共享一套共同的时间信标以进行同步。

设备不会一直保持唤醒状态,而是遵循一个严格的同步时钟,仅在被称为发现窗口 (Discovery Window, DW) 的极短时间片内被唤醒。 在 DW 期间,设备可以广播自己的服务或侦听来自其他设备的服务。在其余绝大部分时间里,设备都处于低功耗的休眠状态。 这种同步休眠/唤醒机制是 NAN 实现低功耗的关键,它避免了传统 Wi-Fi 为了发现彼此而需要持续扫描所带来的较大电量消耗。

../../../_images/nan_cluster.png

Wi-Fi NAN 集群

服务发布/订阅模型

Wi-Fi NAN 采用了一种高效的发布/订阅 (Publish/Subscribe) 模型进行服务发现:

  • 发布服务 (Publish): 设备可以作为发布者向集群广播它所能提供的服务。

  • 订阅服务 (Subscribe): 其他设备(订阅者)则侦听它们感兴趣的特定服务。

  • 服务发现 (Discovery): 当订阅者在发现窗口期间侦听到匹配其订阅请求的发布消息时,则成功订阅服务。

建立数据链路 (NAN Data Path)

一旦服务订阅成功,两个设备之间就可以选择建立一个 NAN 数据链路 (NAN Data Path, NDP)。这是一个基于 Wi-Fi 的点对点直连链路,具有以下特点:

  • 高带宽: 利用 Wi-Fi 的高速率进行数据传输。

  • 低延迟: 直接连接,无需通过 AP 中转。

  • 安全性: 可以使用 WPA2 安全标准对数据链路进行加密。

NDP 建立后,设备就可以进行文件传输、视频串流、实时游戏等需要高带宽和低延迟的交互。

参考资料

Wi-Fi NAN 特性支持

Realtek 设备对 Wi-Fi NAN 协议提供了全面的支持,能够作为 NAN 网络中的任何角色运行。具体支持能力如下:

  • 核心功能支持

    • 创建 NAN 集群: 当周围没有可用的 NAN 网络时,设备能够主动初始化一个新的 NAN 集群,并承担主节点 (Master) 的角色,负责广播同步信标,为其他设备的加入提供基础。

    • 加入 NAN 集群: 设备能够自动扫描并发现附近已经存在的 NAN 集群,并与之同步时钟,无缝融入现有的邻近感知网络中,与其他设备进行服务发现。

    • 发布服务: 设备可以广播(发布)一个或多个服务,让周边设备发现。

    • 订阅服务: 设备可以订阅(搜索)特定的服务,并发现提供这些服务的设备。

    • 建立数据链路: 设备间可以建立开放或加密的 NAN 数据链路,并协商时间窗口以进行点对点数据交换。

  • NAN 安全性支持

    • 支持设备间建立加密的数据路径。基于 WPA2 AES 加密方式对单播数据帧进行保护。

    • 支持 NAN 配对 (NAN Pairing) 进行设备间安全身份认证、密钥协商、分发与管理。

    • 支持使用 PTK 进行单播管理帧保护。

    • 支持使用 GTK 进行多播数据帧保护,使用 IGTK 进行多播管理帧保护。

    • 支持使用 BIGTK 进行信标帧保护 (Beacon Protection)。

  • 主要特性

    • 高带宽、低延迟的数据传输: 基于 Wi-Fi 技术,确保数据交换的性能。

    • 安全连接: 在 Wi-Fi 层对已配对设备间的连接进行认证与加密。

    • 多连接能力:支持与多个 Wi-Fi NAN 设备同时建立连接。

    • 网络并发:支持 Wi-Fi NAN 功能与传统 Wi-Fi 网络(STA 模式)并发使用,互不影响。

    • 稳健的拓扑结构:采用完全的点对点拓扑,单个节点的加入或离开不会中断其他节点间的现有连接。

Wi-Fi NAN 移植指南

Realtek Wi-Fi NAN 功能支持 Linux Host, Wi-Fi 网卡模式 S2H (WHC Wi-Fi 配置选项及典型模式), 或 RTL8730E Linux。

Device 驱动移植参考 Wi-Fi 网卡模式 配置选项及典型模式,Host 驱动移植参考 Wi-Fi 网卡模式 驱动移植 中 Linux 部分。

Wi-Fi NAN 使用指南

Realtek NAN Utility 是一款用户空间工具,它基于开源 iw 库和 nan_vendor_wrapper 私有库,提供了 nan_test 测试脚本,可以直观便捷地操作 Wi-Fi NAN。 NAN Utility 架构如下图所示:

../../../_images/nan_utility_arch.png

Wi-Fi NAN Utility 架构

NAN Utility 获取及编译

  1. 获取 NAN Utility

    SDK 下载: IoT SDK NAN Utility 工具位于: {sdk}/component/wifi/linux_app/nan_utility.

  2. 环境准备

    在 Linux 系统安装以下依赖包:

    sudo apt-get install build-essential
    
  3. 执行编译

    nan_utility 目录复制到 Host Linux 内核源码树,终端执行编译:

    cd nan_utility
    make script
    

    编译完成后,可执行脚本 nan_test 位于 nan_utility/script/ 路径下。

NAN 应用示例

在 NAN 设备间建立 Data Path,需准备两套设备,并完成 NAN 移植以及 NAN Utility 的移植。

备注

在执行示例中的命令时,需要将其中的 MAC 地址替换为您设备的实际 NAN MAC 地址。 可在设备启动 NAN 后,通过 ifconfig 指令查看 nan0 端口的地址信息,如下:

root@raspberrypi:/# ifconfig

nan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
      inet6 fe80::2e2:4cff:fe00:102d  prefixlen 64  scopeid 0x20<link>
      ether 00:e2:4c:00:10:2d  txqueuelen 1000  (Ethernet)
      RX packets 0  bytes 0 (0.0 B)
      RX errors 0  dropped 0  overruns 0  frame 0
      TX packets 6  bytes 516 (516.0 B)
      TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Case 1 - Open NDP 建立

Open NDP 允许设备之间建立直接的数据通道,但不进行加密或认证,适用于对安全性要求不高的场景,具有更低的延迟和更简单的设置过程,建立流程如下图所示:

../../../_images/nan_open_ndp_case.png

Wi-Fi NAN Open NDP 建立流程

按下表所示,在对应的 Host 终端执行指令以建立 Open NDP:

Step

Device A(NDP Responder)

MAC: 00:11:22:33:44:55

Device B(NDP Initiator)

MAC: 66:55:44:33:22:11

Description

1

nan_test init

nan_test start pref 128 bands 2GHz 5GHz

Device A 初始化 NAN,并在 2G 和 5G 启动 NAN。

2

nan_test init

nan_test start pref 5 bands 2GHz 5GHz

Device B 初始化 NAN,并在 2G 和 5G 启动 NAN。

3

nan_test add_func type publish unsolicited name nanservice data_path

Device A 发布一个未加密的服务。

4

nan_test add_func type subscribe name nanservice

Device B 订阅该服务。

5

nan_test data_req req_type ndp rsp_nan_mac 00:11:22:33:44:55 publish_id 1

Device B 向 Device A 发送 Data Path Request,请求建立NDP。

6

nan_test data_rsp rsp_mode peer ndl_rsp accept data_path_id 1

Device A 回复 Data path Response,接受 NDP 请求,NDP 建立成功。

7

nan_test set_ipv6

nan_test set_neigh 66:55:44:33:22:11

nan_test set_ipv6

nan_test set_neigh 00:11:22:33:44:55

Device A & B 设置自身的 IPv6 地址,并将对方的 IPv6 地址添加到 IP 邻居表中。

8

ping6 fe80::6655:44ff:fe33:2211%nan0

Device A 通过 IPv6 地址 ping Device B,可以成功通信。

9

ping6 fe80::0011:22ff:fe33:4455%nan0

Device B 通过 IPv6 地址 ping Device A,可以成功通信。

Case 2 - Secure NDP 建立

Secure NDP 在设备之间建立加密的数据通道,提供了数据传输的机密性和完整性保护,建立流程如下图所示:

../../../_images/nan_secure_ndp_case.png

Wi-Fi NAN Secure NDP 建立流程

按下表所示,在对应的 Host 终端执行指令以建立基于 PMK 的 Secure NDP:

Step

Device A(NDP Responder)

MAC: 00:11:22:33:44:55

Device B(NDP Initiator)

MAC: 66:55:44:33:22:11

Description

1

nan_test init

nan_test start pref 128 bands 2GHz 5GHz

Device A 初始化 NAN,并在 2G 和 5G 启动 NAN。

2

nan_test init

nan_test start pref 5 bands 2GHz 5GHz

Device B 初始化 NAN,并在 2G 和 5G 启动 NAN。

3

nan_test add_func type publish unsolicited name nanservice data_path sec_pmk 123456789abcdef0123456789abcdef0

Device A 发布服务,宣称支持 ND-TKSA (SDEA with Unicast NDP required and Security Required)。

4

nan_test add_func type subscribe name nanservice

Device B 订阅该服务。

5

nan_test data_req req_type ndp rsp_nan_mac 00:11:22:33:44:55 sec publish_id 1 sec_pmk 123456789abcdef0123456789abcdef0

Device B 向 Device A 发送 Data Path Request,携带 sec_pmk,请求建立加密NDP。

6

nan_test data_rsp rsp_mode peer ndl_rsp accept data_path_id 1

Device A 回复 Data path Response,接受 NDP 请求,NDP 建立成功。

7

nan_test set_ipv6

nan_test set_neigh 66:55:44:33:22:11

nan_test set_ipv6

nan_test set_neigh 00:11:22:33:44:55

Device A & B 设置自身的 IPv6 地址,并将对方的 IPv6 地址添加到 IP 邻居表中。

8

iperf -s -i 1 -V

Device A 运行 iperf server。

9

iperf -c fe80::0011:22ff:fe33:4455%nan0 -i 1 -t 30 -V

Device B 运行 iperf client,与 Device A 建立 TCP 连接。

nan_test 参数说明

Command parameter

Usage

Comment

-h

show help message

status

show current NAN status

Include the following information:

Module existence

Main interface down/up

NAN interface existence

init

Init NAN interface

Example:

  • nan_test init

Register nan0 interface by this command.

iw dev result show Interface nan0, and it share the same phy with wlan0

deinit

deinit NAN interface

Example:

  • nan_test deinit

Un-register nan0 interface by this command.

start [pref <value>] [bands [2GHz] [5GHz]]

Start NAN

Example:

  • nan_test start pref 5 bands 2GHz 5GHz

pref:

  • Master Preference, Default pref = 5

  • bands: (publish)

  • Support bands, 2GHz or 2GHz 5GHz

stop

Stop NAN

add_func

type <publish|subscribe|followup> [solicited] [unsolicited]

name <name>

optional param:

  • [info <info>]

  • [active]

  • [bcast]

  • [flw_up_id <id> flw_up_req_id <id> flw_up_dest <mac>]

  • [srf <include|exclude> <bf|list> [bf_idx] [bf_len] <mac1;mac2...>]

  • [rx_filter <str1:str2...>] [tx_filter <str1:str2...>]

Add a NAN function with or without filters

Example:

  • nan_test add_func type publish unsolicited name android data_path

  • nan_test add_func type subscribe active name nan_service

  • type:

    • the type of the adding service

  • solicited / unsolicited: (publish)

    • only present when service type is publish

    • indicate the service is solicited or unsolicited publish

  • name:

    • service name from which service id is generated and is not case sensitive

    • default name : org.wifi.nan.test

  • info:

    • could be a simple buffer or a formatted buffer.

    • A simple buffer will be appended to SDA attribute.

    • A formatted buffer started with supported OUI is expected as a well-structured service Info and will be appended to SDEA.

    • Currently, user can only choose one kind of service info for a service, and driver only support OUI specified in ref[1].

  • active: (subscribe)

    • only present when service type is subscribe

    • present if the service is active subscribe

  • bcast: (publish)

    • only present when the service is solicited publish

    • present if the service is broadcasting as well

Follow up service

  • the following parameters are presented only when service type is followup

  • flw_up_id: (followup)

    • the instance id of the local publish or subscribe service which this followup service wants to follow

  • flw_up_req_id: (followup)

    • the instance id of the remote publish or subscribe service

  • flw_up_dest: (followup)

    • the nmi of the remote publish or subscribe service

Service response filter

  • the following parameters are presented only when srf is configured

  • include / exclude

    • indicate the srf is as a white list or a black list

  • list <mac1;mac2...>

    • indicate a list for memory comparing with peers' nmi

    • e.g. type subscribe active srf include list "00:11:22:33:44:55;66:55:44:33:22:11"

  • bm bf_idx bf_len <mac1;mac2...>

    • indicate the method and the components to generate a bloom filter

    • e.g. type subscribe active srf include bf 3 16 "00:11:22:33:44:55;66:55:44:33:22:11"

Matching filter

  • rx_filter <str1:str2...>

  • tx_filter <str1:str2...>

  • e.g. 1

    • type publish solicited rx_filter RTK:ABCD:A23D

    • type subscribe active tx_filter RTK

  • e.g. 2

    • type publish unsolicited tx_filter ::*

    • type subscribe passive rx_filter none

rm_func <cookie>

Remove a NAN function with cookie

Cookie is shown when add func.

data_req

support param:

  • [req_type <ndp>]

  • [rsp_nan_mac <mac_addr>]

  • [sec]

  • [publish_id <id>]

  • [min_duration <value>]

  • [max_latency <value>]

  • [sec_pmk <key_content | pairing>]

  • [srv_info <hex_data>]

  • [port_num <value>]

  • [hostname <str>]

NAN data request

Example:

  • nan_test data_req req_type ndp rsp_nan_mac 00:11:22:33:44:55:66 publish_id 1

  • req_type:

    • type for data request; only ndp is supported

  • rsp_nan_mac:

    • the mac address of ndp responder

  • sec:

    • present if security data path is required

  • publish_id:

    • specified the instance id of the peer service

    • note: if the id is not specified, the first service of rsp_nan_mac will be selected as publish_id.

  • min_duration:

    • minimum number of available nan slots needed per dw interval. (unit: nan slot)

    • present if qos is required (check NDL QoS attr in nan spec for more details)

  • max_latency:

    • maximum nan slots between every two non-contiguous NDL CRBs. (unit: nan slots)

    • present if qos is required (check NDL QoS attr in nan spec for more details)

  • sec_pmk:

    • only present when the sec is set

    • specified the pmk for secured ndp setup

    • value:

      • pmk content: e.g. sec_pmk 123456789ABCDEF0123456789ABCDEF1 (note: the length of pmk should be 32)

      • pairing: use this value if nan pairing is processed before the ndp setup (the pmk will be generated automatically after nan pairing is completed.)

  • sec_password:

    • only present when the sec is set

    • specified the password using to extend to the pmk for secured ndp setup

    • note: the max length of password is 32

  • srv_info:

    • the info should be presented in hex format, and separated by comma.

    • e.g. srv_info 50,6f,9a,02,00,02,00,58,1b,01,01,00,06

    • note: service info could be in various formats, but for the current command set, srv_info is expected as a simple buffer that is going to append to the NDP attribute.

  • port_num

    • Transport Port : Current port on which the service is listening. if this parameter is set, NDPE will append service info with generic service fromat, and ignore srv_info parameter

  • hostname

    • hostname: DNS-SD hostname. if this parameter is set, NDPE will append service info with generic service fromat, and ignore srv_info parameter

data_rsp

support param:

  • [rsp_mode <peer | auto>]

  • [ndl_rsp <reject | accept>]

  • [data_path_id <id>]

  • [publish_id <id>]

  • [initiator_data_address <mac_addr>]

  • [min_duration <value>]

  • [max_latency <value>]

  • [srv_info <hex_data>]

  • [port_num <value>]

  • [hostname <str>]

NAN data response

Example:

  • nan_test data_rsp rsp_mode peer ndl_rsp accept data_path_id 1

  • rsp_mode:

    • response mode

    • value: peer, auto

  • ndl_rsp:

    • response status

    • value: reject, accept

  • data_path_id:

    • present when the rsp_mode is peer

    • the ndp id created by the initiator (check ndp attr in nan spec for more details)

  • publish_id:

    • present when the rsp_mode is auto

    • the instance id of the peer's publish service

  • initiator_data_address:

    • present when the rsp_mode is peer

    • the mac addr of initiator

  • min_duration:

    • minimum number of available nan slots needed per dw interval. (unit: nan slot)

    • present if qos is required (check NDL QoS attr in nan spec for more details)

  • max_latency:

    • maximum nan slots between every two non-contiguous NDL CRBs. (unit: nan slots)

    • present if qos is required (check NDL QoS attr in nan spec for more details)

  • srv_info:

    • the info should be presented in hex format, and separated by comma.

    • e.g. srv_info 50,6f,9a,02,00,02,00,58,1b,01,01,00,06

    • note: service info could be in various formats, but for the current command set, srv_info is expected as a simple buffer that is going to append to the NDP attribute.

  • port_num

    • Transport Port: Current port on which the service is listening. if this parameter is set, NDPE will append service info with generic service fromat, and ignore srv_info parameter

  • hostname

    • hostname: DNS-SD hostname. if this parameter is set, NDPE will append service info with generic service fromat, and ignore srv_info parameter

data_end [ndp_id <id>] [initiator_ndi <mac>]

NAN data end

set_ipv6

Set own ipv6 link-local address based on mac address via ifconfig

automatically convert own mac address to ipv6 address

set_neigh <dst_mac>

Set neighbor ipv6 link-local address with dst mac address

automatically convert dst mac address to ipv6 address