|
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 */
|