WFB-ng 数据传输标准草案解读
概述
WFB-ng 协议旨在标准化通过原始 WiFi 无线电进行远距离数据传输的通信方式。这里的”远距离”是指标准 802.11 ACK 机制无法工作的距离(超过约 200 米)。
该方案允许使用支持”原始包”传输的普通 WiFi 适配器,以高达 8Mbps(MCS #1 调制)的速度传输任意数据流,传输距离可达数十公里。目前主要基于 Realtek RTL8812AU 芯片的适配器。
应用场景
- 机器人与地面站之间的通信
- 业余卫星(CUBESAT)与地球的通信
- 地面数字无线电通信
工作原理
标准 WiFi 传输范围的主要限制在于:接收方必须在严格规定的时间间隔内发送 ACK 确认包。当两个站点之间的距离超过约 200 米时,接收方无法及时确认数据包,导致数据传输失败。
部分 WiFi 适配器支持”原始模式”(raw mode),可以绕过标准的 802.11 协议栈来收发数据包,关闭 ACK 机制的要求。此时传输距离不再受限于 ACK 超时,仅取决于接收灵敏度和发射功率。但需要自行实现 MAC 层(介质访问控制层)。
协议描述
基本特性
- 支持点对点链路
- 每个节点可同时参与任意数量的链路
- 每条链路拥有独立的加密密钥集
- 最多支持 256 个单向数据流
MAC 地址格式
发送方 MAC 地址的后四个字节用于标识链路归属:
1 | 0x57, 0x42, 0xaa, 0xbb, 0xcc, 0xdd |
- 前两个字节为协议头
'W'(0x57)、'B'(0x42) - 中间三个字节为链路 ID(link id)
- 最后一个字节为流编号(stream number)
第一个地址字节 0x57 的低两位被设置,表示该地址是多播且本地管理的。
数据流分配方案
| 范围 | 方向 | 用途 |
|---|---|---|
| 0 - 127 | 下行(飞行器 → 地面站) | 视频、Mavlink、隧道等 |
| 128 - 255 | 上行(地面站 → 飞行器) | 控制指令等 |
流编号分配:
- 0 - 15: 视频流(默认:0)
- 16 - 31: Mavlink 流(默认:16)
- 32 - 47: 隧道流(默认:32)
- 其他范围保留供将来使用
数据处理流程
1 | 原始 UDP 数据包 → FEC 编码(zfec) → ChaCha20-Poly1305 加密 → WiFi 无线电包发送 |
无线数据包格式
协议定义两种包类型:
| 类型 | packet_type | 说明 |
|---|---|---|
| 数据包 | 1 | 包含 FEC 编码后的加密数据 |
| 会话包 | 2 | 包含加密的会话参数和会话密钥 |
数据包结构
1 | // Session key packet |
IEEE 802.11 帧头
1 | static uint8_t ieee80211_header[] = { |
完整包结构
1 | radiotap_header: |
实现要点
参考实现
wfb-ng.org — WFB-NG 协议栈的参考实现(C + Python/Twisted),GPLv3 许可证。
加密机制
WFB-ng 使用 libsodium 进行数据流加密:
- TX 启动时生成新的会话密钥
- 使用公钥认证加密(cryptobox)加密会话密钥
- 每 SESSION_KEY_ANNOUNCE_MSEC(默认 1 秒)广播一次会话包
- 会话包使用 X25519 ECDH 密钥进行加密和认证
- 数据包使用
crypto_aead_chacha20poly1305_encrypt加密,以 session key 和包索引作为 nonce
密码派生密钥(KDF)
对于低风险场景,可以从用户提供的密码派生密钥:
1 | unsigned char salt[crypto_pwhash_argon2i_SALTBYTES] = |
测试向量: 密码为 secret password 时:
gs.keySHA1:cb8d52ca7602928f67daba6ba1f308f4cfc88aa7drone.keySHA1:7a6ffb44cebc53b4538d20bdcaba8d70c9cf4095
RX-Ring(接收环形缓冲区)
由于多个 RX 无线电有各自的内部队列,数据包可能乱序到达。RX-Ring 是一个循环缓冲区,按 FEC 块分组存储数据包:
rx_ring_front: 第一个已分配 FEC 块的索引alloc_size: 已分配的块数
新包处理逻辑:
- 属于新的 FEC 块 → 在 RX ring 中分配(如果块已被处理则忽略)
- 属于已有的 FEC 块 → 添加到该块(如果包已处理则忽略)
成功解码所有分片后,输出并移除它之前的所有未完成块。当 RX ring 满时,覆盖头部的旧块。
这样可以保证输出的 UDP 数据包始终有序且无重复。
Mavlink 模式优化
默认情况下 WFB-ng 将每个源 UDP 包封装到一个 WiFi 包中。但 Mavlink 包通常很小(小于 100 字节),单独发送会产生过多开销。优化的 Mavlink 模式会将多个 Mavlink 包聚合到一个 UDP 包中,直到达到 MAX_PAYLOAD_SIZE 或超过 mavlink_agg_in_ms 超时时间。
TX FEC 超时
默认情况下,如果少于 K 个数据包且没有新数据可用,WFB-ng 不会关闭 TX FEC 块。对于交互式协议或可变速率的数据流(如 Mavlink、IP 隧道),TX 可以发送带有 WFB_PACKET_FEC_ONLY 标志的空包来关闭非空的 FEC 块。或者可以使用 K=1 的 FEC 配置。
