File: | /tmp/asd-nat/home/nat/Work/ns-3-dev-git/build/../src/wifi/model/minstrel-ht-wifi-manager.cc |
Location: | line 1108, column 30 |
Description: | Division by zero |
1 | /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | |||
2 | /* | |||
3 | * Copyright (c) 2009 Duy Nguyen | |||
4 | * Copyright (c) 2015 Ghada Badawy | |||
5 | * | |||
6 | * This program is free software; you can redistribute it and/or modify | |||
7 | * it under the terms of the GNU General Public License version 2 as | |||
8 | * published by the Free Software Foundation; | |||
9 | * | |||
10 | * This program is distributed in the hope that it will be useful, | |||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
13 | * GNU General Public License for more details. | |||
14 | * | |||
15 | * You should have received a copy of the GNU General Public License | |||
16 | * along with this program; if not, write to the Free Software | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
18 | * | |||
19 | * Authors: Duy Nguyen <duy@soe.ucsc.edu> | |||
20 | * Ghada Badawy <gbadawy@gmail.com> | |||
21 | * Matias Richart <mrichart@fing.edu.uy> | |||
22 | * | |||
23 | * Some Comments: | |||
24 | * | |||
25 | * 1) By default, Minstrel applies the multi-rate retry (the core of Minstrel | |||
26 | * algorithm). Otherwise, please use ConstantRateWifiManager instead. | |||
27 | * | |||
28 | * 2) Sampling is done differently from legacy Minstrel. Minstrel-HT tries | |||
29 | * to sample all rates in all groups at least once and to avoid many | |||
30 | * consecutive samplings. | |||
31 | * | |||
32 | * 3) Sample rate is tried only once, at first place of the MRR chain. | |||
33 | * | |||
34 | * reference: http://lwn.net/Articles/376765/ | |||
35 | */ | |||
36 | ||||
37 | #include "minstrel-ht-wifi-manager.h" | |||
38 | #include "ns3/simulator.h" | |||
39 | #include "ns3/log.h" | |||
40 | #include "ns3/double.h" | |||
41 | #include "ns3/boolean.h" | |||
42 | #include "wifi-mac.h" | |||
43 | #include "wifi-phy.h" | |||
44 | #include <iomanip> | |||
45 | ||||
46 | #define Min(a,b)((a < b) ? a : b) ((a < b) ? a : b) | |||
47 | #define Max(a,b)((a > b) ? a : b) ((a > b) ? a : b) | |||
48 | ||||
49 | NS_LOG_COMPONENT_DEFINE ("MinstrelHtWifiManager")static ns3::LogComponent g_log = ns3::LogComponent ("MinstrelHtWifiManager" , "../src/wifi/model/minstrel-ht-wifi-manager.cc"); | |||
50 | ||||
51 | namespace ns3 { | |||
52 | ||||
53 | ///MinstrelHtWifiRemoteStation structure | |||
54 | struct MinstrelHtWifiRemoteStation : MinstrelWifiRemoteStation | |||
55 | { | |||
56 | /// Dispose station function | |||
57 | void DisposeStation (); | |||
58 | ||||
59 | uint32_t m_sampleGroup; //!< The group that the sample rate belongs to. | |||
60 | ||||
61 | uint32_t m_sampleWait; //!< How many transmission attempts to wait until a new sample. | |||
62 | uint32_t m_sampleTries; //!< Number of sample tries after waiting sampleWait. | |||
63 | uint32_t m_sampleCount; //!< Max number of samples per update interval. | |||
64 | uint32_t m_numSamplesSlow; //!< Number of times a slow rate was sampled. | |||
65 | ||||
66 | double m_avgAmpduLen; //!< Average number of MPDUs in an A-MPDU. | |||
67 | double m_ampduLen; //!< Number of MPDUs in an A-MPDU. | |||
68 | uint32_t m_ampduPacketCount; //!< Number of A-MPDUs transmitted. | |||
69 | ||||
70 | McsGroupData m_groupsTable; //!< Table of groups with stats. | |||
71 | bool m_isHt; //!< If the station is HT capable. | |||
72 | ||||
73 | std::ofstream m_statsFile; //!< File where statistics table is written. | |||
74 | }; | |||
75 | ||||
76 | void | |||
77 | MinstrelHtWifiRemoteStation::DisposeStation () | |||
78 | { | |||
79 | if (m_isHt) | |||
80 | { | |||
81 | std::vector<std::vector<uint32_t> > ().swap (m_sampleTable); | |||
82 | for (uint8_t j = 0; j < m_groupsTable.size (); j++) | |||
83 | { | |||
84 | std::vector<HtRateInfo> ().swap (m_groupsTable[j].m_ratesTable); | |||
85 | } | |||
86 | std::vector<GroupInfo> ().swap (m_groupsTable); | |||
87 | m_statsFile.close (); | |||
88 | } | |||
89 | } | |||
90 | ||||
91 | NS_OBJECT_ENSURE_REGISTERED (MinstrelHtWifiManager)static struct ObjectMinstrelHtWifiManagerRegistrationClass { ObjectMinstrelHtWifiManagerRegistrationClass () { ns3::TypeId tid = MinstrelHtWifiManager::GetTypeId (); tid .SetSize (sizeof (MinstrelHtWifiManager)); tid.GetParent (); } } ObjectMinstrelHtWifiManagerRegistrationVariable; | |||
92 | ||||
93 | TypeId | |||
94 | MinstrelHtWifiManager::GetTypeId (void) | |||
95 | { | |||
96 | static TypeId tid = TypeId ("ns3::MinstrelHtWifiManager") | |||
97 | .SetParent<WifiRemoteStationManager> () | |||
98 | .AddConstructor<MinstrelHtWifiManager> () | |||
99 | .SetGroupName ("Wifi") | |||
100 | .AddAttribute ("UpdateStatistics", | |||
101 | "The interval between updating statistics table ", | |||
102 | TimeValue (MilliSeconds (100)), | |||
103 | MakeTimeAccessor (&MinstrelHtWifiManager::m_updateStats), | |||
104 | MakeTimeChecker ()) | |||
105 | .AddAttribute ("LookAroundRate", | |||
106 | "The percentage to try other rates (for legacy Minstrel)", | |||
107 | DoubleValue (10), | |||
108 | MakeDoubleAccessor (&MinstrelHtWifiManager::m_lookAroundRate), | |||
109 | MakeDoubleChecker<double> (0, 100)) | |||
110 | .AddAttribute ("EWMA", | |||
111 | "EWMA level", | |||
112 | DoubleValue (75), | |||
113 | MakeDoubleAccessor (&MinstrelHtWifiManager::m_ewmaLevel), | |||
114 | MakeDoubleChecker<double> (0, 100)) | |||
115 | .AddAttribute ("SampleColumn", | |||
116 | "The number of columns used for sampling", | |||
117 | UintegerValue (10), | |||
118 | MakeUintegerAccessor (&MinstrelHtWifiManager::m_nSampleCol), | |||
119 | MakeUintegerChecker <uint32_t> ()) | |||
120 | .AddAttribute ("PacketLength", | |||
121 | "The packet length used for calculating mode TxTime", | |||
122 | UintegerValue (1200), | |||
123 | MakeUintegerAccessor (&MinstrelHtWifiManager::m_frameLength), | |||
124 | MakeUintegerChecker <uint32_t> ()) | |||
125 | .AddAttribute ("UseVhtOnly", | |||
126 | "Use only VHT MCSs (and not HT) when VHT is available", | |||
127 | BooleanValue (true), | |||
128 | MakeBooleanAccessor (&MinstrelHtWifiManager::m_useVhtOnly), | |||
129 | MakeBooleanChecker ()) | |||
130 | .AddAttribute ("PrintStats", | |||
131 | "Control the printing of the statistics table", | |||
132 | BooleanValue (false), | |||
133 | MakeBooleanAccessor (&MinstrelHtWifiManager::m_printStats), | |||
134 | MakeBooleanChecker ()) | |||
135 | .AddTraceSource ("RateChange", | |||
136 | "The transmission rate has changed", | |||
137 | MakeTraceSourceAccessor (&MinstrelHtWifiManager::m_rateChange), | |||
138 | "ns3::MinstrelHtWifiManager::RateChangeTracedCallback") | |||
139 | ; | |||
140 | return tid; | |||
141 | } | |||
142 | ||||
143 | MinstrelHtWifiManager::MinstrelHtWifiManager () | |||
144 | : m_numGroups (0), | |||
145 | m_numRates (0) | |||
146 | { | |||
147 | NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this; std::clog << ")" << std::endl; } } while ( false); | |||
148 | m_uniformRandomVariable = CreateObject<UniformRandomVariable> (); | |||
149 | /** | |||
150 | * Create the legacy Minstrel manager in case HT is not supported by the device | |||
151 | * or non-HT stations want to associate. | |||
152 | */ | |||
153 | m_legacyManager = CreateObject<MinstrelWifiManager> (); | |||
154 | } | |||
155 | ||||
156 | MinstrelHtWifiManager::~MinstrelHtWifiManager () | |||
157 | { | |||
158 | NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this; std::clog << ")" << std::endl; } } while ( false); | |||
159 | if (HasHtSupported ()) | |||
160 | { | |||
161 | for (uint32_t i = 0; i < m_numGroups; i++) | |||
162 | { | |||
163 | m_minstrelGroups[i].ratesFirstMpduTxTimeTable.clear (); | |||
164 | m_minstrelGroups[i].ratesTxTimeTable.clear (); | |||
165 | } | |||
166 | } | |||
167 | } | |||
168 | ||||
169 | int64_t | |||
170 | MinstrelHtWifiManager::AssignStreams (int64_t stream) | |||
171 | { | |||
172 | NS_LOG_FUNCTION (this << stream)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << stream; std::clog << ")" << std::endl ; } } while (false); | |||
173 | int64_t numStreamsAssigned = 0; | |||
174 | m_uniformRandomVariable->SetStream (stream); | |||
175 | numStreamsAssigned++; | |||
176 | numStreamsAssigned += m_legacyManager->AssignStreams (stream); | |||
177 | return numStreamsAssigned; | |||
178 | } | |||
179 | ||||
180 | void | |||
181 | MinstrelHtWifiManager::SetupPhy (Ptr<WifiPhy> phy) | |||
182 | { | |||
183 | NS_LOG_FUNCTION (this << phy)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << phy; std::clog << ")" << std::endl ; } } while (false); | |||
184 | // Setup phy for legacy manager. | |||
185 | m_legacyManager->SetupPhy (phy); | |||
186 | WifiRemoteStationManager::SetupPhy (phy); | |||
187 | } | |||
188 | ||||
189 | void | |||
190 | MinstrelHtWifiManager::DoInitialize () | |||
191 | { | |||
192 | NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this; std::clog << ")" << std::endl; } } while ( false); | |||
193 | ||||
194 | /** | |||
195 | * Here we initialize m_minstrelGroups with all the possible groups. | |||
196 | * If a group is not supported by the device, then it is marked as not supported. | |||
197 | * Then, after all initializations are finished, we check actual support for each receiving station. | |||
198 | */ | |||
199 | ||||
200 | // Check if the device supports HT or VHT | |||
201 | if (HasHtSupported () || HasVhtSupported ()) | |||
202 | { | |||
203 | m_numGroups = MAX_SUPPORTED_STREAMS * MAX_HT_STREAM_GROUPS; | |||
204 | m_numRates = MAX_HT_GROUP_RATES; | |||
205 | ||||
206 | if (HasVhtSupported ()) | |||
207 | { | |||
208 | m_numGroups += MAX_SUPPORTED_STREAMS * MAX_VHT_STREAM_GROUPS; | |||
209 | m_numRates = MAX_VHT_GROUP_RATES; | |||
210 | } | |||
211 | ||||
212 | /** | |||
213 | * Initialize the groups array. | |||
214 | * The HT groups come first, then the VHT ones. | |||
215 | * Minstrel maintains different types of indexes: | |||
216 | * - A global continuous index, which identifies all rates within all groups, in [0, m_numGroups * m_numRates] | |||
217 | * - A groupId, which indexes a group in the array, in [0, m_numGroups] | |||
218 | * - A rateId, which identifies a rate within a group, in [0, m_numRates] | |||
219 | * - A deviceIndex, which indexes a MCS in the phy MCS array. | |||
220 | * - A mcsIndex, which indexes a MCS in the wifi-remote-station-manager supported MCSs array. | |||
221 | */ | |||
222 | NS_LOG_DEBUG ("Initialize MCS Groups:")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Initialize MCS Groups:" << std::endl; } } while (false); | |||
223 | m_minstrelGroups = MinstrelMcsGroups (m_numGroups); | |||
224 | ||||
225 | // Initialize all HT groups | |||
226 | for (uint8_t chWidth = 20; chWidth <= MAX_HT_WIDTH; chWidth *= 2) | |||
227 | { | |||
228 | for (uint8_t sgi = 0; sgi <= 1; sgi++) | |||
229 | { | |||
230 | for (uint8_t streams = 1; streams <= MAX_SUPPORTED_STREAMS; streams++) | |||
231 | { | |||
232 | uint32_t groupId = GetHtGroupId (streams, sgi, chWidth); | |||
233 | ||||
234 | m_minstrelGroups[groupId].streams = streams; | |||
235 | m_minstrelGroups[groupId].sgi = sgi; | |||
236 | m_minstrelGroups[groupId].chWidth = chWidth; | |||
237 | m_minstrelGroups[groupId].isVht = false; | |||
238 | m_minstrelGroups[groupId].isSupported = false; | |||
239 | ||||
240 | // Check capabilities of the device | |||
241 | if (!(!GetPhy ()->GetShortGuardInterval () && m_minstrelGroups[groupId].sgi) ///Is SGI supported by the transmitter? | |||
242 | && (GetPhy ()->GetChannelWidth () >= m_minstrelGroups[groupId].chWidth) ///Is channel width supported by the transmitter? | |||
243 | && (GetPhy ()->GetMaxSupportedTxSpatialStreams () >= m_minstrelGroups[groupId].streams)) ///Are streams supported by the transmitter? | |||
244 | { | |||
245 | m_minstrelGroups[groupId].isSupported = true; | |||
246 | ||||
247 | // Calculate tx time for all rates of the group | |||
248 | WifiModeList htMcsList = GetHtDeviceMcsList (); | |||
249 | for (uint8_t i = 0; i < MAX_HT_GROUP_RATES; i++) | |||
250 | { | |||
251 | uint32_t deviceIndex = i + (m_minstrelGroups[groupId].streams - 1) * 8; | |||
252 | WifiMode mode = htMcsList[deviceIndex]; | |||
253 | AddFirstMpduTxTime (groupId, mode, CalculateFirstMpduTxDuration (GetPhy (), streams, sgi, chWidth, mode)); | |||
254 | AddMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, sgi, chWidth, mode)); | |||
255 | } | |||
256 | NS_LOG_DEBUG ("Initialized group " << groupId << ": (" << (uint16_t)streams << "," << (uint16_t)sgi << "," << (uint16_t)chWidth << ")")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Initialized group " << groupId << ": (" << (uint16_t)streams << "," << (uint16_t)sgi << "," << (uint16_t)chWidth << ")" << std::endl; } } while (false); | |||
257 | } | |||
258 | } | |||
259 | } | |||
260 | } | |||
261 | ||||
262 | if (HasVhtSupported ()) | |||
263 | { | |||
264 | // Initialize all VHT groups | |||
265 | for (uint16_t chWidth = 20; chWidth <= MAX_VHT_WIDTH; chWidth *= 2) | |||
266 | { | |||
267 | for (uint8_t sgi = 0; sgi <= 1; sgi++) | |||
268 | { | |||
269 | for (uint8_t streams = 1; streams <= MAX_SUPPORTED_STREAMS; streams++) | |||
270 | { | |||
271 | uint32_t groupId = GetVhtGroupId (streams, sgi, chWidth); | |||
272 | ||||
273 | m_minstrelGroups[groupId].streams = streams; | |||
274 | m_minstrelGroups[groupId].sgi = sgi; | |||
275 | m_minstrelGroups[groupId].chWidth = chWidth; | |||
276 | m_minstrelGroups[groupId].isVht = true; | |||
277 | m_minstrelGroups[groupId].isSupported = false; | |||
278 | ||||
279 | // Check capabilities of the device | |||
280 | if (!(!GetPhy ()->GetShortGuardInterval () && m_minstrelGroups[groupId].sgi) ///Is SGI supported by the transmitter? | |||
281 | && (GetPhy ()->GetChannelWidth () >= m_minstrelGroups[groupId].chWidth) ///Is channel width supported by the transmitter? | |||
282 | && (GetPhy ()->GetMaxSupportedTxSpatialStreams () >= m_minstrelGroups[groupId].streams)) ///Are streams supported by the transmitter? | |||
283 | { | |||
284 | m_minstrelGroups[groupId].isSupported = true; | |||
285 | ||||
286 | // Calculate tx time for all rates of the group | |||
287 | WifiModeList vhtMcsList = GetVhtDeviceMcsList (); | |||
288 | for (uint8_t i = 0; i < MAX_VHT_GROUP_RATES; i++) | |||
289 | { | |||
290 | WifiMode mode = vhtMcsList[i]; | |||
291 | // Check for invalid VHT MCSs and do not add time to array. | |||
292 | if (IsValidMcs (GetPhy (), streams, chWidth, mode)) | |||
293 | { | |||
294 | AddFirstMpduTxTime (groupId, mode, CalculateFirstMpduTxDuration (GetPhy (), streams, sgi, chWidth, mode)); | |||
295 | AddMpduTxTime (groupId, mode, CalculateMpduTxDuration (GetPhy (), streams, sgi, chWidth, mode)); | |||
296 | } | |||
297 | } | |||
298 | NS_LOG_DEBUG ("Initialized group " << groupId << ": (" << (uint16_t)streams << "," << (uint16_t)sgi << "," << (uint16_t)chWidth << ")")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Initialized group " << groupId << ": (" << (uint16_t)streams << "," << (uint16_t)sgi << "," << (uint16_t)chWidth << ")" << std::endl; } } while (false); | |||
299 | } | |||
300 | } | |||
301 | } | |||
302 | } | |||
303 | } | |||
304 | } | |||
305 | } | |||
306 | ||||
307 | void | |||
308 | MinstrelHtWifiManager::SetupMac (Ptr<WifiMac> mac) | |||
309 | { | |||
310 | NS_LOG_FUNCTION (this << mac)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << mac; std::clog << ")" << std::endl ; } } while (false); | |||
311 | m_legacyManager->SetupMac (mac); | |||
312 | WifiRemoteStationManager::SetupMac (mac); | |||
313 | } | |||
314 | ||||
315 | bool | |||
316 | MinstrelHtWifiManager::IsValidMcs (Ptr<WifiPhy> phy, uint8_t streams, uint8_t chWidth, WifiMode mode) | |||
317 | { | |||
318 | NS_LOG_FUNCTION (this << phy << (uint16_t)streams << (uint16_t)chWidth << mode)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << phy << (uint16_t)streams << (uint16_t )chWidth << mode; std::clog << ")" << std:: endl; } } while (false); | |||
319 | ||||
320 | WifiTxVector txvector; | |||
321 | txvector.SetNss (streams); | |||
322 | txvector.SetChannelWidth (chWidth); | |||
323 | txvector.SetMode (mode); | |||
324 | return phy->IsValidTxVector (txvector); | |||
325 | } | |||
326 | ||||
327 | Time | |||
328 | MinstrelHtWifiManager::CalculateFirstMpduTxDuration (Ptr<WifiPhy> phy, uint8_t streams, uint8_t sgi, uint8_t chWidth, WifiMode mode) | |||
329 | { | |||
330 | NS_LOG_FUNCTION (this << phy << (uint16_t)streams << (uint16_t)sgi << (uint16_t)chWidth << mode)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << phy << (uint16_t)streams << (uint16_t )sgi << (uint16_t)chWidth << mode; std::clog << ")" << std::endl; } } while (false); | |||
331 | ||||
332 | WifiTxVector txvector; | |||
333 | txvector.SetNss (streams); | |||
334 | txvector.SetGuardInterval (sgi ? 400 : 800); | |||
335 | txvector.SetChannelWidth (chWidth); | |||
336 | txvector.SetNess (0); | |||
337 | txvector.SetStbc (phy->GetStbc ()); | |||
338 | txvector.SetMode (mode); | |||
339 | txvector.SetPreambleType (WIFI_PREAMBLE_HT_MF); | |||
340 | return phy->CalculateTxDuration (m_frameLength, txvector, phy->GetFrequency (), MPDU_IN_AGGREGATE, 0); | |||
341 | } | |||
342 | ||||
343 | Time | |||
344 | MinstrelHtWifiManager::CalculateMpduTxDuration (Ptr<WifiPhy> phy, uint8_t streams, uint8_t sgi, uint8_t chWidth, WifiMode mode) | |||
345 | { | |||
346 | NS_LOG_FUNCTION (this << phy << (uint16_t)streams << (uint16_t)sgi << (uint16_t)chWidth << mode)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << phy << (uint16_t)streams << (uint16_t )sgi << (uint16_t)chWidth << mode; std::clog << ")" << std::endl; } } while (false); | |||
347 | ||||
348 | WifiTxVector txvector; | |||
349 | txvector.SetNss (streams); | |||
350 | txvector.SetGuardInterval (sgi ? 400 : 800); | |||
351 | txvector.SetChannelWidth (chWidth); | |||
352 | txvector.SetNess (0); | |||
353 | txvector.SetStbc (phy->GetStbc ()); | |||
354 | txvector.SetMode (mode); | |||
355 | txvector.SetPreambleType (WIFI_PREAMBLE_NONE); | |||
356 | return phy->CalculateTxDuration (m_frameLength, txvector, phy->GetFrequency (), MPDU_IN_AGGREGATE, 0); | |||
357 | } | |||
358 | ||||
359 | Time | |||
360 | MinstrelHtWifiManager::GetFirstMpduTxTime (uint32_t groupId, WifiMode mode) const | |||
361 | { | |||
362 | NS_LOG_FUNCTION (this << groupId << mode)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << groupId << mode; std::clog << ")" << std::endl; } } while (false); | |||
363 | ||||
364 | for (TxTime::const_iterator i = m_minstrelGroups[groupId].ratesFirstMpduTxTimeTable.begin (); i != m_minstrelGroups[groupId].ratesFirstMpduTxTimeTable.end (); i++) | |||
365 | { | |||
366 | if (mode == i->second) | |||
367 | { | |||
368 | return i->first; | |||
369 | } | |||
370 | } | |||
371 | NS_ASSERT (false)do { if (!(false)) { std::cerr << "assert failed. cond=\"" << "false" << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 371 << std::endl; ::ns3::FatalImpl:: FlushStreams (); if (true) std::terminate (); } while (false) ; } } while (false); | |||
372 | return Seconds (0); | |||
373 | } | |||
374 | ||||
375 | void | |||
376 | MinstrelHtWifiManager::AddFirstMpduTxTime (uint32_t groupId, WifiMode mode, Time t) | |||
377 | { | |||
378 | NS_LOG_FUNCTION (this << groupId << mode << t)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << groupId << mode << t; std::clog << ")" << std::endl; } } while (false); | |||
379 | ||||
380 | m_minstrelGroups[groupId].ratesFirstMpduTxTimeTable.push_back (std::make_pair (t, mode)); | |||
381 | } | |||
382 | ||||
383 | Time | |||
384 | MinstrelHtWifiManager::GetMpduTxTime (uint32_t groupId, WifiMode mode) const | |||
385 | { | |||
386 | NS_LOG_FUNCTION (this << groupId << mode)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << groupId << mode; std::clog << ")" << std::endl; } } while (false); | |||
387 | ||||
388 | for (TxTime::const_iterator i = m_minstrelGroups[groupId].ratesTxTimeTable.begin (); i != m_minstrelGroups[groupId].ratesTxTimeTable.end (); i++) | |||
389 | { | |||
390 | if (mode == i->second) | |||
391 | { | |||
392 | return i->first; | |||
393 | } | |||
394 | } | |||
395 | NS_ASSERT (false)do { if (!(false)) { std::cerr << "assert failed. cond=\"" << "false" << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 395 << std::endl; ::ns3::FatalImpl:: FlushStreams (); if (true) std::terminate (); } while (false) ; } } while (false); | |||
396 | return Seconds (0); | |||
397 | } | |||
398 | ||||
399 | void | |||
400 | MinstrelHtWifiManager::AddMpduTxTime (uint32_t groupId, WifiMode mode, Time t) | |||
401 | { | |||
402 | NS_LOG_FUNCTION (this << groupId << mode << t)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << groupId << mode << t; std::clog << ")" << std::endl; } } while (false); | |||
403 | ||||
404 | m_minstrelGroups[groupId].ratesTxTimeTable.push_back (std::make_pair (t, mode)); | |||
405 | } | |||
406 | ||||
407 | WifiRemoteStation * | |||
408 | MinstrelHtWifiManager::DoCreateStation (void) const | |||
409 | { | |||
410 | NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this; std::clog << ")" << std::endl; } } while ( false); | |||
411 | ||||
412 | MinstrelHtWifiRemoteStation *station = new MinstrelHtWifiRemoteStation (); | |||
413 | ||||
414 | // Initialize variables common to both stations. | |||
415 | station->m_nextStatsUpdate = Simulator::Now () + m_updateStats; | |||
416 | station->m_col = 0; | |||
417 | station->m_index = 0; | |||
418 | station->m_maxTpRate = 0; | |||
419 | station->m_maxTpRate2 = 0; | |||
420 | station->m_maxProbRate = 0; | |||
421 | station->m_nModes = 0; | |||
422 | station->m_totalPacketsCount = 0; | |||
423 | station->m_samplePacketsCount = 0; | |||
424 | station->m_isSampling = false; | |||
425 | station->m_sampleRate = 0; | |||
426 | station->m_sampleDeferred = false; | |||
427 | station->m_shortRetry = 0; | |||
428 | station->m_longRetry = 0; | |||
429 | station->m_txrate = 0; | |||
430 | station->m_initialized = false; | |||
431 | ||||
432 | // Variables specific to HT station | |||
433 | station->m_sampleGroup = 0; | |||
434 | station->m_numSamplesSlow = 0; | |||
435 | station->m_sampleCount = 16; | |||
436 | station->m_sampleWait = 0; | |||
437 | station->m_sampleTries = 4; | |||
438 | ||||
439 | station->m_avgAmpduLen = 1; | |||
440 | station->m_ampduLen = 0; | |||
441 | station->m_ampduPacketCount = 0; | |||
442 | ||||
443 | // If the device supports HT | |||
444 | if (HasHtSupported () || HasVhtSupported ()) | |||
445 | { | |||
446 | /** | |||
447 | * Assume the station is HT. | |||
448 | * When correct information available it will be checked. | |||
449 | */ | |||
450 | station->m_isHt = true; | |||
451 | } | |||
452 | // Use the variable in the station to indicate that the device do not support HT | |||
453 | else | |||
454 | { | |||
455 | station->m_isHt = false; | |||
456 | } | |||
457 | ||||
458 | return station; | |||
459 | } | |||
460 | ||||
461 | void | |||
462 | MinstrelHtWifiManager::CheckInit (MinstrelHtWifiRemoteStation *station) | |||
463 | { | |||
464 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
465 | ||||
466 | // Note: we appear to be doing late initialization of the table | |||
467 | // to make sure that the set of supported rates has been initialized | |||
468 | // before we perform our own initialization. | |||
469 | if (!station->m_initialized) | |||
470 | { | |||
471 | /** | |||
472 | * Check if the station supports HT. | |||
473 | * Assume that if the device do not supports HT then | |||
474 | * the station will not support HT either. | |||
475 | * We save from using another check and variable. | |||
476 | */ | |||
477 | if (!GetHtSupported (station) && !GetVhtSupported (station)) | |||
478 | { | |||
479 | NS_LOG_DEBUG ("Non-HT station " << station)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Non-HT station " << station << std::endl; } } while (false); | |||
480 | station->m_isHt = false; | |||
481 | // We will use non-HT minstrel for this station. Initialize the manager. | |||
482 | m_legacyManager->SetAttribute ("UpdateStatistics", TimeValue (m_updateStats)); | |||
483 | m_legacyManager->SetAttribute ("LookAroundRate", DoubleValue (m_lookAroundRate)); | |||
484 | m_legacyManager->SetAttribute ("EWMA", DoubleValue (m_ewmaLevel)); | |||
485 | m_legacyManager->SetAttribute ("SampleColumn", UintegerValue (m_nSampleCol)); | |||
486 | m_legacyManager->SetAttribute ("PacketLength", UintegerValue (m_frameLength)); | |||
487 | m_legacyManager->SetAttribute ("PrintStats", BooleanValue (m_printStats)); | |||
488 | m_legacyManager->CheckInit (station); | |||
489 | } | |||
490 | else | |||
491 | { | |||
492 | NS_LOG_DEBUG ("HT station " << station)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "HT station " << station << std::endl; } } while (false); | |||
493 | station->m_isHt = true; | |||
494 | station->m_nModes = GetNMcsSupported (station); | |||
495 | station->m_sampleTable = SampleRate (m_numRates, std::vector<uint32_t> (m_nSampleCol)); | |||
496 | InitSampleTable (station); | |||
497 | RateInit (station); | |||
498 | std::ostringstream tmp; | |||
499 | tmp << "minstrel-ht-stats-" << station->m_state->m_address << ".txt"; | |||
500 | station->m_statsFile.open (tmp.str ().c_str (), std::ios::out); | |||
501 | station->m_initialized = true; | |||
502 | } | |||
503 | } | |||
504 | } | |||
505 | ||||
506 | void | |||
507 | MinstrelHtWifiManager::DoReportRxOk (WifiRemoteStation *st, | |||
508 | double rxSnr, WifiMode txMode) | |||
509 | { | |||
510 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
511 | ||||
512 | NS_LOG_DEBUG ("DoReportRxOk m_txrate=" << ((MinstrelHtWifiRemoteStation *)st)->m_txrate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoReportRxOk m_txrate=" << ((MinstrelHtWifiRemoteStation *)st)->m_txrate << std::endl; } } while (false); | |||
513 | } | |||
514 | ||||
515 | void | |||
516 | MinstrelHtWifiManager::DoReportRtsFailed (WifiRemoteStation *st) | |||
517 | { | |||
518 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
519 | ||||
520 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *)st; | |||
521 | ||||
522 | CheckInit (station); | |||
523 | if (!station->m_initialized) | |||
524 | { | |||
525 | return; | |||
526 | } | |||
527 | ||||
528 | NS_LOG_DEBUG ("DoReportRtsFailed m_txrate=" << station->m_txrate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoReportRtsFailed m_txrate=" << station->m_txrate << std::endl; } } while ( false); | |||
529 | station->m_shortRetry++; | |||
530 | } | |||
531 | ||||
532 | void | |||
533 | MinstrelHtWifiManager::DoReportRtsOk (WifiRemoteStation *st, double ctsSnr, WifiMode ctsMode, double rtsSnr) | |||
534 | { | |||
535 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
536 | ||||
537 | NS_LOG_DEBUG ("self=" << st << " rts ok")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "self=" << st << " rts ok" << std::endl; } } while (false); | |||
538 | } | |||
539 | ||||
540 | void | |||
541 | MinstrelHtWifiManager::DoReportFinalRtsFailed (WifiRemoteStation *st) | |||
542 | { | |||
543 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
544 | ||||
545 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *)st; | |||
546 | NS_LOG_DEBUG ("Final RTS failed")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Final RTS failed" << std::endl; } } while (false); | |||
547 | ||||
548 | CheckInit (station); | |||
549 | if (!station->m_initialized) | |||
550 | { | |||
551 | return; | |||
552 | } | |||
553 | ||||
554 | UpdateRetry (station); | |||
555 | } | |||
556 | ||||
557 | void | |||
558 | MinstrelHtWifiManager::DoReportDataFailed (WifiRemoteStation *st) | |||
559 | { | |||
560 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
561 | ||||
562 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *)st; | |||
563 | ||||
564 | CheckInit (station); | |||
565 | if (!station->m_initialized) | |||
566 | { | |||
567 | return; | |||
568 | } | |||
569 | ||||
570 | if (!station->m_isHt) | |||
571 | { | |||
572 | m_legacyManager->UpdateRate (station); | |||
573 | } | |||
574 | else | |||
575 | { | |||
576 | NS_LOG_DEBUG ("DoReportDataFailed " << station << "\t rate " << station->m_txrate << "\tlongRetry \t" << station->m_longRetry)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoReportDataFailed " << station << "\t rate " << station->m_txrate << "\tlongRetry \t" << station->m_longRetry << std::endl; } } while (false); | |||
577 | ||||
578 | uint32_t rateId = GetRateId (station->m_txrate); | |||
579 | uint32_t groupId = GetGroupId (station->m_txrate); | |||
580 | station->m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt++; // Increment the attempts counter for the rate used. | |||
581 | ||||
582 | UpdateRate (station); | |||
583 | } | |||
584 | } | |||
585 | ||||
586 | void | |||
587 | MinstrelHtWifiManager::DoReportDataOk (WifiRemoteStation *st, | |||
588 | double ackSnr, WifiMode ackMode, double dataSnr) | |||
589 | { | |||
590 | NS_LOG_FUNCTION (this << st << ackSnr << ackMode << dataSnr)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st << ackSnr << ackMode << dataSnr ; std::clog << ")" << std::endl; } } while (false ); | |||
591 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *) st; | |||
592 | ||||
593 | CheckInit (station); | |||
594 | if (!station->m_initialized) | |||
595 | { | |||
596 | return; | |||
597 | } | |||
598 | ||||
599 | NS_LOG_DEBUG ("Data OK - Txrate = " << station->m_txrate )do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Data OK - Txrate = " << station->m_txrate << std::endl; } } while ( false); | |||
600 | ||||
601 | if (!station->m_isHt) | |||
602 | { | |||
603 | station->m_minstrelTable[station->m_txrate].numRateSuccess++; | |||
604 | station->m_minstrelTable[station->m_txrate].numRateAttempt++; | |||
605 | ||||
606 | m_legacyManager->UpdatePacketCounters (station); | |||
607 | ||||
608 | UpdateRetry (station); | |||
609 | m_legacyManager->UpdateStats (station); | |||
610 | ||||
611 | if (station->m_nModes >= 1) | |||
612 | { | |||
613 | station->m_txrate = m_legacyManager->FindRate (station); | |||
614 | } | |||
615 | } | |||
616 | else | |||
617 | { | |||
618 | uint32_t rateId = GetRateId (station->m_txrate); | |||
619 | uint32_t groupId = GetGroupId (station->m_txrate); | |||
620 | station->m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess++; | |||
621 | station->m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt++; | |||
622 | ||||
623 | UpdatePacketCounters (station, 1, 0); | |||
624 | ||||
625 | station->m_isSampling = false; | |||
626 | station->m_sampleDeferred = false; | |||
627 | ||||
628 | UpdateRetry (station); | |||
629 | if (Simulator::Now () >= station->m_nextStatsUpdate) | |||
630 | { | |||
631 | UpdateStats (station); | |||
632 | } | |||
633 | ||||
634 | if (station->m_nModes >= 1) | |||
635 | { | |||
636 | station->m_txrate = FindRate (station); | |||
637 | } | |||
638 | } | |||
639 | ||||
640 | NS_LOG_DEBUG ("Next rate to use TxRate = " << station->m_txrate )do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Next rate to use TxRate = " << station->m_txrate << std::endl; } } while ( false); | |||
641 | } | |||
642 | ||||
643 | void | |||
644 | MinstrelHtWifiManager::DoReportFinalDataFailed (WifiRemoteStation *st) | |||
645 | { | |||
646 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
647 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *) st; | |||
648 | ||||
649 | CheckInit (station); | |||
650 | if (!station->m_initialized) | |||
651 | { | |||
652 | return; | |||
653 | } | |||
654 | ||||
655 | NS_LOG_DEBUG ("DoReportFinalDataFailed - TxRate=" << station->m_txrate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoReportFinalDataFailed - TxRate=" << station->m_txrate << std::endl; } } while ( false); | |||
656 | ||||
657 | if (!station->m_isHt) | |||
658 | { | |||
659 | m_legacyManager->UpdatePacketCounters (station); | |||
660 | ||||
661 | UpdateRetry (station); | |||
662 | ||||
663 | m_legacyManager->UpdateStats (station); | |||
664 | if (station->m_nModes >= 1) | |||
665 | { | |||
666 | station->m_txrate = m_legacyManager->FindRate (station); | |||
667 | } | |||
668 | } | |||
669 | else | |||
670 | { | |||
671 | UpdatePacketCounters (station, 0, 1); | |||
672 | ||||
673 | station->m_isSampling = false; | |||
674 | station->m_sampleDeferred = false; | |||
675 | ||||
676 | UpdateRetry (station); | |||
677 | if (Simulator::Now () >= station->m_nextStatsUpdate) | |||
678 | { | |||
679 | UpdateStats (station); | |||
680 | } | |||
681 | ||||
682 | if (station->m_nModes >= 1) | |||
683 | { | |||
684 | station->m_txrate = FindRate (station); | |||
685 | } | |||
686 | } | |||
687 | NS_LOG_DEBUG ("Next rate to use TxRate = " << station->m_txrate )do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Next rate to use TxRate = " << station->m_txrate << std::endl; } } while ( false); | |||
688 | } | |||
689 | ||||
690 | void | |||
691 | MinstrelHtWifiManager::DoReportAmpduTxStatus (WifiRemoteStation *st, uint8_t nSuccessfulMpdus, uint8_t nFailedMpdus, double rxSnr, double dataSnr) | |||
692 | { | |||
693 | NS_LOG_FUNCTION (this << st << (uint16_t)nSuccessfulMpdus << (uint16_t)nFailedMpdus << rxSnr << dataSnr)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st << (uint16_t)nSuccessfulMpdus << (uint16_t)nFailedMpdus << rxSnr << dataSnr; std:: clog << ")" << std::endl; } } while (false); | |||
694 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *) st; | |||
695 | ||||
696 | CheckInit (station); | |||
697 | if (!station->m_initialized) | |||
698 | { | |||
699 | return; | |||
700 | } | |||
701 | ||||
702 | if (!station->m_isHt) | |||
703 | { | |||
704 | NS_ASSERT_MSG (false,"A-MPDU Tx Status called but no HT or VHT supported.")do { if (!(false)) { std::cerr << "assert failed. cond=\"" << "false" << "\", "; do { std::cerr << "msg=\"" << "A-MPDU Tx Status called but no HT or VHT supported." << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 704 << std::endl; ::ns3::FatalImpl ::FlushStreams (); if (true) std::terminate (); } while (false ); } while (false); } } while (false); | |||
705 | } | |||
706 | ||||
707 | NS_LOG_DEBUG ("DoReportAmpduTxStatus. TxRate=" << station->m_txrate << " SuccMpdus= " <<do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoReportAmpduTxStatus. TxRate=" << station->m_txrate << " SuccMpdus= " << (uint16_t)nSuccessfulMpdus << " FailedMpdus= " << (uint16_t)nFailedMpdus << std::endl; } } while (false) | |||
708 | (uint16_t)nSuccessfulMpdus << " FailedMpdus= " << (uint16_t)nFailedMpdus)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoReportAmpduTxStatus. TxRate=" << station->m_txrate << " SuccMpdus= " << (uint16_t)nSuccessfulMpdus << " FailedMpdus= " << (uint16_t)nFailedMpdus << std::endl; } } while (false); | |||
709 | ||||
710 | station->m_ampduPacketCount++; | |||
711 | station->m_ampduLen += nSuccessfulMpdus + nFailedMpdus; | |||
712 | ||||
713 | UpdatePacketCounters (station, nSuccessfulMpdus, nFailedMpdus); | |||
714 | ||||
715 | uint32_t rateId = GetRateId (station->m_txrate); | |||
716 | uint32_t groupId = GetGroupId (station->m_txrate); | |||
717 | station->m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess += nSuccessfulMpdus; | |||
718 | station->m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt += nSuccessfulMpdus + nFailedMpdus; | |||
719 | ||||
720 | if (nSuccessfulMpdus == 0 && station->m_longRetry < CountRetries (station)) | |||
721 | { | |||
722 | // We do not receive a BlockAck. The entire AMPDU fail. | |||
723 | UpdateRate (station); | |||
724 | } | |||
725 | else | |||
726 | { | |||
727 | station->m_isSampling = false; | |||
728 | station->m_sampleDeferred = false; | |||
729 | ||||
730 | UpdateRetry (station); | |||
731 | if (Simulator::Now () >= station->m_nextStatsUpdate) | |||
732 | { | |||
733 | UpdateStats (station); | |||
734 | } | |||
735 | ||||
736 | if (station->m_nModes >= 1) | |||
737 | { | |||
738 | station->m_txrate = FindRate (station); | |||
739 | } | |||
740 | NS_LOG_DEBUG ("Next rate to use TxRate = " << station->m_txrate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Next rate to use TxRate = " << station->m_txrate << std::endl; } } while ( false); | |||
741 | } | |||
742 | } | |||
743 | ||||
744 | void | |||
745 | MinstrelHtWifiManager::UpdateRate (MinstrelHtWifiRemoteStation *station) | |||
746 | { | |||
747 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
748 | ||||
749 | /** | |||
750 | * Retry Chain table is implemented here. | |||
751 | * | |||
752 | * FIXME | |||
753 | * Currently, NS3 does not retransmit an entire A-MPDU when BACK is missing | |||
754 | * but retransmits each MPDU until MPDUs lifetime expires (or a BACK is received). | |||
755 | * Then, there is no way to control A-MPDU retries (no call to NeedDataRetransmission). | |||
756 | * So, it is possible that the A-MPDU keeps retrying after longRetry reaches its limit. | |||
757 | * | |||
758 | * | |||
759 | * Try | LOOKAROUND RATE | NORMAL RATE | |||
760 | * ------------------------------------------------------- | |||
761 | * 1 | Random rate | Best throughput | |||
762 | * 2 | Next best throughput | Next best throughput | |||
763 | * 3 | Best probability | Best probability | |||
764 | * | |||
765 | * Note: For clarity, multiple blocks of if's and else's are used | |||
766 | * Following implementation in Linux, in MinstrelHT Lowest baserate is not used. | |||
767 | * Explanation can be found here: http://marc.info/?l=linux-wireless&m=144602778611966&w=2 | |||
768 | */ | |||
769 | ||||
770 | CheckInit (station); | |||
771 | if (!station->m_initialized) | |||
772 | { | |||
773 | return; | |||
774 | } | |||
775 | station->m_longRetry++; | |||
776 | ||||
777 | /** | |||
778 | * Get the ids for all rates. | |||
779 | */ | |||
780 | uint32_t maxTpRateId = GetRateId (station->m_maxTpRate); | |||
781 | uint32_t maxTpGroupId = GetGroupId (station->m_maxTpRate); | |||
782 | uint32_t maxTp2RateId = GetRateId (station->m_maxTpRate2); | |||
783 | uint32_t maxTp2GroupId = GetGroupId (station->m_maxTpRate2); | |||
784 | uint32_t maxProbRateId = GetRateId (station->m_maxProbRate); | |||
785 | uint32_t maxProbGroupId = GetGroupId (station->m_maxProbRate); | |||
786 | ||||
787 | /// For normal rate, we're not currently sampling random rates. | |||
788 | if (!station->m_isSampling) | |||
789 | { | |||
790 | /// Use best throughput rate. | |||
791 | if (station->m_longRetry < station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].retryCount) | |||
792 | { | |||
793 | NS_LOG_DEBUG ("Not Sampling; use the same rate again")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Not Sampling; use the same rate again" << std::endl; } } while (false); | |||
794 | station->m_txrate = station->m_maxTpRate; //!< There are still a few retries. | |||
795 | } | |||
796 | ||||
797 | /// Use second best throughput rate. | |||
798 | else if (station->m_longRetry < ( station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].retryCount + | |||
799 | station->m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount)) | |||
800 | { | |||
801 | NS_LOG_DEBUG ("Not Sampling; use the Max TP2")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Not Sampling; use the Max TP2" << std::endl; } } while (false); | |||
802 | station->m_txrate = station->m_maxTpRate2; | |||
803 | } | |||
804 | ||||
805 | /// Use best probability rate. | |||
806 | else if (station->m_longRetry <= ( station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].retryCount + | |||
807 | station->m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount + | |||
808 | station->m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount)) | |||
809 | { | |||
810 | NS_LOG_DEBUG ("Not Sampling; use Max Prob")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Not Sampling; use Max Prob" << std::endl; } } while (false); | |||
811 | station->m_txrate = station->m_maxProbRate; | |||
812 | } | |||
813 | else | |||
814 | { | |||
815 | NS_ASSERT_MSG (false,"Max retries reached and m_longRetry not cleared properly. longRetry= " << station->m_longRetry)do { if (!(false)) { std::cerr << "assert failed. cond=\"" << "false" << "\", "; do { std::cerr << "msg=\"" << "Max retries reached and m_longRetry not cleared properly. longRetry= " << station->m_longRetry << "\", "; do { std:: cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 815 << std::endl; ::ns3::FatalImpl ::FlushStreams (); if (true) std::terminate (); } while (false ); } while (false); } } while (false); | |||
816 | } | |||
817 | } | |||
818 | ||||
819 | /// We're currently sampling random rates. | |||
820 | else | |||
821 | { | |||
822 | /// Sample rate is used only once | |||
823 | /// Use the best rate. | |||
824 | if (station->m_longRetry < 1 + station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTp2RateId].retryCount) | |||
825 | { | |||
826 | NS_LOG_DEBUG ("Sampling use the MaxTP rate")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Sampling use the MaxTP rate" << std::endl; } } while (false); | |||
827 | station->m_txrate = station->m_maxTpRate2; | |||
828 | } | |||
829 | ||||
830 | /// Use the best probability rate. | |||
831 | else if (station->m_longRetry <= 1 + station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTp2RateId].retryCount + | |||
832 | station->m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount) | |||
833 | { | |||
834 | NS_LOG_DEBUG ("Sampling use the MaxProb rate")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Sampling use the MaxProb rate" << std::endl; } } while (false); | |||
835 | station->m_txrate = station->m_maxProbRate; | |||
836 | } | |||
837 | else | |||
838 | { | |||
839 | NS_ASSERT_MSG (false,"Max retries reached and m_longRetry not cleared properly. longRetry= " << station->m_longRetry)do { if (!(false)) { std::cerr << "assert failed. cond=\"" << "false" << "\", "; do { std::cerr << "msg=\"" << "Max retries reached and m_longRetry not cleared properly. longRetry= " << station->m_longRetry << "\", "; do { std:: cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 839 << std::endl; ::ns3::FatalImpl ::FlushStreams (); if (true) std::terminate (); } while (false ); } while (false); } } while (false); | |||
840 | } | |||
841 | } | |||
842 | NS_LOG_DEBUG ("Next rate to use TxRate = " << station->m_txrate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Next rate to use TxRate = " << station->m_txrate << std::endl; } } while ( false); | |||
843 | } | |||
844 | ||||
845 | void | |||
846 | MinstrelHtWifiManager::UpdateRetry (MinstrelHtWifiRemoteStation *station) | |||
847 | { | |||
848 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
849 | station->m_shortRetry = 0; | |||
850 | station->m_longRetry = 0; | |||
851 | ||||
852 | } | |||
853 | ||||
854 | void | |||
855 | MinstrelHtWifiManager::UpdatePacketCounters (MinstrelHtWifiRemoteStation *station, uint8_t nSuccessfulMpdus, uint8_t nFailedMpdus) | |||
856 | { | |||
857 | NS_LOG_FUNCTION (this << station << (uint16_t)nSuccessfulMpdus << (uint16_t)nFailedMpdus)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station << (uint16_t)nSuccessfulMpdus << (uint16_t)nFailedMpdus; std::clog << ")" << std:: endl; } } while (false); | |||
858 | ||||
859 | station->m_totalPacketsCount += nSuccessfulMpdus + nFailedMpdus; | |||
860 | if (station->m_isSampling) | |||
861 | { | |||
862 | station->m_samplePacketsCount += nSuccessfulMpdus + nFailedMpdus; | |||
863 | } | |||
864 | if (station->m_totalPacketsCount == ~0) | |||
865 | { | |||
866 | station->m_samplePacketsCount = 0; | |||
867 | station->m_totalPacketsCount = 0; | |||
868 | } | |||
869 | ||||
870 | if (!station->m_sampleWait && !station->m_sampleTries && station->m_sampleCount > 0) | |||
871 | { | |||
872 | station->m_sampleWait = 16 + 2 * station->m_avgAmpduLen; | |||
873 | station->m_sampleTries = 1; | |||
874 | station->m_sampleCount--; | |||
875 | } | |||
876 | ||||
877 | } | |||
878 | void | |||
879 | MinstrelHtWifiManager::DoDisposeStation (WifiRemoteStation *st) | |||
880 | { | |||
881 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
882 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *) st; | |||
883 | station->DisposeStation (); | |||
884 | } | |||
885 | ||||
886 | WifiTxVector | |||
887 | MinstrelHtWifiManager::DoGetDataTxVector (WifiRemoteStation *st) | |||
888 | { | |||
889 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
890 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *) st; | |||
891 | ||||
892 | if (!station->m_initialized) | |||
893 | { | |||
894 | CheckInit (station); | |||
895 | } | |||
896 | ||||
897 | if (!station->m_isHt) | |||
898 | { | |||
899 | WifiTxVector vector = m_legacyManager->GetDataTxVector (station); | |||
900 | ||||
901 | uint64_t dataRate = vector.GetMode ().GetDataRate (vector); | |||
902 | if (!station->m_isSampling) | |||
903 | { | |||
904 | m_rateChange (dataRate, station->m_state->m_address); | |||
905 | } | |||
906 | ||||
907 | return vector; | |||
908 | } | |||
909 | else | |||
910 | { | |||
911 | NS_LOG_DEBUG ("DoGetDataMode m_txrate= " << station->m_txrate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoGetDataMode m_txrate= " << station->m_txrate << std::endl; } } while ( false); | |||
912 | ||||
913 | uint32_t rateId = GetRateId (station->m_txrate); | |||
914 | uint32_t groupId = GetGroupId (station->m_txrate); | |||
915 | uint32_t mcsIndex = station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex; | |||
916 | ||||
917 | NS_LOG_DEBUG ("DoGetDataMode rateId= " << rateId << " groupId= " << groupId << " mode= " << GetMcsSupported (station, mcsIndex))do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoGetDataMode rateId= " << rateId << " groupId= " << groupId << " mode= " << GetMcsSupported (station, mcsIndex) << std::endl; } } while (false); | |||
918 | ||||
919 | McsGroup group = m_minstrelGroups[groupId]; | |||
920 | ||||
921 | // Check consistency of rate selected. | |||
922 | if ((group.sgi && !GetShortGuardInterval (station)) || group.chWidth > GetChannelWidth (station) || group.streams > GetNumberOfSupportedStreams (station)) | |||
923 | { | |||
924 | NS_ASSERT_MSG (false,"Inconsistent group selected. Group: (" << (uint16_t)group.streams << "," << (uint16_t)group.sgi << "," << (uint16_t)group.chWidth << ")" <<do { if (!(false)) { std::cerr << "assert failed. cond=\"" << "false" << "\", "; do { std::cerr << "msg=\"" << "Inconsistent group selected. Group: (" << (uint16_t )group.streams << "," << (uint16_t)group.sgi << "," << (uint16_t)group.chWidth << ")" << " Station capabilities: (" << GetNumberOfSupportedStreams (station) << "," << GetShortGuardInterval (station) << "," << GetChannelWidth (station) << ")" << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 925 << std::endl; ::ns3::FatalImpl ::FlushStreams (); if (true) std::terminate (); } while (false ); } while (false); } } while (false) | |||
925 | " Station capabilities: (" << GetNumberOfSupportedStreams (station) << "," << GetShortGuardInterval (station) << "," << GetChannelWidth (station) << ")")do { if (!(false)) { std::cerr << "assert failed. cond=\"" << "false" << "\", "; do { std::cerr << "msg=\"" << "Inconsistent group selected. Group: (" << (uint16_t )group.streams << "," << (uint16_t)group.sgi << "," << (uint16_t)group.chWidth << ")" << " Station capabilities: (" << GetNumberOfSupportedStreams (station) << "," << GetShortGuardInterval (station) << "," << GetChannelWidth (station) << ")" << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 925 << std::endl; ::ns3::FatalImpl ::FlushStreams (); if (true) std::terminate (); } while (false ); } while (false); } } while (false); | |||
926 | } | |||
927 | ||||
928 | uint64_t dataRate = GetMcsSupported (station, mcsIndex).GetDataRate (group.chWidth, group.sgi ? 400 : 800, group.streams); | |||
929 | if (!station->m_isSampling) | |||
930 | { | |||
931 | m_rateChange (dataRate, station->m_state->m_address); | |||
932 | } | |||
933 | WifiMode mode = GetMcsSupported (station, mcsIndex); | |||
934 | return WifiTxVector (mode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), | |||
935 | GetPreambleForTransmission (mode, GetAddress (station)), group.sgi ? 400 : 800, GetNumberOfAntennas (), group.streams, GetNess (station), group.chWidth, GetAggregation (station) && !station->m_isSampling, GetStbc (station)); | |||
936 | } | |||
937 | } | |||
938 | ||||
939 | WifiTxVector | |||
940 | MinstrelHtWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) | |||
941 | { | |||
942 | NS_LOG_FUNCTION (this << st)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st; std::clog << ")" << std::endl; } } while (false); | |||
943 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *) st; | |||
944 | ||||
945 | if (!station->m_initialized) | |||
946 | { | |||
947 | CheckInit (station); | |||
948 | } | |||
949 | ||||
950 | if (!station->m_isHt) | |||
951 | { | |||
952 | return m_legacyManager->GetRtsTxVector (station); | |||
953 | } | |||
954 | else | |||
955 | { | |||
956 | NS_LOG_DEBUG ("DoGetRtsMode m_txrate=" << station->m_txrate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "DoGetRtsMode m_txrate=" << station->m_txrate << std::endl; } } while ( false); | |||
957 | ||||
958 | /* RTS is sent in a non-HT frame. RTS with HT is not supported yet in NS3. | |||
959 | * When supported, decision of using HT has to follow rules in Section 9.7.6 from 802.11-2012. | |||
960 | * From Sec. 9.7.6.5: "A frame other than a BlockAckReq or BlockAck that is carried in a | |||
961 | * non-HT PPDU shall be transmitted by the STA using a rate no higher than the highest | |||
962 | * rate in the BSSBasicRateSet parameter that is less than or equal to the rate or | |||
963 | * non-HT reference rate (see 9.7.9) of the previously transmitted frame that was | |||
964 | * directed to the same receiving STA. If no rate in the BSSBasicRateSet parameter meets | |||
965 | * these conditions, the control frame shall be transmitted at a rate no higher than the | |||
966 | * highest mandatory rate of the attached PHY that is less than or equal to the rate | |||
967 | * or non-HT reference rate (see 9.7.9) of the previously transmitted frame that was | |||
968 | * directed to the same receiving STA." | |||
969 | */ | |||
970 | ||||
971 | // As we are in Minstrel HT, assume the last rate was an HT rate. | |||
972 | uint32_t rateId = GetRateId (station->m_txrate); | |||
973 | uint32_t groupId = GetGroupId (station->m_txrate); | |||
974 | uint32_t mcsIndex = station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex; | |||
975 | ||||
976 | WifiMode lastRate = GetMcsSupported (station, mcsIndex); | |||
977 | uint64_t lastDataRate = lastRate.GetNonHtReferenceRate (); | |||
978 | uint32_t nBasicRates = GetNBasicModes (); | |||
979 | ||||
980 | WifiMode rtsRate; | |||
981 | bool rateFound = false; | |||
982 | ||||
983 | for (uint32_t i = 0; i < nBasicRates; i++) | |||
984 | { | |||
985 | uint64_t rate = GetBasicMode (i).GetDataRate (20); | |||
986 | if (rate <= lastDataRate) | |||
987 | { | |||
988 | rtsRate = GetBasicMode (i); | |||
989 | rateFound = true; | |||
990 | } | |||
991 | } | |||
992 | ||||
993 | if (!rateFound) | |||
994 | { | |||
995 | Ptr<WifiPhy> phy = GetPhy (); | |||
996 | uint32_t nSupportRates = phy->GetNModes (); | |||
997 | for (uint32_t i = 0; i < nSupportRates; i++) | |||
998 | { | |||
999 | uint64_t rate = phy->GetMode (i).GetDataRate (20); | |||
1000 | if (rate <= lastDataRate) | |||
1001 | { | |||
1002 | rtsRate = phy->GetMode (i); | |||
1003 | rateFound = true; | |||
1004 | } | |||
1005 | } | |||
1006 | } | |||
1007 | ||||
1008 | NS_ASSERT (rateFound)do { if (!(rateFound)) { std::cerr << "assert failed. cond=\"" << "rateFound" << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 1008 << std::endl; ::ns3:: FatalImpl::FlushStreams (); if (true) std::terminate (); } while (false); } } while (false); | |||
1009 | ||||
1010 | return WifiTxVector (rtsRate, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetPreambleForTransmission (rtsRate, GetAddress (station)), | |||
1011 | 800, 1, 1, 0, GetChannelWidth (station), GetAggregation (station), false); | |||
1012 | } | |||
1013 | } | |||
1014 | ||||
1015 | bool | |||
1016 | MinstrelHtWifiManager::DoNeedDataRetransmission (WifiRemoteStation *st, Ptr<const Packet> packet, bool normally) | |||
1017 | { | |||
1018 | NS_LOG_FUNCTION (this << st << packet << normally)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << st << packet << normally; std::clog << ")" << std::endl; } } while (false); | |||
1019 | ||||
1020 | MinstrelHtWifiRemoteStation *station = (MinstrelHtWifiRemoteStation *)st; | |||
1021 | ||||
1022 | CheckInit (station); | |||
1023 | if (!station->m_initialized) | |||
1024 | { | |||
1025 | return normally; | |||
1026 | } | |||
1027 | ||||
1028 | uint32_t maxRetries; | |||
1029 | ||||
1030 | if (!station->m_isHt) | |||
1031 | { | |||
1032 | maxRetries = m_legacyManager->CountRetries (station); | |||
1033 | } | |||
1034 | else | |||
1035 | { | |||
1036 | maxRetries = CountRetries (station); | |||
1037 | } | |||
1038 | ||||
1039 | if (station->m_longRetry >= maxRetries) | |||
1040 | { | |||
1041 | NS_LOG_DEBUG ("No re-transmission allowed. Retries: " << station->m_longRetry << " Max retries: " << maxRetries)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "No re-transmission allowed. Retries: " << station->m_longRetry << " Max retries: " << maxRetries << std::endl; } } while (false); | |||
1042 | return false; | |||
1043 | } | |||
1044 | else | |||
1045 | { | |||
1046 | NS_LOG_DEBUG ("Re-transmit. Retries: " << station->m_longRetry << " Max retries: " << maxRetries)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Re-transmit. Retries: " << station->m_longRetry << " Max retries: " << maxRetries << std::endl; } } while (false); | |||
1047 | return true; | |||
1048 | } | |||
1049 | } | |||
1050 | ||||
1051 | uint32_t | |||
1052 | MinstrelHtWifiManager::CountRetries (MinstrelHtWifiRemoteStation *station) | |||
1053 | { | |||
1054 | uint32_t maxProbRateId = GetRateId (station->m_maxProbRate); | |||
1055 | uint32_t maxProbGroupId = GetGroupId (station->m_maxProbRate); | |||
1056 | uint32_t maxTpRateId = GetRateId (station->m_maxTpRate); | |||
1057 | uint32_t maxTpGroupId = GetGroupId (station->m_maxTpRate); | |||
1058 | uint32_t maxTp2RateId = GetRateId (station->m_maxTpRate2); | |||
1059 | uint32_t maxTp2GroupId = GetGroupId (station->m_maxTpRate2); | |||
1060 | ||||
1061 | if (!station->m_isSampling) | |||
1062 | { | |||
1063 | return station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].retryCount + | |||
1064 | station->m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].retryCount + | |||
1065 | station->m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount; | |||
1066 | } | |||
1067 | else | |||
1068 | { | |||
1069 | return 1 + station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTp2RateId].retryCount + | |||
1070 | station->m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].retryCount; | |||
1071 | } | |||
1072 | } | |||
1073 | ||||
1074 | bool | |||
1075 | MinstrelHtWifiManager::IsLowLatency (void) const | |||
1076 | { | |||
1077 | NS_LOG_FUNCTION (this)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this; std::clog << ")" << std::endl; } } while ( false); | |||
1078 | return true; | |||
1079 | } | |||
1080 | ||||
1081 | uint32_t | |||
1082 | MinstrelHtWifiManager::GetNextSample (MinstrelHtWifiRemoteStation *station) | |||
1083 | { | |||
1084 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
1085 | ||||
1086 | uint32_t sampleGroup = station->m_sampleGroup; | |||
1087 | ||||
1088 | uint32_t index = station->m_groupsTable[sampleGroup].m_index; | |||
1089 | uint32_t col = station->m_groupsTable[sampleGroup].m_col; | |||
1090 | ||||
1091 | uint32_t sampleIndex = station->m_sampleTable[index][col]; | |||
1092 | ||||
1093 | uint32_t rateIndex = GetIndex (sampleGroup, sampleIndex); | |||
1094 | NS_LOG_DEBUG ("Next Sample is " << rateIndex)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Next Sample is " << rateIndex << std::endl; } } while (false); | |||
1095 | ||||
1096 | SetNextSample (station); //Calculate the next sample rate. | |||
1097 | ||||
1098 | return rateIndex; | |||
1099 | } | |||
1100 | ||||
1101 | void | |||
1102 | MinstrelHtWifiManager::SetNextSample (MinstrelHtWifiRemoteStation *station) | |||
1103 | { | |||
1104 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
1105 | do | |||
1106 | { | |||
1107 | station->m_sampleGroup++; | |||
1108 | station->m_sampleGroup %= m_numGroups; | |||
| ||||
1109 | } | |||
1110 | while (!station->m_groupsTable[station->m_sampleGroup].m_supported); | |||
1111 | ||||
1112 | station->m_groupsTable[station->m_sampleGroup].m_index++; | |||
1113 | ||||
1114 | uint32_t sampleGroup = station->m_sampleGroup; | |||
1115 | uint8_t index = station->m_groupsTable[station->m_sampleGroup].m_index; | |||
1116 | uint8_t col = station->m_groupsTable[sampleGroup].m_col; | |||
1117 | ||||
1118 | if (index >= m_numRates) | |||
1119 | { | |||
1120 | station->m_groupsTable[station->m_sampleGroup].m_index = 0; | |||
1121 | station->m_groupsTable[station->m_sampleGroup].m_col++; | |||
1122 | if (station->m_groupsTable[station->m_sampleGroup].m_col >= m_nSampleCol) | |||
1123 | { | |||
1124 | station->m_groupsTable[station->m_sampleGroup].m_col = 0; | |||
1125 | } | |||
1126 | index = station->m_groupsTable[station->m_sampleGroup].m_index; | |||
1127 | col = station->m_groupsTable[sampleGroup].m_col; | |||
1128 | } | |||
1129 | NS_LOG_DEBUG ("New sample set: group= " << sampleGroup << " index= " << station->m_sampleTable[index][col])do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "New sample set: group= " << sampleGroup << " index= " << station-> m_sampleTable[index][col] << std::endl; } } while (false ); | |||
1130 | } | |||
1131 | ||||
1132 | uint32_t | |||
1133 | MinstrelHtWifiManager::FindRate (MinstrelHtWifiRemoteStation *station) | |||
1134 | { | |||
1135 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
1136 | NS_LOG_DEBUG ("FindRate " << "packet=" << station->m_totalPacketsCount )do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "FindRate " << "packet=" << station->m_totalPacketsCount << std::endl; } } while (false); | |||
1137 | ||||
1138 | if ((station->m_samplePacketsCount + station->m_totalPacketsCount) == 0) | |||
1139 | { | |||
1140 | return station->m_maxTpRate; | |||
1141 | } | |||
1142 | ||||
1143 | // If we have waited enough, then sample. | |||
1144 | if (station->m_sampleWait == 0 && station->m_sampleTries != 0) | |||
1145 | { | |||
1146 | //SAMPLING | |||
1147 | NS_LOG_DEBUG ("Obtaining a sampling rate")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Obtaining a sampling rate" << std::endl; } } while (false); | |||
1148 | /// Now go through the table and find an index rate. | |||
1149 | uint32_t sampleIdx = GetNextSample (station); | |||
1150 | NS_LOG_DEBUG ("Sampling rate = " << sampleIdx)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Sampling rate = " << sampleIdx << std::endl; } } while (false); | |||
1151 | ||||
1152 | //Evaluate if the sampling rate selected should be used. | |||
1153 | uint32_t sampleGroupId = GetGroupId (sampleIdx); | |||
1154 | uint32_t sampleRateId = GetRateId (sampleIdx); | |||
1155 | ||||
1156 | // If the rate selected is not supported, then don't sample. | |||
1157 | if (station->m_groupsTable[sampleGroupId].m_supported && station->m_groupsTable[sampleGroupId].m_ratesTable[sampleRateId].supported) | |||
1158 | { | |||
1159 | /** | |||
1160 | * Sampling might add some overhead to the frame. | |||
1161 | * Hence, don't use sampling for the currently used rates. | |||
1162 | * | |||
1163 | * Also do not sample if the probability is already higher than 95% | |||
1164 | * to avoid wasting airtime. | |||
1165 | */ | |||
1166 | HtRateInfo sampleRateInfo = station->m_groupsTable[sampleGroupId].m_ratesTable[sampleRateId]; | |||
1167 | ||||
1168 | NS_LOG_DEBUG ("Use sample rate? MaxTpRate= " << station->m_maxTpRate << " CurrentRate= " << station->m_txrate <<do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Use sample rate? MaxTpRate= " << station->m_maxTpRate << " CurrentRate= " << station->m_txrate << " SampleRate= " << sampleIdx << " SampleProb= " << sampleRateInfo.ewmaProb << std::endl; } } while (false) | |||
1169 | " SampleRate= " << sampleIdx << " SampleProb= " << sampleRateInfo.ewmaProb)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Use sample rate? MaxTpRate= " << station->m_maxTpRate << " CurrentRate= " << station->m_txrate << " SampleRate= " << sampleIdx << " SampleProb= " << sampleRateInfo.ewmaProb << std::endl; } } while (false); | |||
1170 | ||||
1171 | if (sampleIdx != station->m_maxTpRate && sampleIdx != station->m_maxTpRate2 | |||
1172 | && sampleIdx != station->m_maxProbRate && sampleRateInfo.ewmaProb <= 95) | |||
1173 | { | |||
1174 | ||||
1175 | /** | |||
1176 | * Make sure that lower rates get sampled only occasionally, | |||
1177 | * if the link is working perfectly. | |||
1178 | */ | |||
1179 | ||||
1180 | uint32_t maxTpGroupId = GetGroupId (station->m_maxTpRate); | |||
1181 | uint32_t maxTp2GroupId = GetGroupId (station->m_maxTpRate2); | |||
1182 | uint32_t maxTp2RateId = GetRateId (station->m_maxTpRate2); | |||
1183 | uint32_t maxProbGroupId = GetGroupId (station->m_maxProbRate); | |||
1184 | uint32_t maxProbRateId = GetRateId (station->m_maxProbRate); | |||
1185 | ||||
1186 | uint8_t maxTpStreams = m_minstrelGroups[maxTpGroupId].streams; | |||
1187 | uint8_t sampleStreams = m_minstrelGroups[sampleGroupId].streams; | |||
1188 | ||||
1189 | Time sampleDuration = sampleRateInfo.perfectTxTime; | |||
1190 | Time maxTp2Duration = station->m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].perfectTxTime; | |||
1191 | Time maxProbDuration = station->m_groupsTable[maxProbGroupId].m_ratesTable[maxProbRateId].perfectTxTime; | |||
1192 | ||||
1193 | NS_LOG_DEBUG ("Use sample rate? SampleDuration= " << sampleDuration << " maxTp2Duration= " << maxTp2Duration <<do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Use sample rate? SampleDuration= " << sampleDuration << " maxTp2Duration= " << maxTp2Duration << " maxProbDuration= " << maxProbDuration << " sampleStreams= " << (uint16_t)sampleStreams << " maxTpStreams= " << (uint16_t)maxTpStreams << std::endl; } } while (false) | |||
1194 | " maxProbDuration= " << maxProbDuration << " sampleStreams= " << (uint16_t)sampleStreams <<do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Use sample rate? SampleDuration= " << sampleDuration << " maxTp2Duration= " << maxTp2Duration << " maxProbDuration= " << maxProbDuration << " sampleStreams= " << (uint16_t)sampleStreams << " maxTpStreams= " << (uint16_t)maxTpStreams << std::endl; } } while (false) | |||
1195 | " maxTpStreams= " << (uint16_t)maxTpStreams)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Use sample rate? SampleDuration= " << sampleDuration << " maxTp2Duration= " << maxTp2Duration << " maxProbDuration= " << maxProbDuration << " sampleStreams= " << (uint16_t)sampleStreams << " maxTpStreams= " << (uint16_t)maxTpStreams << std::endl; } } while (false); | |||
1196 | if (sampleDuration < maxTp2Duration || (sampleStreams < maxTpStreams && sampleDuration < maxProbDuration)) | |||
1197 | { | |||
1198 | /// Set flag that we are currently sampling. | |||
1199 | station->m_isSampling = true; | |||
1200 | ||||
1201 | /// set the rate that we're currently sampling | |||
1202 | station->m_sampleRate = sampleIdx; | |||
1203 | ||||
1204 | NS_LOG_DEBUG ("FindRate " << "sampleRate=" << sampleIdx)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "FindRate " << "sampleRate=" << sampleIdx << std::endl ; } } while (false); | |||
1205 | station->m_sampleTries--; | |||
1206 | return sampleIdx; | |||
1207 | } | |||
1208 | else | |||
1209 | { | |||
1210 | station->m_numSamplesSlow++; | |||
1211 | if (sampleRateInfo.numSamplesSkipped >= 20 && station->m_numSamplesSlow <= 2) | |||
1212 | { | |||
1213 | /// Set flag that we are currently sampling. | |||
1214 | station->m_isSampling = true; | |||
1215 | ||||
1216 | /// set the rate that we're currently sampling | |||
1217 | station->m_sampleRate = sampleIdx; | |||
1218 | ||||
1219 | NS_LOG_DEBUG ("FindRate " << "sampleRate=" << sampleIdx)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "FindRate " << "sampleRate=" << sampleIdx << std::endl ; } } while (false); | |||
1220 | station->m_sampleTries--; | |||
1221 | return sampleIdx; | |||
1222 | } | |||
1223 | } | |||
1224 | } | |||
1225 | } | |||
1226 | } | |||
1227 | if (station->m_sampleWait > 0) | |||
1228 | { | |||
1229 | station->m_sampleWait--; | |||
1230 | } | |||
1231 | ||||
1232 | /// Continue using the best rate. | |||
1233 | ||||
1234 | NS_LOG_DEBUG ("FindRate " << "maxTpRrate=" << station->m_maxTpRate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "FindRate " << "maxTpRrate=" << station->m_maxTpRate << std::endl; } } while (false); | |||
1235 | return station->m_maxTpRate; | |||
1236 | } | |||
1237 | void | |||
1238 | MinstrelHtWifiManager::UpdateStats (MinstrelHtWifiRemoteStation *station) | |||
1239 | { | |||
1240 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
1241 | ||||
1242 | NS_LOG_DEBUG ("Updating stats=" << this)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Updating stats=" << this << std::endl; } } while (false); | |||
1243 | ||||
1244 | station->m_nextStatsUpdate = Simulator::Now () + m_updateStats; | |||
1245 | ||||
1246 | station->m_numSamplesSlow = 0; | |||
1247 | station->m_sampleCount = 0; | |||
1248 | ||||
1249 | double tempProb; | |||
1250 | ||||
1251 | if (station->m_ampduPacketCount > 0) | |||
1252 | { | |||
1253 | double newLen = station->m_ampduLen / station->m_ampduPacketCount; | |||
1254 | station->m_avgAmpduLen = ( newLen * (100 - m_ewmaLevel) + (station->m_avgAmpduLen * m_ewmaLevel) ) / 100; | |||
1255 | station->m_ampduLen = 0; | |||
1256 | station->m_ampduPacketCount = 0; | |||
1257 | } | |||
1258 | ||||
1259 | /* Initialize global rate indexes */ | |||
1260 | station->m_maxTpRate = GetLowestIndex (station); | |||
1261 | station->m_maxTpRate2 = GetLowestIndex (station); | |||
1262 | station->m_maxProbRate = GetLowestIndex (station); | |||
1263 | ||||
1264 | /// Update throughput and EWMA for each rate inside each group. | |||
1265 | for (uint32_t j = 0; j < m_numGroups; j++) | |||
1266 | { | |||
1267 | if (station->m_groupsTable[j].m_supported) | |||
1268 | { | |||
1269 | station->m_sampleCount++; | |||
1270 | ||||
1271 | /* (re)Initialize group rate indexes */ | |||
1272 | station->m_groupsTable[j].m_maxTpRate = GetLowestIndex (station, j); | |||
1273 | station->m_groupsTable[j].m_maxTpRate2 = GetLowestIndex (station, j); | |||
1274 | station->m_groupsTable[j].m_maxProbRate = GetLowestIndex (station, j); | |||
1275 | ||||
1276 | for (uint32_t i = 0; i < m_numRates; i++) | |||
1277 | { | |||
1278 | if (station->m_groupsTable[j].m_ratesTable[i].supported) | |||
1279 | { | |||
1280 | station->m_groupsTable[j].m_ratesTable[i].retryUpdated = false; | |||
1281 | ||||
1282 | NS_LOG_DEBUG (i << " " << GetMcsSupported (station, station->m_groupsTable[j].m_ratesTable[i].mcsIndex) <<do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << i << " " << GetMcsSupported (station, station->m_groupsTable [j].m_ratesTable[i].mcsIndex) << "\t attempt=" << station->m_groupsTable[j].m_ratesTable[i].numRateAttempt << "\t success=" << station->m_groupsTable[j].m_ratesTable [i].numRateSuccess << std::endl; } } while (false) | |||
1283 | "\t attempt=" << station->m_groupsTable[j].m_ratesTable[i].numRateAttempt <<do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << i << " " << GetMcsSupported (station, station->m_groupsTable [j].m_ratesTable[i].mcsIndex) << "\t attempt=" << station->m_groupsTable[j].m_ratesTable[i].numRateAttempt << "\t success=" << station->m_groupsTable[j].m_ratesTable [i].numRateSuccess << std::endl; } } while (false) | |||
1284 | "\t success=" << station->m_groupsTable[j].m_ratesTable[i].numRateSuccess)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << i << " " << GetMcsSupported (station, station->m_groupsTable [j].m_ratesTable[i].mcsIndex) << "\t attempt=" << station->m_groupsTable[j].m_ratesTable[i].numRateAttempt << "\t success=" << station->m_groupsTable[j].m_ratesTable [i].numRateSuccess << std::endl; } } while (false); | |||
1285 | ||||
1286 | /// If we've attempted something. | |||
1287 | if (station->m_groupsTable[j].m_ratesTable[i].numRateAttempt > 0) | |||
1288 | { | |||
1289 | station->m_groupsTable[j].m_ratesTable[i].numSamplesSkipped = 0; | |||
1290 | /** | |||
1291 | * Calculate the probability of success. | |||
1292 | * Assume probability scales from 0 to 100. | |||
1293 | */ | |||
1294 | tempProb = (100 * station->m_groupsTable[j].m_ratesTable[i].numRateSuccess) / station->m_groupsTable[j].m_ratesTable[i].numRateAttempt; | |||
1295 | ||||
1296 | /// Bookeeping. | |||
1297 | station->m_groupsTable[j].m_ratesTable[i].prob = tempProb; | |||
1298 | ||||
1299 | if (station->m_groupsTable[j].m_ratesTable[i].successHist == 0) | |||
1300 | { | |||
1301 | station->m_groupsTable[j].m_ratesTable[i].ewmaProb = tempProb; | |||
1302 | } | |||
1303 | else | |||
1304 | { | |||
1305 | station->m_groupsTable[j].m_ratesTable[i].ewmsdProb = CalculateEwmsd (station->m_groupsTable[j].m_ratesTable[i].ewmsdProb, | |||
1306 | tempProb, station->m_groupsTable[j].m_ratesTable[i].ewmaProb, | |||
1307 | m_ewmaLevel); | |||
1308 | /// EWMA probability | |||
1309 | tempProb = (tempProb * (100 - m_ewmaLevel) + station->m_groupsTable[j].m_ratesTable[i].ewmaProb * m_ewmaLevel) / 100; | |||
1310 | station->m_groupsTable[j].m_ratesTable[i].ewmaProb = tempProb; | |||
1311 | } | |||
1312 | ||||
1313 | station->m_groupsTable[j].m_ratesTable[i].throughput = CalculateThroughput (station, j, i, tempProb); | |||
1314 | ||||
1315 | station->m_groupsTable[j].m_ratesTable[i].successHist += station->m_groupsTable[j].m_ratesTable[i].numRateSuccess; | |||
1316 | station->m_groupsTable[j].m_ratesTable[i].attemptHist += station->m_groupsTable[j].m_ratesTable[i].numRateAttempt; | |||
1317 | } | |||
1318 | else | |||
1319 | { | |||
1320 | station->m_groupsTable[j].m_ratesTable[i].numSamplesSkipped++; | |||
1321 | } | |||
1322 | ||||
1323 | /// Bookeeping. | |||
1324 | station->m_groupsTable[j].m_ratesTable[i].prevNumRateSuccess = station->m_groupsTable[j].m_ratesTable[i].numRateSuccess; | |||
1325 | station->m_groupsTable[j].m_ratesTable[i].prevNumRateAttempt = station->m_groupsTable[j].m_ratesTable[i].numRateAttempt; | |||
1326 | station->m_groupsTable[j].m_ratesTable[i].numRateSuccess = 0; | |||
1327 | station->m_groupsTable[j].m_ratesTable[i].numRateAttempt = 0; | |||
1328 | ||||
1329 | if (station->m_groupsTable[j].m_ratesTable[i].throughput != 0) | |||
1330 | { | |||
1331 | SetBestStationThRates (station, GetIndex (j, i)); | |||
1332 | SetBestProbabilityRate (station, GetIndex (j, i)); | |||
1333 | } | |||
1334 | ||||
1335 | } | |||
1336 | } | |||
1337 | } | |||
1338 | } | |||
1339 | ||||
1340 | //Try to sample all available rates during each interval. | |||
1341 | station->m_sampleCount *= 8; | |||
1342 | ||||
1343 | //Recalculate retries for the rates selected. | |||
1344 | CalculateRetransmits (station, station->m_maxTpRate); | |||
1345 | CalculateRetransmits (station, station->m_maxTpRate2); | |||
1346 | CalculateRetransmits (station, station->m_maxProbRate); | |||
1347 | ||||
1348 | NS_LOG_DEBUG ("max tp=" << station->m_maxTpRate << "\nmax tp2=" << station->m_maxTpRate2 << "\nmax prob=" << station->m_maxProbRate)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "max tp=" << station->m_maxTpRate << "\nmax tp2=" << station ->m_maxTpRate2 << "\nmax prob=" << station-> m_maxProbRate << std::endl; } } while (false); | |||
1349 | if (m_printStats) | |||
1350 | { | |||
1351 | PrintTable (station); | |||
1352 | } | |||
1353 | } | |||
1354 | ||||
1355 | double | |||
1356 | MinstrelHtWifiManager::CalculateThroughput (MinstrelHtWifiRemoteStation *station, uint32_t groupId, uint32_t rateId, double ewmaProb) | |||
1357 | { | |||
1358 | /** | |||
1359 | * Calculating throughput. | |||
1360 | * Do not account throughput if sucess prob is below 10% | |||
1361 | * (as done in minstrel_ht linux implementation). | |||
1362 | */ | |||
1363 | if (ewmaProb < 10) | |||
1364 | { | |||
1365 | return 0; | |||
1366 | } | |||
1367 | else | |||
1368 | { | |||
1369 | /** | |||
1370 | * For the throughput calculation, limit the probability value to 90% to | |||
1371 | * account for collision related packet error rate fluctuation. | |||
1372 | */ | |||
1373 | Time txTime = station->m_groupsTable[groupId].m_ratesTable[rateId].perfectTxTime; | |||
1374 | if (ewmaProb > 90) | |||
1375 | { | |||
1376 | return 90 / txTime.GetSeconds (); | |||
1377 | } | |||
1378 | else | |||
1379 | { | |||
1380 | return ewmaProb / txTime.GetSeconds (); | |||
1381 | } | |||
1382 | } | |||
1383 | } | |||
1384 | ||||
1385 | void | |||
1386 | MinstrelHtWifiManager::SetBestProbabilityRate (MinstrelHtWifiRemoteStation *station, uint32_t index) | |||
1387 | { | |||
1388 | GroupInfo *group; | |||
1389 | HtRateInfo rate; | |||
1390 | uint32_t tmpGroupId, tmpRateId; | |||
1391 | double tmpTh, tmpProb; | |||
1392 | uint32_t groupId, rateId; | |||
1393 | double currentTh; | |||
1394 | // maximum group probability (GP) variables | |||
1395 | uint32_t maxGPGroupId, maxGPRateId; | |||
1396 | double maxGPTh; | |||
1397 | ||||
1398 | groupId = GetGroupId (index); | |||
1399 | rateId = GetRateId (index); | |||
1400 | group = &station->m_groupsTable[groupId]; | |||
1401 | rate = group->m_ratesTable[rateId]; | |||
1402 | ||||
1403 | tmpGroupId = GetGroupId (station->m_maxProbRate); | |||
1404 | tmpRateId = GetRateId (station->m_maxProbRate); | |||
1405 | tmpProb = station->m_groupsTable[tmpGroupId].m_ratesTable[tmpRateId].ewmaProb; | |||
1406 | tmpTh = station->m_groupsTable[tmpGroupId].m_ratesTable[tmpRateId].throughput; | |||
1407 | ||||
1408 | if (rate.ewmaProb > 75) | |||
1409 | { | |||
1410 | currentTh = station->m_groupsTable[groupId].m_ratesTable[rateId].throughput; | |||
1411 | if (currentTh > tmpTh) | |||
1412 | { | |||
1413 | station->m_maxProbRate = index; | |||
1414 | } | |||
1415 | ||||
1416 | maxGPGroupId = GetGroupId (group->m_maxProbRate); | |||
1417 | maxGPRateId = GetRateId (group->m_maxProbRate); | |||
1418 | maxGPTh = station->m_groupsTable[maxGPGroupId].m_ratesTable[maxGPRateId].throughput; | |||
1419 | ||||
1420 | if (currentTh > maxGPTh) | |||
1421 | { | |||
1422 | group->m_maxProbRate = index; | |||
1423 | } | |||
1424 | } | |||
1425 | else | |||
1426 | { | |||
1427 | if (rate.ewmaProb > tmpProb) | |||
1428 | { | |||
1429 | station->m_maxProbRate = index; | |||
1430 | } | |||
1431 | maxGPRateId = GetRateId (group->m_maxProbRate); | |||
1432 | if (rate.ewmaProb > group->m_ratesTable[maxGPRateId].ewmaProb) | |||
1433 | { | |||
1434 | group->m_maxProbRate = index; | |||
1435 | } | |||
1436 | } | |||
1437 | } | |||
1438 | ||||
1439 | /* | |||
1440 | * Find & sort topmost throughput rates | |||
1441 | * | |||
1442 | * If multiple rates provide equal throughput the sorting is based on their | |||
1443 | * current success probability. Higher success probability is preferred among | |||
1444 | * MCS groups. | |||
1445 | */ | |||
1446 | void | |||
1447 | MinstrelHtWifiManager::SetBestStationThRates (MinstrelHtWifiRemoteStation *station, uint32_t index) | |||
1448 | { | |||
1449 | uint32_t groupId, rateId; | |||
1450 | double th, prob; | |||
1451 | uint32_t maxTpGroupId, maxTpRateId; | |||
1452 | uint32_t maxTp2GroupId, maxTp2RateId; | |||
1453 | double maxTpTh, maxTpProb; | |||
1454 | double maxTp2Th, maxTp2Prob; | |||
1455 | ||||
1456 | groupId = GetGroupId (index); | |||
1457 | rateId = GetRateId (index); | |||
1458 | prob = station->m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb; | |||
1459 | th = station->m_groupsTable[groupId].m_ratesTable[rateId].throughput; | |||
1460 | ||||
1461 | maxTpGroupId = GetGroupId (station->m_maxTpRate); | |||
1462 | maxTpRateId = GetRateId (station->m_maxTpRate); | |||
1463 | maxTpProb = station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].ewmaProb; | |||
1464 | maxTpTh = station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].throughput; | |||
1465 | ||||
1466 | maxTp2GroupId = GetGroupId (station->m_maxTpRate2); | |||
1467 | maxTp2RateId = GetRateId (station->m_maxTpRate2); | |||
1468 | maxTp2Prob = station->m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].ewmaProb; | |||
1469 | maxTp2Th = station->m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].throughput; | |||
1470 | ||||
1471 | if (th > maxTpTh || (th == maxTpTh && prob > maxTpProb)) | |||
1472 | { | |||
1473 | station->m_maxTpRate2 = station->m_maxTpRate; | |||
1474 | station->m_maxTpRate = index; | |||
1475 | } | |||
1476 | else if (th > maxTp2Th || (th == maxTp2Th && prob > maxTp2Prob)) | |||
1477 | { | |||
1478 | station->m_maxTpRate2 = index; | |||
1479 | } | |||
1480 | ||||
1481 | //Find best rates per group | |||
1482 | ||||
1483 | GroupInfo *group = &station->m_groupsTable[groupId]; | |||
1484 | maxTpGroupId = GetGroupId (group->m_maxTpRate); | |||
1485 | maxTpRateId = GetRateId (group->m_maxTpRate); | |||
1486 | maxTpProb = group->m_ratesTable[maxTpRateId].ewmaProb; | |||
1487 | maxTpTh = station->m_groupsTable[maxTpGroupId].m_ratesTable[maxTpRateId].throughput; | |||
1488 | ||||
1489 | maxTp2GroupId = GetGroupId (group->m_maxTpRate2); | |||
1490 | maxTp2RateId = GetRateId (group->m_maxTpRate2); | |||
1491 | maxTp2Prob = group->m_ratesTable[maxTp2RateId].ewmaProb; | |||
1492 | maxTp2Th = station->m_groupsTable[maxTp2GroupId].m_ratesTable[maxTp2RateId].throughput; | |||
1493 | ||||
1494 | if (th > maxTpTh || (th == maxTpTh && prob > maxTpProb)) | |||
1495 | { | |||
1496 | group->m_maxTpRate2 = group->m_maxTpRate; | |||
1497 | group->m_maxTpRate = index; | |||
1498 | } | |||
1499 | else if (th > maxTp2Th || (th == maxTp2Th && prob > maxTp2Prob)) | |||
1500 | { | |||
1501 | group->m_maxTpRate2 = index; | |||
1502 | } | |||
1503 | } | |||
1504 | ||||
1505 | void | |||
1506 | MinstrelHtWifiManager::RateInit (MinstrelHtWifiRemoteStation *station) | |||
1507 | { | |||
1508 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
1509 | NS_LOG_DEBUG ("RateInit=" << station)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "RateInit=" << station << std::endl; } } while (false); | |||
1510 | ||||
1511 | station->m_groupsTable = McsGroupData (m_numGroups); | |||
1512 | ||||
1513 | /** | |||
1514 | * Initialize groups supported by the receiver. | |||
1515 | */ | |||
1516 | NS_LOG_DEBUG ("Supported groups by station:")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Supported groups by station:" << std::endl; } } while (false); | |||
1517 | for (uint32_t groupId = 0; groupId < m_numGroups; groupId++) | |||
| ||||
1518 | { | |||
1519 | if (m_minstrelGroups[groupId].isSupported) | |||
1520 | { | |||
1521 | station->m_groupsTable[groupId].m_supported = false; | |||
1522 | if (!(!GetVhtSupported (station) && m_minstrelGroups[groupId].isVht) ///Is VHT supported by the receiver? | |||
1523 | && (m_minstrelGroups[groupId].isVht || !GetVhtSupported (station) || !m_useVhtOnly) ///If it is an HT MCS, check if VHT only is disabled | |||
1524 | && !(!GetShortGuardInterval (station) && m_minstrelGroups[groupId].sgi) ///Is SGI supported by the receiver? | |||
1525 | && (GetChannelWidth (station) >= m_minstrelGroups[groupId].chWidth) ///Is channel width supported by the receiver? | |||
1526 | && (GetNumberOfSupportedStreams (station) >= m_minstrelGroups[groupId].streams)) ///Are streams supported by the receiver? | |||
1527 | { | |||
1528 | NS_LOG_DEBUG ("Group " << groupId << ": (" << (uint16_t)m_minstrelGroups[groupId].streams <<do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Group " << groupId << ": (" << (uint16_t)m_minstrelGroups[groupId ].streams << "," << (uint16_t)m_minstrelGroups[groupId ].sgi << "," << (uint16_t)m_minstrelGroups[groupId ].chWidth << ")" << std::endl; } } while (false) | |||
1529 | "," << (uint16_t)m_minstrelGroups[groupId].sgi << "," << (uint16_t)m_minstrelGroups[groupId].chWidth << ")")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Group " << groupId << ": (" << (uint16_t)m_minstrelGroups[groupId ].streams << "," << (uint16_t)m_minstrelGroups[groupId ].sgi << "," << (uint16_t)m_minstrelGroups[groupId ].chWidth << ")" << std::endl; } } while (false); | |||
1530 | ||||
1531 | station->m_groupsTable[groupId].m_supported = true; ///Group supported. | |||
1532 | station->m_groupsTable[groupId].m_col = 0; | |||
1533 | station->m_groupsTable[groupId].m_index = 0; | |||
1534 | ||||
1535 | station->m_groupsTable[groupId].m_ratesTable = HtMinstrelRate (m_numRates); ///Create the rate list for the group. | |||
1536 | for (uint32_t i = 0; i < m_numRates; i++) | |||
1537 | { | |||
1538 | station->m_groupsTable[groupId].m_ratesTable[i].supported = false; | |||
1539 | } | |||
1540 | ||||
1541 | // Initialize all modes supported by the remote station that belong to the current group. | |||
1542 | for (uint32_t i = 0; i < station->m_nModes; i++) | |||
1543 | { | |||
1544 | WifiMode mode = GetMcsSupported (station, i); | |||
1545 | ||||
1546 | ///Use the McsValue as the index in the rate table. | |||
1547 | ///This way, MCSs not supported are not initialized. | |||
1548 | uint32_t rateId = mode.GetMcsValue (); | |||
1549 | if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT) | |||
1550 | { | |||
1551 | rateId %= MAX_HT_GROUP_RATES; | |||
1552 | } | |||
1553 | ||||
1554 | if ((m_minstrelGroups[groupId].isVht && mode.GetModulationClass () == WIFI_MOD_CLASS_VHT ///If it is a VHT MCS only add to a VHT group. | |||
1555 | && IsValidMcs (GetPhy (), m_minstrelGroups[groupId].streams, m_minstrelGroups[groupId].chWidth, mode)) ///Check validity of the VHT MCS | |||
1556 | || (!m_minstrelGroups[groupId].isVht && mode.GetModulationClass () == WIFI_MOD_CLASS_HT ///If it is a HT MCS only add to a HT group. | |||
1557 | && mode.GetMcsValue () < (m_minstrelGroups[groupId].streams * 8) ///Check if the HT MCS corresponds to groups number of streams. | |||
1558 | && mode.GetMcsValue () >= ((m_minstrelGroups[groupId].streams - 1) * 8))) | |||
1559 | { | |||
1560 | NS_LOG_DEBUG ("Mode " << i << ": " << mode << " isVht: " << m_minstrelGroups[groupId].isVht)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "Mode " << i << ": " << mode << " isVht: " << m_minstrelGroups [groupId].isVht << std::endl; } } while (false); | |||
1561 | ||||
1562 | station->m_groupsTable[groupId].m_ratesTable[rateId].supported = true; | |||
1563 | station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex = i; ///Mapping between rateId and operationalMcsSet | |||
1564 | station->m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt = 0; | |||
1565 | station->m_groupsTable[groupId].m_ratesTable[rateId].numRateSuccess = 0; | |||
1566 | station->m_groupsTable[groupId].m_ratesTable[rateId].prob = 0; | |||
1567 | station->m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb = 0; | |||
1568 | station->m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateAttempt = 0; | |||
1569 | station->m_groupsTable[groupId].m_ratesTable[rateId].prevNumRateSuccess = 0; | |||
1570 | station->m_groupsTable[groupId].m_ratesTable[rateId].numSamplesSkipped = 0; | |||
1571 | station->m_groupsTable[groupId].m_ratesTable[rateId].successHist = 0; | |||
1572 | station->m_groupsTable[groupId].m_ratesTable[rateId].attemptHist = 0; | |||
1573 | station->m_groupsTable[groupId].m_ratesTable[rateId].throughput = 0; | |||
1574 | station->m_groupsTable[groupId].m_ratesTable[rateId].perfectTxTime = GetFirstMpduTxTime (groupId, GetMcsSupported (station, i)); | |||
1575 | station->m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 0; | |||
1576 | station->m_groupsTable[groupId].m_ratesTable[rateId].adjustedRetryCount = 0; | |||
1577 | CalculateRetransmits (station, groupId, rateId); | |||
1578 | } | |||
1579 | } | |||
1580 | } | |||
1581 | } | |||
1582 | } | |||
1583 | SetNextSample (station); /// Select the initial sample index. | |||
1584 | UpdateStats (station); /// Calculate the initial high throughput rates. | |||
1585 | station->m_txrate = FindRate (station); /// Select the rate to use. | |||
1586 | } | |||
1587 | ||||
1588 | void | |||
1589 | MinstrelHtWifiManager::CalculateRetransmits (MinstrelHtWifiRemoteStation *station, uint32_t index) | |||
1590 | { | |||
1591 | NS_LOG_FUNCTION (this << station << index)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station << index; std::clog << ")" << std::endl; } } while (false); | |||
1592 | uint32_t groupId = GetGroupId (index); | |||
1593 | uint32_t rateId = GetRateId (index); | |||
1594 | if (!station->m_groupsTable[groupId].m_ratesTable[rateId].retryUpdated) | |||
1595 | { | |||
1596 | CalculateRetransmits (station, groupId, rateId); | |||
1597 | } | |||
1598 | } | |||
1599 | ||||
1600 | void | |||
1601 | MinstrelHtWifiManager::CalculateRetransmits (MinstrelHtWifiRemoteStation *station, uint32_t groupId, uint32_t rateId) | |||
1602 | { | |||
1603 | NS_LOG_FUNCTION (this << station << groupId << groupId)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station << groupId << groupId; std ::clog << ")" << std::endl; } } while (false); | |||
1604 | NS_LOG_DEBUG (" Calculating the number of retries")do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << " Calculating the number of retries" << std::endl; } } while (false); | |||
1605 | ||||
1606 | uint32_t cw = 15; // Is an approximation. | |||
1607 | uint32_t cwMax = 1023; | |||
1608 | Time cwTime, txTime, dataTxTime; | |||
1609 | Time slotTime = GetMac ()->GetSlot (); | |||
1610 | Time ackTime = GetMac ()->GetBasicBlockAckTimeout (); | |||
1611 | ||||
1612 | if (station->m_groupsTable[groupId].m_ratesTable[rateId].ewmaProb < 1) | |||
1613 | { | |||
1614 | station->m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 1; | |||
1615 | } | |||
1616 | else | |||
1617 | { | |||
1618 | station->m_groupsTable[groupId].m_ratesTable[rateId].retryCount = 2; | |||
1619 | station->m_groupsTable[groupId].m_ratesTable[rateId].retryUpdated = true; | |||
1620 | ||||
1621 | dataTxTime = GetFirstMpduTxTime (groupId, GetMcsSupported (station, station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex)) + | |||
1622 | GetMpduTxTime (groupId, GetMcsSupported (station, station->m_groupsTable[groupId].m_ratesTable[rateId].mcsIndex)) * (station->m_avgAmpduLen - 1); | |||
1623 | ||||
1624 | /* Contention time for first 2 tries */ | |||
1625 | cwTime = (cw / 2) * slotTime; | |||
1626 | cw = Min ((cw + 1) * 2, cwMax)(((cw + 1) * 2 < cwMax) ? (cw + 1) * 2 : cwMax); | |||
1627 | cwTime += (cw / 2) * slotTime; | |||
1628 | cw = Min ((cw + 1) * 2, cwMax)(((cw + 1) * 2 < cwMax) ? (cw + 1) * 2 : cwMax); | |||
1629 | ||||
1630 | /* Total TX time for data and Contention after first 2 tries */ | |||
1631 | txTime = cwTime + 2 * (dataTxTime + ackTime); | |||
1632 | ||||
1633 | /* See how many more tries we can fit inside segment size */ | |||
1634 | do | |||
1635 | { | |||
1636 | /* Contention time for this try */ | |||
1637 | cwTime = (cw / 2) * slotTime; | |||
1638 | cw = Min ((cw + 1) * 2, cwMax)(((cw + 1) * 2 < cwMax) ? (cw + 1) * 2 : cwMax); | |||
1639 | ||||
1640 | /* Total TX time after this try */ | |||
1641 | txTime += cwTime + ackTime + dataTxTime; | |||
1642 | } | |||
1643 | while ((txTime < MilliSeconds (6)) | |||
1644 | && (++station->m_groupsTable[groupId].m_ratesTable[rateId].retryCount < 7)); | |||
1645 | } | |||
1646 | } | |||
1647 | ||||
1648 | double | |||
1649 | MinstrelHtWifiManager::CalculateEwmsd (double oldEwmsd, double currentProb, double ewmaProb, uint32_t weight) | |||
1650 | { | |||
1651 | double diff, incr, tmp; | |||
1652 | ||||
1653 | /* calculate exponential weighted moving variance */ | |||
1654 | diff = currentProb - ewmaProb; | |||
1655 | incr = (100 - weight) * diff / 100; | |||
1656 | tmp = oldEwmsd * oldEwmsd; | |||
1657 | tmp = weight * (tmp + diff * incr) / 100; | |||
1658 | ||||
1659 | /* return standard deviation */ | |||
1660 | return sqrt (tmp); | |||
1661 | } | |||
1662 | ||||
1663 | void | |||
1664 | MinstrelHtWifiManager::InitSampleTable (MinstrelHtWifiRemoteStation *station) | |||
1665 | { | |||
1666 | NS_LOG_DEBUG ("InitSampleTable=" << this)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "InitSampleTable=" << this << std::endl; } } while (false); | |||
1667 | ||||
1668 | station->m_col = station->m_index = 0; | |||
1669 | ||||
1670 | //for off-setting to make rates fall between 0 and nModes | |||
1671 | uint32_t numSampleRates = m_numRates; | |||
1672 | ||||
1673 | uint32_t newIndex; | |||
1674 | for (uint32_t col = 0; col < m_nSampleCol; col++) | |||
1675 | { | |||
1676 | for (uint32_t i = 0; i < numSampleRates; i++ ) | |||
1677 | { | |||
1678 | /** | |||
1679 | * The next two lines basically tries to generate a random number | |||
1680 | * between 0 and the number of available rates | |||
1681 | */ | |||
1682 | int uv = m_uniformRandomVariable->GetInteger (0, numSampleRates); | |||
1683 | newIndex = (i + uv) % numSampleRates; | |||
1684 | ||||
1685 | //this loop is used for filling in other uninitialized places | |||
1686 | while (station->m_sampleTable[newIndex][col] != 0) | |||
1687 | { | |||
1688 | newIndex = (newIndex + 1) % m_numRates; | |||
1689 | } | |||
1690 | station->m_sampleTable[newIndex][col] = i; | |||
1691 | } | |||
1692 | } | |||
1693 | } | |||
1694 | ||||
1695 | void | |||
1696 | MinstrelHtWifiManager::PrintTable (MinstrelHtWifiRemoteStation *station) | |||
1697 | { | |||
1698 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
1699 | NS_LOG_DEBUG ("PrintTable=" << station)do { if (g_log.IsEnabled (ns3::LOG_DEBUG)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; if (g_log.IsEnabled (ns3::LOG_PREFIX_FUNC)) { std ::clog << g_log.Name () << ":" << __FUNCTION__ << "(): "; }; if (g_log.IsEnabled (ns3::LOG_PREFIX_LEVEL )) { std::clog << "[" << g_log.GetLevelLabel (ns3 ::LOG_DEBUG) << "] "; }; std::clog << "PrintTable=" << station << std::endl; } } while (false); | |||
1700 | ||||
1701 | station->m_statsFile << " best ____________rate__________ ________statistics________ ________last_______ ______sum-of________\n" << | |||
1702 | " mode guard # rate [name idx airtime max_tp] [avg(tp) avg(prob) sd(prob)] [prob.|retry|suc|att] [#success | #attempts]\n"; | |||
1703 | for (uint32_t i = 0; i < m_numGroups; i++) | |||
1704 | { | |||
1705 | StatsDump (station, i, station->m_statsFile); | |||
1706 | } | |||
1707 | ||||
1708 | station->m_statsFile << "\nTotal packet count:: ideal " << Max (0, station->m_totalPacketsCount - station->m_samplePacketsCount)((0 > station->m_totalPacketsCount - station->m_samplePacketsCount ) ? 0 : station->m_totalPacketsCount - station->m_samplePacketsCount ) << | |||
1709 | " lookaround " << station->m_samplePacketsCount << "\n"; | |||
1710 | station->m_statsFile << "Average # of aggregated frames per A-MPDU: " << station->m_avgAmpduLen << "\n\n"; | |||
1711 | ||||
1712 | station->m_statsFile.flush (); | |||
1713 | } | |||
1714 | ||||
1715 | void | |||
1716 | MinstrelHtWifiManager::StatsDump (MinstrelHtWifiRemoteStation *station, uint32_t groupId, std::ofstream &of) | |||
1717 | { | |||
1718 | uint32_t numRates = m_numRates; | |||
1719 | McsGroup group = m_minstrelGroups[groupId]; | |||
1720 | Time txTime; | |||
1721 | char giMode; | |||
1722 | if (group.sgi) | |||
1723 | { | |||
1724 | giMode = 'S'; | |||
1725 | } | |||
1726 | else | |||
1727 | { | |||
1728 | giMode = 'L'; | |||
1729 | } | |||
1730 | for (uint32_t i = 0; i < numRates; i++) | |||
1731 | { | |||
1732 | if (station->m_groupsTable[groupId].m_supported && station->m_groupsTable[groupId].m_ratesTable[i].supported) | |||
1733 | { | |||
1734 | if (!group.isVht) | |||
1735 | { | |||
1736 | of << "HT" << group.chWidth << " " << giMode << "GI " << (int)group.streams << " "; | |||
1737 | } | |||
1738 | else | |||
1739 | { | |||
1740 | of << "VHT" << group.chWidth << " " << giMode << "GI " << (int)group.streams << " "; | |||
1741 | } | |||
1742 | ||||
1743 | uint32_t maxTpRate = station->m_maxTpRate; | |||
1744 | uint32_t maxTpRate2 = station->m_maxTpRate2; | |||
1745 | uint32_t maxProbRate = station->m_maxProbRate; | |||
1746 | ||||
1747 | uint32_t idx = GetIndex (groupId, i); | |||
1748 | if (idx == maxTpRate) | |||
1749 | { | |||
1750 | of << 'A'; | |||
1751 | } | |||
1752 | else | |||
1753 | { | |||
1754 | of << ' '; | |||
1755 | } | |||
1756 | if (idx == maxTpRate2) | |||
1757 | { | |||
1758 | of << 'B'; | |||
1759 | } | |||
1760 | else | |||
1761 | { | |||
1762 | of << ' '; | |||
1763 | } | |||
1764 | if (idx == maxProbRate) | |||
1765 | { | |||
1766 | of << 'P'; | |||
1767 | } | |||
1768 | else | |||
1769 | { | |||
1770 | of << ' '; | |||
1771 | } | |||
1772 | ||||
1773 | if (!group.isVht) | |||
1774 | { | |||
1775 | of << std::setw (4) << " MCS" << (group.streams - 1) * 8 + i; | |||
1776 | } | |||
1777 | else | |||
1778 | { | |||
1779 | of << std::setw (7) << " MCS" << i << "/" << (int) group.streams; | |||
1780 | } | |||
1781 | ||||
1782 | of << " " << std::setw (3) << idx << " "; | |||
1783 | ||||
1784 | /* tx_time[rate(i)] in usec */ | |||
1785 | txTime = GetFirstMpduTxTime (groupId, GetMcsSupported (station, station->m_groupsTable[groupId].m_ratesTable[i].mcsIndex)); | |||
1786 | of << std::setw (6) << txTime.GetMicroSeconds () << " "; | |||
1787 | ||||
1788 | of << std::setw (7) << CalculateThroughput (station, groupId, i, 100) / 100 << " " << | |||
1789 | std::setw (7) << station->m_groupsTable[groupId].m_ratesTable[i].throughput / 100 << " " << | |||
1790 | std::setw (7) << station->m_groupsTable[groupId].m_ratesTable[i].ewmaProb << " " << | |||
1791 | std::setw (7) << station->m_groupsTable[groupId].m_ratesTable[i].ewmsdProb << " " << | |||
1792 | std::setw (7) << station->m_groupsTable[groupId].m_ratesTable[i].prob << " " << | |||
1793 | std::setw (2) << station->m_groupsTable[groupId].m_ratesTable[i].retryCount << " " << | |||
1794 | std::setw (3) << station->m_groupsTable[groupId].m_ratesTable[i].prevNumRateSuccess << " " << | |||
1795 | std::setw (3) << station->m_groupsTable[groupId].m_ratesTable[i].prevNumRateAttempt << " " << | |||
1796 | std::setw (9) << station->m_groupsTable[groupId].m_ratesTable[i].successHist << " " << | |||
1797 | std::setw (9) << station->m_groupsTable[groupId].m_ratesTable[i].attemptHist << "\n"; | |||
1798 | } | |||
1799 | } | |||
1800 | } | |||
1801 | uint32_t | |||
1802 | MinstrelHtWifiManager::GetIndex (uint32_t groupId, uint32_t rateId) | |||
1803 | { | |||
1804 | NS_LOG_FUNCTION (this << groupId << rateId)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << groupId << rateId; std::clog << ")" << std::endl; } } while (false); | |||
1805 | uint32_t index; | |||
1806 | index = groupId * m_numRates + rateId; | |||
1807 | return index; | |||
1808 | } | |||
1809 | ||||
1810 | uint32_t | |||
1811 | MinstrelHtWifiManager::GetRateId (uint32_t index) | |||
1812 | { | |||
1813 | NS_LOG_FUNCTION (this << index)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << index; std::clog << ")" << std::endl ; } } while (false); | |||
1814 | ||||
1815 | uint32_t id; | |||
1816 | id = index % m_numRates; | |||
1817 | return id; | |||
1818 | } | |||
1819 | ||||
1820 | uint32_t | |||
1821 | MinstrelHtWifiManager::GetGroupId (uint32_t index) | |||
1822 | { | |||
1823 | NS_LOG_FUNCTION (this << index)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << index; std::clog << ")" << std::endl ; } } while (false); | |||
1824 | ||||
1825 | return index / m_numRates; | |||
1826 | } | |||
1827 | ||||
1828 | uint32_t | |||
1829 | MinstrelHtWifiManager::GetHtGroupId (uint8_t txstreams, uint8_t sgi, uint8_t chWidth) | |||
1830 | { | |||
1831 | NS_LOG_FUNCTION (this << (uint16_t)txstreams << (uint16_t)sgi << (uint16_t)chWidth)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << (uint16_t)txstreams << (uint16_t)sgi << (uint16_t)chWidth; std::clog << ")" << std::endl ; } } while (false); | |||
1832 | ||||
1833 | return MAX_SUPPORTED_STREAMS * 2 * (chWidth == 40 ? 1 : 0) + MAX_SUPPORTED_STREAMS * sgi + txstreams - 1; | |||
1834 | } | |||
1835 | ||||
1836 | uint32_t | |||
1837 | MinstrelHtWifiManager::GetVhtGroupId (uint8_t txstreams, uint8_t sgi, uint8_t chWidth) | |||
1838 | { | |||
1839 | NS_LOG_FUNCTION (this << (uint16_t)txstreams << (uint16_t)sgi << (uint16_t)chWidth)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << (uint16_t)txstreams << (uint16_t)sgi << (uint16_t)chWidth; std::clog << ")" << std::endl ; } } while (false); | |||
1840 | ||||
1841 | return MAX_HT_STREAM_GROUPS * MAX_SUPPORTED_STREAMS + MAX_SUPPORTED_STREAMS * 2 * (chWidth == 160 ? 3 : chWidth == 80 ? 2 : chWidth == 40 ? 1 : 0) + MAX_SUPPORTED_STREAMS * sgi + txstreams - 1; | |||
1842 | } | |||
1843 | ||||
1844 | uint32_t | |||
1845 | MinstrelHtWifiManager::GetLowestIndex (MinstrelHtWifiRemoteStation *station) | |||
1846 | { | |||
1847 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
1848 | ||||
1849 | uint32_t groupId = 0; | |||
1850 | uint32_t rateId = 0; | |||
1851 | while (groupId < m_numGroups && !station->m_groupsTable[groupId].m_supported) | |||
1852 | { | |||
1853 | groupId++; | |||
1854 | } | |||
1855 | while (rateId < m_numRates && !station->m_groupsTable[groupId].m_ratesTable[rateId].supported) | |||
1856 | { | |||
1857 | rateId++; | |||
1858 | } | |||
1859 | NS_ASSERT (station->m_groupsTable[groupId].m_supported && station->m_groupsTable[groupId].m_ratesTable[rateId].supported)do { if (!(station->m_groupsTable[groupId].m_supported && station->m_groupsTable[groupId].m_ratesTable[rateId].supported )) { std::cerr << "assert failed. cond=\"" << "station->m_groupsTable[groupId].m_supported && station->m_groupsTable[groupId].m_ratesTable[rateId].supported" << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 1859 << std::endl; ::ns3:: FatalImpl::FlushStreams (); if (true) std::terminate (); } while (false); } } while (false); | |||
1860 | return GetIndex (groupId, rateId); | |||
1861 | } | |||
1862 | ||||
1863 | uint32_t | |||
1864 | MinstrelHtWifiManager::GetLowestIndex (MinstrelHtWifiRemoteStation *station, uint32_t groupId) | |||
1865 | { | |||
1866 | NS_LOG_FUNCTION (this << station)do { if (g_log.IsEnabled (ns3::LOG_FUNCTION)) { if (g_log.IsEnabled (ns3::LOG_PREFIX_TIME)) { ns3::LogTimePrinter printer = ns3:: LogGetTimePrinter (); if (printer != 0) { (*printer)(std::clog ); std::clog << " "; } }; if (g_log.IsEnabled (ns3::LOG_PREFIX_NODE )) { ns3::LogNodePrinter printer = ns3::LogGetNodePrinter (); if (printer != 0) { (*printer)(std::clog); std::clog << " "; } }; ; std::clog << g_log.Name () << ":" << __FUNCTION__ << "("; ns3::ParameterLogger (std::clog) << this << station; std::clog << ")" << std:: endl; } } while (false); | |||
1867 | ||||
1868 | uint32_t rateId = 0; | |||
1869 | while (rateId < m_numRates && !station->m_groupsTable[groupId].m_ratesTable[rateId].supported) | |||
1870 | { | |||
1871 | rateId++; | |||
1872 | } | |||
1873 | NS_ASSERT (station->m_groupsTable[groupId].m_supported && station->m_groupsTable[groupId].m_ratesTable[rateId].supported)do { if (!(station->m_groupsTable[groupId].m_supported && station->m_groupsTable[groupId].m_ratesTable[rateId].supported )) { std::cerr << "assert failed. cond=\"" << "station->m_groupsTable[groupId].m_supported && station->m_groupsTable[groupId].m_ratesTable[rateId].supported" << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 1873 << std::endl; ::ns3:: FatalImpl::FlushStreams (); if (true) std::terminate (); } while (false); } } while (false); | |||
1874 | return GetIndex (groupId, rateId); | |||
1875 | } | |||
1876 | ||||
1877 | ||||
1878 | WifiModeList | |||
1879 | MinstrelHtWifiManager::GetVhtDeviceMcsList (void) const | |||
1880 | { | |||
1881 | WifiModeList vhtMcsList; | |||
1882 | Ptr<WifiPhy> phy = GetPhy (); | |||
1883 | for (uint32_t i = 0; i < phy->GetNMcs (); i++) | |||
1884 | { | |||
1885 | WifiMode mode = phy->GetMcs (i); | |||
1886 | if (mode.GetModulationClass () == WIFI_MOD_CLASS_VHT) | |||
1887 | { | |||
1888 | vhtMcsList.push_back (mode); | |||
1889 | } | |||
1890 | } | |||
1891 | return vhtMcsList; | |||
1892 | } | |||
1893 | ||||
1894 | WifiModeList | |||
1895 | MinstrelHtWifiManager::GetHtDeviceMcsList (void) const | |||
1896 | { | |||
1897 | WifiModeList htMcsList; | |||
1898 | Ptr<WifiPhy> phy = GetPhy (); | |||
1899 | for (uint32_t i = 0; i < phy->GetNMcs (); i++) | |||
1900 | { | |||
1901 | WifiMode mode = phy->GetMcs (i); | |||
1902 | if (mode.GetModulationClass () == WIFI_MOD_CLASS_HT) | |||
1903 | { | |||
1904 | htMcsList.push_back (mode); | |||
1905 | } | |||
1906 | } | |||
1907 | return htMcsList; | |||
1908 | } | |||
1909 | ||||
1910 | void | |||
1911 | MinstrelHtWifiManager::SetHeSupported (bool enable) | |||
1912 | { | |||
1913 | //HE is not supported yet by this algorithm. | |||
1914 | if (enable) | |||
1915 | { | |||
1916 | NS_FATAL_ERROR ("WifiRemoteStationManager selected does not support HE rates")do { std::cerr << "msg=\"" << "WifiRemoteStationManager selected does not support HE rates" << "\", "; do { std::cerr << "file=" << "../src/wifi/model/minstrel-ht-wifi-manager.cc" << ", line=" << 1916 << std::endl; ::ns3:: FatalImpl::FlushStreams (); if (true) std::terminate (); } while (false); } while (false); | |||
1917 | } | |||
1918 | } | |||
1919 | ||||
1920 | } // namespace ns3 | |||
1921 | ||||
1922 | ||||
1923 | ||||
1924 | ||||
1925 |