src/devices/wifi/minstrel-wifi-manager.h
author Duy Nguyen <duy@soe.ucsc.edu>
Thu Aug 13 08:45:47 2009 +0200 (2009-08-13)
changeset 4703 e1259e2fdaad
child 6065 0f012e7d9128
permissions -rw-r--r--
add an implementation of the minstrel rate control algorithm
duy@4703
     1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
duy@4703
     2
/* 
duy@4703
     3
 * Copyright (c) 2009 Duy Nguyen 
duy@4703
     4
 * 
duy@4703
     5
 * This program is free software; you can redistribute it and/or modify
duy@4703
     6
 * it under the terms of the GNU General Public License version 2 as
duy@4703
     7
 * published by the Free Software Foundation;
duy@4703
     8
 *
duy@4703
     9
 * This program is distributed in the hope that it will be useful,
duy@4703
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
duy@4703
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
duy@4703
    12
 * GNU General Public License for more details.
duy@4703
    13
 *
duy@4703
    14
 * You should have received a copy of the GNU General Public License
duy@4703
    15
 * along with this program; if not, write to the Free Software
duy@4703
    16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
duy@4703
    17
 * 
duy@4703
    18
 * Author: Duy Nguyen <duy@soe.ucsc.edu> 
duy@4703
    19
 */
duy@4703
    20
duy@4703
    21
duy@4703
    22
duy@4703
    23
#ifndef MINSTREL_WIFI_MANAGER_H
duy@4703
    24
#define MINSTREL_WIFI_MANAGER_H
duy@4703
    25
duy@4703
    26
#include "wifi-remote-station-manager.h"
duy@4703
    27
#include "wifi-mode.h"
duy@4703
    28
#include "ns3/nstime.h"
duy@4703
    29
#include <vector>
duy@4703
    30
duy@4703
    31
duy@4703
    32
duy@4703
    33
/**
duy@4703
    34
 * \author Duy Nguyen
duy@4703
    35
 * \brief Implementation of Minstrel Rate Control Algorithm 
duy@4703
    36
 *
duy@4703
    37
 * Porting Minstrel from Madwifi and Linux Kernel 
duy@4703
    38
 * http://linuxwireless.org/en/developers/Documentation/mac80211/RateControl/minstrel
duy@4703
    39
 */
duy@4703
    40
duy@4703
    41
duy@4703
    42
