LEFT | RIGHT |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2006, 2009 INRIA | 3 * Copyright (c) 2006, 2009 INRIA |
4 * Copyright (c) 2009 MIRKO BANCHI | 4 * Copyright (c) 2009 MIRKO BANCHI |
5 * | 5 * |
6 * This program is free software; you can redistribute it and/or modify | 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 | 7 * it under the terms of the GNU General Public License version 2 as |
8 * published by the Free Software Foundation; | 8 * published by the Free Software Foundation; |
9 * | 9 * |
10 * This program is distributed in the hope that it will be useful, | 10 * This program is distributed in the hope that it will be useful, |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 * GNU General Public License for more details. | 13 * GNU General Public License for more details. |
14 * | 14 * |
15 * You should have received a copy of the GNU General Public License | 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 | 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 | 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 * | 18 * |
19 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> | 19 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
20 * Mirko Banchi <mk.banchi@gmail.com> | 20 * Mirko Banchi <mk.banchi@gmail.com> |
21 */ | 21 */ |
22 | 22 |
| 23 #include "ns3/log.h" |
| 24 #include "ns3/packet.h" |
| 25 #include "ns3/simulator.h" |
| 26 #include "ns3/pointer.h" |
| 27 #include "ns3/string.h" |
| 28 #include "ns3/random-variable-stream.h" |
23 #include "ap-wifi-mac.h" | 29 #include "ap-wifi-mac.h" |
24 #include "ns3/log.h" | |
25 #include "ns3/simulator.h" | |
26 #include "ns3/string.h" | |
27 #include "ns3/pointer.h" | |
28 #include "mac-low.h" | 30 #include "mac-low.h" |
29 #include "mac-tx-middle.h" | 31 #include "mac-tx-middle.h" |
| 32 #include "mgt-headers.h" |
| 33 #include "msdu-aggregator.h" |
| 34 #include "amsdu-subframe-header.h" |
| 35 #include "wifi-phy.h" |
30 | 36 |
31 namespace ns3 { | 37 namespace ns3 { |
32 | 38 |
33 NS_LOG_COMPONENT_DEFINE ("ApWifiMac"); | 39 NS_LOG_COMPONENT_DEFINE ("ApWifiMac"); |
34 | 40 |
35 NS_OBJECT_ENSURE_REGISTERED (ApWifiMac); | 41 NS_OBJECT_ENSURE_REGISTERED (ApWifiMac); |
36 | 42 |
37 TypeId | 43 TypeId |
38 ApWifiMac::GetTypeId (void) | 44 ApWifiMac::GetTypeId (void) |
39 { | 45 { |
(...skipping 14 matching lines...) Expand all Loading... |
54 MakePointerAccessor (&ApWifiMac::m_beaconJitter), | 60 MakePointerAccessor (&ApWifiMac::m_beaconJitter), |
55 MakePointerChecker<UniformRandomVariable> ()) | 61 MakePointerChecker<UniformRandomVariable> ()) |
56 .AddAttribute ("EnableBeaconJitter", | 62 .AddAttribute ("EnableBeaconJitter", |
57 "If beacons are enabled, whether to jitter the initial send e
vent.", | 63 "If beacons are enabled, whether to jitter the initial send e
vent.", |
58 BooleanValue (true), | 64 BooleanValue (true), |
59 MakeBooleanAccessor (&ApWifiMac::m_enableBeaconJitter), | 65 MakeBooleanAccessor (&ApWifiMac::m_enableBeaconJitter), |
60 MakeBooleanChecker ()) | 66 MakeBooleanChecker ()) |
61 .AddAttribute ("BeaconGeneration", | 67 .AddAttribute ("BeaconGeneration", |
62 "Whether or not beacons are generated.", | 68 "Whether or not beacons are generated.", |
63 BooleanValue (true), | 69 BooleanValue (true), |
64 MakeBooleanAccessor (&ApWifiMac::SetBeaconGeneration, | 70 MakeBooleanAccessor (&ApWifiMac::SetBeaconGeneration), |
65 &ApWifiMac::GetBeaconGeneration), | |
66 MakeBooleanChecker ()) | 71 MakeBooleanChecker ()) |
67 .AddAttribute ("EnableNonErpProtection", "Whether or not protection mechanis
m should be used when non-ERP STAs are present within the BSS." | 72 .AddAttribute ("EnableNonErpProtection", "Whether or not protection mechanis
m should be used when non-ERP STAs are present within the BSS." |
68 "This parameter is only used when ERP is supported by the AP.
", | 73 "This parameter is only used when ERP is supported by the AP.
", |
69 BooleanValue (true), | 74 BooleanValue (true), |
70 MakeBooleanAccessor (&ApWifiMac::m_enableNonErpProtection), | 75 MakeBooleanAccessor (&ApWifiMac::m_enableNonErpProtection), |
71 MakeBooleanChecker ()) | 76 MakeBooleanChecker ()) |
72 .AddAttribute ("RifsMode", "If non-HT STAs are detected, whether to force RI
FS to be disabled within the BSS." | 77 .AddAttribute ("RifsMode", "If non-HT STAs are detected, whether to force RI
FS to be disabled within the BSS." |
73 "This parameter is only used when HT is supported by the AP."
, | 78 "This parameter is only used when HT is supported by the AP."
, |
74 BooleanValue (true), | 79 BooleanValue (true), |
75 MakeBooleanAccessor (&ApWifiMac::m_disableRifs), | 80 MakeBooleanAccessor (&ApWifiMac::m_disableRifs), |
76 MakeBooleanChecker ()) | 81 MakeBooleanChecker ()) |
77 ; | 82 ; |
78 return tid; | 83 return tid; |
79 } | 84 } |
80 | 85 |
81 ApWifiMac::ApWifiMac () | 86 ApWifiMac::ApWifiMac () |
82 : m_enableBeaconGeneration (false) | 87 : m_enableBeaconGeneration (false) |
83 { | 88 { |
84 NS_LOG_FUNCTION (this); | 89 NS_LOG_FUNCTION (this); |
85 m_beaconDca = CreateObject<DcaTxop> (); | 90 m_beaconDca = CreateObject<DcaTxop> (); |
86 m_beaconDca->SetAifsn (1); | 91 m_beaconDca->SetAifsn (1); |
87 m_beaconDca->SetMinCw (0); | 92 m_beaconDca->SetMinCw (0); |
88 m_beaconDca->SetMaxCw (0); | 93 m_beaconDca->SetMaxCw (0); |
89 m_beaconDca->SetLow (m_low); | 94 m_beaconDca->SetMacLow (m_low); |
90 m_beaconDca->SetManager (m_dcfManager); | 95 m_beaconDca->SetDcfManager (m_dcfManager); |
91 m_beaconDca->SetTxMiddle (m_txMiddle); | 96 m_beaconDca->SetTxMiddle (m_txMiddle); |
92 | 97 |
93 //Let the lower layers know that we are acting as an AP. | 98 //Let the lower layers know that we are acting as an AP. |
94 SetTypeOfStation (AP); | 99 SetTypeOfStation (AP); |
95 } | 100 } |
96 | 101 |
97 ApWifiMac::~ApWifiMac () | 102 ApWifiMac::~ApWifiMac () |
98 { | 103 { |
99 NS_LOG_FUNCTION (this); | 104 NS_LOG_FUNCTION (this); |
100 m_staList.clear (); | 105 m_staList.clear (); |
(...skipping 30 matching lines...) Expand all Loading... |
131 { | 136 { |
132 m_beaconEvent.Cancel (); | 137 m_beaconEvent.Cancel (); |
133 } | 138 } |
134 else if (enable && !m_enableBeaconGeneration) | 139 else if (enable && !m_enableBeaconGeneration) |
135 { | 140 { |
136 m_beaconEvent = Simulator::ScheduleNow (&ApWifiMac::SendOneBeacon, this); | 141 m_beaconEvent = Simulator::ScheduleNow (&ApWifiMac::SendOneBeacon, this); |
137 } | 142 } |
138 m_enableBeaconGeneration = enable; | 143 m_enableBeaconGeneration = enable; |
139 } | 144 } |
140 | 145 |
141 bool | |
142 ApWifiMac::GetBeaconGeneration (void) const | |
143 { | |
144 NS_LOG_FUNCTION (this); | |
145 return m_enableBeaconGeneration; | |
146 } | |
147 | |
148 Time | 146 Time |
149 ApWifiMac::GetBeaconInterval (void) const | 147 ApWifiMac::GetBeaconInterval (void) const |
150 { | 148 { |
151 NS_LOG_FUNCTION (this); | 149 NS_LOG_FUNCTION (this); |
152 return m_beaconInterval; | 150 return m_beaconInterval; |
153 } | 151 } |
154 | 152 |
155 void | 153 void |
156 ApWifiMac::SetWifiRemoteStationManager (const Ptr<WifiRemoteStationManager> stat
ionManager) | 154 ApWifiMac::SetWifiRemoteStationManager (const Ptr<WifiRemoteStationManager> stat
ionManager) |
157 { | 155 { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 | 191 |
194 bool | 192 bool |
195 ApWifiMac::GetShortSlotTimeEnabled (void) const | 193 ApWifiMac::GetShortSlotTimeEnabled (void) const |
196 { | 194 { |
197 if (m_nonErpStations.size () != 0) | 195 if (m_nonErpStations.size () != 0) |
198 { | 196 { |
199 return false; | 197 return false; |
200 } | 198 } |
201 if (m_erpSupported == true && GetShortSlotTimeSupported () == true) | 199 if (m_erpSupported == true && GetShortSlotTimeSupported () == true) |
202 { | 200 { |
203 for (std::list<Mac48Address>::const_iterator i = m_staList.begin (); i !=
m_staList.end (); i++) | 201 for (std::map<uint16_t, Mac48Address>::const_iterator i = m_staList.begin
(); i != m_staList.end (); i++) |
204 { | 202 { |
205 if (m_stationManager->GetShortSlotTimeSupported (*i) == false) | 203 if (m_stationManager->GetShortSlotTimeSupported (i->second) == false) |
206 { | 204 { |
207 return false; | 205 return false; |
208 } | 206 } |
209 } | 207 } |
210 return true; | 208 return true; |
211 } | 209 } |
212 return false; | 210 return false; |
213 } | 211 } |
214 | 212 |
215 bool | 213 bool |
(...skipping 10 matching lines...) Expand all Loading... |
226 } | 224 } |
227 return true; | 225 return true; |
228 } | 226 } |
229 return false; | 227 return false; |
230 } | 228 } |
231 | 229 |
232 bool | 230 bool |
233 ApWifiMac::IsNonGfHtStasPresent (void) const | 231 ApWifiMac::IsNonGfHtStasPresent (void) const |
234 { | 232 { |
235 bool isNonGfHtStasPresent = false; | 233 bool isNonGfHtStasPresent = false; |
236 for (std::list<Mac48Address>::const_iterator i = m_staList.begin (); i != m_st
aList.end (); i++) | 234 for (std::map<uint16_t, Mac48Address>::const_iterator i = m_staList.begin ();
i != m_staList.end (); i++) |
237 { | 235 { |
238 if (m_stationManager->GetGreenfieldSupported (*i) == false) | 236 if (m_stationManager->GetGreenfieldSupported (i->second) == false) |
239 { | 237 { |
240 isNonGfHtStasPresent = true; | 238 isNonGfHtStasPresent = true; |
241 break; | 239 break; |
242 } | 240 } |
243 } | 241 } |
244 m_stationManager->SetUseGreenfieldProtection (isNonGfHtStasPresent); | 242 m_stationManager->SetUseGreenfieldProtection (isNonGfHtStasPresent); |
245 return isNonGfHtStasPresent; | 243 return isNonGfHtStasPresent; |
246 } | 244 } |
247 | 245 |
248 uint8_t | 246 uint16_t |
249 ApWifiMac::GetVhtOperationalChannelWidth (void) const | 247 ApWifiMac::GetVhtOperationalChannelWidth (void) const |
250 { | 248 { |
251 uint8_t channelWidth = m_phy->GetChannelWidth (); | 249 uint16_t channelWidth = m_phy->GetChannelWidth (); |
252 for (std::list<Mac48Address>::const_iterator i = m_staList.begin (); i != m_st
aList.end (); i++) | 250 for (std::map<uint16_t, Mac48Address>::const_iterator i = m_staList.begin ();
i != m_staList.end (); i++) |
253 { | 251 { |
254 if (m_stationManager->GetVhtSupported (*i)) | 252 if (m_stationManager->GetVhtSupported (i->second)) |
255 { | 253 { |
256 if (m_stationManager->GetChannelWidthSupported (*i) < channelWidth) | 254 if (m_stationManager->GetChannelWidthSupported (i->second) < channelWi
dth) |
257 { | 255 { |
258 channelWidth = m_stationManager->GetChannelWidthSupported (*i); | 256 channelWidth = m_stationManager->GetChannelWidthSupported (i->seco
nd); |
259 } | 257 } |
260 } | 258 } |
261 } | 259 } |
262 return channelWidth; | 260 return channelWidth; |
263 } | 261 } |
264 | 262 |
265 void | 263 void |
266 ApWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, | 264 ApWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, |
267 Mac48Address to) | 265 Mac48Address to) |
268 { | 266 { |
(...skipping 16 matching lines...) Expand all Loading... |
285 } | 283 } |
286 } | 284 } |
287 | 285 |
288 ForwardDown (packet, from, to, tid); | 286 ForwardDown (packet, from, to, tid); |
289 } | 287 } |
290 | 288 |
291 void | 289 void |
292 ApWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, | 290 ApWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, |
293 Mac48Address to, uint8_t tid) | 291 Mac48Address to, uint8_t tid) |
294 { | 292 { |
295 NS_LOG_FUNCTION (this << packet << from << to << static_cast<uint32_t> (tid)); | 293 NS_LOG_FUNCTION (this << packet << from << to << +tid); |
296 WifiMacHeader hdr; | 294 WifiMacHeader hdr; |
297 | 295 |
298 //For now, an AP that supports QoS does not support non-QoS | 296 //For now, an AP that supports QoS does not support non-QoS |
299 //associations, and vice versa. In future the AP model should | 297 //associations, and vice versa. In future the AP model should |
300 //support simultaneously associated QoS and non-QoS STAs, at which | 298 //support simultaneously associated QoS and non-QoS STAs, at which |
301 //point there will need to be per-association QoS state maintained | 299 //point there will need to be per-association QoS state maintained |
302 //by the association state machine, and consulted here. | 300 //by the association state machine, and consulted here. |
303 if (m_qosSupported) | 301 if (m_qosSupported) |
304 { | 302 { |
305 hdr.SetType (WIFI_MAC_QOSDATA); | 303 hdr.SetType (WIFI_MAC_QOSDATA); |
306 hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); | 304 hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); |
307 hdr.SetQosNoEosp (); | 305 hdr.SetQosNoEosp (); |
308 hdr.SetQosNoAmsdu (); | 306 hdr.SetQosNoAmsdu (); |
309 //Transmission of multiple frames in the same Polled TXOP is not supported
for now | 307 //Transmission of multiple frames in the same Polled TXOP is not supported
for now |
310 hdr.SetQosTxopLimit (0); | 308 hdr.SetQosTxopLimit (0); |
311 //Fill in the QoS control field in the MAC header | 309 //Fill in the QoS control field in the MAC header |
312 hdr.SetQosTid (tid); | 310 hdr.SetQosTid (tid); |
313 } | 311 } |
314 else | 312 else |
315 { | 313 { |
316 hdr.SetType (WIFI_MAC_DATA); | 314 hdr.SetType (WIFI_MAC_DATA); |
317 } | 315 } |
318 | 316 |
319 if (m_htSupported || m_vhtSupported || m_heSupported) | 317 if (m_qosSupported || m_htSupported || m_vhtSupported || m_heSupported) |
320 { | 318 { |
321 hdr.SetNoOrder (); | 319 hdr.SetNoOrder (); |
322 } | 320 } |
323 hdr.SetAddr1 (to); | 321 hdr.SetAddr1 (to); |
324 hdr.SetAddr2 (GetAddress ()); | 322 hdr.SetAddr2 (GetAddress ()); |
325 hdr.SetAddr3 (from); | 323 hdr.SetAddr3 (from); |
326 hdr.SetDsFrom (); | 324 hdr.SetDsFrom (); |
327 hdr.SetDsNotTo (); | 325 hdr.SetDsNotTo (); |
328 | 326 |
329 if (m_qosSupported) | 327 if (m_qosSupported) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 NS_LOG_DEBUG ("Adding basic mode " << mode.GetUniqueName ()); | 400 NS_LOG_DEBUG ("Adding basic mode " << mode.GetUniqueName ()); |
403 m_stationManager->AddBasicMode (mode); | 401 m_stationManager->AddBasicMode (mode); |
404 } | 402 } |
405 } | 403 } |
406 //set the basic rates | 404 //set the basic rates |
407 for (uint8_t j = 0; j < m_stationManager->GetNBasicModes (); j++) | 405 for (uint8_t j = 0; j < m_stationManager->GetNBasicModes (); j++) |
408 { | 406 { |
409 WifiMode mode = m_stationManager->GetBasicMode (j); | 407 WifiMode mode = m_stationManager->GetBasicMode (j); |
410 uint64_t modeDataRate = mode.GetDataRate (m_phy->GetChannelWidth ()); | 408 uint64_t modeDataRate = mode.GetDataRate (m_phy->GetChannelWidth ()); |
411 NS_LOG_DEBUG ("Setting basic rate " << mode.GetUniqueName ()); | 409 NS_LOG_DEBUG ("Setting basic rate " << mode.GetUniqueName ()); |
412 rates.SetBasicRate (static_cast<uint32_t>(modeDataRate)); | 410 rates.SetBasicRate (modeDataRate); |
413 } | 411 } |
414 | 412 |
415 return rates; | 413 return rates; |
416 } | 414 } |
417 | 415 |
418 DsssParameterSet | 416 DsssParameterSet |
419 ApWifiMac::GetDsssParameterSet (void) const | 417 ApWifiMac::GetDsssParameterSet (void) const |
420 { | 418 { |
421 NS_LOG_FUNCTION (this); | 419 NS_LOG_FUNCTION (this); |
422 DsssParameterSet dsssParameters; | 420 DsssParameterSet dsssParameters; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 EdcaParameterSet edcaParameters; | 466 EdcaParameterSet edcaParameters; |
469 if (m_qosSupported) | 467 if (m_qosSupported) |
470 { | 468 { |
471 edcaParameters.SetQosSupported (1); | 469 edcaParameters.SetQosSupported (1); |
472 Ptr<EdcaTxopN> edca; | 470 Ptr<EdcaTxopN> edca; |
473 Time txopLimit; | 471 Time txopLimit; |
474 | 472 |
475 edca = m_edca.find (AC_BE)->second; | 473 edca = m_edca.find (AC_BE)->second; |
476 txopLimit = edca->GetTxopLimit (); | 474 txopLimit = edca->GetTxopLimit (); |
477 edcaParameters.SetBeAci (0); | 475 edcaParameters.SetBeAci (0); |
478 edcaParameters.SetBeCWmin (static_cast<uint8_t>(edca->GetMinCw ())); | 476 edcaParameters.SetBeCWmin (edca->GetMinCw ()); |
479 edcaParameters.SetBeCWmax (static_cast<uint8_t>(edca->GetMaxCw ())); | 477 edcaParameters.SetBeCWmax (edca->GetMaxCw ()); |
480 edcaParameters.SetBeAifsn (static_cast<uint8_t>(edca->GetAifsn ())); | 478 edcaParameters.SetBeAifsn (static_cast<uint8_t> (edca->GetAifsn ())); |
481 edcaParameters.SetBeTXOPLimit (static_cast<uint16_t>(txopLimit.GetMicroSec
onds () / 32)); | 479 edcaParameters.SetBeTXOPLimit (static_cast<uint16_t> (txopLimit.GetMicroSe
conds () / 32)); |
482 edcaParameters.SetBeAcm (0); | |
483 | 480 |
484 edca = m_edca.find (AC_BK)->second; | 481 edca = m_edca.find (AC_BK)->second; |
485 txopLimit = edca->GetTxopLimit (); | 482 txopLimit = edca->GetTxopLimit (); |
486 edcaParameters.SetBkAci (1); | 483 edcaParameters.SetBkAci (1); |
487 edcaParameters.SetBkCWmin (static_cast<uint8_t>(edca->GetMinCw ())); | 484 edcaParameters.SetBkCWmin (edca->GetMinCw ()); |
488 edcaParameters.SetBkCWmax (static_cast<uint8_t>(edca->GetMaxCw ())); | 485 edcaParameters.SetBkCWmax (edca->GetMaxCw ()); |
489 edcaParameters.SetBkAifsn (static_cast<uint8_t>(edca->GetAifsn ())); | 486 edcaParameters.SetBkAifsn (static_cast<uint8_t> (edca->GetAifsn ())); |
490 edcaParameters.SetBkTXOPLimit (static_cast<uint16_t>(txopLimit.GetMicroSec
onds () / 32)); | 487 edcaParameters.SetBkTXOPLimit (static_cast<uint16_t> (txopLimit.GetMicroSe
conds () / 32)); |
491 edcaParameters.SetBkAcm (0); | |
492 | 488 |
493 edca = m_edca.find (AC_VI)->second; | 489 edca = m_edca.find (AC_VI)->second; |
494 txopLimit = edca->GetTxopLimit (); | 490 txopLimit = edca->GetTxopLimit (); |
495 edcaParameters.SetViAci (2); | 491 edcaParameters.SetViAci (2); |
496 edcaParameters.SetViCWmin (static_cast<uint8_t>(edca->GetMinCw ())); | 492 edcaParameters.SetViCWmin (edca->GetMinCw ()); |
497 edcaParameters.SetViCWmax (static_cast<uint8_t>(edca->GetMaxCw ())); | 493 edcaParameters.SetViCWmax (edca->GetMaxCw ()); |
498 edcaParameters.SetViAifsn (static_cast<uint8_t>(edca->GetAifsn ())); | 494 edcaParameters.SetViAifsn (static_cast<uint8_t> (edca->GetAifsn ())); |
499 edcaParameters.SetViTXOPLimit (static_cast<uint16_t>(txopLimit.GetMicroSec
onds () / 32)); | 495 edcaParameters.SetViTXOPLimit (static_cast<uint16_t> (txopLimit.GetMicroSe
conds () / 32)); |
500 edcaParameters.SetViAcm (0); | |
501 | 496 |
502 edca = m_edca.find (AC_VO)->second; | 497 edca = m_edca.find (AC_VO)->second; |
503 txopLimit = edca->GetTxopLimit (); | 498 txopLimit = edca->GetTxopLimit (); |
504 edcaParameters.SetVoAci (3); | 499 edcaParameters.SetVoAci (3); |
505 edcaParameters.SetVoCWmin (static_cast<uint8_t>(edca->GetMinCw ())); | 500 edcaParameters.SetVoCWmin (edca->GetMinCw ()); |
506 edcaParameters.SetVoCWmax (static_cast<uint8_t>(edca->GetMaxCw ())); | 501 edcaParameters.SetVoCWmax (edca->GetMaxCw ()); |
507 edcaParameters.SetVoAifsn (static_cast<uint8_t>(edca->GetAifsn ())); | 502 edcaParameters.SetVoAifsn (static_cast<uint8_t> (edca->GetAifsn ())); |
508 edcaParameters.SetVoTXOPLimit (static_cast<uint16_t>(txopLimit.GetMicroSec
onds () / 32)); | 503 edcaParameters.SetVoTXOPLimit (static_cast<uint16_t> (txopLimit.GetMicroSe
conds () / 32)); |
509 edcaParameters.SetVoAcm (0); | |
510 | 504 |
511 edcaParameters.SetQosInfo (0); | 505 edcaParameters.SetQosInfo (0); |
512 } | 506 } |
513 return edcaParameters; | 507 return edcaParameters; |
514 } | 508 } |
515 | 509 |
516 HtOperation | 510 HtOperation |
517 ApWifiMac::GetHtOperation (void) const | 511 ApWifiMac::GetHtOperation (void) const |
518 { | 512 { |
519 NS_LOG_FUNCTION (this); | 513 NS_LOG_FUNCTION (this); |
(...skipping 28 matching lines...) Expand all Loading... |
548 NS_ASSERT (nss > 0 && nss < 5); | 542 NS_ASSERT (nss > 0 && nss < 5); |
549 uint64_t dataRate = mcs.GetDataRate (m_phy->GetChannelWidth (), m_phy-
>GetShortGuardInterval () ? 400 : 800, nss); | 543 uint64_t dataRate = mcs.GetDataRate (m_phy->GetChannelWidth (), m_phy-
>GetShortGuardInterval () ? 400 : 800, nss); |
550 if (dataRate > maxSupportedRate) | 544 if (dataRate > maxSupportedRate) |
551 { | 545 { |
552 maxSupportedRate = dataRate; | 546 maxSupportedRate = dataRate; |
553 NS_LOG_DEBUG ("Updating maxSupportedRate to " << maxSupportedRate)
; | 547 NS_LOG_DEBUG ("Updating maxSupportedRate to " << maxSupportedRate)
; |
554 } | 548 } |
555 } | 549 } |
556 uint8_t maxSpatialStream = m_phy->GetMaxSupportedTxSpatialStreams (); | 550 uint8_t maxSpatialStream = m_phy->GetMaxSupportedTxSpatialStreams (); |
557 uint8_t nMcs = m_phy->GetNMcs (); | 551 uint8_t nMcs = m_phy->GetNMcs (); |
558 for (std::list<Mac48Address>::const_iterator i = m_staList.begin (); i !=
m_staList.end (); i++) | 552 for (std::map<uint16_t, Mac48Address>::const_iterator i = m_staList.begin
(); i != m_staList.end (); i++) |
559 { | 553 { |
560 if (m_stationManager->GetHtSupported (*i)) | 554 if (m_stationManager->GetHtSupported (i->second)) |
561 { | 555 { |
562 uint64_t maxSupportedRateByHtSta = 0; //in bit/s | 556 uint64_t maxSupportedRateByHtSta = 0; //in bit/s |
563 for (uint8_t j = 0; j < (std::min (nMcs, m_stationManager->GetNMcs
Supported (*i))); j++) | 557 for (uint8_t j = 0; j < (std::min (nMcs, m_stationManager->GetNMcs
Supported (i->second))); j++) |
564 { | 558 { |
565 WifiMode mcs = m_phy->GetMcs (j); | 559 WifiMode mcs = m_phy->GetMcs (j); |
566 if (mcs.GetModulationClass () != WIFI_MOD_CLASS_HT) | 560 if (mcs.GetModulationClass () != WIFI_MOD_CLASS_HT) |
567 { | 561 { |
568 continue; | 562 continue; |
569 } | 563 } |
570 uint8_t nss = (mcs.GetMcsValue () / 8) + 1; | 564 uint8_t nss = (mcs.GetMcsValue () / 8) + 1; |
571 NS_ASSERT (nss > 0 && nss < 5); | 565 NS_ASSERT (nss > 0 && nss < 5); |
572 uint64_t dataRate = mcs.GetDataRate (m_stationManager->GetChan
nelWidthSupported (*i), m_stationManager->GetShortGuardInterval (*i) ? 400 : 800
, nss); | 566 uint64_t dataRate = mcs.GetDataRate (m_stationManager->GetChan
nelWidthSupported (i->second), m_stationManager->GetShortGuardInterval (i->secon
d) ? 400 : 800, nss); |
573 if (dataRate > maxSupportedRateByHtSta) | 567 if (dataRate > maxSupportedRateByHtSta) |
574 { | 568 { |
575 maxSupportedRateByHtSta = dataRate; | 569 maxSupportedRateByHtSta = dataRate; |
576 } | 570 } |
577 } | 571 } |
578 if (maxSupportedRateByHtSta < maxSupportedRate) | 572 if (maxSupportedRateByHtSta < maxSupportedRate) |
579 { | 573 { |
580 maxSupportedRate = maxSupportedRateByHtSta; | 574 maxSupportedRate = maxSupportedRateByHtSta; |
581 } | 575 } |
582 if (m_stationManager->GetNMcsSupported (*i) < nMcs) | 576 if (m_stationManager->GetNMcsSupported (i->second) < nMcs) |
583 { | 577 { |
584 nMcs = m_stationManager->GetNMcsSupported (*i); | 578 nMcs = m_stationManager->GetNMcsSupported (i->second); |
585 } | 579 } |
586 if (m_stationManager->GetNumberOfSupportedStreams (*i) < maxSpatia
lStream) | 580 if (m_stationManager->GetNumberOfSupportedStreams (i->second) < ma
xSpatialStream) |
587 { | 581 { |
588 maxSpatialStream = m_stationManager->GetNumberOfSupportedStrea
ms (*i); | 582 maxSpatialStream = m_stationManager->GetNumberOfSupportedStrea
ms (i->second); |
589 } | 583 } |
590 } | 584 } |
591 } | 585 } |
592 operation.SetRxHighestSupportedDataRate (static_cast<uint16_t>(maxSupporte
dRate / 1e6)); //in Mbit/s | 586 operation.SetRxHighestSupportedDataRate (static_cast<uint16_t> (maxSupport
edRate / 1e6)); //in Mbit/s |
593 operation.SetTxMcsSetDefined (nMcs > 0); | 587 operation.SetTxMcsSetDefined (nMcs > 0); |
594 operation.SetTxMaxNSpatialStreams (maxSpatialStream); | 588 operation.SetTxMaxNSpatialStreams (maxSpatialStream); |
595 //To be filled in once supported | 589 //To be filled in once supported |
596 operation.SetObssNonHtStasPresent (0); | 590 operation.SetObssNonHtStasPresent (0); |
597 operation.SetDualBeacon (0); | 591 operation.SetDualBeacon (0); |
598 operation.SetDualCtsProtection (0); | 592 operation.SetDualCtsProtection (0); |
599 operation.SetStbcBeacon (0); | 593 operation.SetStbcBeacon (0); |
600 operation.SetLSigTxopProtectionFullSupport (0); | 594 operation.SetLSigTxopProtectionFullSupport (0); |
601 operation.SetPcoActive (0); | 595 operation.SetPcoActive (0); |
602 operation.SetPhase (0); | 596 operation.SetPhase (0); |
603 operation.SetRxMcsBitmask (0); | 597 operation.SetRxMcsBitmask (0); |
604 operation.SetTxRxMcsSetUnequal (0); | 598 operation.SetTxRxMcsSetUnequal (0); |
605 operation.SetTxUnequalModulation (0); | 599 operation.SetTxUnequalModulation (0); |
606 } | 600 } |
607 return operation; | 601 return operation; |
608 } | 602 } |
609 | 603 |
610 VhtOperation | 604 VhtOperation |
611 ApWifiMac::GetVhtOperation (void) const | 605 ApWifiMac::GetVhtOperation (void) const |
612 { | 606 { |
613 NS_LOG_FUNCTION (this); | 607 NS_LOG_FUNCTION (this); |
614 VhtOperation operation; | 608 VhtOperation operation; |
615 if (m_vhtSupported) | 609 if (m_vhtSupported) |
616 { | 610 { |
617 operation.SetVhtSupported (1); | 611 operation.SetVhtSupported (1); |
618 uint8_t channelWidth = GetVhtOperationalChannelWidth (); | 612 uint16_t channelWidth = GetVhtOperationalChannelWidth (); |
619 if (channelWidth == 160) | 613 if (channelWidth == 160) |
620 { | 614 { |
621 operation.SetChannelWidth (2); | 615 operation.SetChannelWidth (2); |
622 } | 616 } |
623 else if (channelWidth == 80) | 617 else if (channelWidth == 80) |
624 { | 618 { |
625 operation.SetChannelWidth (1); | 619 operation.SetChannelWidth (1); |
626 } | 620 } |
627 else | 621 else |
628 { | 622 { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 packet->AddHeader (probe); | 706 packet->AddHeader (probe); |
713 | 707 |
714 //The standard is not clear on the correct queue for management | 708 //The standard is not clear on the correct queue for management |
715 //frames if we are a QoS AP. The approach taken here is to always | 709 //frames if we are a QoS AP. The approach taken here is to always |
716 //use the DCF for these regardless of whether we have a QoS | 710 //use the DCF for these regardless of whether we have a QoS |
717 //association or not. | 711 //association or not. |
718 m_dca->Queue (packet, hdr); | 712 m_dca->Queue (packet, hdr); |
719 } | 713 } |
720 | 714 |
721 void | 715 void |
722 ApWifiMac::SendAssocResp (Mac48Address to, bool success) | 716 ApWifiMac::SendAssocResp (Mac48Address to, bool success, bool isReassoc) |
723 { | 717 { |
724 NS_LOG_FUNCTION (this << to << success); | 718 NS_LOG_FUNCTION (this << to << success << isReassoc); |
725 WifiMacHeader hdr; | 719 WifiMacHeader hdr; |
726 hdr.SetType (WIFI_MAC_MGT_ASSOCIATION_RESPONSE); | 720 hdr.SetType (isReassoc ? WIFI_MAC_MGT_REASSOCIATION_RESPONSE : WIFI_MAC_MGT_AS
SOCIATION_RESPONSE); |
727 hdr.SetAddr1 (to); | 721 hdr.SetAddr1 (to); |
728 hdr.SetAddr2 (GetAddress ()); | 722 hdr.SetAddr2 (GetAddress ()); |
729 hdr.SetAddr3 (GetAddress ()); | 723 hdr.SetAddr3 (GetAddress ()); |
730 hdr.SetDsNotFrom (); | 724 hdr.SetDsNotFrom (); |
731 hdr.SetDsNotTo (); | 725 hdr.SetDsNotTo (); |
732 hdr.SetNoOrder (); | 726 hdr.SetNoOrder (); |
733 Ptr<Packet> packet = Create<Packet> (); | 727 Ptr<Packet> packet = Create<Packet> (); |
734 MgtAssocResponseHeader assoc; | 728 MgtAssocResponseHeader assoc; |
735 StatusCode code; | 729 StatusCode code; |
736 if (success) | 730 if (success) |
737 { | 731 { |
738 code.SetSuccess (); | 732 code.SetSuccess (); |
739 m_staList.push_back (to); | 733 uint16_t aid = 0; |
| 734 bool found = false; |
| 735 if (isReassoc) |
| 736 { |
| 737 for (std::map<uint16_t, Mac48Address>::const_iterator i = m_staList.be
gin (); i != m_staList.end (); ++i) |
| 738 { |
| 739 if (i->second == to) |
| 740 { |
| 741 aid = i->first; |
| 742 found = true; |
| 743 break; |
| 744 } |
| 745 } |
| 746 } |
| 747 if (!found) |
| 748 { |
| 749 aid = GetNextAssociationId (); |
| 750 m_staList.insert (std::make_pair (aid, to)); |
| 751 } |
| 752 assoc.SetAssociationId (aid); |
740 } | 753 } |
741 else | 754 else |
742 { | 755 { |
743 code.SetFailure (); | 756 code.SetFailure (); |
744 } | 757 } |
745 assoc.SetSupportedRates (GetSupportedRates ()); | 758 assoc.SetSupportedRates (GetSupportedRates ()); |
746 assoc.SetStatusCode (code); | 759 assoc.SetStatusCode (code); |
747 assoc.SetCapabilities (GetCapabilities ()); | 760 assoc.SetCapabilities (GetCapabilities ()); |
748 if (m_erpSupported) | 761 if (m_erpSupported) |
749 { | 762 { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 SetSlot (MicroSeconds (20)); | 861 SetSlot (MicroSeconds (20)); |
849 } | 862 } |
850 } | 863 } |
851 } | 864 } |
852 | 865 |
853 void | 866 void |
854 ApWifiMac::TxOk (const WifiMacHeader &hdr) | 867 ApWifiMac::TxOk (const WifiMacHeader &hdr) |
855 { | 868 { |
856 NS_LOG_FUNCTION (this); | 869 NS_LOG_FUNCTION (this); |
857 RegularWifiMac::TxOk (hdr); | 870 RegularWifiMac::TxOk (hdr); |
858 | 871 if ((hdr.IsAssocResp () || hdr.IsReassocResp ()) |
859 if (hdr.IsAssocResp () | |
860 && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) | 872 && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
861 { | 873 { |
862 NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ()); | 874 NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ()); |
863 m_stationManager->RecordGotAssocTxOk (hdr.GetAddr1 ()); | 875 m_stationManager->RecordGotAssocTxOk (hdr.GetAddr1 ()); |
864 } | 876 } |
865 } | 877 } |
866 | 878 |
867 void | 879 void |
868 ApWifiMac::TxFailed (const WifiMacHeader &hdr) | 880 ApWifiMac::TxFailed (const WifiMacHeader &hdr) |
869 { | 881 { |
870 NS_LOG_FUNCTION (this); | 882 NS_LOG_FUNCTION (this); |
871 RegularWifiMac::TxFailed (hdr); | 883 RegularWifiMac::TxFailed (hdr); |
872 | 884 |
873 if (hdr.IsAssocResp () | 885 if ((hdr.IsAssocResp () || hdr.IsReassocResp ()) |
874 && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) | 886 && m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ())) |
875 { | 887 { |
876 NS_LOG_DEBUG ("assoc failed with sta=" << hdr.GetAddr1 ()); | 888 NS_LOG_DEBUG ("association failed with sta=" << hdr.GetAddr1 ()); |
877 m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ()); | 889 m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ()); |
878 } | 890 } |
879 } | 891 } |
880 | 892 |
881 void | 893 void |
882 ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr) | 894 ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr) |
883 { | 895 { |
884 NS_LOG_FUNCTION (this << packet << hdr); | 896 NS_LOG_FUNCTION (this << packet << hdr); |
885 | |
886 Mac48Address from = hdr->GetAddr2 (); | 897 Mac48Address from = hdr->GetAddr2 (); |
887 | |
888 if (hdr->IsData ()) | 898 if (hdr->IsData ()) |
889 { | 899 { |
890 Mac48Address bssid = hdr->GetAddr1 (); | 900 Mac48Address bssid = hdr->GetAddr1 (); |
891 if (!hdr->IsFromDs () | 901 if (!hdr->IsFromDs () |
892 && hdr->IsToDs () | 902 && hdr->IsToDs () |
893 && bssid == GetAddress () | 903 && bssid == GetAddress () |
894 && m_stationManager->IsAssociated (from)) | 904 && m_stationManager->IsAssociated (from)) |
895 { | 905 { |
896 Mac48Address to = hdr->GetAddr3 (); | 906 Mac48Address to = hdr->GetAddr3 (); |
897 if (to == GetAddress ()) | 907 if (to == GetAddress ()) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
952 //they are not targeted at the AP | 962 //they are not targeted at the AP |
953 NotifyRxDrop (packet); | 963 NotifyRxDrop (packet); |
954 } | 964 } |
955 return; | 965 return; |
956 } | 966 } |
957 else if (hdr->IsMgt ()) | 967 else if (hdr->IsMgt ()) |
958 { | 968 { |
959 if (hdr->IsProbeReq ()) | 969 if (hdr->IsProbeReq ()) |
960 { | 970 { |
961 NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ()); | 971 NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ()); |
| 972 NS_LOG_DEBUG ("Probe request received from " << from << ": send probe
response"); |
962 SendProbeResp (from); | 973 SendProbeResp (from); |
963 return; | 974 return; |
964 } | 975 } |
965 else if (hdr->GetAddr1 () == GetAddress ()) | 976 else if (hdr->GetAddr1 () == GetAddress ()) |
966 { | 977 { |
967 if (hdr->IsAssocReq ()) | 978 if (hdr->IsAssocReq ()) |
968 { | 979 { |
| 980 NS_LOG_DEBUG ("Association request received from " << from); |
969 //first, verify that the the station's supported | 981 //first, verify that the the station's supported |
970 //rate set is compatible with our Basic Rate set | 982 //rate set is compatible with our Basic Rate set |
971 MgtAssocRequestHeader assocReq; | 983 MgtAssocRequestHeader assocReq; |
972 packet->RemoveHeader (assocReq); | 984 packet->RemoveHeader (assocReq); |
973 CapabilityInformation capabilities = assocReq.GetCapabilities (); | 985 CapabilityInformation capabilities = assocReq.GetCapabilities (); |
974 m_stationManager->AddSupportedPlcpPreamble (from, capabilities.IsS
hortPreamble ()); | 986 m_stationManager->AddSupportedPlcpPreamble (from, capabilities.IsS
hortPreamble ()); |
975 SupportedRates rates = assocReq.GetSupportedRates (); | 987 SupportedRates rates = assocReq.GetSupportedRates (); |
976 bool problem = false; | 988 bool problem = false; |
977 bool isHtStation = false; | 989 bool isHtStation = false; |
978 bool isOfdmStation = false; | 990 bool isOfdmStation = false; |
979 bool isErpStation = false; | 991 bool isErpStation = false; |
980 bool isDsssStation = false; | 992 bool isDsssStation = false; |
981 for (uint8_t i = 0; i < m_stationManager->GetNBasicModes (); i++) | 993 for (uint8_t i = 0; i < m_stationManager->GetNBasicModes (); i++) |
982 { | 994 { |
983 WifiMode mode = m_stationManager->GetBasicMode (i); | 995 WifiMode mode = m_stationManager->GetBasicMode (i); |
984 if (!rates.IsSupportedRate (static_cast<uint32_t>(mode.GetData
Rate (m_phy->GetChannelWidth ())))) | 996 if (!rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChanne
lWidth ()))) |
985 { | 997 { |
986 if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) ||
(mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)) | 998 if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) ||
(mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)) |
987 { | 999 { |
988 isDsssStation = false; | 1000 isDsssStation = false; |
989 } | 1001 } |
990 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_
OFDM) | 1002 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_
OFDM) |
991 { | 1003 { |
992 isErpStation = false; | 1004 isErpStation = false; |
993 } | 1005 } |
994 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
) | 1006 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
) |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 if (!hecapabilities.IsSupportedTxMcs (mcs.GetMcsValue
())) | 1077 if (!hecapabilities.IsSupportedTxMcs (mcs.GetMcsValue
())) |
1066 { | 1078 { |
1067 problem = true; | 1079 problem = true; |
1068 break; | 1080 break; |
1069 } | 1081 } |
1070 } | 1082 } |
1071 } | 1083 } |
1072 } | 1084 } |
1073 if (problem) | 1085 if (problem) |
1074 { | 1086 { |
1075 //One of the Basic Rate set mode is not | 1087 NS_LOG_DEBUG ("One of the Basic Rate set mode is not supported
by the station: send association response with an error status"); |
1076 //supported by the station. So, we return an assoc | 1088 SendAssocResp (hdr->GetAddr2 (), false, false); |
1077 //response with an error status. | |
1078 SendAssocResp (hdr->GetAddr2 (), false); | |
1079 } | 1089 } |
1080 else | 1090 else |
1081 { | 1091 { |
1082 //station supports all rates in Basic Rate Set. | 1092 NS_LOG_DEBUG ("The Basic Rate set modes are supported by the s
tation"); |
1083 //record all its supported modes in its associated WifiRemoteS
tation | 1093 //record all its supported modes in its associated WifiRemoteS
tation |
1084 for (uint8_t j = 0; j < m_phy->GetNModes (); j++) | 1094 for (uint8_t j = 0; j < m_phy->GetNModes (); j++) |
1085 { | 1095 { |
1086 WifiMode mode = m_phy->GetMode (j); | 1096 WifiMode mode = m_phy->GetMode (j); |
1087 if (rates.IsSupportedRate (static_cast<uint32_t>(mode.GetD
ataRate (m_phy->GetChannelWidth ())))) | 1097 if (rates.IsSupportedRate (mode.GetDataRate (m_phy->GetCha
nnelWidth ()))) |
1088 { | 1098 { |
1089 m_stationManager->AddSupportedMode (from, mode); | 1099 m_stationManager->AddSupportedMode (from, mode); |
1090 } | 1100 } |
1091 } | 1101 } |
1092 if (m_htSupported) | 1102 if (m_htSupported) |
1093 { | 1103 { |
1094 HtCapabilities htCapabilities = assocReq.GetHtCapabilities
(); | 1104 HtCapabilities htCapabilities = assocReq.GetHtCapabilities
(); |
1095 if (htCapabilities.IsSupportedMcs (0)) | 1105 if (htCapabilities.IsSupportedMcs (0)) |
1096 { | 1106 { |
1097 m_stationManager->AddStationHtCapabilities (from, htCa
pabilities); | 1107 m_stationManager->AddStationHtCapabilities (from, htCa
pabilities); |
1098 } | 1108 } |
1099 } | 1109 } |
1100 if (m_vhtSupported) | 1110 if (m_vhtSupported) |
1101 { | 1111 { |
1102 VhtCapabilities vhtCapabilities = assocReq.GetVhtCapabilit
ies (); | 1112 VhtCapabilities vhtCapabilities = assocReq.GetVhtCapabilit
ies (); |
1103 //we will always fill in RxHighestSupportedLgiDataRate fie
ld at TX, so this can be used to check whether it supports VHT | 1113 //we will always fill in RxHighestSupportedLgiDataRate fie
ld at TX, so this can be used to check whether it supports VHT |
1104 if (vhtCapabilities.GetRxHighestSupportedLgiDataRate () >
0) | 1114 if (vhtCapabilities.GetRxHighestSupportedLgiDataRate () >
0) |
1105 { | 1115 { |
1106 m_stationManager->AddStationVhtCapabilities (from, vht
Capabilities); | 1116 m_stationManager->AddStationVhtCapabilities (from, vht
Capabilities); |
1107 for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) | 1117 for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) |
1108 { | 1118 { |
1109 WifiMode mcs = m_phy->GetMcs (static_cast<uint8_t>
(i)); | 1119 WifiMode mcs = m_phy->GetMcs (i); |
1110 if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VH
T && vhtCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) | 1120 if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VH
T && vhtCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
1111 { | 1121 { |
1112 m_stationManager->AddSupportedMcs (hdr->GetAdd
r2 (), mcs); | 1122 m_stationManager->AddSupportedMcs (hdr->GetAdd
r2 (), mcs); |
1113 //here should add a control to add basic MCS w
hen it is implemented | 1123 //here should add a control to add basic MCS w
hen it is implemented |
1114 } | 1124 } |
1115 } | 1125 } |
1116 } | 1126 } |
1117 } | 1127 } |
| 1128 if (m_htSupported || m_vhtSupported) |
| 1129 { |
| 1130 ExtendedCapabilities extendedCapabilities = assocReq.GetEx
tendedCapabilities (); |
| 1131 //TODO: to be completed |
| 1132 } |
1118 if (m_heSupported) | 1133 if (m_heSupported) |
1119 { | 1134 { |
1120 HeCapabilities heCapabilities = assocReq.GetHeCapabilities
(); | 1135 HeCapabilities heCapabilities = assocReq.GetHeCapabilities
(); |
1121 //todo: once we support non constant rate managers, we sho
uld add checks here whether HE is supported by the peer | 1136 //todo: once we support non constant rate managers, we sho
uld add checks here whether HE is supported by the peer |
1122 m_stationManager->AddStationHeCapabilities (from, heCapabi
lities); | 1137 m_stationManager->AddStationHeCapabilities (from, heCapabi
lities); |
1123 for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) | 1138 for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) |
1124 { | 1139 { |
1125 WifiMode mcs = m_phy->GetMcs (static_cast<uint8_t>(i))
; | 1140 WifiMode mcs = m_phy->GetMcs (i); |
1126 if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HE &&
heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) | 1141 if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HE &&
heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
1127 { | 1142 { |
1128 m_stationManager->AddSupportedMcs (hdr->GetAddr2 (
), mcs); | 1143 m_stationManager->AddSupportedMcs (hdr->GetAddr2 (
), mcs); |
1129 //here should add a control to add basic MCS when
it is implemented | 1144 //here should add a control to add basic MCS when
it is implemented |
1130 } | 1145 } |
1131 } | 1146 } |
1132 } | 1147 } |
1133 m_stationManager->RecordWaitAssocTxOk (from); | 1148 m_stationManager->RecordWaitAssocTxOk (from); |
1134 if (!isHtStation) | 1149 if (!isHtStation) |
1135 { | 1150 { |
1136 m_nonHtStations.push_back (hdr->GetAddr2 ()); | 1151 m_nonHtStations.push_back (hdr->GetAddr2 ()); |
| 1152 m_nonHtStations.unique (); |
1137 } | 1153 } |
1138 if (!isErpStation && isDsssStation) | 1154 if (!isErpStation && isDsssStation) |
1139 { | 1155 { |
1140 m_nonErpStations.push_back (hdr->GetAddr2 ()); | 1156 m_nonErpStations.push_back (hdr->GetAddr2 ()); |
1141 } | 1157 m_nonErpStations.unique (); |
1142 // send assoc response with success status. | 1158 } |
1143 SendAssocResp (hdr->GetAddr2 (), true); | 1159 NS_LOG_DEBUG ("Send association response with success status")
; |
| 1160 SendAssocResp (hdr->GetAddr2 (), true, false); |
| 1161 } |
| 1162 return; |
| 1163 } |
| 1164 else if (hdr->IsReassocReq ()) |
| 1165 { |
| 1166 NS_LOG_DEBUG ("Reassociation request received from " << from); |
| 1167 //first, verify that the the station's supported |
| 1168 //rate set is compatible with our Basic Rate set |
| 1169 MgtReassocRequestHeader reassocReq; |
| 1170 packet->RemoveHeader (reassocReq); |
| 1171 CapabilityInformation capabilities = reassocReq.GetCapabilities ()
; |
| 1172 m_stationManager->AddSupportedPlcpPreamble (from, capabilities.IsS
hortPreamble ()); |
| 1173 SupportedRates rates = reassocReq.GetSupportedRates (); |
| 1174 bool problem = false; |
| 1175 bool isHtStation = false; |
| 1176 bool isOfdmStation = false; |
| 1177 bool isErpStation = false; |
| 1178 bool isDsssStation = false; |
| 1179 for (uint8_t i = 0; i < m_stationManager->GetNBasicModes (); i++) |
| 1180 { |
| 1181 WifiMode mode = m_stationManager->GetBasicMode (i); |
| 1182 if (!rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChanne
lWidth ()))) |
| 1183 { |
| 1184 if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) ||
(mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)) |
| 1185 { |
| 1186 isDsssStation = false; |
| 1187 } |
| 1188 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_
OFDM) |
| 1189 { |
| 1190 isErpStation = false; |
| 1191 } |
| 1192 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
) |
| 1193 { |
| 1194 isOfdmStation = false; |
| 1195 } |
| 1196 if (isDsssStation == false && isErpStation == false && isO
fdmStation == false) |
| 1197 { |
| 1198 problem = true; |
| 1199 break; |
| 1200 } |
| 1201 } |
| 1202 else |
| 1203 { |
| 1204 if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) ||
(mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS)) |
| 1205 { |
| 1206 isDsssStation = true; |
| 1207 } |
| 1208 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_
OFDM) |
| 1209 { |
| 1210 isErpStation = true; |
| 1211 } |
| 1212 else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM
) |
| 1213 { |
| 1214 isOfdmStation = true; |
| 1215 } |
| 1216 } |
| 1217 } |
| 1218 m_stationManager->AddSupportedErpSlotTime (from, capabilities.IsSh
ortSlotTime () && isErpStation); |
| 1219 if (m_htSupported) |
| 1220 { |
| 1221 //check whether the HT STA supports all MCSs in Basic MCS Set |
| 1222 HtCapabilities htcapabilities = reassocReq.GetHtCapabilities (
); |
| 1223 if (htcapabilities.IsSupportedMcs (0)) |
| 1224 { |
| 1225 isHtStation = true; |
| 1226 for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs ();
i++) |
| 1227 { |
| 1228 WifiMode mcs = m_stationManager->GetBasicMcs (i); |
| 1229 if (!htcapabilities.IsSupportedMcs (mcs.GetMcsValue ()
)) |
| 1230 { |
| 1231 problem = true; |
| 1232 break; |
| 1233 } |
| 1234 } |
| 1235 } |
| 1236 } |
| 1237 if (m_vhtSupported) |
| 1238 { |
| 1239 //check whether the VHT STA supports all MCSs in Basic MCS Set |
| 1240 VhtCapabilities vhtcapabilities = reassocReq.GetVhtCapabilitie
s (); |
| 1241 if (vhtcapabilities.GetVhtCapabilitiesInfo () != 0) |
| 1242 { |
| 1243 for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs ();
i++) |
| 1244 { |
| 1245 WifiMode mcs = m_stationManager->GetBasicMcs (i); |
| 1246 if (!vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue
())) |
| 1247 { |
| 1248 problem = true; |
| 1249 break; |
| 1250 } |
| 1251 } |
| 1252 } |
| 1253 } |
| 1254 if (m_heSupported) |
| 1255 { |
| 1256 //check whether the HE STA supports all MCSs in Basic MCS Set |
| 1257 HeCapabilities hecapabilities = reassocReq.GetHeCapabilities (
); |
| 1258 if (hecapabilities.GetSupportedMcsAndNss () != 0) |
| 1259 { |
| 1260 for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs ();
i++) |
| 1261 { |
| 1262 WifiMode mcs = m_stationManager->GetBasicMcs (i); |
| 1263 if (!hecapabilities.IsSupportedTxMcs (mcs.GetMcsValue
())) |
| 1264 { |
| 1265 problem = true; |
| 1266 break; |
| 1267 } |
| 1268 } |
| 1269 } |
| 1270 } |
| 1271 if (problem) |
| 1272 { |
| 1273 NS_LOG_DEBUG ("One of the Basic Rate set mode is not supported
by the station: send reassociation response with an error status"); |
| 1274 SendAssocResp (hdr->GetAddr2 (), false, true); |
| 1275 } |
| 1276 else |
| 1277 { |
| 1278 NS_LOG_DEBUG ("The Basic Rate set modes are supported by the s
tation"); |
| 1279 //update all its supported modes in its associated WifiRemoteS
tation |
| 1280 for (uint8_t j = 0; j < m_phy->GetNModes (); j++) |
| 1281 { |
| 1282 WifiMode mode = m_phy->GetMode (j); |
| 1283 if (rates.IsSupportedRate (mode.GetDataRate (m_phy->GetCha
nnelWidth ()))) |
| 1284 { |
| 1285 m_stationManager->AddSupportedMode (from, mode); |
| 1286 } |
| 1287 } |
| 1288 if (m_htSupported) |
| 1289 { |
| 1290 HtCapabilities htCapabilities = reassocReq.GetHtCapabiliti
es (); |
| 1291 if (htCapabilities.IsSupportedMcs (0)) |
| 1292 { |
| 1293 m_stationManager->AddStationHtCapabilities (from, htCa
pabilities); |
| 1294 } |
| 1295 } |
| 1296 if (m_vhtSupported) |
| 1297 { |
| 1298 VhtCapabilities vhtCapabilities = reassocReq.GetVhtCapabil
ities (); |
| 1299 //we will always fill in RxHighestSupportedLgiDataRate fie
ld at TX, so this can be used to check whether it supports VHT |
| 1300 if (vhtCapabilities.GetRxHighestSupportedLgiDataRate () >
0) |
| 1301 { |
| 1302 m_stationManager->AddStationVhtCapabilities (from, vht
Capabilities); |
| 1303 for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) |
| 1304 { |
| 1305 WifiMode mcs = m_phy->GetMcs (i); |
| 1306 if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VH
T && vhtCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
| 1307 { |
| 1308 m_stationManager->AddSupportedMcs (hdr->GetAdd
r2 (), mcs); |
| 1309 //here should add a control to add basic MCS w
hen it is implemented |
| 1310 } |
| 1311 } |
| 1312 } |
| 1313 } |
| 1314 if (m_htSupported || m_vhtSupported) |
| 1315 { |
| 1316 ExtendedCapabilities extendedCapabilities = reassocReq.Get
ExtendedCapabilities (); |
| 1317 //TODO: to be completed |
| 1318 } |
| 1319 if (m_heSupported) |
| 1320 { |
| 1321 HeCapabilities heCapabilities = reassocReq.GetHeCapabiliti
es (); |
| 1322 //todo: once we support non constant rate managers, we sho
uld add checks here whether HE is supported by the peer |
| 1323 m_stationManager->AddStationHeCapabilities (from, heCapabi
lities); |
| 1324 for (uint8_t i = 0; i < m_phy->GetNMcs (); i++) |
| 1325 { |
| 1326 WifiMode mcs = m_phy->GetMcs (i); |
| 1327 if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HE &&
heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ())) |
| 1328 { |
| 1329 m_stationManager->AddSupportedMcs (hdr->GetAddr2 (
), mcs); |
| 1330 //here should add a control to add basic MCS when
it is implemented |
| 1331 } |
| 1332 } |
| 1333 } |
| 1334 m_stationManager->RecordWaitAssocTxOk (from); |
| 1335 if (!isHtStation) |
| 1336 { |
| 1337 m_nonHtStations.push_back (hdr->GetAddr2 ()); |
| 1338 m_nonHtStations.unique (); |
| 1339 } |
| 1340 if (!isErpStation && isDsssStation) |
| 1341 { |
| 1342 m_nonErpStations.push_back (hdr->GetAddr2 ()); |
| 1343 m_nonErpStations.unique (); |
| 1344 } |
| 1345 NS_LOG_DEBUG ("Send reassociation response with success status
"); |
| 1346 SendAssocResp (hdr->GetAddr2 (), true, true); |
1144 } | 1347 } |
1145 return; | 1348 return; |
1146 } | 1349 } |
1147 else if (hdr->IsDisassociation ()) | 1350 else if (hdr->IsDisassociation ()) |
1148 { | 1351 { |
| 1352 NS_LOG_DEBUG ("Disassociation received from " << from); |
1149 m_stationManager->RecordDisassociated (from); | 1353 m_stationManager->RecordDisassociated (from); |
1150 for (std::list<Mac48Address>::const_iterator i = m_staList.begin (
); i != m_staList.end (); i++) | 1354 for (std::map<uint16_t, Mac48Address>::const_iterator j = m_staLis
t.begin (); j != m_staList.end (); j++) |
1151 { | 1355 { |
1152 if ((*i) == from) | 1356 if (j->second == from) |
1153 { | 1357 { |
1154 m_staList.erase (i); | 1358 m_staList.erase (j); |
1155 break; | 1359 break; |
1156 } | 1360 } |
1157 } | 1361 } |
1158 for (std::list<Mac48Address>::const_iterator j = m_nonErpStations.
begin (); j != m_nonErpStations.end (); j++) | 1362 for (std::list<Mac48Address>::const_iterator j = m_nonErpStations.
begin (); j != m_nonErpStations.end (); j++) |
1159 { | 1363 { |
1160 if ((*j) == from) | 1364 if ((*j) == from) |
1161 { | 1365 { |
1162 m_nonErpStations.erase (j); | 1366 m_nonErpStations.erase (j); |
1163 break; | 1367 break; |
1164 } | 1368 } |
(...skipping 11 matching lines...) Expand all Loading... |
1176 } | 1380 } |
1177 } | 1381 } |
1178 | 1382 |
1179 //Invoke the receive handler of our parent class to deal with any | 1383 //Invoke the receive handler of our parent class to deal with any |
1180 //other frames. Specifically, this will handle Block Ack-related | 1384 //other frames. Specifically, this will handle Block Ack-related |
1181 //Management Action frames. | 1385 //Management Action frames. |
1182 RegularWifiMac::Receive (packet, hdr); | 1386 RegularWifiMac::Receive (packet, hdr); |
1183 } | 1387 } |
1184 | 1388 |
1185 void | 1389 void |
1186 ApWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, | 1390 ApWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiM
acHeader *hdr) |
1187 const WifiMacHeader *hdr) | |
1188 { | 1391 { |
1189 NS_LOG_FUNCTION (this << aggregatedPacket << hdr); | 1392 NS_LOG_FUNCTION (this << aggregatedPacket << hdr); |
1190 MsduAggregator::DeaggregatedMsdus packets = | 1393 MsduAggregator::DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggre
gatedPacket); |
1191 MsduAggregator::Deaggregate (aggregatedPacket); | |
1192 | |
1193 for (MsduAggregator::DeaggregatedMsdusCI i = packets.begin (); | 1394 for (MsduAggregator::DeaggregatedMsdusCI i = packets.begin (); |
1194 i != packets.end (); ++i) | 1395 i != packets.end (); ++i) |
1195 { | 1396 { |
1196 if ((*i).second.GetDestinationAddr () == GetAddress ()) | 1397 if ((*i).second.GetDestinationAddr () == GetAddress ()) |
1197 { | 1398 { |
1198 ForwardUp ((*i).first, (*i).second.GetSourceAddr (), | 1399 ForwardUp ((*i).first, (*i).second.GetSourceAddr (), |
1199 (*i).second.GetDestinationAddr ()); | 1400 (*i).second.GetDestinationAddr ()); |
1200 } | 1401 } |
1201 else | 1402 else |
1202 { | 1403 { |
1203 Mac48Address from = (*i).second.GetSourceAddr (); | 1404 Mac48Address from = (*i).second.GetSourceAddr (); |
1204 Mac48Address to = (*i).second.GetDestinationAddr (); | 1405 Mac48Address to = (*i).second.GetDestinationAddr (); |
1205 NS_LOG_DEBUG ("forwarding QoS frame from=" << from << ", to=" << to); | 1406 NS_LOG_DEBUG ("forwarding QoS frame from=" << from << ", to=" << to); |
1206 ForwardDown ((*i).first, from, to, hdr->GetQosTid ()); | 1407 ForwardDown ((*i).first, from, to, hdr->GetQosTid ()); |
1207 } | 1408 } |
1208 } | 1409 } |
1209 } | 1410 } |
1210 | 1411 |
1211 void | 1412 void |
1212 ApWifiMac::DoInitialize (void) | 1413 ApWifiMac::DoInitialize (void) |
1213 { | 1414 { |
1214 NS_LOG_FUNCTION (this); | 1415 NS_LOG_FUNCTION (this); |
1215 m_beaconDca->Initialize (); | 1416 m_beaconDca->Initialize (); |
1216 m_beaconEvent.Cancel (); | 1417 m_beaconEvent.Cancel (); |
1217 if (m_enableBeaconGeneration) | 1418 if (m_enableBeaconGeneration) |
1218 { | 1419 { |
1219 if (m_enableBeaconJitter) | 1420 if (m_enableBeaconJitter) |
1220 { | 1421 { |
1221 int64_t jitter = static_cast<int64_t>(m_beaconJitter->GetValue (0, sta
tic_cast<double>(m_beaconInterval.GetMicroSeconds ()))); | 1422 int64_t jitter = static_cast<int64_t> (m_beaconJitter->GetValue (0, st
atic_cast<double> (m_beaconInterval.GetMicroSeconds ()))); |
1222 NS_LOG_DEBUG ("Scheduling initial beacon for access point " << GetAddr
ess () << " at time " << jitter << " microseconds"); | 1423 NS_LOG_DEBUG ("Scheduling initial beacon for access point " << GetAddr
ess () << " at time " << jitter << " microseconds"); |
1223 m_beaconEvent = Simulator::Schedule (MicroSeconds (jitter), &ApWifiMac
::SendOneBeacon, this); | 1424 m_beaconEvent = Simulator::Schedule (MicroSeconds (jitter), &ApWifiMac
::SendOneBeacon, this); |
1224 } | 1425 } |
1225 else | 1426 else |
1226 { | 1427 { |
1227 NS_LOG_DEBUG ("Scheduling initial beacon for access point " << GetAddr
ess () << " at time 0"); | 1428 NS_LOG_DEBUG ("Scheduling initial beacon for access point " << GetAddr
ess () << " at time 0"); |
1228 m_beaconEvent = Simulator::ScheduleNow (&ApWifiMac::SendOneBeacon, thi
s); | 1429 m_beaconEvent = Simulator::ScheduleNow (&ApWifiMac::SendOneBeacon, thi
s); |
1229 } | 1430 } |
1230 } | 1431 } |
1231 RegularWifiMac::DoInitialize (); | 1432 RegularWifiMac::DoInitialize (); |
(...skipping 22 matching lines...) Expand all Loading... |
1254 { | 1455 { |
1255 m_stationManager->SetRifsPermitted (true); | 1456 m_stationManager->SetRifsPermitted (true); |
1256 } | 1457 } |
1257 else | 1458 else |
1258 { | 1459 { |
1259 m_stationManager->SetRifsPermitted (false); | 1460 m_stationManager->SetRifsPermitted (false); |
1260 } | 1461 } |
1261 return rifsMode; | 1462 return rifsMode; |
1262 } | 1463 } |
1263 | 1464 |
| 1465 uint16_t |
| 1466 ApWifiMac::GetNextAssociationId (void) |
| 1467 { |
| 1468 //Return the first free AID value between 1 and 2007 |
| 1469 for (uint16_t nextAid = 1; nextAid <= 2007; nextAid++) |
| 1470 { |
| 1471 if (m_staList.find (nextAid) == m_staList.end ()) |
| 1472 { |
| 1473 return nextAid; |
| 1474 } |
| 1475 } |
| 1476 NS_ASSERT_MSG (false, "No free association ID available!"); |
| 1477 return 0; |
| 1478 } |
| 1479 |
1264 } //namespace ns3 | 1480 } //namespace ns3 |
LEFT | RIGHT |