树下棋缘

V1

2022/07/17阅读:15主题:默认主题

Radiotap

radiotap介绍

  • radiotap官网
  • radio header已成为802.11发射和接收的事实标准(无论是否符合法律或官方规定)

已支持的操作系统

  • FreeBSD
  • Linux
  • NetBSD
  • OpenBSD
  • Windows

radiotap标头

struct ieee80211_radiotap_header {
        u_int8_t        it_version;     /* set to 0 */
        u_int8_t        it_pad;
        u_int16_t       it_len;         /* entire length */
        u_int32_t       it_present;     /* fields present */
} __attribute__((__packed__));
  • it_version字段:radiotap的版本,此值始终为0。添加其它radiotap字段不会更改该版本号。
  • it_pad字段:it_version占8位,补充8位it_pad,用于对齐it_len的16位。然后it_version/it_pad/it_len组合占32位,与对齐it_present对齐。
  • it_len字段:radiotap整个字段的长度,包含radiotap标头。
  • it_present字段:radiotap数据字段的掩码位。it_present的最高位(31位)如果为0,则后面紧跟radiotap数据字段,如果为1,则后面又是一个it_present。新增的it_present的规则相同,也就是说后面还可以一直新增it_present, 直至最后一个it_present的最高位为0.

重要约束

  • 字段是严格排序的,开发人员可以选择字段的任意组合,但字段的顺序必须严格遵守规定的顺序
  • radiotap所有字段(包含数据中的字段和标头中的字段)都是小端字节序
  • 字段长度是隐式的,开发人员根据字段名称知道相应的长度
  • 不支持可变字段长度,因为字段长度是隐式的
  • 支持扩展掩码
  • 域需要自然对齐,如标头中需要it_pad

扩展掩码

radiotap标头中it_present有32位,分两个功能:

  • 31位:扩展位
  • 0~30位:数据字段掩码位 如果it_present的第31位为1,则存下扩展位掩码,表示后续仍是it_present掩码,该掩码的第32位为1仍表示后续为it_present掩码。

radiotap数据段

目前radiotap数据段,总结为以下三类:

  • 已定义字段
  • 建议字段
  • 已拒绝字段

radiotap已定义字段

已定义字段 位掩码 字段内容 单位 说明
flags 1 u8 flags 位图 传输和接收帧的属性
rate 2 u8 rate 500Kbps TX/RX速率
channel 3 u16 frequency
u16 flags
MHz, bitmap TX/RX频率及标志
Antenna signal 5 s8 dbm_antsignal 分贝 天线的射频信号功率
Antenna noise 6 s8 dbm_antnoise 分贝 天下的射频噪声
dBm TX power 10 s8 dbm_tx_power 分贝 发射功率
Antenna 11 u8 ant_idx - 当前数据包RX/TX天线编号,第一根天线为天线0
TX flags 15 u16 flags 位图 发送帧的属性
Vendor Namespace 30 u8 OUI[3]
u8 sub_namespace
u16 skip_lengh
- 厂商命名空间

radiotap解析库

github地址:radiotap parser library

https://github.com/radiotap/radiotap-library

radiotap生成样例

步骤简要说明:

  1. 由两部分组成,radiotap标头和radiotap数据
  2. 明确radiotap数据有哪些字段,即radiotap标头的掩码位确定,然后就可以计算出radiotap数据长度
  3. 配置radiotap数据每个字段
/* defined in ieee80211_radiotap.h */
enum ieee80211_radiotap_type {
 IEEE80211_RADIOTAP_TSFT = 0,
 IEEE80211_RADIOTAP_FLAGS = 1,
 IEEE80211_RADIOTAP_RATE = 2,
 IEEE80211_RADIOTAP_CHANNEL = 3,
 IEEE80211_RADIOTAP_FHSS = 4,
 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
 IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
 IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
 IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
 IEEE80211_RADIOTAP_ANTENNA = 11,
 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
 IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
 IEEE80211_RADIOTAP_RX_FLAGS = 14,
 IEEE80211_RADIOTAP_TX_FLAGS = 15,
 IEEE80211_RADIOTAP_RTS_RETRIES = 16,
 IEEE80211_RADIOTAP_DATA_RETRIES = 17,

 IEEE80211_RADIOTAP_MCS = 19,
 IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
 IEEE80211_RADIOTAP_VHT = 21,
 IEEE80211_RADIOTAP_TIMESTAMP = 22,

 /* valid in every it_present bitmap, even vendor namespaces */
 IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
 IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
 IEEE80211_RADIOTAP_EXT = 31
};

#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
u16 create_radiotap(u8* buffer)
{
    u16 i = sizeof(struct ieee80211_radiotap_header);

    /* initialize flags */
    u8 flags = 0;
    
    /* initialize TX/RX rate, unit: 500kbps */
    u8 rate = 2/* 2*500kbps = 1Mbps */
    
    /* initialize channel, followed with flags */
    u16 freq = 2407 + (1 * 5); /* freq = 2407+channel*5 */
    u16 freq_flags = IEEE80211_CHAN_2GHZ; /* 2.4G Wi-Fi */
    
    /* initialize dBm antenna signal */
    s8 dbm_antsignal = -55
    
    /* initialize antenna */
    u8 antenna = 0;
    
    /* initialize TX flags */
    u16 tx_flags = 0x0000;
    
    /* initialize radiotap header */
    struct ieee80211_radiotap_header *hdr = (struct ieee80211_radiotap_header *)buffer;
    hdr->it_version = 0// set verson to 0
    hdr->it_pad = 0;
    hdr->it_len = sizeof(struct ieee80211_radiotap_header) + 
            sizeof(flags) +
            sizeof(rate) + 
            sizeof(freq) + sizeof(chan_flags) +
            sizeof(ssi_signal) + 
            sizeof(antenna) + 
            sizeof(tx_flags);
    hdr->it_present =   (1 << IEEE80211_RADIOTAP_FLAGS) |
            (1 << IEEE80211_RADIOTAP_RATE) | 
            (1 << IEEE80211_RADIOTAP_CHANNEL) |
            (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
            (1 << IEEE80211_RADIOTAP_ANTENNA) |
            (1 << IEEE80211_RADIOTAP_TX_FLAGS);
                    
    // flags: 1byte
    buffer[i++] = flags;

    // rate: 1byte
    buffer[i++] = rate; // TX/RX data rate

    // channel: 2bytes frequency + 2bytes flags
    buffer[i++] = (freq & 0xFF);
    buffer[i++] = (freq >> 8);
    buffer[i++] = (freq_flags & 0xFF);
    buffer[i++] = (freq_flags >> 8);

    // Antenna signal: 1byte
    buffer[i++] = dbm_antsignal;

    // Antenna: 1byte
    buffer[i++] = antenna;

    // tx flags: 2byte
    buffer[i++] = (tx_flags & 0xFF);
    buffer[i++] = (tx_flags >> 8);

    return hdr->it_len;
}

👉🏻 微信公众号:Matter物联网开发者联盟,感兴趣的同学可以关注下呀!

分类:

移动端开发

标签:

计算机网络

作者介绍

树下棋缘
V1