17 * |
17 * |
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
19 */ |
19 */ |
20 |
20 |
21 #include "ns3/assert.h" |
21 #include "ns3/assert.h" |
22 |
|
23 #include "ns3/packet.h" |
22 #include "ns3/packet.h" |
24 #include "ns3/simulator.h" |
23 #include "ns3/simulator.h" |
25 #include "ns3/tag.h" |
24 #include "ns3/tag.h" |
|
25 #include "ns3/log.h" |
26 |
26 |
27 #include "mac-low.h" |
27 #include "mac-low.h" |
28 #include "wifi-phy.h" |
28 #include "wifi-phy.h" |
29 #include "wifi-mac-trailer.h" |
29 #include "wifi-mac-trailer.h" |
30 #include "wifi-net-device.h" |
30 #include "wifi-net-device.h" |
31 #include "mac-stations.h" |
31 #include "mac-stations.h" |
32 #include "mac-parameters.h" |
32 #include "mac-parameters.h" |
33 |
33 |
34 #define noMAC_LOW_TRACE 1 |
34 NS_LOG_COMPONENT_DEFINE ("MacLow"); |
35 |
|
36 #ifdef MAC_LOW_TRACE |
|
37 # include <iostream> |
|
38 # define TRACE(x) \ |
|
39 std::cout << "MAC LOW " << x << std::endl; |
|
40 #else /* MAC_LOW_TRACE */ |
|
41 # define TRACE(x) |
|
42 #endif /* MAC_LOW_TRACE */ |
|
43 |
35 |
44 namespace ns3 { |
36 namespace ns3 { |
45 |
37 |
46 class SnrTag : public Tag |
38 class SnrTag : public Tag |
47 { |
39 { |
365 m_listener = listener; |
357 m_listener = listener; |
366 m_txParams = parameters; |
358 m_txParams = parameters; |
367 |
359 |
368 //NS_ASSERT (m_phy->IsStateIdle ()); |
360 //NS_ASSERT (m_phy->IsStateIdle ()); |
369 |
361 |
370 TRACE ("startTx size="<< GetCurrentSize () << ", to=" << m_currentHdr.GetAddr1()); |
362 NS_LOG_DEBUG ("startTx size="<< GetCurrentSize () << ", to=" << m_currentHdr.GetAddr1()); |
371 |
363 |
372 if (m_txParams.MustSendRts ()) |
364 if (m_txParams.MustSendRts ()) |
373 { |
365 { |
374 SendRtsForPacket (); |
366 SendRtsForPacket (); |
375 } |
367 } |
383 } |
375 } |
384 |
376 |
385 void |
377 void |
386 MacLow::ReceiveError (Packet packet, double rxSnr) |
378 MacLow::ReceiveError (Packet packet, double rxSnr) |
387 { |
379 { |
388 TRACE ("rx failed "); |
380 NS_LOG_DEBUG ("rx failed "); |
389 m_dropError (packet); |
381 m_dropError (packet); |
390 if (m_txParams.MustWaitFastAck ()) |
382 if (m_txParams.MustWaitFastAck ()) |
391 { |
383 { |
392 NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ()); |
384 NS_ASSERT (m_fastAckFailedTimeoutEvent.IsExpired ()); |
393 m_fastAckFailedTimeoutEvent = Simulator::Schedule (GetSifs (), |
385 m_fastAckFailedTimeoutEvent = Simulator::Schedule (GetSifs (), |
406 */ |
398 */ |
407 WifiMacHeader hdr; |
399 WifiMacHeader hdr; |
408 packet.RemoveHeader (hdr); |
400 packet.RemoveHeader (hdr); |
409 |
401 |
410 bool isPrevNavZero = IsNavZero (Simulator::Now ()); |
402 bool isPrevNavZero = IsNavZero (Simulator::Now ()); |
411 TRACE ("duration/id=" << hdr.GetDuration ()); |
403 NS_LOG_DEBUG ("duration/id=" << hdr.GetDuration ()); |
412 NotifyNav (Simulator::Now (), &hdr); |
404 NotifyNav (Simulator::Now (), &hdr); |
413 if (hdr.IsRts ()) |
405 if (hdr.IsRts ()) |
414 { |
406 { |
415 /* XXX see section 9.9.2.2.1 802.11e/D12.1 */ |
407 /* XXX see section 9.9.2.2.1 802.11e/D12.1 */ |
416 if (isPrevNavZero && |
408 if (isPrevNavZero && |
417 hdr.GetAddr1 () == m_device->GetSelfAddress ()) |
409 hdr.GetAddr1 () == m_device->GetSelfAddress ()) |
418 { |
410 { |
419 TRACE ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS"); |
411 NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", schedule CTS"); |
420 NS_ASSERT (m_sendCtsEvent.IsExpired ()); |
412 NS_ASSERT (m_sendCtsEvent.IsExpired ()); |
421 MacStation *station = m_stations->Lookup (hdr.GetAddr2 ()); |
413 MacStation *station = m_stations->Lookup (hdr.GetAddr2 ()); |
422 station->ReportRxOk (rxSnr, txMode); |
414 station->ReportRxOk (rxSnr, txMode); |
423 m_sendCtsEvent = Simulator::Schedule (GetSifs (), |
415 m_sendCtsEvent = Simulator::Schedule (GetSifs (), |
424 &MacLow::SendCtsAfterRts, this, |
416 &MacLow::SendCtsAfterRts, this, |
429 GetCtsTxModeForRts (hdr.GetAddr2 (), txMode), |
421 GetCtsTxModeForRts (hdr.GetAddr2 (), txMode), |
430 rxSnr); |
422 rxSnr); |
431 } |
423 } |
432 else |
424 else |
433 { |
425 { |
434 TRACE ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS"); |
426 NS_LOG_DEBUG ("rx RTS from=" << hdr.GetAddr2 () << ", cannot schedule CTS"); |
435 } |
427 } |
436 } |
428 } |
437 else if (hdr.IsCts () && |
429 else if (hdr.IsCts () && |
438 hdr.GetAddr1 () == m_device->GetSelfAddress () && |
430 hdr.GetAddr1 () == m_device->GetSelfAddress () && |
439 m_ctsTimeoutEvent.IsRunning () && |
431 m_ctsTimeoutEvent.IsRunning () && |
440 m_hasCurrent) |
432 m_hasCurrent) |
441 { |
433 { |
442 TRACE ("receive cts from="<<m_currentHdr.GetAddr1 ()); |
434 NS_LOG_DEBUG ("receive cts from="<<m_currentHdr.GetAddr1 ()); |
443 SnrTag tag; |
435 SnrTag tag; |
444 packet.PeekTag (tag); |
436 packet.PeekTag (tag); |
445 MacStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
437 MacStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
446 station->ReportRxOk (rxSnr, txMode); |
438 station->ReportRxOk (rxSnr, txMode); |
447 station->ReportRtsOk (rxSnr, txMode, tag.Get ()); |
439 station->ReportRtsOk (rxSnr, txMode, tag.Get ()); |
460 (m_normalAckTimeoutEvent.IsRunning () || |
452 (m_normalAckTimeoutEvent.IsRunning () || |
461 m_fastAckTimeoutEvent.IsRunning () || |
453 m_fastAckTimeoutEvent.IsRunning () || |
462 m_superFastAckTimeoutEvent.IsRunning ()) && |
454 m_superFastAckTimeoutEvent.IsRunning ()) && |
463 m_txParams.MustWaitAck ()) |
455 m_txParams.MustWaitAck ()) |
464 { |
456 { |
465 TRACE ("receive ack from="<<m_currentHdr.GetAddr1 ()); |
457 NS_LOG_DEBUG ("receive ack from="<<m_currentHdr.GetAddr1 ()); |
466 SnrTag tag; |
458 SnrTag tag; |
467 packet.PeekTag (tag); |
459 packet.PeekTag (tag); |
468 MacStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
460 MacStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
469 station->ReportRxOk (rxSnr, txMode); |
461 station->ReportRxOk (rxSnr, txMode); |
470 station->ReportDataOk (rxSnr, txMode, tag.Get ()); |
462 station->ReportDataOk (rxSnr, txMode, tag.Get ()); |
491 &MacLow::WaitSifsAfterEndTx, this); |
483 &MacLow::WaitSifsAfterEndTx, this); |
492 } |
484 } |
493 } |
485 } |
494 else if (hdr.IsCtl ()) |
486 else if (hdr.IsCtl ()) |
495 { |
487 { |
496 TRACE ("rx drop " << hdr.GetTypeString ()); |
488 NS_LOG_DEBUG ("rx drop " << hdr.GetTypeString ()); |
497 } |
489 } |
498 else if (hdr.GetAddr1 () == m_device->GetSelfAddress ()) |
490 else if (hdr.GetAddr1 () == m_device->GetSelfAddress ()) |
499 { |
491 { |
500 MacStation *station = GetStation (hdr.GetAddr2 ()); |
492 MacStation *station = GetStation (hdr.GetAddr2 ()); |
501 station->ReportRxOk (rxSnr, txMode); |
493 station->ReportRxOk (rxSnr, txMode); |
502 |
494 |
503 if (hdr.IsQosData () && hdr.IsQosNoAck ()) |
495 if (hdr.IsQosData () && hdr.IsQosNoAck ()) |
504 { |
496 { |
505 TRACE ("rx unicast/noAck from="<<hdr.GetAddr2 ()); |
497 NS_LOG_DEBUG ("rx unicast/noAck from="<<hdr.GetAddr2 ()); |
506 } |
498 } |
507 else if (hdr.IsData () || hdr.IsMgt ()) |
499 else if (hdr.IsData () || hdr.IsMgt ()) |
508 { |
500 { |
509 TRACE ("rx unicast/sendAck from=" << hdr.GetAddr2 ()); |
501 NS_LOG_DEBUG ("rx unicast/sendAck from=" << hdr.GetAddr2 ()); |
510 NS_ASSERT (m_sendAckEvent.IsExpired ()); |
502 NS_ASSERT (m_sendAckEvent.IsExpired ()); |
511 m_sendAckEvent = Simulator::Schedule (GetSifs (), |
503 m_sendAckEvent = Simulator::Schedule (GetSifs (), |
512 &MacLow::SendAckAfterData, this, |
504 &MacLow::SendAckAfterData, this, |
513 hdr.GetAddr2 (), |
505 hdr.GetAddr2 (), |
514 MicroSeconds (hdr.GetDurationUs ()), |
506 MicroSeconds (hdr.GetDurationUs ()), |
519 } |
511 } |
520 else if (hdr.GetAddr1 ().IsBroadcast ()) |
512 else if (hdr.GetAddr1 ().IsBroadcast ()) |
521 { |
513 { |
522 if (hdr.IsData () || hdr.IsMgt ()) |
514 if (hdr.IsData () || hdr.IsMgt ()) |
523 { |
515 { |
524 TRACE ("rx broadcast from=" << hdr.GetAddr2 ()); |
516 NS_LOG_DEBUG ("rx broadcast from=" << hdr.GetAddr2 ()); |
525 goto rxPacket; |
517 goto rxPacket; |
526 } |
518 } |
527 else |
519 else |
528 { |
520 { |
529 // DROP. |
521 // DROP. |
530 } |
522 } |
531 } |
523 } |
532 else |
524 else |
533 { |
525 { |
534 //TRACE_VERBOSE ("rx not-for-me from %d", GetSource (packet)); |
526 //NS_LOG_DEBUG_VERBOSE ("rx not-for-me from %d", GetSource (packet)); |
535 } |
527 } |
536 return; |
528 return; |
537 rxPacket: |
529 rxPacket: |
538 WifiMacTrailer fcs; |
530 WifiMacTrailer fcs; |
539 packet.RemoveTrailer (fcs); |
531 packet.RemoveTrailer (fcs); |
736 { |
728 { |
737 MacStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
729 MacStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
738 station->ReportDataFailed (); |
730 station->ReportDataFailed (); |
739 if (m_phy->IsStateIdle ()) |
731 if (m_phy->IsStateIdle ()) |
740 { |
732 { |
741 TRACE ("fast Ack idle missed"); |
733 NS_LOG_DEBUG ("fast Ack idle missed"); |
742 m_listener->MissedAck (); |
734 m_listener->MissedAck (); |
743 } |
735 } |
744 m_listener = 0; |
736 m_listener = 0; |
745 } |
737 } |
746 void |
738 void |
748 { |
740 { |
749 MacStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
741 MacStation *station = GetStation (m_currentHdr.GetAddr1 ()); |
750 station->ReportDataFailed (); |
742 station->ReportDataFailed (); |
751 if (m_phy->IsStateIdle ()) |
743 if (m_phy->IsStateIdle ()) |
752 { |
744 { |
753 TRACE ("super fast Ack failed"); |
745 NS_LOG_DEBUG ("super fast Ack failed"); |
754 m_listener->MissedAck (); |
746 m_listener->MissedAck (); |
755 } |
747 } |
756 else |
748 else |
757 { |
749 { |
758 TRACE ("super fast Ack ok"); |
750 NS_LOG_DEBUG ("super fast Ack ok"); |
759 m_listener->GotAck (0.0, WifiMode ()); |
751 m_listener->GotAck (0.0, WifiMode ()); |
760 } |
752 } |
761 m_listener = 0; |
753 m_listener = 0; |
762 } |
754 } |
763 |
755 |
789 duration += GetSifs (); |
781 duration += GetSifs (); |
790 duration += m_phy->CalculateTxDuration (GetAckSize (), ackTxMode, WIFI_PREAMBLE_LONG); |
782 duration += m_phy->CalculateTxDuration (GetAckSize (), ackTxMode, WIFI_PREAMBLE_LONG); |
791 } |
783 } |
792 rts.SetDurationUs (duration.GetMicroSeconds ()); |
784 rts.SetDurationUs (duration.GetMicroSeconds ()); |
793 |
785 |
794 TRACE ("tx RTS to="<< rts.GetAddr1 () << ", mode=" << (uint32_t)rtsTxMode); |
786 NS_LOG_DEBUG ("tx RTS to="<< rts.GetAddr1 () << ", mode=" << rtsTxMode.GetPhyRate ()); |
795 |
787 |
796 Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG); |
788 Time txDuration = m_phy->CalculateTxDuration (GetRtsSize (), rtsTxMode, WIFI_PREAMBLE_LONG); |
797 Time timerDelay = txDuration + GetCtsTimeout (); |
789 Time timerDelay = txDuration + GetCtsTimeout (); |
798 |
790 |
799 NS_ASSERT (m_ctsTimeoutEvent.IsExpired ()); |
791 NS_ASSERT (m_ctsTimeoutEvent.IsExpired ()); |
849 { |
841 { |
850 /* send this packet directly. No RTS is needed. */ |
842 /* send this packet directly. No RTS is needed. */ |
851 StartDataTxTimers (); |
843 StartDataTxTimers (); |
852 |
844 |
853 WifiMode dataTxMode = GetDataTxMode (m_currentHdr.GetAddr1 (), GetCurrentSize ()); |
845 WifiMode dataTxMode = GetDataTxMode (m_currentHdr.GetAddr1 (), GetCurrentSize ()); |
854 TRACE ("tx "<< m_currentHdr.GetTypeString () << |
846 NS_LOG_DEBUG ("tx "<< m_currentHdr.GetTypeString () << |
855 ", to=" << m_currentHdr.GetAddr1 () << |
847 ", to=" << m_currentHdr.GetAddr1 () << |
856 ", mode=" << dataTxMode.GetPhyRate ()); |
848 ", mode=" << dataTxMode.GetPhyRate ()); |
857 Time duration = Seconds (0); |
849 Time duration = Seconds (0); |
858 if (m_txParams.HasDurationId ()) |
850 if (m_txParams.HasDurationId ()) |
859 { |
851 { |
913 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr) |
905 MacLow::SendCtsAfterRts (Mac48Address source, Time duration, WifiMode txMode, double rtsSnr) |
914 { |
906 { |
915 /* send a CTS when you receive a RTS |
907 /* send a CTS when you receive a RTS |
916 * right after SIFS. |
908 * right after SIFS. |
917 */ |
909 */ |
918 TRACE ("tx CTS to=" << source << ", mode=" << (uint32_t)txMode); |
910 NS_LOG_DEBUG ("tx CTS to=" << source << ", mode=" << txMode.GetPhyRate ()); |
919 WifiMacHeader cts; |
911 WifiMacHeader cts; |
920 cts.SetType (WIFI_MAC_CTL_CTS); |
912 cts.SetType (WIFI_MAC_CTL_CTS); |
921 cts.SetDsNotFrom (); |
913 cts.SetDsNotFrom (); |
922 cts.SetDsNotTo (); |
914 cts.SetDsNotTo (); |
923 cts.SetAddr1 (source); |
915 cts.SetAddr1 (source); |
944 * RTS/CTS/DATA/ACK hanshake |
936 * RTS/CTS/DATA/ACK hanshake |
945 */ |
937 */ |
946 NS_ASSERT (m_hasCurrent); |
938 NS_ASSERT (m_hasCurrent); |
947 WifiMode dataTxMode = GetDataTxMode (m_currentHdr.GetAddr1 (), GetCurrentSize ()); |
939 WifiMode dataTxMode = GetDataTxMode (m_currentHdr.GetAddr1 (), GetCurrentSize ()); |
948 |
940 |
949 TRACE ("tx " << m_currentHdr.GetTypeString () << " to=" << m_currentHdr.GetAddr2 () << |
941 NS_LOG_DEBUG ("tx " << m_currentHdr.GetTypeString () << " to=" << m_currentHdr.GetAddr2 () << |
950 ", mode=" << dataTxMode.GetPhyRate () << ", seq=0x"<< m_currentHdr.GetSequenceControl ()); |
942 ", mode=" << dataTxMode.GetPhyRate () << ", seq=0x"<< m_currentHdr.GetSequenceControl ()); |
951 |
943 |
952 StartDataTxTimers (); |
944 StartDataTxTimers (); |
953 Time txDuration = m_phy->CalculateTxDuration (GetCurrentSize (), dataTxMode, WIFI_PREAMBLE_LONG); |
945 Time txDuration = m_phy->CalculateTxDuration (GetCurrentSize (), dataTxMode, WIFI_PREAMBLE_LONG); |
954 duration -= txDuration; |
946 duration -= txDuration; |
971 |
963 |
972 void |
964 void |
973 MacLow::FastAckFailedTimeout (void) |
965 MacLow::FastAckFailedTimeout (void) |
974 { |
966 { |
975 m_listener->MissedAck (); |
967 m_listener->MissedAck (); |
976 TRACE ("fast Ack busy but missed"); |
968 NS_LOG_DEBUG ("fast Ack busy but missed"); |
977 } |
969 } |
978 |
970 |
979 void |
971 void |
980 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode txMode, double dataSnr) |
972 MacLow::SendAckAfterData (Mac48Address source, Time duration, WifiMode txMode, double dataSnr) |
981 { |
973 { |
982 /* send an ACK when you receive |
974 /* send an ACK when you receive |
983 * a packet after SIFS. |
975 * a packet after SIFS. |
984 */ |
976 */ |
985 TRACE ("tx ACK to=" << source << ", mode=" << txMode.GetPhyRate ()); |
977 NS_LOG_DEBUG ("tx ACK to=" << source << ", mode=" << txMode.GetPhyRate ()); |
986 WifiMacHeader ack; |
978 WifiMacHeader ack; |
987 ack.SetType (WIFI_MAC_CTL_ACK); |
979 ack.SetType (WIFI_MAC_CTL_ACK); |
988 ack.SetDsNotFrom (); |
980 ack.SetDsNotFrom (); |
989 ack.SetDsNotTo (); |
981 ack.SetDsNotTo (); |
990 ack.SetAddr1 (source); |
982 ack.SetAddr1 (source); |