端到端数据流

本文从应用数据出发, 追踪一个数据包从发送端到接收端经过的完整处理链路, 涵盖 MAC 层封装、信道编码、调制成型、空口传输、接收解调和数据恢复的全过程。

全局视图

        flowchart LR
    subgraph TX["发送端"]
        A1["应用数据"] --> A2["QoS管理"]
        A2 --> A3["MAC封帧"]
        A3 --> A4["信道编码"]
        A4 --> A5["调制成型"]
    end
    subgraph CH["空口"]
        B["无线信道"]
    end
    subgraph RX["接收端"]
        C1["解调滤波"] --> C2["信道解码"]
        C2 --> C3["MAC解帧"]
        C3 --> C4["QoS管理"]
        C4 --> C5["应用数据"]
    end
    A5 --> B --> C1
    

发射流水线

第一步: QoS 决策

SleNode.transmit() 首先调用 QosManager.prepare_tx(), 从优先级队列中取出待发送数据:

  • 五级优先级队列: CONTROL > REALTIME > HIGH > NORMAL > LOW

  • 流控检查: 发送窗口是否有信用额度

  • HARQ 检查: 是否有需要重传的码块

第二步: 帧加密 (可选)

如果链路已开启加密, 调用 FrameCryptoContext.encrypt():

  1. 计算 IV: compute_iv(iv_base, sync_or_link_id, frame_type)

  2. 构建 CCM nonce: build_ccm_nonce_async(flag, payload_count, direction, iv, data_len), 取 B0[1:14] 作为 13 字节 nonce

  3. AES-CCM 加密: aes_ccm_encrypt(session_key, nonce, plaintext, aad, mic_len) → 密文 + MIC

  4. payload_count 递增

第三步: MAC 封帧

数据被封装为 AsyncDataFrame:

┌────────────┬─────────────┬──────────┬──────────┐
│ 分段标志   │ 数据长度    │  保留    │  载荷    │
│  2 bit     │  11 bit     │  3 bit   │  N 字节  │
└────────────┴─────────────┴──────────┴──────────┘

如果数据超过最大 PDU 长度, 按 FIRST / MIDDLE / LAST 分段。

第四步: 信道编码 (tx_chain)

mac_to_iq() 将 MAC 字节转换为比特流, 构建控制信息, 然后调用 tx_chain():

头部编码 (encode_head)

控制信息比特 (28 或 44 位) 经过:

  1. Polar 编码: 按可靠性序列选择信息位位置, 冻结位填零, 蝶形运算生成码字

  2. 加扰: 7 位 Galois LFSR (\(x^7 + x^4 + 1\)), 异或每个比特

载荷编码 (encode_payload)

用户数据比特经过:

  1. CRC 附加: 计算 CRC-24 或 CRC-32, 附加到数据尾部

  2. 码块分割: 当编码后比特数超过 Polar 码最大母码长度时, 将数据拆分为多个码块

  3. Polar 编码: 每个码块独立 Polar 编码, 按 MCS 指定的码率

  4. 加扰: 与头部使用相同的 LFSR, 异或每个码字比特

第五步: 帧组装

编码后的比特按帧结构组装:

┌──────────┬──────────┬──────────┬──────────┬──────────┐
│ 前导码   │ 同步序列 │ 头部     │ 载荷     │ (导频)   │
│ m序列    │ SyncWord │ Polar码字│ Polar码字│ 定期插入 │
└──────────┴──────────┴──────────┴──────────┴──────────┘
  • 前导码: m 序列, 不同帧类型使用不同长度 (FT1: 32 bit, FT2: 64 sym, FT3: 62 sym, FT4: 126 sym)

  • 同步序列: 由 PID 生成, 用于帧同步检测

  • 导频: 按 pilot_interval 周期性插入已知符号, 用于信道估计

第六步: 调制成型

  • FT1 (GFSK): 高斯频移键控, BT = 0.5, 直接调制为瞬时频率变化

  • FT2-FT4 (PSK): 相移键控 (BPSK/QPSK/8PSK), 先映射星座点, 再经 RRC 脉冲成型滤波 (滚降系数 \(\beta = 0.4\))

输出为复数基带 IQ 信号。

