请选择 进入手机版 | 继续访问电脑版
查看: 1126|回复: 0

[技术交流] 无线学习之mac80211专题-自适应速率控制算法

[复制链接]

185

主题

204

帖子

596

积分

利尔达员工

Rank: 9Rank: 9Rank: 9

积分
596
发表于 2020-11-3 09:51:50 | 显示全部楼层 |阅读模式
  1,自适应速率控制算法概述

  自适应速率控制算法的目的是在信道质量好的时候提高发送速率,信道质量差的时候降低发送速率。自适应速率控制算法是通过选择不同的调制或编码方式来改变发送的速率。

  IEEE 802.11x标准在物理层提供了多种发送速率的能力,如IEEE 802.11a支持从6Mbit/s到54Mbit/s的8种速率;IEEE 802.11g标准在2.4GHz的频率拓展了802.11b支持了12种速率;IEEE 802.11n的物理速率依赖于调制方式,编码率,空间流数量,是否40MHz绑定等多个因素,这些因素组合在一起产生了非常多的物理速率供选择使用,因此802.11n采用了MCS对射频速率进行配置。

  IEEE 802.11x标准在MAC层并没有规定如何选择合适的发送速率,因此不同的wifi芯片厂商会有不同的自适应控制算法。现有的自适应速率算法主要分为两类:第一类是基于信道直接测量的方法,需要修改IEEE802.11标准;第二类是基于统计的方法,不需要修改IEEE 802.11标准,实现简单,被大部分的芯片厂商采用。基于统计方法又可以分为两种:基于吞吐量统计的方法和基于ACK帧的方法。基于吞吐量统计的方法统计在一个时间内的吞吐量,从而判断信道的质量,该方法适合缓慢变化的信道环境。基于ACK帧的方法是指发送端根据连续收到的ACK帧来快速判断信道质量,从而自动调整发送速率的自适应算法,此方法能够较快的响应信道。

  2,源码分析1,关键结构体分析

  Atheros驱动提供了两种速率调整算法,分别是Ath9k和Minstrel。本章节重点介绍一个重要的结构体struct ieee80211_tx_info,引出速率调整算法的基本概念。在应用网络编程中我们对常用接口SOCKET非常熟悉,在MAC层有一个与之对应的结构体叫sk_buff,简称skb,skb中有一个域叫做control_buff也就是skb->cb,是一个48字节长度的内存区域。数据包的流向是应用层-->网络层-->MAC层-->物理层。MAC层接收到数据包后,需要指定发送参数后才交给物理层去发送该数据包,参数有发送的带宽(20MHz/40MHz),速率,重传次数等,这些参数存储在skb->cb这个结构体中,其存储的格式按struct ieee80211_tx_info 结构体来存。

  上图结构体中,我们关心的重点是union字段的control和status,而他们的核心都是struct ieee80211_tx_rate结构体。
  struct ieee80211_tx_rate {
      s8 idx;
      u8 count;
      u8 flags;
  } __packed;
  这个结构体代表的是一个速率,有三个参数:速率号(idx),发送次数(count),标志位(flags)。从struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES] 数组可知,速率调整算法的任务是把该数组内容填充好交给底层。

  回到union字段,包括control和status两个部分,其中control部分是在发送过程中被使用,使用的例子如下:
  struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
  struct ieee80211_tx_rate *rates = tx_info->control.rates;

  rates[0].idx=0; rates[0].count=2; rates[0].flags=zzz0;
  rates[1].idx=1; rates[1].count=4; rates[1].flags=zzz1;
  rates[2].idx=2; rates[2].count=8; rates[2].flags=zzz2;
  我们指定了发送数据包依次使用0、1、2这三个速率最多发送2、4、8次,直到发送成功为止。在发送完毕后,我们需要知道发送是否成功,最后哪个速率发送成功等信息。这个结构体又会被底层返回给我们,可以通过status访问返回的数据(其实是每一项的count域被底层重写了),status的count表示每个速率的实际发送次数。
  struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
  struct ieee80211_tx_rate *rates = tx_info->status.rates;

  // rates[0].count == 4
  // rates[1].count == 1
  // rates[2].count == 0

  上述表示速率0发了4次,最终都失败了,速率1发了1次就成功了,当然速率2没有用到,发了0次。

  总结:速率调整算法的任务就是在发送过程中把tx_info->control.rates填充好,发送结束后根据tx_info->status.rates来做速率的调整。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表