namespace ns3 {
duy@4703
    43
duy@4703
    44
duy@4703
    45
/**
duy@4703
    46
 * A struct to contain all information related to a data rate 
duy@4703
    47
 */
duy@4703
    48
struct RateInfo{
duy@4703
    49
duy@4703
    50
  /**
duy@4703
    51
   * Perfect transmission time calculation, or frame calculation
duy@4703
    52
   * Given a bit rate and a packet length n bytes 
duy@4703
    53
   */
duy@4703
    54
  Time perfectTxTime;		
duy@4703
    55
duy@4703
    56
duy@4703
    57
  uint32_t retryCount;  ///< retry limit
duy@4703
    58
  uint32_t adjustedRetryCount;  ///< adjust the retry limit for this rate
duy@4703
    59
  uint32_t numRateAttempt;  ///< how many number of attempts so far
duy@4703
    60
  uint32_t numRateSuccess;  ///< number of successful pkts 
duy@4703
    61
  uint32_t prob;  ///< (# pkts success )/(# total pkts)
duy@4703
    62
duy@4703
    63
  /**
duy@4703
    64
   * EWMA calculation
duy@4703
    65
   * ewma_prob =[prob *(100 - ewma_level) + (ewma_prob_old * ewma_level)]/100 
duy@4703
    66
   */
duy@4703
    67
  uint32_t ewmaProb;
duy@4703
    68
duy@4703
    69
  uint32_t prevNumRateAttempt;  ///< from last rate
duy@4703
    70
  uint32_t prevNumRateSuccess;  ///< from last rate
duy@4703
    71
  uint64_t successHist;  ///< aggregate of all successes
duy@4703
    72
  uint64_t attemptHist;  ///< aggregate of all attempts
duy@4703
    73
  uint32_t throughput;  ///< throughput of a rate
duy@4703
    74
};
duy@4703
    75
duy@4703
    76
/**
duy@4703
    77
 * Data structure for a Minstrel Rate table 
duy@4703
    78
 * A vector of a struct RateInfo 
duy@4703
    79
 */
duy@4703
    80
typedef std::vector<struct RateInfo> MinstrelRate;
duy@4703
    81
duy@4703
    82
/**
duy@4703
    83
 * Data structure for a Sample Rate table
duy@4703
    84
 * A vector of a vector uint32_t 
duy@4703
    85
 */
duy@4703
    86
typedef std::vector<std::vector<uint32_t> > SampleRate;
duy@4703
    87
duy@4703
    88
duy@4703
    89
class MinstrelWifiManager : public WifiRemoteStationManager
duy@4703
    90
{
duy@4703
    91
duy@4703
    92
public:
duy@4703
    93
  static TypeId GetTypeId (void);
duy@4703
    94
  MinstrelWifiManager ();
duy@4703
    95
  virtual ~MinstrelWifiManager();
duy@4703
    96
duy@4703
    97
  virtual void SetupPhy (Ptr<WifiPhy> phy);
duy@4703
    98
duy@4703
    99
  /// for estimating the TxTime of a packet with a given mode  
duy@4703
   100
  Time GetCalcTxTime (WifiMode mode) const;
duy@4703
   101
  void AddCalcTxTime (WifiMode mode, Time t);
duy@4703
   102
duy@4703
   103
private:
duy@4703
   104
  friend class MinstrelWifiRemoteStation;
duy@4703
   105
  virtual class WifiRemoteStation *CreateStation (void);
duy@4703
   106
duy@4703
   107
  typedef std::vector<std::pair<Time,WifiMode> > TxTime;
duy@4703
   108
duy@4703
   109
  TxTime m_calcTxTime;  ///< to hold all the calculated TxTime for all modes
duy@4703
   110
  Time m_updateStats;  ///< how frequent do we calculate the stats(1/10 seconds)
duy@4703
   111
  double m_lookAroundRate;  ///< the % to try other rates than our current rate 
duy@4703
   112
  double m_ewmaLevel;  ///< exponential weighted moving average
duy@4703
   113
  uint32_t m_segmentSize;  ///< largest allowable segment size
duy@4703
   114
  uint32_t m_sampleCol;  ///< number of sample columns
duy@4703
   115
  uint32_t m_pktLen;  ///< packet length used  for calculate mode TxTime
duy@4703
   116
  
duy@4703
   117
};
duy@4703
   118
duy@4703
   119
class MinstrelWifiRemoteStation : public WifiRemoteStation
duy@4703
   120
{
duy@4703
   121
public:
duy@4703
   122
  MinstrelWifiRemoteStation (Ptr<MinstrelWifiManager> stations);
duy@4703
   123
 
duy@4703
   124
  virtual ~MinstrelWifiRemoteStation ();
duy@4703
   125
duy@4703
   126
protected:
duy@4703
   127
duy@4703
   128
  /** 
duy@4703
   129
   * when packet is successfully received
duy@4703
   130
   * see wifi-remote-station-manager.h for more documentation
duy@4703
   131
   */
duy@4703
   132
  virtual void DoReportRxOk (double rxSnr, WifiMode txMode);
duy@4703
   133
duy@4703
   134
  /// when RTS timeout expires
duy@4703
   135
  virtual void DoReportRtsFailed (void);
duy@4703
   136
duy@4703
   137
duy@4703
   138
  /**
duy@4703
   139
   *
duy@4703
   140
   * Retry Chain table is implemented here
duy@4703
   141
   *
duy@4703
   142
   * Try |         LOOKAROUND RATE              | NORMAL RATE
duy@4703
   143
   *     | random < best    | random > best     |
duy@4703
   144
   * --------------------------------------------------------------
duy@4703
   145
   *  1  | Best throughput  | Random rate       | Best throughput
duy@4703
   146
   *  2  | Random rate      | Best throughput   | Next best throughput
duy@4703
   147
   *  3  | Best probability | Best probability  | Best probability
duy@4703
   148
   *  4  | Lowest Baserate  | Lowest baserate   | Lowest baserate
duy@4703
   149
   *
duy@4703
   150
   * Note: For clarity, multiple blocks of if's and else's are used
duy@4703
   151
   * After a failing 7 times, DoReportFinalDataFailed will be called
duy@4703
   152
   */
duy@4703
   153
  virtual void DoReportDataFailed (void);
duy@4703
   154
duy@4703
   155
  /// when receive a CTS, associated with an RTS
duy@4703
   156
  virtual void DoReportRtsOk (double ctsSnr, WifiMode ctsMode, double rtsSnr);
duy@4703
   157
duy@4703
   158
  /// when an ACK, associated with a data pkt, is received
duy@4703
   159
  virtual void DoReportDataOk (double ackSnr, WifiMode ackMode, double dataSnr);
duy@4703
   160
duy@4703
   161
  /// after calling ReportRtsFailed if NeedRtsRetransmission returns false
duy@4703
   162
  virtual void DoReportFinalRtsFailed (void);
duy@4703
   163
duy@4703
   164
  /// after calling ReportDataFailed if NeedDataRetransmission returns false
duy@4703
   165
  virtual void DoReportFinalDataFailed (void);
duy@4703
   166
duy@4703
   167
duy@4703
   168
private:
duy@4703
   169
  virtual Ptr<WifiRemoteStationManager> GetManager (void) const;
duy@4703
   170
duy@4703
   171
  /** 
duy@4703
   172
   * returns the transmission mode for sending this packet
duy@4703
   173
   * this function gets called when node is getting ready to send DATA
duy@4703
   174
   * see wifi-remote-station-manager.h for more documentation
duy@4703
   175
   */
duy@4703
   176
  virtual WifiMode DoGetDataMode (uint32_t size);
duy@4703
   177
duy@4703
   178
  /// returns the transmission mode for sending RTS packet
duy@4703
   179
  virtual WifiMode DoGetRtsMode (void);
duy@4703
   180
duy@4703
   181
  /// update the number of retries and reset accordingly
duy@4703
   182
  void UpdateRetry (void);
duy@4703
   183
duy@4703
   184
  /// getting the next sample from Sample Table
duy@4703
   185
  uint32_t GetNextSample (void);
duy@4703
   186
duy@4703
   187
  /// find a rate to use from Minstrel Table
duy@4703
   188
  uint32_t FindRate (void);
duy@4703
   189
duy@4703
   190
  /// updating the Minstrel Table every 1/10 seconds
duy@4703
   191
  void UpdateStats (void);
duy@4703
   192
duy@4703
   193
  /// initialize Minstrel Table
duy@4703
   194
  void RateInit (void);
duy@4703
   195
duy@4703
   196
  /// initialize Sample Table
duy@4703
   197
  void InitSampleTable (void);
duy@4703
   198
duy@4703
   199
  /// printing Sample Table
duy@4703
   200
  void PrintSampleTable (void);
duy@4703
   201
duy@4703
   202
  /// printing Minstrel Table
duy@4703
   203
  void PrintTable (void);
duy@4703
   204
duy@4703
   205
  /**
duy@4703
   206
   * \param packet lenghth 
duy@4703
   207
   * \param current WifiMode
duy@4703
   208
   * \returns calcuated transmit duration 
duy@4703
   209
   */
duy@4703
   210
  Time CalcRatePacket (uint32_t, WifiMode);
duy@4703
   211
duy@4703
   212
  void CheckInit(void);  ///< check for initializations
duy@4703
   213
duy@4703
   214
  Ptr<MinstrelWifiManager> m_stations;
duy@4703
   215
duy@4703
   216
  Time m_nextStatsUpdate;  ///< 10 times every second
duy@4703
   217
duy@4703
   218
  MinstrelRate m_minstrelTable;  ///< minstrel table	
duy@4703
   219
duy@4703
   220
  SampleRate m_sampleTable;  ///< sample table
duy@4703
   221
duy@4703
   222
  /**
duy@4703
   223
   * To keep track of the current position in the our random sample table
duy@4703
   224
   * going row by row from 1st column until the 10th column(Minstrel defines 10)
duy@4703
   225
   * then we wrap back to the row 1 col 1.
duy@4703
   226
   * note: there are many other ways to do this.
duy@4703
   227
   */
duy@4703
   228
  uint32_t m_col, m_index;							
duy@4703
   229
duy@4703
   230
  uint32_t m_maxTpRate;  ///< the current throughput rate 
duy@4703
   231
  uint32_t m_maxTpRate2;  ///< second highest throughput rate
duy@4703
   232
  uint32_t m_maxProbRate;  ///< rate with highest prob of success
duy@4703
   233
duy@4703
   234
  int m_packetCount;  ///< total number of packets as of now
duy@4703
   235
  int m_sampleCount;  ///< how many packets we have sample so far
duy@4703
   236
duy@4703
   237
  bool m_isSampling;  ///< a flag to indicate we are currently sampling
duy@4703
   238
  uint32_t m_sampleRate;  ///< current sample rate
duy@4703
   239
  bool 	m_sampleRateSlower;  ///< a flag to indicate sample rate is slower
duy@4703
   240
  uint32_t m_currentRate;  ///< current rate we are using
duy@4703
   241
duy@4703
   242
  uint32_t m_shortRetry;  ///< short retries such as control packts
duy@4703
   243
  uint32_t m_longRetry;  ///< long retries such as data packets
duy@4703
   244
  uint32_t m_retry;  ///< total retries short + long
duy@4703
   245
  uint32_t m_err;  ///< retry errors
duy@4703
   246
  uint32_t m_txrate;  ///< current transmit rate
duy@4703
   247
duy@4703
   248
  bool m_initialized;  ///< for initializing tables
duy@4703
   249
duy@4703
   250
duy@4703
   251
}; 
duy@4703
   252
duy@4703
   253
}// namespace ns3
duy@4703
   254
duy@4703
   255
#endif /* MINSTREL_WIFI_MANAGER_H */