第七步: 射频发送

  • 仿真模式: IQ 直接进入信道模型

  • USRP 模式: IQ 通过 SLETransceiver 发送到 USRP E310 硬件, 上变频到 2.4 GHz 频段

空口传输

信道效应

数据经过无线信道时受到:

  • 多径衰落: Rayleigh/Rician 衰落, 多径时延扩展

  • 频率偏移: 本振不匹配导致的载波频偏

  • 多普勒扩展: 相对运动引起的时变信道

  • 噪声: 高斯白噪声 (AWGN)

  • 多用户干扰: 其他设备同频信号干扰

跳频

发射和接收两端按相同的跳频序列在 2402-2480 MHz 频段内切换信道, 每个时隙跳到不同频点, 改善频率分集增益并降低窄带干扰影响。

接收流水线

第一步: 射频接收

  • USRP 模式: 硬件下变频, ADC 采样得到基带 IQ

  • 仿真模式: 从信道模型输出获取 IQ 信号

第二步: 匹配滤波

  • FT1 (GFSK): GFSK 解调器直接提取瞬时频率

  • FT2-FT4 (PSK): RRC 匹配滤波, 最大化信噪比, 然后降至 1 样本/符号

第三步: 帧同步 (frame_sync)

滑动互相关检测同步序列:

  1. 根据帧类型生成同步参考序列

  2. 计算接收信号与参考序列的互相关

  3. 峰值超过均值 2 倍时判定同步成功, 返回帧起始位置

第四步: 帧结构解析

symbols_to_data_bits() 根据帧配置参数拆分各段:

  1. 跳过前导码和同步序列

  2. 提取头部符号 (固定长度)

  3. 提取载荷符号 (长度由头部指示或预知)

  4. 移除导频符号

第五步: 头部解码 (decode_head)

  1. 解扰: 相同的 LFSR 异或恢复原始码字

  2. Polar 解码: SC (逐次消除) 解码, 恢复控制信息比特

  3. CRC-12 校验: 验证头部完整性

第六步: 载荷解码 (decode_payload)

  1. 解扰: LFSR 异或

  2. Polar 解码: 每个码块独立解码

  3. 码块重组: 多个码块合并为完整数据

  4. CRC 校验: CRC-24 或 CRC-32 验证数据完整性

第七步: MAC 解帧

  1. 比特流转换为字节: bits_to_bytes()

  2. 解析 AsyncDataFrame: 提取分段标志和载荷

  3. 分段重组: 如有分段, 按序号拼接

第八步: 帧解密 (可选)

调用 FrameCryptoContext.decrypt():

  1. 用与发送端相同的参数构建 nonce

  2. AES-CCM 解密并验证 MIC

  3. payload_count 递增

  4. MIC 验证失败则丢弃

第九步: QoS 反馈

  • ARQ: 发送 ACK/NACK

  • HARQ: 反馈 TB 或 CBG 粒度的确认

  • 流控: 更新信用额度

  • 质量跟踪: 更新帧错误率统计, 推荐 MCS

MAC-PHY 适配层

phy.mac_interface 模块是 MAC 和 PHY 之间的桥接:

函数

方向

说明

mac_to_iq()

TX

MAC 字节 → IQ 信号

iq_to_mac()

RX

IQ 信号 → MAC 字节

signaling_to_iq()

TX

信令对象 → IQ

iq_to_signaling()

RX

IQ → 信令对象

bytes_to_bits()

工具

字节 → 比特 (MSB)

bits_to_bytes()

工具

比特 → 字节

SleNode 集成

SleNode 是将所有功能集成到一个实体的节点类:

SleNode
├── TxConfig          发射配置
├── QosManager        QoS 管理 (ARQ/HARQ/流控)
├── LinkManager       链路状态机 (8 状态)
├── FreqTable         跳频表
├── PowerController   功率控制
├── ScheduleManager   时序调度
├── FrameCryptoContext 帧加密上下文
├── ChannelModel      仿真信道 (可选)
└── SLETransceiver    USRP 收发器 (可选)

数据流路径:

  • 发送: send(data) → 入队 → transmit() → QoS → 加密 → MAC → PHY → IQ → 空口

  • 接收: 空口 → IQ → receive() → PHY → MAC → 解密 → QoS 反馈 → on_data_received()