zoukankan      html  css  js  c++  java
  • 80211 发送速率选择算法分析

    转:https://blog.csdn.net/junglefly/article/details/48974077

    1. 介绍
    《802.11无线网络权威指南  第二版》中对于选速和降速的描述:

    市面上所有802.11接口均支持某种降速机制,可以根据不同网络环境调整所使用的数据传输速率。速率选择主要决定一张网卡该在何时提高速率以提高链路品质。802.11标准并未规范工作站如何决定降速(或者升速),因此速率选择如何实现就留给芯片组厂商自行决定。几乎所有芯片组具有自己的一套选速机制,因此大多数802.11接口的操作方式均有所不同。速率选择是可编程的,一般由驱动程序控制。

    最常被用来判断何时应该变速的算法,其实是通过一些不是那么严格的信号质量测量。信号质量可以直接就信噪比加以测量,或者间接观察有多少帧需要重传。直接测量信噪比可以针对最近一个帧的瞬间信号质量,或者就最近一段时间所接收到的一定数量的帧取平均数。有些芯片会直接测量信噪比,不过随后会将之转换为相应的“信号质量signal quality”。当信号质量变差,芯片就会以降速来应变。

    至于间接测量,则是监测瞬间或者平均遗失多少帧,然后予以适当补偿。采用间接测量的算法简单来说就是:如果帧已经遗失且帧重试计数器已经用尽,那就降速到下一档,然后重试一遍。反复进行以上步骤直到帧送出,或者一直尝试到以最低速率都无法成功传送为止。采用间接信号质量测量的芯片组或许会稍微修改上述算法,以避免耗费过多时间在物理层所支持的所有速度间逐次降速。尤其是近来的芯片组均支持不少的速率,在较低速率上反复重试将会相当费时。

    1.1 发送速率的选择
     

    代码中的数据结构如下所示:

    /* MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition!!! */

    typedef union _HTTRANSMIT_SETTING {

    #ifdef RT_BIG_ENDIAN

             struct {

                       USHORT MODE:2;   /* Use definition MODE_xxx. */

                       USHORT iTxBF:1;

                       USHORT rsv:1;

                       USHORT eTxBF:1;

                       USHORT STBC:2;      /* SPACE */

                       USHORT ShortGI:1;

                       USHORT BW:1;         /* channel bandwidth 20MHz or 40 MHz */

                       USHORT MCS:7;       /* MCS */

             } field;

    #else

             struct {

                       USHORT MCS:7;       /* MCS */

                       USHORT BW:1;         /* channel bandwidth 20MHz or 40 MHz */

                       USHORT ShortGI:1;

                       USHORT STBC:2;      /* SPACE */

                       USHORT eTxBF:1;

                       USHORT rsv:1;

                       USHORT iTxBF:1;

                       USHORT MODE:2;   /* Use definition MODE_xxx. */

             } field;

    #endif

             USHORT word;

    } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;

    由上面的代码可知:

    *  Ralink是通过APHardTransmit函数来发送所有的帧的。而驱动在发送数据时的速率是直接用节点的成员变量PMacEntry->HTPhyMode;

    *  在发送一个报文时,它找到对应的节点,就可以取出当前的速率。

    *  至于PMacEntry->HTPhyMode,driver中是通过APMlmeDynamicTxRateSwitching函数(call this routine every second ,walk through MAC table, see if need to change AP's TX rate towardeach entry)来实现对每个节点的速率的周期性维护。

    2. 算法分析
    2.1 算法的流程
    在算法中会使用到如下的速率表,算法中会使用该表中的TrainUp以及TrainDown来决定是降速还是升速。

    如下是传输速率表的一个例子:

    UCHAR RateSwitchTable[] = {

    /* Item No.   Mode   Curr-MCS   TrainUp   TrainDown                

    Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)*/

        0x11, 0x00,  0,  0,  0,                   /* Initial used item after association;连接后刚开始使用这个速率表项*/

        0x00, 0x00,  0, 40, 101,

        0x01, 0x00,  1, 40, 50,

        0x02, 0x00,  2, 35, 45,

        0x03, 0x00,  3, 20, 45,

        0x04, 0x21,  0, 30, 50,

        0x05, 0x21,  1, 20, 50,

        0x06, 0x21,  2, 20, 50,

        0x07, 0x21,  3, 15, 50,

        0x08, 0x21,  4, 15, 30,

        0x09, 0x21,  5, 10, 25,

        0x0a, 0x21,  6,  8, 25,

        0x0b, 0x21,  7,  8, 25,

        0x0c, 0x20, 12,  15, 30,

        0x0d, 0x20, 13,  8, 20,

        0x0e, 0x20, 14,  8, 20,

        0x0f, 0x20, 15,  8, 25,

        0x10, 0x22, 15,  8, 25,

        0x11, 0x00,  0,  0,  0,

        0x12, 0x00,  0,  0,  0,

        0x13, 0x00,  0,  0,  0,

        0x14, 0x00,  0,  0,  0,

        0x15, 0x00,  0,  0,  0,

        0x16, 0x00,  0,  0,  0,

        0x17, 0x00,  0,  0,  0,

        0x18, 0x00,  0,  0,  0,

        0x19, 0x00,  0,  0,  0,

        0x1a, 0x00,  0,  0,  0,

        0x1b, 0x00,  0,  0,  0,

        0x1c, 0x00,  0,  0,  0,

        0x1d, 0x00,  0,  0,  0,

        0x1e, 0x00,  0,  0,  0,

        0x1f, 0x00,  0,  0,  0,

    };

    表项对应的数据结构为:

    typedef struct _RTMP_TX_RATE_SWITCH

    {

             UCHAR   ItemNo;

    #ifdef RT_BIG_ENDIAN

             UCHAR     Rsv2:2;

             UCHAR     Mode:2;

             UCHAR     Rsv1:1;    

             UCHAR     BW:1;

             UCHAR     ShortGI:1;

             UCHAR     STBC:1;

    #else

             UCHAR     STBC:1;

             UCHAR     ShortGI:1;

             UCHAR     BW:1;

             UCHAR     Rsv1:1;

             UCHAR     Mode:2;

             UCHAR     Rsv2:2;

    #endif      

             UCHAR   CurrMCS;

             UCHAR   TrainUp;

             UCHAR   TrainDown;

    } RTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;

    上面的接口中我们重点关注TrainUp和TrainDown。

    如果发包错误率(PER: Packet Error Rate)大于等于TrainDown,并且一秒钟内发包数量大于一定数值,Driver就会选择降速;

    如果发包错误率小于等于TrainUp, 并且一秒钟内发包数量大于一定数值,Driver就会选择升速;

      算法流程参见下图:

    2.2算法的分析
    *  如果上一秒统计的总的发送报文数<=15,那么仅根据Rssi来选择发送的速率,原则是选择出满足RSSI条件的最大的发送速率;

    *  如果发送报文个数>15个,根据发包错误率来决定未来的传输速度。

           #  如果发包错误率(PER: Packet Error Rate)大于等于TrainDown,Driver就会选择降速;

           #  如果发包错误率小于等于TrainUp,Driver就会选择升速;

     
    ---------------------
    作者:飞越丛林
    来源:CSDN
    原文:https://blog.csdn.net/junglefly/article/details/48974077
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    cocos2d-x Tests讲解 Particle System(粒子系统)
    c++ 知识点
    详解C/C++函数指针声明
    VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径
    cocos2d-x学习知识点记录
    Ogre实现简单地形
    Ogre内部渲染流程分析系列
    gcc/g++编译
    gcc和g++的区别
    Hack with rewrite
  • 原文地址:https://www.cnblogs.com/newjiang/p/10804495.html
Copyright © 2011-2022 走看看