|
1 |
/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ |
1 |
/home/quincy/code/ns3/devices/wifi/mac-low.cc |
2 |
/* |
|
|
3 |
* Copyright (c) 2005,2006 INRIA |
4 |
* |
5 |
* This program is free software; you can redistribute it and/or modify |
6 |
* it under the terms of the GNU General Public License version 2 as |
7 |
* published by the Free Software Foundation; |
8 |
* |
9 |
* This program is distributed in the hope that it will be useful, |
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 |
* GNU General Public License for more details. |
13 |
* |
14 |
* You should have received a copy of the GNU General Public License |
15 |
* along with this program; if not, write to the Free Software |
16 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 |
* |
18 |
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
19 |
*/ |
20 |
|
21 |
#include "ns3/assert.h" |
22 |
#include "ns3/packet.h" |
23 |
#include "ns3/simulator.h" |
24 |
#include "ns3/tag.h" |
25 |
#include "ns3/log.h" |
26 |
#include "ns3/node.h" |
27 |
|
28 |
#include "mac-low.h" |
29 |
#include "wifi-phy.h" |
30 |
#include "wifi-mac-trailer.h" |
31 |
|
32 |
NS_LOG_COMPONENT_DEFINE ("MacLow"); |
33 |
|
34 |
#undef NS_LOG_APPEND_CONTEXT |
35 |
#define NS_LOG_APPEND_CONTEXT std::clog << "[mac=" << m_self << "] " |
36 |
|
37 |
|
38 |
namespace ns3 { |
39 |
|
40 |
class SnrTag : public Tag |
41 |
{ |
42 |
public: |
43 |
|
44 |
static TypeId GetTypeId (void); |
45 |
virtual TypeId GetInstanceTypeId (void) const; |
46 |
|
47 |
virtual uint32_t GetSerializedSize (void) const; |
48 |
virtual void Serialize (TagBuffer i) const; |
49 |
virtual void Deserialize (TagBuffer i); |
50 |
virtual void Print (std::ostream &os) const; |
51 |
|
52 |
void Set (double snr); |
53 |
double Get (void) const; |
54 |
private: |
55 |
double m_snr; |
56 |
}; |
57 |
|
58 |
TypeId |
59 |
SnrTag::GetTypeId (void) |
60 |
{ |
61 |
static TypeId tid = TypeId ("ns3::SnrTag") |
62 |
.SetParent<Tag> () |
63 |
.AddConstructor<SnrTag> () |
64 |
.AddAttribute ("Snr", "The snr of the last packet received", |
65 |
DoubleValue (0.0), |
66 |
MakeDoubleAccessor (&SnrTag::Get), |
67 |
MakeDoubleChecker<double> ()) |
68 |
; |
69 |
return tid; |
70 |
} |
71 |
TypeId |
72 |
SnrTag::GetInstanceTypeId (void) const |
73 |
{ |
74 |
return GetTypeId (); |
75 |
} |
76 |
|
77 |
uint32_t |
78 |
SnrTag::GetSerializedSize (void) const |
79 |
{ |
80 |
return sizeof (double); |
81 |
} |
82 |
void |
83 |
SnrTag::Serialize (TagBuffer i) const |
84 |
{ |
85 |
i.WriteDouble (m_snr); |
86 |
} |
87 |
void |
88 |
SnrTag::Deserialize (TagBuffer i) |
89 |
{ |
90 |
m_snr = i.ReadDouble (); |
91 |
} |
92 |
void |
93 |
SnrTag::Print (std::ostream &os) const |
94 |
{ |
95 |
os << "Snr=" << m_snr; |
96 |
} |
97 |
void |
98 |
SnrTag::Set (double snr) |
99 |
{ |
100 |
m_snr = snr; |
101 |
} |
102 |
double |
103 |
SnrTag::Get (void) const |
104 |
{ |
105 |
return m_snr; |
106 |
} |
107 |
|
108 |
|
109 |
MacLowTransmissionListener::MacLowTransmissionListener () |
110 |
{} |
111 |
MacLowTransmissionListener::~MacLowTransmissionListener () |
112 |
{} |
113 |
MacLowDcfListener::MacLowDcfListener () |
114 |
{} |
115 |
MacLowDcfListener::~MacLowDcfListener () |
116 |
{} |
117 |
|
118 |
MacLowTransmissionParameters::MacLowTransmissionParameters () |
119 |
: m_nextSize (0), |
120 |
m_waitAck (ACK_NONE), |
121 |
m_sendRts (false), |
122 |
m_overrideDurationId (Seconds (0)) |
123 |
{} |
124 |
void |
125 |
MacLowTransmissionParameters::EnableNextData (uint32_t size) |
126 |
{ |
127 |
m_nextSize = size; |
128 |
} |
129 |
void |
130 |
MacLowTransmissionParameters::DisableNextData (void) |
131 |
{ |
132 |
m_nextSize = 0; |
133 |
} |
134 |
void |
135 |
MacLowTransmissionParameters::EnableOverrideDurationId (Time durationId) |
136 |
{ |
137 |
m_overrideDurationId = durationId; |
138 |
} |
139 |
void |
140 |
MacLowTransmissionParameters::DisableOverrideDurationId (void) |
141 |
{ |
142 |
m_overrideDurationId = Seconds (0); |
143 |
} |
144 |
void |
145 |
MacLowTransmissionParameters::EnableSuperFastAck (void) |
146 |
{ |
147 |
m_waitAck = ACK_SUPER_FAST; |
148 |
} |
149 |
void |
150 |
MacLowTransmissionParameters::EnableFastAck (void) |
151 |
{ |
152 |
m_waitAck = ACK_FAST; |
153 |
} |
154 |
void |
155 |
MacLowTransmissionParameters::EnableAck (void) |
156 |
{ |
157 |
m_waitAck = ACK_NORMAL; |
158 |
} |
159 |
void |
160 |
MacLowTransmissionParameters::DisableAck (void) |
161 |
{ |
162 |
m_waitAck = ACK_NONE; |
163 |
} |
164 |
void |
165 |
MacLowTransmissionParameters::EnableRts (void) |
166 |
{ |
167 |
m_sendRts = true; |
168 |
} |
169 |
void |
170 |
MacLowTransmissionParameters::DisableRts (void) |
171 |
{ |
172 |
m_sendRts = false; |
173 |
} |
174 |
bool |
175 |
MacLowTransmissionParameters::MustWaitAck (void) const |
176 |
{ |
177 |
return (m_waitAck != ACK_NONE); |
178 |
} |
179 |
bool |
180 |
MacLowTransmissionParameters::MustWaitNormalAck (void) const |
181 |
{ |
182 |
return (m_waitAck == ACK_NORMAL); |
183 |
} |
184 |
bool |
185 |
MacLowTransmissionParameters::MustWaitFastAck (void) const |
186 |
{ |
187 |
return (m_waitAck == ACK_FAST); |
188 |
} |
189 |
bool |
190 |
MacLowTransmissionParameters::MustWaitSuperFastAck (void) const |
191 |
{ |
192 |
return (m_waitAck == ACK_SUPER_FAST); |
193 |
} |
194 |
bool |
195 |
MacLowTransmissionParameters::MustSendRts (void) const |
196 |
{ |
197 |
return m_sendRts; |
198 |
} |
199 |
bool |
200 |
MacLowTransmissionParameters::HasDurationId (void) const |
201 |
{ |
202 |
return (m_overrideDurationId != Seconds (0)); |
203 |
} |
204 |
Time |
205 |
MacLowTransmissionParameters::GetDurationId (void) const |
206 |
{ |
207 |
NS_ASSERT (m_overrideDurationId != Seconds (0)); |
208 |
return m_overrideDurationId; |
209 |
} |
210 |
bool |
211 |
MacLowTransmissionParameters::HasNextPacket (void) const |
212 |
{ |
213 |
return (m_nextSize != 0); |
214 |
} |
215 |
uint32_t |
216 |
MacLowTransmissionParameters::GetNextPacketSize (void) const |
217 |
{ |
218 |
NS_ASSERT (HasNextPacket ()); |
219 |
return m_nextSize; |
220 |
} |
221 |
|
222 |
std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters ¶ms) |
223 |
{ |
224 |
os << "[" |
225 |
<< "send rts=" << params.m_sendRts << ", " |
226 |
<< "next size=" << params.m_nextSize << ", " |
227 |
<< "dur=" << params.m_overrideDurationId << ", " |
228 |
<< "ack="; |
229 |
switch (params.m_waitAck) { |
230 |
case MacLowTransmissionParameters::ACK_NONE: |
231 |
os << "none"; |
232 |
break; |
233 |
case MacLowTransmissionParameters::ACK_NORMAL: |
234 |
os << "normal"; |
235 |
break; |
236 |
case MacLowTransmissionParameters::ACK_FAST: |
237 |
os << "fast"; |
238 |
break; |
239 |
case MacLowTransmissionParameters::ACK_SUPER_FAST: |
240 |
os << "super-fast"; |
241 |
break; |
242 |
} |
243 |
os << "]"; |
244 |
return os; |
245 |
} |
246 |
|
247 |
|
248 |
/*************************************************************** |
249 |
* Listener for PHY events. Forwards to MacLow |
250 |
***************************************************************/ |
251 |
|
252 |
|
253 |
class PhyMacLowListener : public ns3::WifiPhyListener { |
254 |
public: |
255 |
PhyMacLowListener (ns3::MacLow *macLow) |
256 |
: m_macLow (macLow) {} |
257 |
virtual ~PhyMacLowListener () {} |
258 |
virtual void NotifyRxStart (Time duration) {} |
259 |
virtual void NotifyRxEndOk (void) {} |
260 |
virtual void NotifyRxEndError (void) {} |
261 |
virtual void NotifyTxStart (Time duration) {} |
262 |
virtual void NotifyMaybeCcaBusyStart (Time duration) {} |
263 |
virtual void NotifySwitchingStart (Time duration) { |
264 |
m_macLow->NotifySwitchingStartNow (duration); |
265 |
} |
266 |
private: |
267 |
ns3::MacLow *m_macLow; |
268 |
}; |
269 |
|
270 |
|
271 |
MacLow::MacLow () |
272 |
: m_normalAckTimeoutEvent (), |
273 |
m_fastAckTimeoutEvent (), |
274 |
m_superFastAckTimeoutEvent (), |
275 |
m_fastAckFailedTimeoutEvent (), |
276 |
m_ctsTimeoutEvent (), |
277 |
m_sendCtsEvent (), |
278 |
m_sendAckEvent (), |
279 |
m_sendDataEvent (), |
280 |
m_waitSifsEvent (), |
281 |
m_currentPacket (0), |
282 |
m_listener (0) |
283 |
{ |
284 |
NS_LOG_FUNCTION (this); |
285 |
m_lastNavDuration = Seconds (0); |
286 |
m_lastNavStart = Seconds (0); |
287 |
} |
288 |
|
289 |
MacLow::~MacLow () |
290 |
{ |
291 |
NS_LOG_FUNCTION (this); |
292 |
} |
293 |
|
294 |
void |
295 |
MacLow::SetupPhyMacLowListener (Ptr<WifiPhy> phy) |
296 |
{ |
297 |
m_phyMacLowListener = new PhyMacLowListener (this); |
298 |
phy->RegisterListener (m_phyMacLowListener); |
299 |
} |
300 |
|
301 |
|
302 |
void |
303 |
MacLow::DoDispose (void) |
304 |
{ |
305 |
NS_LOG_FUNCTION (this); |
306 |
m_normalAckTimeoutEvent.Cancel (); |
307 |
m_fastAckTimeoutEvent.Cancel (); |
308 |
m_superFastAckTimeoutEvent.Cancel (); |
309 |
m_fastAckFailedTimeoutEvent.Cancel (); |
310 |
m_ctsTimeoutEvent.Cancel (); |
311 |
m_sendCtsEvent.Cancel (); |
312 |
m_sendAckEvent.Cancel (); |
313 |
m_sendDataEvent.Cancel (); |
314 |
m_waitSifsEvent.Cancel (); |
315 |
m_phy = 0; |
316 |
m_stationManager = 0; |
317 |
delete m_phyMacLowListener; |
318 |
m_phyMacLowListener = 0; |
319 |
} |
320 |
|
321 |
void |
322 |
MacLow::CancelAllEvents (void) |
323 |
{ |
324 |
NS_LOG_FUNCTION (this); |
325 |
bool oneRunning = false; |
326 |
if (m_normalAckTimeoutEvent.IsRunning ()) |
327 |
{ |
328 |
m_normalAckTimeoutEvent.Cancel (); |
329 |
oneRunning = true; |
330 |
} |
331 |
if (m_fastAckTimeoutEvent.IsRunning ()) |
332 |
{ |
333 |
m_fastAckTimeoutEvent.Cancel (); |
334 |
oneRunning = true; |
335 |
} |
336 |
if (m_superFastAckTimeoutEvent.IsRunning ()) |
337 |
{ |
338 |
m_superFastAckTimeoutEvent.Cancel (); |
339 |
oneRunning = true; |
340 |
} |
341 |
if (m_fastAckFailedTimeoutEvent.IsRunning ()) |
342 |
{ |
343 |
m_fastAckFailedTimeoutEvent.Cancel (); |
344 |
oneRunning = true; |
345 |
} |
346 |
if (m_ctsTimeoutEvent.IsRunning ()) |
347 |
{ |
348 |
m_ctsTimeoutEvent.Cancel (); |
349 |
oneRunning = true; |
350 |
} |
351 |
if (m_sendCtsEvent.IsRunning ()) |
352 |
{ |
353 |
m_sendCtsEvent.Cancel (); |
354 |
oneRunning = true; |
355 |
} |
356 |
if (m_sendAckEvent.IsRunning ()) |
357 |
{ |
358 |
m_sendAckEvent.Cancel (); |
359 |
oneRunning = true; |
360 |
} |
361 |
if (m_sendDataEvent.IsRunning ()) |
362 |
{ |
363 |
m_sendDataEvent.Cancel (); |
364 |
oneRunning = true; |
365 |
} |
366 |
if (m_waitSifsEvent.IsRunning ()) |
367 |
{ |
368 |
m_waitSifsEvent.Cancel (); |
369 |
oneRunning = true; |
370 |
} |
371 |
if (oneRunning && m_listener != 0) |
372 |
{ |
373 |
m_listener->Cancel (); |
374 |
m_listener = 0; |
375 |
} |
376 |
} |
377 |
|
378 |
void |
379 |
MacLow::SetPhy (Ptr<WifiPhy> phy) |
380 |
{ |
381 |
m_phy = phy; |
382 |
m_phy->SetReceiveOkCallback (MakeCallback (&MacLow::ReceiveOk, this)); |
383 |
m_phy->SetReceiveErrorCallback (MakeCallback (&MacLow::ReceiveError, this)); |
384 |
SetupPhyMacLowListener(phy); |
385 |
} |
386 |
void |
387 |
MacLow::SetWifiRemoteStationManager (Ptr<WifiRemoteStationManager> manager) |
388 |
{ |
389 |
m_stationManager = manager; |
390 |
} |
391 |
|
392 |
void |
393 |
MacLow::SetAddress (Mac48Address ad) |
394 |
{ |
395 |
m_self = ad; |
396 |
} |
397 |
void |
398 |
MacLow::SetAckTimeout (Time ackTimeout) |
399 |
{ |
400 |
m_ackTimeout = ackTimeout; |
401 |
} |
402 |
void |
403 |
MacLow::SetCtsTimeout (Time ctsTimeout) |
404 |
{ |
405 |
m_ctsTimeout = ctsTimeout; |
406 |
} |
407 |
void |
408 |
MacLow::SetSifs (Time sifs) |
409 |
{ |
410 |
m_sifs = sifs; |
411 |
} |
412 |
void |
413 |
MacLow::SetSlotTime (Time slotTime) |
414 |
{ |
415 |
m_slotTime = slotTime; |
416 |
} |
417 |
void |
418 |
MacLow::SetPifs (Time pifs) |
419 |
{ |
420 |
m_pifs = pifs; |
421 |
} |
422 |
void |
423 |
MacLow::SetBssid (Mac48Address bssid) |
424 |
{ |
425 |
m_bssid = bssid; |
426 |
} |
427 |
Mac48Address |
428 |
MacLow::GetAddress (void) const |
429 |
{ |
430 |
return m_self; |
431 |
} |
432 |
Time |
433 |
MacLow::GetAckTimeout (void) const |
434 |
{ |
435 |
return m_ackTimeout; |
436 |
} |
437 |
Time |
438 |
MacLow::GetCtsTimeout (void) const |
439 |
{ |
440 |
return m_ctsTimeout; |
441 |
} |
442 |
Time |
443 |
MacLow::GetSifs (void) const |
444 |
{ |
445 |
return m_sifs; |
446 |
} |
447 |
Time |
448 |
MacLow::GetSlotTime (void) const |
449 |
{ |
450 |
return m_slotTime; |
451 |
} |
452 |
Time |
453 |
MacLow::GetPifs (void) const |
454 |
{ |
455 |
return m_pifs; |
456 |
} |
457 |
Mac48Address |
458 |
MacLow::GetBssid (void) const |
459 |
{ |
460 |
return m_bssid; |
461 |
} |
462 |
|
463 |
void |
464 |
MacLow::SetRxCallback (Callback<void,Ptr<Packet>,const WifiMacHeader *> callback) |
465 |
{ |
466 |
m_rxCallback = callback; |
467 |
} |
468 |
void |
469 |
MacLow::RegisterDcfListener (MacLowDcfListener *listener) |
470 |
{ |
471 |
m_dcfListeners.push_back (listener); |
472 |
} |
473 |
|
474 |
|
475 |
void |
476 |
MacLow::StartTransmission (Ptr<const Packet> packet, |
477 |
const WifiMacHeader* hdr, |
478 |
MacLowTransmissionParameters params, |
479 |
MacLowTransmissionListener *listener) |
480 |
{ |
481 |
NS_LOG_FUNCTION (this << packet << hdr << params << listener); |
482 |
/* m_currentPacket is not NULL because someone started |
483 |
* a transmission and was interrupted before one of: |
484 |
* - ctsTimeout |
485 |
* - sendDataAfterCTS |
486 |
* expired. This means that one of these timers is still |
487 |
* running. They are all cancelled below anyway by the |
488 |
* call to CancelAllEvents (because of at least one |
489 |
* of these two timer) which will trigger a call to the |
490 |
* previous listener's cancel method. |
491 |
* |
492 |
* This typically happens because the high-priority |
493 |
* QapScheduler has taken access to the channel from |
494 |
* one of the Edca of the QAP. |
495 |
*/ |
496 |
m_currentPacket = packet->Copy (); |
497 |
m_currentHdr = *hdr; |
498 |
CancelAllEvents (); |
499 |
m_listener = listener; |
500 |
m_txParams = params; |
501 |
|
502 |
//NS_ASSERT (m_phy->IsStateIdle ()); |
503 |
|
504 |
NS_LOG_DEBUG ("startTx size="<< GetSize (m_currentPacket, &m_currentHdr) << |
505 |
", to=" << m_currentHdr.GetAddr1()<<", listener="<<m_listener); |
506 |
|
507 |
if (m_txParams.MustSendRts ()) |
508 |
{ |
509 |
SendRtsForPacket (); |
510 |
} |
511 |
else |
512 |
{ |
513 |
SendDataPacket (); |
514 |
} |
515 |
|
516 |
/* When this method completes, we have taken ownership of the medium. */ |
517 |
NS_ASSERT (m_phy->IsStateTx ()); |
518 |
} |
519 |
|
520 |
void |
521 |
MacLow::ReceiveError (Ptr<const Packet> packet, double rxSnr) |
522 |
{ |
523 |
NS_LOG_FUNCTION (this << packet << rxSnr); |
524 |
NS_LOG_DEBUG ("rx failed "); |
525 |
if (m_txParams.MustWaitFastAck ()) |
526 |
{ |
527 |
NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ()); |
528 |
m_fastAckFailedTimeoutEvent = Simulator::Schedule (GetSifs (), |
529 |
&MacLow::FastAckFailedTimeout, this); |
530 |
} |
531 |
return; |
532 |
} |
533 |
|
534 |
void |
535 |
MacLow::NotifySwitchingStartNow (Time duration) |
536 |
{ |
537 |
NS_LOG_DEBUG ("switching channel. Cancelling MAC pending events"); |
538 |
m_stationManager->Reset(); |
539 |
CancelAllEvents(); |
540 |
if (m_navCounterResetCtsMissed.IsRunning ()) |
541 |
{ |
542 |
m_navCounterResetCtsMissed.Cancel(); |
543 |
} |
544 |
m_lastNavStart = Simulator::Now (); |
545 |
m_lastNavDuration = Seconds (0); |
546 |
m_currentPacket = 0; |
547 |
m_listener = 0; |
548 |
} |
549 |
|
550 |
void |
551 |
MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiMode txMode, WifiPreamble preamble) |
552 |
{ |
553 |
NS_LOG_FUNCTION (this << packet << rxSnr << txMode << preamble); |
554 |
/* A packet is received from the PHY. |
555 |
* When we have handled this packet, |
556 |
* we handle any packet present in the |
557 |
* packet queue. |
558 |
*/ |
559 |
WifiMacHeader hdr; |
560 |
packet->RemoveHeader (hdr); |
561 |
|
562 |
bool isPrevNavZero = IsNavZero (); |
563 |
NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ()); |
564 |
NotifyNav (hdr, txMode, preamble); |
565 |
if (hdr.IsRts ()) |
566 |
{ |
567 |
/* see section 9.2.5.7 802.11-1999 |
568 |
* A STA that is addressed by an RTS frame shall transmit a CTS frame after a SIFS |
569 |
* period if the NAV at the STA receiving the RTS frame indicates that the medium is |
570 |
* idle. If the NAV at the STA receiving the RTS indicates the medium is not idle, |
571 |
* that STA shall not respond to the RTS frame. |
572 |
*/ |
573 |
if (isPrevNavZero && |
574 |
hdr.GetAddr1 () == m_self) |
575 |
{ |
576 |
NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS"); |
577 |
NS_ASSERT (m_sendCtsEvent.IsExpired ()); |
578 |
WifiRemoteStation *station = GetStation (hdr.GetAddr2 ()); |
579 |
station->ReportRxOk (rxSnr, txMode); |
580 |
m_sendCtsEvent = Simulator::Schedule (GetSifs (), |
581 |
&MacLow::SendCtsAfterRts, this, |
582 |
hdr.GetAddr2 (), |
583 |
hdr.GetDuration (), |
584 |
txMode, |
585 |
rxSnr); |
586 |
} |
587 |
else |
588 |
{ |
589 |
NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS"); |
590 |
} |
591 |
} |
592 |
else if (hdr.IsCts () && |
593 |
hdr.GetAddr1 () == m_self && |
594 |
m_ctsTimeoutEvent.IsRunning () && |
595 |
m_currentPacket != 0) |
596 |
{ |
597 |
NS_LOG_DEBUG ("receive cts from="<<m_currentHdr.GetAddr1 ()); |
598 |
SnrTag tag; |
599 |
packet->RemovePacketTag (tag); |
600 |
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
601 |
station->ReportRxOk (rxSnr, txMode); |
602 |
station->ReportRtsOk (rxSnr, txMode, tag.Get ()); |
603 |
|
604 |
m_ctsTimeoutEvent.Cancel (); |
605 |
NotifyCtsTimeoutResetNow (); |
606 |
m_listener->GotCts (rxSnr, txMode); |
607 |
NS_ASSERT (m_sendDataEvent.IsExpired ()); |
608 |
m_sendDataEvent = Simulator::Schedule (GetSifs (), |
609 |
&MacLow::SendDataAfterCts, this, |
610 |
hdr.GetAddr1 (), |
611 |
hdr.GetDuration (), |
612 |
txMode); |
613 |
} |
614 |
else if (hdr.IsAck () && |
615 |
hdr.GetAddr1 () == m_self && |
616 |
(m_normalAckTimeoutEvent.IsRunning () || |
617 |
m_fastAckTimeoutEvent.IsRunning () || |
618 |
m_superFastAckTimeoutEvent.IsRunning ()) && |
619 |
m_txParams.MustWaitAck ()) |
620 |
{ |
621 |
NS_LOG_DEBUG ("receive ack from="<<m_currentHdr.GetAddr1 ()); |
622 |
SnrTag tag; |
623 |
packet->RemovePacketTag (tag); |
624 |
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
625 |
station->ReportRxOk (rxSnr, txMode); |
626 |
station->ReportDataOk (rxSnr, txMode, tag.Get ()); |
627 |
bool gotAck = false; |
628 |
if (m_txParams.MustWaitNormalAck () && |
629 |
m_normalAckTimeoutEvent.IsRunning ()) |
630 |
{ |
631 |
m_normalAckTimeoutEvent.Cancel (); |
632 |
NotifyAckTimeoutResetNow (); |
633 |
gotAck = true; |
634 |
} |
635 |
if (m_txParams.MustWaitFastAck () && |
636 |
m_fastAckTimeoutEvent.IsRunning ()) |
637 |
{ |
638 |
m_fastAckTimeoutEvent.Cancel (); |
639 |
NotifyAckTimeoutResetNow (); |
640 |
gotAck = true; |
641 |
} |
642 |
if (gotAck) |
643 |
{ |
644 |
m_listener->GotAck (rxSnr, txMode); |
645 |
} |
646 |
if (m_txParams.HasNextPacket ()) |
647 |
{ |
648 |
m_waitSifsEvent = Simulator::Schedule (GetSifs (), |
649 |
&MacLow::WaitSifsAfterEndTx, this); |
650 |
} |
651 |
} |
652 |
else if (hdr.IsCtl ()) |
653 |
{ |
654 |
NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ()); |
655 |
} |
656 |
else if (hdr.GetAddr1 () == m_self) |
657 |
{ |
658 |
WifiRemoteStation *station = GetStation (hdr.GetAddr2 ()); |
659 |
station->ReportRxOk (rxSnr, txMode); |
660 |
|
661 |
if (hdr.IsQosData () && hdr.IsQosNoAck ()) |
662 |
{ |
663 |
NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ()); |
664 |
} |
665 |
else if (hdr.IsData () || hdr.IsMgt ()) |
666 |
{ |
667 |
NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ()); |
668 |
NS_ASSERT (m_sendAckEvent.IsExpired ()); |
669 |
m_sendAckEvent = Simulator::Schedule (GetSifs (), |
670 |
&MacLow::SendAckAfterData, this, |
671 |
hdr.GetAddr2 (), |
672 |
hdr.GetDuration (), |
673 |
txMode, |
674 |
rxSnr); |
675 |
} |
676 |
goto rxPacket; |
677 |
} |
678 |
else if (hdr.GetAddr1 ().IsGroup ()) |
679 |
{ |
680 |
if (hdr.IsData () || hdr.IsMgt ()) |
681 |
{ |
682 |
NS_LOG_DEBUG ("rx group from=" << hdr.GetAddr2 ()); |
683 |
goto rxPacket; |
684 |
} |
685 |
else |
686 |
{ |
687 |
// DROP |
688 |
} |
689 |
} |
690 |
else |
691 |
{ |
692 |
//NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet)); |
693 |
} |
694 |
return; |
695 |
rxPacket: |
696 |
WifiMacTrailer fcs; |
697 |
packet->RemoveTrailer (fcs); |
698 |
m_rxCallback (packet, &hdr); |
699 |
return; |
700 |
} |
701 |
|
702 |
uint32_t |
703 |
MacLow::GetAckSize (void) const |
704 |
{ |
705 |
WifiMacHeader ack; |
706 |
ack.SetType (WIFI_MAC_CTL_ACK); |
707 |
return ack.GetSize () + 4; |
708 |
} |
709 |
uint32_t |
710 |
MacLow::GetRtsSize (void) const |
711 |
{ |
712 |
WifiMacHeader rts; |
713 |
rts.SetType (WIFI_MAC_CTL_RTS); |
714 |
return rts.GetSize () + 4; |
715 |
} |
716 |
Time |
717 |
MacLow::GetAckDuration (Mac48Address to, WifiMode dataTxMode) const |
718 |
{ |
719 |
WifiMode ackMode = GetAckTxModeForData (to, dataTxMode); |
720 |
return m_phy->CalculateTxDuration (GetAckSize (), ackMode, WIFI_PREAMBLE_LONG); |
721 |
} |
722 |
Time |
723 |
MacLow::GetCtsDuration (Mac48Address to, WifiMode rtsTxMode) const |
724 |
{ |
725 |
WifiMode ctsMode = GetCtsTxModeForRts (to, rtsTxMode); |
726 |
return m_phy->CalculateTxDuration (GetCtsSize (), ctsMode, WIFI_PREAMBLE_LONG); |
727 |
} |
728 |
uint32_t |
729 |
MacLow::GetCtsSize (void) const |
730 |
{ |
731 |
WifiMacHeader cts; |
732 |
cts.SetType (WIFI_MAC_CTL_CTS); |
733 |
return cts.GetSize () + 4; |
734 |
} |
735 |
uint32_t |
736 |
MacLow::GetSize (Ptr<const Packet> packet, const WifiMacHeader *hdr) const |
737 |
{ |
738 |
WifiMacTrailer fcs; |
739 |
return packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize (); |
740 |
} |
741 |
|
742 |
WifiMode |
743 |
MacLow::GetRtsTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const |
744 |
{ |
745 |
Mac48Address to = hdr->GetAddr1 (); |
746 |
return GetStation (to)->GetRtsMode (packet); |
747 |
} |
748 |
WifiMode |
749 |
MacLow::GetDataTxMode (Ptr<const Packet> packet, const WifiMacHeader *hdr) const |
750 |
{ |
751 |
Mac48Address to = hdr->GetAddr1 (); |
752 |
WifiMacTrailer fcs; |
753 |
uint32_t size = packet->GetSize () + hdr->GetSize () + fcs.GetSerializedSize (); |
754 |
return GetStation (to)->GetDataMode (packet, size); |
755 |
} |
756 |
|
757 |
WifiMode |
758 |
MacLow::GetCtsTxModeForRts (Mac48Address to, WifiMode rtsTxMode) const |
759 |
{ |
760 |
return GetStation (to)->GetCtsMode (rtsTxMode); |
761 |
} |
762 |
WifiMode |
763 |
MacLow::GetAckTxModeForData (Mac48Address to, WifiMode dataTxMode) const |
764 |
{ |
765 |
return GetStation (to)->GetAckMode (dataTxMode); |
766 |
} |
767 |
|
768 |
|
769 |
Time |
770 |
MacLow::CalculateOverallTxTime (Ptr<const Packet> packet, |
771 |
const WifiMacHeader* hdr, |
772 |
const MacLowTransmissionParameters& params) const |
773 |
{ |
774 |
Time txTime = Seconds (0); |
775 |
WifiMode rtsMode = GetRtsTxMode (packet, hdr); |
776 |
WifiMode dataMode = GetDataTxMode (packet, hdr); |
777 |
if (params.MustSendRts ()) |
778 |
{ |
779 |
txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsMode, WIFI_PREAMBLE_LONG); |
780 |
txTime += GetCtsDuration (hdr->GetAddr1 (), rtsMode); |
781 |
txTime += GetSifs () * Scalar (2); |
782 |
} |
783 |
uint32_t dataSize = GetSize (packet, hdr); |
784 |
txTime += m_phy->CalculateTxDuration (dataSize, dataMode, WIFI_PREAMBLE_LONG); |
785 |
if (params.MustWaitAck ()) |
786 |
{ |
787 |
txTime += GetSifs (); |
788 |
txTime += GetAckDuration (hdr->GetAddr1 (), dataMode); |
789 |
} |
790 |
return txTime; |
791 |
} |
792 |
|
793 |
Time |
794 |
MacLow::CalculateTransmissionTime (Ptr<const Packet> packet, |
795 |
const WifiMacHeader* hdr, |
796 |
const MacLowTransmissionParameters& params) const |
797 |
{ |
798 |
Time txTime = CalculateOverallTxTime (packet, hdr, params); |
799 |
if (params.HasNextPacket ()) |
800 |
{ |
801 |
WifiMode dataMode = GetDataTxMode (packet, hdr); |
802 |
txTime += GetSifs (); |
803 |
txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataMode, WIFI_PREAMBLE_LONG); |
804 |
} |
805 |
return txTime; |
806 |
} |
807 |
|
808 |
void |
809 |
MacLow::NotifyNav (const WifiMacHeader &hdr, WifiMode txMode, WifiPreamble preamble) |
810 |
{ |
811 |
NS_ASSERT (m_lastNavStart <= Simulator::Now ()); |
812 |
Time duration = hdr.GetDuration (); |
813 |
|
814 |
if (hdr.IsCfpoll () && |
815 |
hdr.GetAddr2 () == m_bssid) |
816 |
{ |
817 |
// see section 9.3.2.2 802.11-1999 |
818 |
DoNavResetNow (duration); |
819 |
return; |
820 |
} |
821 |
// XXX Note that we should also handle CF_END specially here |
822 |
// but we don't for now because we do not generate them. |
823 |
else if (hdr.GetAddr1 () != m_self) |
824 |
{ |
825 |
// see section 9.2.5.4 802.11-1999 |
826 |
bool navUpdated = DoNavStartNow (duration); |
827 |
if (hdr.IsRts () && navUpdated) |
828 |
{ |
829 |
/** |
830 |
* A STA that used information from an RTS frame as the most recent basis to update its NAV setting |
831 |
* is permitted to reset its NAV if no PHY-RXSTART.indication is detected from the PHY during a |
832 |
* period with a duration of (2 * aSIFSTime) + (CTS_Time) + (2 * aSlotTime) starting at the |
833 |
* PHY-RXEND.indication corresponding to the detection of the RTS frame. The “CTS_Time” shall |
834 |
* be calculated using the length of the CTS frame and the data rate at which the RTS frame |
835 |
* used for the most recent NAV update was received. |
836 |
*/ |
837 |
WifiMacHeader cts; |
838 |
cts.SetType (WIFI_MAC_CTL_CTS); |
839 |
Time navCounterResetCtsMissedDelay = |
840 |
m_phy->CalculateTxDuration (cts.GetSerializedSize (), txMode, preamble) + |
841 |
Scalar (2) * GetSifs () + Scalar (2) * GetSlotTime (); |
842 |
m_navCounterResetCtsMissed = Simulator::Schedule (navCounterResetCtsMissedDelay, |
843 |
&MacLow::NavCounterResetCtsMissed, this, |
844 |
Simulator::Now ()); |
845 |
} |
846 |
} |
847 |
} |
848 |
|
849 |
void |
850 |
MacLow::NavCounterResetCtsMissed (Time rtsEndRxTime) |
851 |
{ |
852 |
if (m_phy->GetLastRxStartTime () > rtsEndRxTime) |
853 |
{ |
854 |
DoNavResetNow (Seconds (0.0)); |
855 |
} |
856 |
} |
857 |
|
858 |
void |
859 |
MacLow::DoNavResetNow (Time duration) |
860 |
{ |
861 |
for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) |
862 |
{ |
863 |
(*i)->NavReset (duration); |
864 |
} |
865 |
m_lastNavStart = Simulator::Now (); |
866 |
m_lastNavStart = duration; |
867 |
} |
868 |
bool |
869 |
MacLow::DoNavStartNow (Time duration) |
870 |
{ |
871 |
for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) |
872 |
{ |
873 |
(*i)->NavStart (duration); |
874 |
} |
875 |
Time newNavEnd = Simulator::Now () + duration; |
876 |
Time oldNavEnd = m_lastNavStart + m_lastNavDuration; |
877 |
if (newNavEnd > oldNavEnd) |
878 |
{ |
879 |
m_lastNavStart = Simulator::Now (); |
880 |
m_lastNavDuration = duration; |
881 |
return true; |
882 |
} |
883 |
return false; |
884 |
} |
885 |
void |
886 |
MacLow::NotifyAckTimeoutStartNow (Time duration) |
887 |
{ |
888 |
for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) |
889 |
{ |
890 |
(*i)->AckTimeoutStart (duration); |
891 |
} |
892 |
} |
893 |
void |
894 |
MacLow::NotifyAckTimeoutResetNow () |
895 |
{ |
896 |
for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) |
897 |
{ |
898 |
(*i)->AckTimeoutReset (); |
899 |
} |
900 |
} |
901 |
void |
902 |
MacLow::NotifyCtsTimeoutStartNow (Time duration) |
903 |
{ |
904 |
for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) |
905 |
{ |
906 |
(*i)->CtsTimeoutStart (duration); |
907 |
} |
908 |
} |
909 |
void |
910 |
MacLow::NotifyCtsTimeoutResetNow () |
911 |
{ |
912 |
for (DcfListenersCI i = m_dcfListeners.begin (); i != m_dcfListeners.end (); i++) |
913 |
{ |
914 |
(*i)->CtsTimeoutReset (); |
915 |
} |
916 |
} |
917 |
|
918 |
void |
919 |
MacLow::ForwardDown (Ptr<const Packet> packet, const WifiMacHeader* hdr, |
920 |
WifiMode txMode) |
921 |
{ |
922 |
NS_LOG_FUNCTION (this << packet << hdr << txMode); |
923 |
NS_LOG_DEBUG ("send " << hdr->GetTypeString () << |
924 |
", to=" << hdr->GetAddr1 () << |
925 |
", size=" << packet->GetSize () << |
926 |
", mode=" << txMode << |
927 |
", duration=" << hdr->GetDuration () << |
928 |
", seq=0x"<< std::hex << m_currentHdr.GetSequenceControl () << std::dec); |
929 |
m_phy->SendPacket (packet, txMode, WIFI_PREAMBLE_LONG, 0); |
930 |
} |
931 |
|
932 |
void |
933 |
MacLow::CtsTimeout (void) |
934 |
{ |
935 |
NS_LOG_FUNCTION (this); |
936 |
NS_LOG_DEBUG ("cts timeout"); |
937 |
// XXX: should check that there was no rx start before now. |
938 |
// we should restart a new cts timeout now until the expected |
939 |
// end of rx if there was a rx start before now. |
940 |
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
941 |
station->ReportRtsFailed (); |
942 |
m_currentPacket = 0; |
943 |
MacLowTransmissionListener *listener = m_listener; |
944 |
m_listener = 0; |
945 |
listener->MissedCts (); |
946 |
} |
947 |
void |
948 |
MacLow::NormalAckTimeout (void) |
949 |
{ |
950 |
NS_LOG_FUNCTION (this); |
951 |
NS_LOG_DEBUG ("normal ack timeout"); |
952 |
// XXX: should check that there was no rx start before now. |
953 |
// we should restart a new ack timeout now until the expected |
954 |
// end of rx if there was a rx start before now. |
955 |
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
956 |
station->ReportDataFailed (); |
957 |
MacLowTransmissionListener *listener = m_listener; |
958 |
m_listener = 0; |
959 |
listener->MissedAck (); |
960 |
} |
961 |
void |
962 |
MacLow::FastAckTimeout (void) |
963 |
{ |
964 |
NS_LOG_FUNCTION (this); |
965 |
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
966 |
station->ReportDataFailed (); |
967 |
MacLowTransmissionListener *listener = m_listener; |
968 |
m_listener = 0; |
969 |
if (m_phy->IsStateIdle ()) |
970 |
{ |
971 |
NS_LOG_DEBUG ("fast Ack idle missed"); |
972 |
listener->MissedAck (); |
973 |
} |
974 |
else |
975 |
{ |
976 |
NS_LOG_DEBUG ("fast Ack ok"); |
977 |
} |
978 |
} |
979 |
void |
980 |
MacLow::SuperFastAckTimeout () |
981 |
{ |
982 |
NS_LOG_FUNCTION (this); |
983 |
WifiRemoteStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
984 |
station->ReportDataFailed (); |
985 |
MacLowTransmissionListener *listener = m_listener; |
986 |
m_listener = 0; |
987 |
if (m_phy->IsStateIdle ()) |
988 |
{ |
989 |
NS_LOG_DEBUG ("super fast Ack failed"); |
990 |
listener->MissedAck (); |
991 |
} |
992 |
else |
993 |
{ |
994 |
NS_LOG_DEBUG ("super fast Ack ok"); |
995 |
listener->GotAck (0.0, WifiMode ()); |
996 |
} |
997 |
} |
998 |
|
999 |
void |
1000 |
MacLow::SendRtsForPacket (void) |
1001 |
{ |
1002 |
NS_LOG_FUNCTION (this); |
1003 |
/* send an RTS for this packet. */ |
1004 |
WifiMacHeader rts; |
1005 |
rts.SetType (WIFI_MAC_CTL_RTS); |
1006 |
rts.SetDsNotFrom (); |
1007 |
rts.SetDsNotTo (); |
1008 |
rts.SetNoRetry (); |
1009 |
rts.SetNoMoreFragments (); |
1010 |
rts.SetAddr1 (m_currentHdr.GetAddr1 ()); |
1011 |
rts.SetAddr2 (m_self); |
1012 |
WifiMode rtsTxMode = GetRtsTxMode (m_currentPacket, &m_currentHdr); |
1013 |
Time duration = Seconds (0); |
1014 |
if (m_txParams.HasDurationId ()) |
1015 |
{ |
1016 |
duration += m_txParams.GetDurationId (); |
1017 |
} |
1018 |
else |
1019 |
{ |
1020 |
WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr); |
1021 |
duration += GetSifs (); |
1022 |
duration += GetCtsDuration (m_currentHdr.GetAddr1 (), rtsTxMode); |
1023 |
duration += GetSifs (); |
1024 |
duration += m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), |
1025 |
dataTxMode, WIFI_PREAMBLE_LONG); |
1026 |
duration += GetSifs (); |
1027 |
duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode); |
1028 |
} |
1029 |
rts.SetDuration (duration); |
1030 |
|
1031 |
Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG); |
1032 |
Time timerDelay = txDuration + GetCtsTimeout (); |
1033 |
|
1034 |
NS_ASSERT (m_ctsTimeoutEvent.IsExpired ()); |
1035 |
NotifyCtsTimeoutStartNow (timerDelay); |
1036 |
m_ctsTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::CtsTimeout, this); |
1037 |
|
1038 |
Ptr<Packet> packet = Create<Packet> (); |
1039 |
packet->AddHeader (rts); |
1040 |
WifiMacTrailer fcs; |
1041 |
packet->AddTrailer (fcs); |
1042 |
|
1043 |
ForwardDown (packet, &rts, rtsTxMode); |
1044 |
} |
1045 |
|
1046 |
void |
1047 |
MacLow::StartDataTxTimers (void) |
1048 |
{ |
1049 |
WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr); |
1050 |
Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), dataTxMode, WIFI_PREAMBLE_LONG); |
1051 |
if (m_txParams.MustWaitNormalAck ()) |
1052 |
{ |
1053 |
Time timerDelay = txDuration + GetAckTimeout (); |
1054 |
NS_ASSERT (m_normalAckTimeoutEvent.IsExpired ()); |
1055 |
NotifyAckTimeoutStartNow (timerDelay); |
1056 |
m_normalAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::NormalAckTimeout, this); |
1057 |
} |
1058 |
else if (m_txParams.MustWaitFastAck ()) |
1059 |
{ |
1060 |
Time timerDelay = txDuration + GetPifs (); |
1061 |
NS_ASSERT (m_fastAckTimeoutEvent.IsExpired ()); |
1062 |
NotifyAckTimeoutStartNow (timerDelay); |
1063 |
m_fastAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::FastAckTimeout, this); |
1064 |
} |
1065 |
else if (m_txParams.MustWaitSuperFastAck ()) |
1066 |
{ |
1067 |
Time timerDelay = txDuration + GetPifs (); |
1068 |
NS_ASSERT (m_superFastAckTimeoutEvent.IsExpired ()); |
1069 |
NotifyAckTimeoutStartNow (timerDelay); |
1070 |
m_superFastAckTimeoutEvent = Simulator::Schedule (timerDelay, |
1071 |
&MacLow::SuperFastAckTimeout, this); |
1072 |
} |
1073 |
else if (m_txParams.HasNextPacket ()) |
1074 |
{ |
1075 |
Time delay = txDuration + GetSifs (); |
1076 |
NS_ASSERT (m_waitSifsEvent.IsExpired ()); |
1077 |
m_waitSifsEvent = Simulator::Schedule (delay, &MacLow::WaitSifsAfterEndTx, this); |
1078 |
} |
1079 |
else |
1080 |
{ |
1081 |
// since we do not expect any timer to be triggered. |
1082 |
m_listener = 0; |
1083 |
} |
1084 |
} |
1085 |
|
1086 |
void |
1087 |
MacLow::SendDataPacket (void) |
1088 |
{ |
1089 |
NS_LOG_FUNCTION (this); |
1090 |
/* send this packet directly. No RTS is needed. */ |
1091 |
StartDataTxTimers (); |
1092 |
|
1093 |
WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr); |
1094 |
Time duration = Seconds (0.0); |
1095 |
if (m_txParams.HasDurationId ()) |
1096 |
{ |
1097 |
duration += m_txParams.GetDurationId (); |
1098 |
} |
1099 |
else |
1100 |
{ |
1101 |
if (m_txParams.MustWaitAck ()) |
1102 |
{ |
1103 |
duration += GetSifs (); |
1104 |
duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode); |
1105 |
} |
1106 |
if (m_txParams.HasNextPacket ()) |
1107 |
{ |
1108 |
duration += GetSifs (); |
1109 |
duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), |
1110 |
dataTxMode, WIFI_PREAMBLE_LONG); |
1111 |
if (m_txParams.MustWaitAck ()) |
1112 |
{ |
1113 |
duration += GetSifs (); |
1114 |
duration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode); |
1115 |
} |
1116 |
} |
1117 |
} |
1118 |
m_currentHdr.SetDuration (duration); |
1119 |
|
1120 |
m_currentPacket->AddHeader (m_currentHdr); |
1121 |
WifiMacTrailer fcs; |
1122 |
m_currentPacket->AddTrailer (fcs); |
1123 |
|
1124 |
ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode); |
1125 |
m_currentPacket = 0; |
1126 |
} |
1127 |
|
1128 |
bool |
1129 |
MacLow::IsNavZero (void) const |
1130 |
{ |
1131 |
if (m_lastNavStart + m_lastNavDuration < Simulator::Now ()) |
1132 |
{ |
1133 |
return true; |
1134 |
} |
1135 |
else |
1136 |
{ |
1137 |
return false; |
1138 |
} |
1139 |
} |
1140 |
|
1141 |
WifiRemoteStation * |
1142 |
MacLow::GetStation (Mac48Address ad) const |
1143 |
{ |
1144 |
return m_stationManager->Lookup (ad); |
1145 |
} |
1146 |
|
1147 |
void |
1148 |
MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode rtsTxMode, double rtsSnr) |
1149 |
{ |
1150 |
NS_LOG_FUNCTION (this << source << duration << rtsTxMode << rtsSnr); |
1151 |
/* send a CTS when you receive a RTS |
1152 |
* right after SIFS. |
1153 |
*/ |
1154 |
WifiMode ctsTxMode = GetCtsTxModeForRts (source, rtsTxMode); |
1155 |
WifiMacHeader cts; |
1156 |
cts.SetType (WIFI_MAC_CTL_CTS); |
1157 |
cts.SetDsNotFrom (); |
1158 |
cts.SetDsNotTo (); |
1159 |
cts.SetNoMoreFragments (); |
1160 |
cts.SetNoRetry (); |
1161 |
cts.SetAddr1 (source); |
1162 |
duration -= GetCtsDuration (source, rtsTxMode); |
1163 |
duration -= GetSifs (); |
1164 |
NS_ASSERT (duration >= MicroSeconds (0)); |
1165 |
cts.SetDuration (duration); |
1166 |
|
1167 |
Ptr<Packet> packet = Create<Packet> (); |
1168 |
packet->AddHeader (cts); |
1169 |
WifiMacTrailer fcs; |
1170 |
packet->AddTrailer (fcs); |
1171 |
|
1172 |
struct SnrTag tag; |
1173 |
tag.Set (rtsSnr); |
1174 |
packet->AddPacketTag (tag); |
1175 |
|
1176 |
ForwardDown (packet, &cts, ctsTxMode); |
1177 |
} |
1178 |
|
1179 |
void |
1180 |
MacLow::SendDataAfterCts (Mac48Address source, Time duration, WifiMode txMode) |
1181 |
{ |
1182 |
NS_LOG_FUNCTION (this); |
1183 |
/* send the third step in a |
1184 |
* RTS/CTS/DATA/ACK hanshake |
1185 |
*/ |
1186 |
NS_ASSERT (m_currentPacket != 0); |
1187 |
StartDataTxTimers (); |
1188 |
|
1189 |
WifiMode dataTxMode = GetDataTxMode (m_currentPacket, &m_currentHdr); |
1190 |
Time newDuration = Seconds (0); |
1191 |
newDuration += GetSifs (); |
1192 |
newDuration += GetAckDuration (m_currentHdr.GetAddr1 (), dataTxMode); |
1193 |
Time txDuration = m_phy->CalculateTxDuration (GetSize (m_currentPacket, &m_currentHdr), |
1194 |
dataTxMode, WIFI_PREAMBLE_LONG); |
1195 |
duration -= txDuration; |
1196 |
duration -= GetSifs (); |
1197 |
|
1198 |
duration = std::max (duration, newDuration); |
1199 |
NS_ASSERT (duration >= MicroSeconds (0)); |
1200 |
m_currentHdr.SetDuration (duration); |
1201 |
|
1202 |
m_currentPacket->AddHeader (m_currentHdr); |
1203 |
WifiMacTrailer fcs; |
1204 |
m_currentPacket->AddTrailer (fcs); |
1205 |
|
1206 |
ForwardDown (m_currentPacket, &m_currentHdr, dataTxMode); |
1207 |
m_currentPacket = 0; |
1208 |
} |
1209 |
|
1210 |
void |
1211 |
MacLow::WaitSifsAfterEndTx (void) |
1212 |
{ |
1213 |
m_listener->StartNext (); |
1214 |
} |
1215 |
|
1216 |
void |
1217 |
MacLow::FastAckFailedTimeout (void) |
1218 |
{ |
1219 |
NS_LOG_FUNCTION (this); |
1220 |
MacLowTransmissionListener *listener = m_listener; |
1221 |
m_listener = 0; |
1222 |
listener->MissedAck (); |
1223 |
NS_LOG_DEBUG ("fast Ack busy but missed"); |
1224 |
} |
1225 |
|
1226 |
void |
1227 |
MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode dataTxMode, double dataSnr) |
1228 |
{ |
1229 |
NS_LOG_FUNCTION (this); |
1230 |
/* send an ACK when you receive |
1231 |
* a packet after SIFS. |
1232 |
*/ |
1233 |
WifiMode ackTxMode = GetAckTxModeForData (source, dataTxMode); |
1234 |
WifiMacHeader ack; |
1235 |
ack.SetType (WIFI_MAC_CTL_ACK); |
1236 |
ack.SetDsNotFrom (); |
1237 |
ack.SetDsNotTo (); |
1238 |
ack.SetNoRetry (); |
1239 |
ack.SetNoMoreFragments (); |
1240 |
ack.SetAddr1 (source); |
1241 |
duration -= GetAckDuration (source, dataTxMode); |
1242 |
duration -= GetSifs (); |
1243 |
NS_ASSERT (duration >= MicroSeconds (0)); |
1244 |
ack.SetDuration (duration); |
1245 |
|
1246 |
Ptr<Packet> packet = Create<Packet> (); |
1247 |
packet->AddHeader (ack); |
1248 |
WifiMacTrailer fcs; |
1249 |
packet->AddTrailer (fcs); |
1250 |
|
1251 |
struct SnrTag tag; |
1252 |
tag.Set (dataSnr); |
1253 |
packet->AddPacketTag (tag); |
1254 |
|
1255 |
ForwardDown (packet, &ack, ackTxMode); |
1256 |
} |
1257 |
|
1258 |
} // namespace ns3 |