View | Details | Raw Unified | Return to bug 2470
Collapse All | Expand All

(-)a/src/wifi/model/block-ack-manager.cc (-8 / +34 lines)
 Lines 104-111   BlockAckManager::ExistsAgreementInState (Mac48Address recipient, uint8_t tid, Link Here 
104
          return it->second.first.IsEstablished ();
104
          return it->second.first.IsEstablished ();
105
        case OriginatorBlockAckAgreement::PENDING:
105
        case OriginatorBlockAckAgreement::PENDING:
106
          return it->second.first.IsPending ();
106
          return it->second.first.IsPending ();
107
        case OriginatorBlockAckAgreement::UNSUCCESSFUL:
107
        case OriginatorBlockAckAgreement::REJECTED:
108
          return it->second.first.IsUnsuccessful ();
108
          return it->second.first.IsRejected ();
109
        case OriginatorBlockAckAgreement::NO_REPLY:
110
          return it->second.first.IsNoReply ();
111
        case OriginatorBlockAckAgreement::RESET:
112
          return it->second.first.IsReset ();
109
        default:
113
        default:
110
          NS_FATAL_ERROR ("Invalid state for block ack agreement");
114
          NS_FATAL_ERROR ("Invalid state for block ack agreement");
111
        }
115
        }
 Lines 138-143   BlockAckManager::CreateAgreement (const MgtAddBaRequestHeader *reqHdr, Mac48Addr Link Here 
138
  agreement.SetState (OriginatorBlockAckAgreement::PENDING);
142
  agreement.SetState (OriginatorBlockAckAgreement::PENDING);
139
  PacketQueue queue;
143
  PacketQueue queue;
140
  std::pair<OriginatorBlockAckAgreement, PacketQueue> value (agreement, queue);
144
  std::pair<OriginatorBlockAckAgreement, PacketQueue> value (agreement, queue);
145
  if (ExistsAgreement (recipient, reqHdr->GetTid ()))
146
    {
147
      // Delete agreement if it exists and in RESET state
148
      NS_ASSERT (ExistsAgreementInState (recipient, reqHdr->GetTid (), OriginatorBlockAckAgreement::RESET));
149
      m_agreements.erase (key);
150
    }
141
  m_agreements.insert (std::make_pair (key, value));
151
  m_agreements.insert (std::make_pair (key, value));
142
  m_blockPackets (recipient, reqHdr->GetTid ());
152
  m_blockPackets (recipient, reqHdr->GetTid ());
143
}
153
}
 Lines 710-724   BlockAckManager::NotifyAgreementEstablished (Mac48Address recipient, uint8_t tid Link Here 
710
}
720
}
711
721
712
void
722
void
713
BlockAckManager::NotifyAgreementUnsuccessful (Mac48Address recipient, uint8_t tid)
723
BlockAckManager::NotifyAgreementRejected (Mac48Address recipient, uint8_t tid)
714
{
724
{
715
  NS_LOG_FUNCTION (this << recipient << +tid);
725
  NS_LOG_FUNCTION (this << recipient << +tid);
716
  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
726
  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
717
  NS_ASSERT (it != m_agreements.end ());
727
  NS_ASSERT (it != m_agreements.end ());
718
  if (it != m_agreements.end ())
728
  it->second.first.SetState (OriginatorBlockAckAgreement::REJECTED);
719
    {
729
}
720
      it->second.first.SetState (OriginatorBlockAckAgreement::UNSUCCESSFUL);
730
721
    }
731
void
732
BlockAckManager::NotifyAgreementNoReply (Mac48Address recipient, uint8_t tid)
733
{
734
  NS_LOG_FUNCTION (this << recipient << +tid);
735
  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
736
  NS_ASSERT (it != m_agreements.end ());
737
  it->second.first.SetState (OriginatorBlockAckAgreement::NO_REPLY);
738
  m_unblockPackets (recipient, tid);
739
}
740
741
void
742
BlockAckManager::NotifyAgreementReset (Mac48Address recipient, uint8_t tid)
743
{
744
  NS_LOG_FUNCTION (this << recipient << +tid);
745
  AgreementsI it = m_agreements.find (std::make_pair (recipient, tid));
746
  NS_ASSERT (it != m_agreements.end ());
747
  it->second.first.SetState (OriginatorBlockAckAgreement::RESET);
722
}
748
}
723
749
724
void
750
void
 Lines 761-767   BlockAckManager::SwitchToBlockAckIfNeeded (Mac48Address recipient, uint8_t tid, Link Here 
761
{
787
{
762
  NS_LOG_FUNCTION (this << recipient << +tid << startingSeq);
788
  NS_LOG_FUNCTION (this << recipient << +tid << startingSeq);
763
  NS_ASSERT (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING));
789
  NS_ASSERT (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING));
764
  if (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::UNSUCCESSFUL) && ExistsAgreement (recipient, tid))
790
  if (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::REJECTED) && ExistsAgreement (recipient, tid))
765
    {
791
    {
766
      uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, recipient) +
792
      uint32_t packets = m_queue->GetNPacketsByTidAndAddress (tid, recipient) +
767
        GetNBufferedPackets (recipient, tid);
793
        GetNBufferedPackets (recipient, tid);
(-)a/src/wifi/model/block-ack-manager.h (-2 / +18 lines)
 Lines 225-235   public: Link Here 
225
   * \param recipient Address of peer station involved in block ack mechanism.
225
   * \param recipient Address of peer station involved in block ack mechanism.
226
   * \param tid Traffic ID of transmitted packet.
226
   * \param tid Traffic ID of transmitted packet.
227
   *
227
   *
228
   * Marks an agreement as unsuccessful. This happens if <i>recipient</i> station reject block ack setup
228
   * Marks an agreement as rejected. This happens if <i>recipient</i> station reject block ack setup
229
   * by an ADDBA Response frame with a failure status code. For now we assume that every QoS station accepts
229
   * by an ADDBA Response frame with a failure status code. For now we assume that every QoS station accepts
230
   * a block ack setup.
230
   * a block ack setup.
231
   */
231
   */
232
  void NotifyAgreementUnsuccessful (Mac48Address recipient, uint8_t tid);
232
  void NotifyAgreementRejected (Mac48Address recipient, uint8_t tid);
233
  /**
234
   * \param recipient Address of peer station involved in block ack mechanism.
235
   * \param tid Traffic ID of transmitted packet.
236
   *
237
   * Marks an agreement after not receiving response to ADDBA request. During this state
238
   * any packets in queue will be transmitted using normal MPDU. This also unblock
239
   * recipient adress.
240
   */
241
  void NotifyAgreementNoReply (Mac48Address recipient, uint8_t tid);
242
  /**
243
   * \param recipient Address of peer station involved in block ack mechanism.
244
   * \param tid Traffic ID of transmitted packet.
245
   *
246
   * Set BA agreement to a transitory state to reset it after not receiving response to ADDBA request.
247
   */
248
  void NotifyAgreementReset (Mac48Address recipient, uint8_t tid);
233
  /**
249
  /**
234
   * \param recipient Address of peer station involved in block ack mechanism.
250
   * \param recipient Address of peer station involved in block ack mechanism.
235
   * \param tid Traffic ID of transmitted packet.
251
   * \param tid Traffic ID of transmitted packet.
(-)a/src/wifi/model/mac-low.cc (-3 / +3 lines)
 Lines 2594-2601   MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr) Link Here 
2594
2594
2595
      if (!hdr.GetAddr1 ().IsBroadcast () && edcaIt->second->GetMpduAggregator () != 0)
2595
      if (!hdr.GetAddr1 ().IsBroadcast () && edcaIt->second->GetMpduAggregator () != 0)
2596
        {
2596
        {
2597
          //Have to make sure that their exist a block Ack agreement before sending an AMPDU (BlockAck Manager)
2597
          //Have to make sure that the block ACK agreement is established before sending an AMPDU (BlockAck Manager)
2598
          if (edcaIt->second->GetBaAgreementExists (hdr.GetAddr1 (), tid))
2598
          if (edcaIt->second->GetBaAgreementEstablished (hdr.GetAddr1 (), tid))
2599
            {
2599
            {
2600
              /* here is performed mpdu aggregation */
2600
              /* here is performed mpdu aggregation */
2601
              /* MSDU aggregation happened in edca if the user asked for it so m_currentPacket may contains a normal packet or a A-MSDU*/
2601
              /* MSDU aggregation happened in edca if the user asked for it so m_currentPacket may contains a normal packet or a A-MSDU*/
 Lines 2849-2855   MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr) Link Here 
2849
                {
2849
                {
2850
                  InsertInTxQueue (packet, peekedHdr, tstamp, tid);
2850
                  InsertInTxQueue (packet, peekedHdr, tstamp, tid);
2851
                }
2851
                }
2852
              if (edcaIt->second->GetBaAgreementExists (hdr.GetAddr1 (), tid))
2852
              if (edcaIt->second->GetBaAgreementEstablished (hdr.GetAddr1 (), tid))
2853
                {
2853
                {
2854
                  edcaIt->second->CompleteAmpduTransfer (peekedHdr.GetAddr1 (), tid);
2854
                  edcaIt->second->CompleteAmpduTransfer (peekedHdr.GetAddr1 (), tid);
2855
                }
2855
                }
(-)a/src/wifi/model/originator-block-ack-agreement.cc (-2 / +14 lines)
 Lines 65-73   OriginatorBlockAckAgreement::IsInactive (void) const Link Here 
65
}
65
}
66
66
67
bool
67
bool
68
OriginatorBlockAckAgreement::IsUnsuccessful (void) const
68
OriginatorBlockAckAgreement::IsRejected (void) const
69
{
69
{
70
  return (m_state == UNSUCCESSFUL) ? true : false;
70
  return (m_state == REJECTED) ? true : false;
71
}
72
73
bool
74
OriginatorBlockAckAgreement::IsNoReply (void) const
75
{
76
  return (m_state == NO_REPLY) ? true : false;
77
}
78
79
bool
80
OriginatorBlockAckAgreement::IsReset (void) const
81
{
82
  return (m_state == RESET) ? true : false;
71
}
83
}
72
84
73
void
85
void
(-)a/src/wifi/model/originator-block-ack-agreement.h (-24 / +60 lines)
 Lines 28-34   namespace ns3 { Link Here 
28
/**
28
/**
29
 * \ingroup wifi
29
 * \ingroup wifi
30
 * Maintains the state and information about transmitted MPDUs with ack policy block ack
30
 * Maintains the state and information about transmitted MPDUs with ack policy block ack
31
 * for an originator station.
31
 * for an originator station. The state diagram is as follows:
32
 *
33
   \verbatim
34
                                    --------------
35
                                    |  REJECTED  |
36
                                    --------------
37
                                          ^
38
                   receive ADDBAResponse  |
39
                   status code = failure  |
40
                                          |
41
                                          |           receive ADDBAResponse
42
   /------------\ send ADDBARequest ----------------  status code = success  ----------------
43
   |   START    |------------------>|   PENDING    |------------------------>|  ESTABLISHED |-----
44
   \------------/                   ----------------                         ----------------     |
45
         ^                                |                                    /   ^    ^         |
46
         |              no ADDBAResponse  |                receive BlockAck   /    |    |         | receive BlockAck
47
         |                                v           retryPkts + queuePkts  /     |    |         | retryPkts + queuePkts
48
         |                          ----------------            <           /      |    |         |           >=
49
         |--------------------------|   NO_REPLY   |   blockAckThreshold   /       |    |         | blockAckThreshold
50
            Reset after timeout     ----------------                      /        |    |         |
51
                                                                         v         |    ----------|
52
                                                            ---------------        |
53
                                                            |  INACTIVE   |        |
54
                                                            ---------------        |
55
                                        send a MPDU (Normal Ack)   |               |
56
                                        retryPkts + queuePkts      |               |
57
                                                  >=               |               |
58
                                         blockAckThreshold         |----------------
59
   \endverbatim
60
 *
61
 * See also OriginatorBlockAckAgreement::State
32
 */
62
 */
33
class OriginatorBlockAckAgreement : public BlockAckAgreement
63
class OriginatorBlockAckAgreement : public BlockAckAgreement
34
{
64
{
 Lines 45-69   public: Link Here 
45
   */
75
   */
46
  OriginatorBlockAckAgreement (Mac48Address recipient, uint8_t tid);
76
  OriginatorBlockAckAgreement (Mac48Address recipient, uint8_t tid);
47
  ~OriginatorBlockAckAgreement ();
77
  ~OriginatorBlockAckAgreement ();
48
  /*                                      receive ADDBAResponse
49
   *  send ADDBARequest ---------------   status code = success  ---------------
50
   *  ----------------->|   PENDING    |------------------------>|  ESTABLISHED |-----
51
   *                    ---------------                          ---------------      |
52
   *                          |                                    /   ^    ^         |
53
   *   receive ADDBAResponse  |                receive BlockAck   /    |    |         | receive BlockAck
54
   *   status code = failure  |           retryPkts + queuePkts  /     |    |         | retryPkts + queuePkts
55
   *                          v                     <           /      |    |         |           >=
56
   *                   ---------------     blockAckThreshold   /       |    |         | blockAckThreshold
57
   *                   | UNSUCCESSFUL |                       /        |    |         |
58
   *                   ---------------                       v         |    ----------|
59
   *                                            --------------         |
60
   *                                            |  INACTIVE   |        |
61
   *                                            --------------         |
62
   *                        send a MPDU (Normal Ack)   |               |
63
   *                        retryPkts + queuePkts      |               |
64
   *                                  >=               |               |
65
   *                         blockAckThreshold         |----------------
66
   */
67
  /**
78
  /**
68
  * Represents the state for this agreement.
79
  * Represents the state for this agreement.
69
  *
80
  *
 Lines 82-87   public: Link Here 
82
  *    m_blockAckThreshold (see ns3::BlockAckManager). In these conditions the agreement becomes
93
  *    m_blockAckThreshold (see ns3::BlockAckManager). In these conditions the agreement becomes
83
  *    INACTIVE until that the number of packets reaches the value of m_blockAckThreshold again.
94
  *    INACTIVE until that the number of packets reaches the value of m_blockAckThreshold again.
84
  *
95
  *
96
  *  NO_REPLY
97
  *    No reply after an ADDBA request. In this state the originator will send the rest of packets
98
  *    in queue using normal MPDU.
99
  *
100
  *  RESET
101
  *    A transient state to mark the agreement for reinitialzation after failed ADDBA request.
102
  *    Since it is a temporary state, it is not included in the state diagram above. In this
103
  *    state the next transmission will be treated as if the BA agreement is not created yet.
104
  *
85
  *  UNSUCCESSFUL (not used for now):
105
  *  UNSUCCESSFUL (not used for now):
86
  *    The agreement's state becomes UNSUCCESSFUL if:
106
  *    The agreement's state becomes UNSUCCESSFUL if:
87
  *
107
  *
 Lines 100-106   public: Link Here 
100
    PENDING,
120
    PENDING,
101
    ESTABLISHED,
121
    ESTABLISHED,
102
    INACTIVE,
122
    INACTIVE,
103
    UNSUCCESSFUL
123
    NO_REPLY,
124
    RESET,
125
    REJECTED
104
  };
126
  };
105
  /**
127
  /**
106
   * Set the current state.
128
   * Set the current state.
 Lines 130-141   public: Link Here 
130
   */
152
   */
131
  bool IsInactive (void) const;
153
  bool IsInactive (void) const;
132
  /**
154
  /**
133
   * Check if the current state of this agreement is UNSUCCESSFUL.
155
   * Check if the current state of this agreement is NO_REPLY.
156
   *
157
   * \return true if the current state of this agreement is NO_REPLY,
158
   *         false otherwise
159
   */
160
  bool IsNoReply (void) const;
161
  /**
162
   * Check if the current state of this agreement is RESET.
163
   *
164
   * \return true if the current state of this agreement is RESET,
165
   *         false otherwise
166
   */
167
  bool IsReset (void) const;
168
  /**
169
   * Check if the current state of this agreement is REJECTED.
134
   *
170
   *
135
   * \return true if the current state of this agreement is UNSUCCESSFUL,
171
   * \return true if the current state of this agreement is REJECTED,
136
   *         false otherwise
172
   *         false otherwise
137
   */
173
   */
138
  bool IsUnsuccessful (void) const;
174
  bool IsRejected (void) const;
139
  /**
175
  /**
140
   * Notifies a packet's transmission with ack policy Block Ack.
176
   * Notifies a packet's transmission with ack policy Block Ack.
141
   *
177
   *
(-)a/src/wifi/model/qos-txop.cc (-16 / +107 lines)
 Lines 52-57   QosTxop::GetTypeId (void) Link Here 
52
    .SetParent<ns3::Txop> ()
52
    .SetParent<ns3::Txop> ()
53
    .SetGroupName ("Wifi")
53
    .SetGroupName ("Wifi")
54
    .AddConstructor<QosTxop> ()
54
    .AddConstructor<QosTxop> ()
55
    .AddAttribute ("AddBaResponseTimeout",
56
                   "The timeout to wait for ADDBA response after the ACK to "
57
                   "ADDBA request is received.",
58
                   TimeValue (MilliSeconds (1)),
59
                   MakeTimeAccessor (&QosTxop::SetAddBaResponseTimeout,
60
                                     &QosTxop::GetAddBaResponseTimeout),
61
                   MakeTimeChecker ())
62
    .AddAttribute ("FailedAddBaTimeout",
63
                   "The timeout after a failed BA agreement. During this "
64
                   "timeout, the originator resumes sending packets using normal "
65
                   "MPDU. After that, BA agreement is reset and the originator "
66
                   "will retry BA negotiation.",
67
                   TimeValue (MilliSeconds (200)),
68
                   MakeTimeAccessor (&QosTxop::SetFailedAddBaTimeout,
69
                                     &QosTxop::GetFailedAddBaTimeout),
70
                   MakeTimeChecker ())
55
    .AddTraceSource ("BackoffTrace",
71
    .AddTraceSource ("BackoffTrace",
56
                     "Trace source for backoff values",
72
                     "Trace source for backoff values",
57
                     MakeTraceSourceAccessor (&QosTxop::m_backoffTrace),
73
                     MakeTraceSourceAccessor (&QosTxop::m_backoffTrace),
 Lines 106-114   QosTxop::DoDispose (void) Link Here 
106
}
122
}
107
123
108
bool
124
bool
109
QosTxop::GetBaAgreementExists (Mac48Address address, uint8_t tid) const
125
QosTxop::GetBaAgreementEstablished (Mac48Address address, uint8_t tid) const
110
{
126
{
111
  return m_baManager->ExistsAgreement (address, tid);
127
  return m_baManager->ExistsAgreementInState (address, tid, OriginatorBlockAckAgreement::ESTABLISHED);
112
}
128
}
113
129
114
void
130
void
 Lines 196-202   QosTxop::NotifyAccessGranted (void) Link Here 
196
          m_currentPacketTimestamp = item->GetTimeStamp ();
212
          m_currentPacketTimestamp = item->GetTimeStamp ();
197
          if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ()
213
          if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ()
198
              && m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ())
214
              && m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ())
199
              && !m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ())
215
              && (!m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ())
216
                  || m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), OriginatorBlockAckAgreement::RESET))
200
              && SetupBlockAckIfNeeded ())
217
              && SetupBlockAckIfNeeded ())
201
            {
218
            {
202
              return;
219
              return;
 Lines 442-448   QosTxop::MissedCts (void) Link Here 
442
          uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
459
          uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
443
          m_low->FlushAggregateQueue (tid);
460
          m_low->FlushAggregateQueue (tid);
444
461
445
          if (GetBaAgreementExists (m_currentHdr.GetAddr1 (), tid))
462
          if (GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), tid))
446
            {
463
            {
447
              NS_LOG_DEBUG ("Transmit Block Ack Request");
464
              NS_LOG_DEBUG ("Transmit Block Ack Request");
448
              CtrlBAckRequestHeader reqHdr;
465
              CtrlBAckRequestHeader reqHdr;
 Lines 505-522   QosTxop::GotAck (void) Link Here 
505
          WifiActionHeader actionHdr;
522
          WifiActionHeader actionHdr;
506
          Ptr<Packet> p = m_currentPacket->Copy ();
523
          Ptr<Packet> p = m_currentPacket->Copy ();
507
          p->RemoveHeader (actionHdr);
524
          p->RemoveHeader (actionHdr);
508
          if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK
525
          if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK)
509
              && actionHdr.GetAction ().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
510
            {
526
            {
511
              MgtDelBaHeader delBa;
527
              if (actionHdr.GetAction ().blockAck == WifiActionHeader::BLOCK_ACK_DELBA)
512
              p->PeekHeader (delBa);
513
              if (delBa.IsByOriginator ())
514
                {
528
                {
515
                  m_baManager->DestroyAgreement (m_currentHdr.GetAddr1 (), delBa.GetTid ());
529
                  MgtDelBaHeader delBa;
530
                  p->PeekHeader (delBa);
531
                  if (delBa.IsByOriginator ())
532
                    {
533
                      m_baManager->DestroyAgreement (m_currentHdr.GetAddr1 (), delBa.GetTid ());
534
                    }
535
                  else
536
                    {
537
                      m_low->DestroyBlockAckAgreement (m_currentHdr.GetAddr1 (), delBa.GetTid ());
538
                    }
516
                }
539
                }
517
              else
540
              else if (actionHdr.GetAction ().blockAck == WifiActionHeader::BLOCK_ACK_ADDBA_REQUEST)
518
                {
541
                {
519
                  m_low->DestroyBlockAckAgreement (m_currentHdr.GetAddr1 (), delBa.GetTid ());
542
                  // Setup addba response timeout
543
                  MgtAddBaRequestHeader addBa;
544
                  p->PeekHeader (addBa);
545
                  Simulator::Schedule (m_addBaResponseTimeout,
546
                                       &QosTxop::AddBaResponseTimeout, this,
547
                                       m_currentHdr.GetAddr1 (), addBa.GetTid ());
520
                }
548
                }
521
            }
549
            }
522
        }
550
        }
 Lines 567-577   QosTxop::MissedAck (void) Link Here 
567
        {
595
        {
568
          m_txFailedCallback (m_currentHdr);
596
          m_txFailedCallback (m_currentHdr);
569
        }
597
        }
598
      if (m_currentHdr.IsAction ())
599
        {
600
          WifiActionHeader actionHdr;
601
          m_currentPacket->PeekHeader (actionHdr);
602
          if (actionHdr.GetCategory () == WifiActionHeader::BLOCK_ACK)
603
            {
604
              uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
605
              if (m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), tid, OriginatorBlockAckAgreement::PENDING))
606
                {
607
                  NS_LOG_DEBUG ("No ACK after ADDBA request");
608
                  m_baManager->NotifyAgreementNoReply (m_currentHdr.GetAddr1 (), tid);
609
                  Simulator::Schedule (m_failedAddBaTimeout, &QosTxop::ResetBa, this, m_currentHdr.GetAddr1 (), tid);
610
                }
611
            }
612
        }
570
      if (GetAmpduExist (m_currentHdr.GetAddr1 ()) || m_currentHdr.IsQosData ())
613
      if (GetAmpduExist (m_currentHdr.GetAddr1 ()) || m_currentHdr.IsQosData ())
571
        {
614
        {
572
          uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
615
          uint8_t tid = GetTid (m_currentPacket, m_currentHdr);
573
616
          if (GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), tid))
574
          if (GetBaAgreementExists (m_currentHdr.GetAddr1 (), tid))
575
            {
617
            {
576
              //send Block ACK Request in order to shift WinStart at the receiver
618
              //send Block ACK Request in order to shift WinStart at the receiver
577
              NS_LOG_DEBUG ("Transmit Block Ack Request");
619
              NS_LOG_DEBUG ("Transmit Block Ack Request");
 Lines 955-961   QosTxop::NeedFragmentation (void) const Link Here 
955
      || GetAmpduExist (m_currentHdr.GetAddr1 ())
997
      || GetAmpduExist (m_currentHdr.GetAddr1 ())
956
      || (m_stationManager->GetHtSupported ()
998
      || (m_stationManager->GetHtSupported ()
957
          && m_currentHdr.IsQosData ()
999
          && m_currentHdr.IsQosData ()
958
          && GetBaAgreementExists (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr))
1000
          && GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr))
959
          && GetMpduAggregator ()->GetMaxAmpduSize () >= m_currentPacket->GetSize ()))
1001
          && GetMpduAggregator ()->GetMaxAmpduSize () >= m_currentPacket->GetSize ()))
960
    {
1002
    {
961
      //MSDU is not fragmented when it is transmitted using an HT-immediate or
1003
      //MSDU is not fragmented when it is transmitted using an HT-immediate or
 Lines 1238-1244   QosTxop::GotAddBaResponse (const MgtAddBaResponseHeader *respHdr, Mac48Address r Link Here 
1238
      else
1280
      else
1239
        {
1281
        {
1240
          NS_LOG_DEBUG ("discard ADDBA response" << recipient);
1282
          NS_LOG_DEBUG ("discard ADDBA response" << recipient);
1241
          m_baManager->NotifyAgreementUnsuccessful (recipient, tid);
1283
          m_baManager->NotifyAgreementRejected (recipient, tid);
1242
        }
1284
        }
1243
    }
1285
    }
1244
  RestartAccessIfNeeded ();
1286
  RestartAccessIfNeeded ();
 Lines 1559-1564   QosTxop::BaTxFailed (const WifiMacHeader &hdr) Link Here 
1559
    }
1601
    }
1560
}
1602
}
1561
1603
1604
void
1605
QosTxop::AddBaResponseTimeout (Mac48Address recipient, uint8_t tid)
1606
{
1607
  NS_LOG_FUNCTION (this << recipient << +tid);
1608
  // If agreement is still pending, ADDBA response is not received
1609
  if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::PENDING))
1610
    {
1611
      m_baManager->NotifyAgreementNoReply (recipient, tid);
1612
      Simulator::Schedule (m_failedAddBaTimeout, &QosTxop::ResetBa, this, m_currentHdr.GetAddr1 (), tid);
1613
      m_backoffTrace = m_rng->GetInteger (0, GetCw ());
1614
      StartBackoffNow (m_backoffTrace);
1615
      RestartAccessIfNeeded ();
1616
    }
1617
}
1618
1619
void
1620
QosTxop::ResetBa (Mac48Address recipient, uint8_t tid)
1621
{
1622
  NS_LOG_FUNCTION (this << recipient << +tid);
1623
  NS_ASSERT (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::NO_REPLY));
1624
  m_baManager->NotifyAgreementReset (recipient, tid);
1625
}
1626
1627
void
1628
QosTxop::SetAddBaResponseTimeout (Time addBaResponseTimeout)
1629
{
1630
  NS_LOG_FUNCTION (this << addBaResponseTimeout);
1631
  m_addBaResponseTimeout = addBaResponseTimeout;
1632
}
1633
1634
Time
1635
QosTxop::GetAddBaResponseTimeout (void) const
1636
{
1637
  return m_addBaResponseTimeout;
1638
}
1639
1640
void
1641
QosTxop::SetFailedAddBaTimeout (Time failedAddBaTimeout)
1642
{
1643
  NS_LOG_FUNCTION (this << failedAddBaTimeout);
1644
  m_failedAddBaTimeout = failedAddBaTimeout;
1645
}
1646
1647
Time
1648
QosTxop::GetFailedAddBaTimeout (void) const
1649
{
1650
  return m_failedAddBaTimeout;
1651
}
1652
1562
bool
1653
bool
1563
QosTxop::IsQosTxop (void) const
1654
QosTxop::IsQosTxop (void) const
1564
{
1655
{
(-)a/src/wifi/model/qos-txop.h (-3 / +44 lines)
 Lines 147-158   public: Link Here 
147
   * \param address recipient address of the peer station
147
   * \param address recipient address of the peer station
148
   * \param tid traffic ID.
148
   * \param tid traffic ID.
149
   *
149
   *
150
   * \return true if a block ack agreement exists, false otherwise.
150
   * \return true if a block ack agreement is established, false otherwise.
151
   *
151
   *
152
   * Checks if a block ack agreement exists with station addressed by
152
   * Checks if a block ack agreement is established with station addressed by
153
   * <i>recipient</i> for tid <i>tid</i>.
153
   * <i>recipient</i> for tid <i>tid</i>.
154
   */
154
   */
155
  bool GetBaAgreementExists (Mac48Address address, uint8_t tid) const;
155
  bool GetBaAgreementEstablished (Mac48Address address, uint8_t tid) const;
156
  /**
156
  /**
157
   * \param recipient address of peer station involved in block ack mechanism.
157
   * \param recipient address of peer station involved in block ack mechanism.
158
   * \param tid Ttraffic ID of transmitted packet.
158
   * \param tid Ttraffic ID of transmitted packet.
 Lines 349-354   public: Link Here 
349
   * \param enableAmpdu flag whether A-MPDU is used or not.
349
   * \param enableAmpdu flag whether A-MPDU is used or not.
350
   */
350
   */
351
  void SetAmpduExist (Mac48Address dest, bool enableAmpdu);
351
  void SetAmpduExist (Mac48Address dest, bool enableAmpdu);
352
  /**
353
   * Set the timeout to wait for ADDBA response.
354
   *
355
   * \param addBaResponseTimeout the timeout to wait for ADDBA response
356
   */
357
  void SetAddBaResponseTimeout (Time addBaResponseTimeout);
358
  /**
359
   * Get the timeout for ADDBA response.
360
   *
361
   * \returns the timeout to wait for ADDBA response
362
   */
363
  Time GetAddBaResponseTimeout (void) const;
364
  /**
365
   * Set the timeout for failed BA agreement. During the timeout period,
366
   * all packets will be transmitted using normal MPDU.
367
   *
368
   * \param failedAddBaTimeout the timeout for failed BA agreement
369
   */
370
  void SetFailedAddBaTimeout (Time failedAddBaTimeout);
371
  /**
372
   * Get the timeout for failed BA agreement.
373
   *
374
   * \returns the timeout for failed BA agreement
375
   */
376
  Time GetFailedAddBaTimeout (void) const;
352
377
353
  /**
378
  /**
354
   * Return the next sequence number for the given header.
379
   * Return the next sequence number for the given header.
 Lines 533-538   private: Link Here 
533
   * \returns the TXOP fragment offset
558
   * \returns the TXOP fragment offset
534
   */
559
   */
535
  uint32_t GetTxopFragmentOffset (uint32_t fragmentNumber) const;
560
  uint32_t GetTxopFragmentOffset (uint32_t fragmentNumber) const;
561
  /**
562
   * Callback when ADDBA response is not received after timeout.
563
   *
564
   * \param recipient MAC address of recipient
565
   * \param tid traffic ID
566
   */
567
  void AddBaResponseTimeout (Mac48Address recipient, uint8_t tid);
568
  /**
569
   * Reset BA agreement after BA negotiation failed.
570
   *
571
   * \param recipient MAC address of recipient
572
   * \param tid traffic ID
573
   */
574
  void ResetBa (Mac48Address recipient, uint8_t tid);
536
575
537
  void DoDispose (void);
576
  void DoDispose (void);
538
  void DoInitialize (void);
577
  void DoInitialize (void);
 Lines 551-556   private: Link Here 
551
  Time m_startTxop;                                 //!< the start TXOP time
590
  Time m_startTxop;                                 //!< the start TXOP time
552
  bool m_isAccessRequestedForRts;                   //!< flag whether access is requested to transmit a RTS frame
591
  bool m_isAccessRequestedForRts;                   //!< flag whether access is requested to transmit a RTS frame
553
  bool m_currentIsFragmented;                       //!< flag whether current packet is fragmented
592
  bool m_currentIsFragmented;                       //!< flag whether current packet is fragmented
593
  Time m_addBaResponseTimeout;                      //!< timeout for ADDBA response
594
  Time m_failedAddBaTimeout;                        //!< timeout after failed BA agreement
554
595
555
  TracedValue<uint32_t> m_backoffTrace;   //!< backoff trace value
596
  TracedValue<uint32_t> m_backoffTrace;   //!< backoff trace value
556
  TracedValue<uint32_t> m_cwTrace;        //!< CW trace value
597
  TracedValue<uint32_t> m_cwTrace;        //!< CW trace value
(-)a/src/wifi/model/wifi-phy.cc (-1 / +25 lines)
 Lines 24-29    Link Here 
24
#include "ns3/pointer.h"
24
#include "ns3/pointer.h"
25
#include "ns3/mobility-model.h"
25
#include "ns3/mobility-model.h"
26
#include "ns3/random-variable-stream.h"
26
#include "ns3/random-variable-stream.h"
27
#include "ns3/error-model.h"
27
#include "wifi-phy.h"
28
#include "wifi-phy.h"
28
#include "wifi-phy-tag.h"
29
#include "wifi-phy-tag.h"
29
#include "ampdu-tag.h"
30
#include "ampdu-tag.h"
 Lines 298-303   WifiPhy::GetTypeId (void) Link Here 
298
                   PointerValue (),
299
                   PointerValue (),
299
                   MakePointerAccessor (&WifiPhy::m_frameCaptureModel),
300
                   MakePointerAccessor (&WifiPhy::m_frameCaptureModel),
300
                   MakePointerChecker <FrameCaptureModel> ())
301
                   MakePointerChecker <FrameCaptureModel> ())
302
    .AddAttribute ("PostReceptionErrorModel",
303
                   "An optional packet error model can be added to the receive "
304
                   "packet process after any propagation-based (SNR-based) error "
305
                   "models have been applied. Typically this is used to force "
306
                   "specific packet drops, for testing purposes.",
307
                   PointerValue (),
308
                   MakePointerAccessor (&WifiPhy::m_postReceptionErrorModel),
309
                   MakePointerChecker<ErrorModel> ())
301
    .AddTraceSource ("PhyTxBegin",
310
    .AddTraceSource ("PhyTxBegin",
302
                     "Trace source indicating a packet "
311
                     "Trace source indicating a packet "
303
                     "has begun transmitting over the channel medium",
312
                     "has begun transmitting over the channel medium",
 Lines 387-392   WifiPhy::DoDispose (void) Link Here 
387
  m_mobility = 0;
396
  m_mobility = 0;
388
  m_state = 0;
397
  m_state = 0;
389
  m_wifiRadioEnergyModel = 0;
398
  m_wifiRadioEnergyModel = 0;
399
  m_postReceptionErrorModel = 0;
390
  m_deviceRateSet.clear ();
400
  m_deviceRateSet.clear ();
391
  m_deviceMcsSet.clear ();
401
  m_deviceMcsSet.clear ();
392
}
402
}
 Lines 719-724   WifiPhy::SetErrorRateModel (const Ptr<ErrorRateModel> rate) Link Here 
719
}
729
}
720
730
721
void
731
void
732
WifiPhy::SetPostReceptionErrorModel (const Ptr<ErrorModel> em)
733
{
734
  NS_LOG_FUNCTION (this << em);
735
  m_postReceptionErrorModel = em;
736
}
737
738
void
722
WifiPhy::SetFrameCaptureModel (const Ptr<FrameCaptureModel> model)
739
WifiPhy::SetFrameCaptureModel (const Ptr<FrameCaptureModel> model)
723
{
740
{
724
  m_frameCaptureModel = model;
741
  m_frameCaptureModel = model;
 Lines 2588-2594   WifiPhy::EndReceive (Ptr<Packet> packet, WifiPreamble preamble, MpduType mpdutyp Link Here 
2588
      NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate (event->GetTxVector ())) <<
2605
      NS_LOG_DEBUG ("mode=" << (event->GetPayloadMode ().GetDataRate (event->GetTxVector ())) <<
2589
                    ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
2606
                    ", snr(dB)=" << RatioToDb (snrPer.snr) << ", per=" << snrPer.per << ", size=" << packet->GetSize ());
2590
2607
2591
      if (m_random->GetValue () > snrPer.per)
2608
      //
2609
      // There are two error checks: PER and receive error model check.
2610
      // PER check models is typical for Wi-Fi and is based on signal modulation;
2611
      // Receive error model is optional, if we have an error model and
2612
      // it indicates that the packet is corrupt, drop the packet.
2613
      //
2614
      if (m_random->GetValue () > snrPer.per &&
2615
          !(m_postReceptionErrorModel && m_postReceptionErrorModel->IsCorrupt (packet)))
2592
        {
2616
        {
2593
          NotifyRxEnd (packet);
2617
          NotifyRxEnd (packet);
2594
          SignalNoiseDbm signalNoise;
2618
          SignalNoiseDbm signalNoise;
(-)a/src/wifi/model/wifi-phy.h (+14 lines)
 Lines 41-46   class WifiPhyStateHelper; Link Here 
41
class FrameCaptureModel;
41
class FrameCaptureModel;
42
class WifiRadioEnergyModel;
42
class WifiRadioEnergyModel;
43
class UniformRandomVariable;
43
class UniformRandomVariable;
44
class ErrorModel;
44
45
45
/// SignalNoiseDbm structure
46
/// SignalNoiseDbm structure
46
struct SignalNoiseDbm
47
struct SignalNoiseDbm
 Lines 1410-1415   public: Link Here 
1410
   */
1411
   */
1411
  void SetErrorRateModel (const Ptr<ErrorRateModel> rate);
1412
  void SetErrorRateModel (const Ptr<ErrorRateModel> rate);
1412
  /**
1413
  /**
1414
   * Attach a receive ErrorModel to the WifiPhy.
1415
   *
1416
   * The WifiPhy may optionally include an ErrorModel in
1417
   * the packet receive chain. The error model is additive
1418
   * to any modulation-based error model based on SNR, and
1419
   * is typically used to force specific packet losses or
1420
   * for testing purposes.
1421
   *
1422
   * \param em Ptr to the ErrorModel.
1423
   */
1424
  void SetPostReceptionErrorModel (const Ptr<ErrorModel> em);
1425
  /**
1413
   * Sets the frame capture model.
1426
   * Sets the frame capture model.
1414
   *
1427
   *
1415
   * \param frameCaptureModel the frame capture model
1428
   * \param frameCaptureModel the frame capture model
 Lines 1777-1782   private: Link Here 
1777
  Ptr<Event> m_currentEvent; //!< Hold the current event
1790
  Ptr<Event> m_currentEvent; //!< Hold the current event
1778
  Ptr<FrameCaptureModel> m_frameCaptureModel; //!< Frame capture model
1791
  Ptr<FrameCaptureModel> m_frameCaptureModel; //!< Frame capture model
1779
  Ptr<WifiRadioEnergyModel> m_wifiRadioEnergyModel; //!< Wifi radio energy model
1792
  Ptr<WifiRadioEnergyModel> m_wifiRadioEnergyModel; //!< Wifi radio energy model
1793
  Ptr<ErrorModel> m_postReceptionErrorModel; //!< Error model for receive packet events
1780
1794
1781
  Callback<void> m_capabilitiesChangedCallback; //!< Callback when PHY capabilities changed
1795
  Callback<void> m_capabilitiesChangedCallback; //!< Callback when PHY capabilities changed
1782
};
1796
};
(-)a/src/wifi/test/wifi-aggregation-test.cc (+1 lines)
 Lines 128-133   AmpduAggregationTest::DoRun (void) Link Here 
128
  reqHdr.SetTimeout (0);
128
  reqHdr.SetTimeout (0);
129
  reqHdr.SetStartingSequence (0);
129
  reqHdr.SetStartingSequence (0);
130
  m_mac->GetBEQueue ()->m_baManager->CreateAgreement (&reqHdr, hdr.GetAddr1 ());
130
  m_mac->GetBEQueue ()->m_baManager->CreateAgreement (&reqHdr, hdr.GetAddr1 ());
131
  m_mac->GetBEQueue ()->m_baManager->NotifyAgreementEstablished (hdr.GetAddr1 (), 0, 0);
131
132
132
  //-----------------------------------------------------------------------------------------------------
133
  //-----------------------------------------------------------------------------------------------------
133
134
(-)a/src/wifi/test/wifi-test.cc (-4 / +226 lines)
 Lines 34-39    Link Here 
34
#include "ns3/pointer.h"
34
#include "ns3/pointer.h"
35
#include "ns3/rng-seed-manager.h"
35
#include "ns3/rng-seed-manager.h"
36
#include "ns3/config.h"
36
#include "ns3/config.h"
37
#include "ns3/error-model.h"
37
#include "ns3/packet-socket-server.h"
38
#include "ns3/packet-socket-server.h"
38
#include "ns3/packet-socket-client.h"
39
#include "ns3/packet-socket-client.h"
39
#include "ns3/packet-socket-helper.h"
40
#include "ns3/packet-socket-helper.h"
 Lines 1268-1276   Bug2483TestCase::SendPacketBurst (uint8_t numPackets, Ptr<NetDevice> sourceDevic Link Here 
1268
void
1269
void
1269
Bug2483TestCase::DoRun (void)
1270
Bug2483TestCase::DoRun (void)
1270
{
1271
{
1271
  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("500")); // so as to force RTS/CTS for data frames
1272
  Config::SetDefault ("ns3::WifiPhy::CcaMode1Threshold", DoubleValue (-62.0));
1273
1274
  uint16_t channelWidth = 40; // at least 40 MHz expected here
1272
  uint16_t channelWidth = 40; // at least 40 MHz expected here
1275
1273
1276
  NodeContainer wifiStaNode;
1274
  NodeContainer wifiStaNode;
 Lines 1295-1306   Bug2483TestCase::DoRun (void) Link Here 
1295
  spectrumPhy.Set ("ChannelWidth", UintegerValue (channelWidth));
1293
  spectrumPhy.Set ("ChannelWidth", UintegerValue (channelWidth));
1296
  spectrumPhy.Set ("TxPowerStart", DoubleValue (10));
1294
  spectrumPhy.Set ("TxPowerStart", DoubleValue (10));
1297
  spectrumPhy.Set ("TxPowerEnd", DoubleValue (10));
1295
  spectrumPhy.Set ("TxPowerEnd", DoubleValue (10));
1296
  spectrumPhy.Set ("CcaMode1Threshold", DoubleValue (-62.0));
1298
1297
1299
  WifiHelper wifi;
1298
  WifiHelper wifi;
1300
  wifi.SetStandard (WIFI_PHY_STANDARD_80211ac);
1299
  wifi.SetStandard (WIFI_PHY_STANDARD_80211ac);
1301
  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
1300
  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
1302
                                "DataMode", StringValue ("VhtMcs8"),
1301
                                "DataMode", StringValue ("VhtMcs8"),
1303
                                "ControlMode", StringValue ("VhtMcs8"));
1302
                                "ControlMode", StringValue ("VhtMcs8"),
1303
                                "RtsCtsThreshold", StringValue ("500")); // so as to force RTS/CTS for data frames
1304
1304
1305
  WifiMacHelper mac;
1305
  WifiMacHelper mac;
1306
  mac.SetType ("ns3::StaWifiMac");
1306
  mac.SetType ("ns3::StaWifiMac");
 Lines 1700-1705   StaWifiMacScanningTestCase::DoRun (void) Link Here 
1700
  }
1700
  }
1701
}
1701
}
1702
1702
1703
//-----------------------------------------------------------------------------
1704
/**
1705
 * Make sure that the ADDBA handshake process is protected.
1706
 *
1707
 * The scenario considers an access point and a station. It utilizes
1708
 * ReceiveListErrorModel to drop by force ADDBA request on STA or ADDBA
1709
 * response on AP. The AP sends 5 packets of each 1000 bytes (thus generating
1710
 * BA agreement), 2 times during the test at 0.5s and 0.8s. We only drop the
1711
 * first ADDBA request/response of the first BA negotiation. Therefore, we
1712
 * expect that the packets still in queue after the failed BA agreement will be
1713
 * sent with normal MPDU, and packets queued after that should be sent with
1714
 * A-MPDU.
1715
 *
1716
 * This test consider 2 cases:
1717
 *
1718
 *   1. ADDBA request packets are blocked on receive at STA, triggering
1719
 *      transmission failure at AP
1720
 *   2. ADDBA response packets are blocked on receive at AP, STA stops
1721
 *      retransmission of ADDBA response
1722
 *
1723
 * See \bugid{2470}
1724
 */
1725
1726
class Bug2470TestCase : public TestCase
1727
{
1728
public:
1729
  Bug2470TestCase ();
1730
  virtual ~Bug2470TestCase ();
1731
  virtual void DoRun (void);
1732
1733
private:
1734
  /**
1735
   * Callback when packet is received
1736
   * \param context node context
1737
   * \param p the received packet
1738
   * \param channelFreqMhz the channel frequency in MHz
1739
   * \param txVector the TX vector
1740
   * \param aMpdu the A-MPDU info
1741
   * \param signalNoise the signal noise in dBm
1742
   */
1743
  void RxCallback (std::string context, Ptr<const Packet> p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise);
1744
  /**
1745
   * Callback when packet is dropped
1746
   * \param context node context
1747
   * \param p the received packet
1748
   */
1749
  void RxDropCallback (std::string context, Ptr<const Packet> p);
1750
  /**
1751
   * Triggers the arrival of a burst of 1000 Byte-long packets in the source device
1752
   * \param numPackets number of packets in burst
1753
   * \param sourceDevice pointer to the source NetDevice
1754
   * \param destination address of the destination device
1755
   */
1756
  void SendPacketBurst (uint32_t numPackets, Ptr<NetDevice> sourceDevice, Address& destination) const;
1757
  /**
1758
   * Run subtest for this test suite
1759
   * \param apErrorModel ErrorModel used for AP
1760
   * \param staErrorModel ErrorModel used for STA
1761
   */
1762
  void RunSubtest (PointerValue apErrorModel, PointerValue staErrorModel);
1763
1764
  uint8_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA
1765
  uint8_t m_receivedAmpduCount;      ///< Count received A-MPDU packets on STA
1766
  uint8_t m_droppedActionCount;      ///< Count dropped ADDBA request/response
1767
};
1768
1769
Bug2470TestCase::Bug2470TestCase ()
1770
  : TestCase ("Test case for Bug 2470"),
1771
    m_receivedNormalMpduCount (0),
1772
    m_receivedAmpduCount (0),
1773
    m_droppedActionCount (0)
1774
{
1775
}
1776
1777
Bug2470TestCase::~Bug2470TestCase ()
1778
{
1779
}
1780
1781
void
1782
Bug2470TestCase::RxCallback (std::string context, Ptr<const Packet> p, uint16_t channelFreqMhz, WifiTxVector txVector, MpduInfo aMpdu, SignalNoiseDbm signalNoise)
1783
{
1784
  Ptr<Packet> packet = p->Copy ();
1785
  if (aMpdu.type != MpduType::NORMAL_MPDU)
1786
    {
1787
      m_receivedAmpduCount++;
1788
    }
1789
  else
1790
    {
1791
      WifiMacHeader hdr;
1792
      packet->RemoveHeader (hdr);
1793
      if (hdr.IsData ())
1794
        {
1795
          m_receivedNormalMpduCount++;
1796
        }
1797
    }
1798
}
1799
1800
void
1801
Bug2470TestCase::RxDropCallback (std::string context, Ptr<const Packet> p)
1802
{
1803
  Ptr<Packet> packet = p->Copy ();
1804
  WifiMacHeader hdr;
1805
  packet->RemoveHeader (hdr);
1806
  if (hdr.IsAction ())
1807
    {
1808
      m_droppedActionCount++;
1809
    }
1810
}
1811
1812
void
1813
Bug2470TestCase::SendPacketBurst (uint32_t numPackets, Ptr<NetDevice> sourceDevice,
1814
                                  Address& destination) const
1815
{
1816
  for (uint32_t i = 0; i < numPackets; i++)
1817
    {
1818
      Ptr<Packet> pkt = Create<Packet> (1000); // 1000 dummy bytes of data
1819
      sourceDevice->Send (pkt, destination, 0);
1820
    }
1821
}
1822
1823
void
1824
Bug2470TestCase::RunSubtest (PointerValue apErrorModel, PointerValue staErrorModel)
1825
{
1826
  RngSeedManager::SetSeed (1);
1827
  RngSeedManager::SetRun (1);
1828
1829
  NodeContainer wifiApNode, wifiStaNode;
1830
  wifiApNode.Create (1);
1831
  wifiStaNode.Create (1);
1832
1833
  YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
1834
  YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
1835
  phy.SetChannel (channel.Create ());
1836
1837
  WifiHelper wifi;
1838
  wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
1839
  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
1840
                                "DataMode", StringValue ("HtMcs7"),
1841
                                "ControlMode", StringValue ("HtMcs7"));
1842
1843
  WifiMacHelper mac;
1844
  NetDeviceContainer apDevice;
1845
  phy.Set ("PostReceptionErrorModel", apErrorModel);
1846
  mac.SetType ("ns3::ApWifiMac", "EnableBeaconJitter", BooleanValue (false));
1847
  apDevice = wifi.Install (phy, mac, wifiApNode);
1848
1849
  NetDeviceContainer staDevice;
1850
  phy.Set ("PostReceptionErrorModel", staErrorModel);
1851
  mac.SetType ("ns3::StaWifiMac");
1852
  staDevice = wifi.Install (phy, mac, wifiStaNode);
1853
1854
  MobilityHelper mobility;
1855
  Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
1856
  positionAlloc->Add (Vector (0.0, 0.0, 0.0));
1857
  positionAlloc->Add (Vector (1.0, 0.0, 0.0));
1858
  mobility.SetPositionAllocator (positionAlloc);
1859
1860
  mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
1861
  mobility.Install (wifiApNode);
1862
  mobility.Install (wifiStaNode);
1863
1864
  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/MonitorSnifferRx", MakeCallback (&Bug2470TestCase::RxCallback, this));
1865
  Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxDrop", MakeCallback (&Bug2470TestCase::RxDropCallback, this));
1866
1867
  Simulator::Schedule (Seconds (0.5), &Bug2470TestCase::SendPacketBurst, this, 5, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
1868
  Simulator::Schedule (Seconds (0.8), &Bug2470TestCase::SendPacketBurst, this, 5, apDevice.Get (0), staDevice.Get (0)->GetAddress ());
1869
1870
  Simulator::Stop (Seconds (1.0));
1871
  Simulator::Run ();
1872
  Simulator::Destroy ();
1873
}
1874
1875
void
1876
Bug2470TestCase::DoRun (void)
1877
{
1878
  // Create ReceiveListErrorModel to corrupt ADDBA req packet. We use ReceiveListErrorModel
1879
  // instead of ListErrorModel since packet UID is incremented between simulations. But
1880
  // problem may occur because of random stream, therefore we suppress usage of RNG as
1881
  // much as possible (i.e., removing beacon jitter).
1882
  Ptr<ReceiveListErrorModel> staPem = CreateObject<ReceiveListErrorModel> ();
1883
  std::list<uint32_t> blackList;
1884
  // Block ADDBA request 6 times (== maximum number of MAC frame transmissions in the addba response timeout interval)
1885
  blackList.push_back (8);
1886
  blackList.push_back (9);
1887
  blackList.push_back (10);
1888
  blackList.push_back (11);
1889
  blackList.push_back (12);
1890
  blackList.push_back (13);
1891
  staPem->SetList (blackList);
1892
1893
  {
1894
    RunSubtest (PointerValue (), PointerValue (staPem));
1895
    NS_TEST_ASSERT_MSG_EQ (m_droppedActionCount, 6, "ADDBA request packet is not dropped correctly");
1896
    // There are two sets of 5 packets to be transmitted. The first 5 packets should be sent by normal
1897
    // MPDU because of failed ADDBA handshake. For the second set, the first packet should be sent by
1898
    // normal MPDU, and the rest with A-MPDU. In total we expect to receive 2 normal MPDU packets and
1899
    // 8 A-MPDU packets.
1900
    NS_TEST_ASSERT_MSG_EQ (m_receivedNormalMpduCount, 2, "Receiving incorrect number of normal MPDU packet on subtest 1");
1901
    NS_TEST_ASSERT_MSG_EQ (m_receivedAmpduCount, 8, "Receiving incorrect number of A-MPDU packet on subtest 1");
1902
  }
1903
1904
  m_receivedNormalMpduCount = 0;
1905
  m_receivedAmpduCount = 0;
1906
  m_droppedActionCount = 0;
1907
  Ptr<ReceiveListErrorModel> apPem = CreateObject<ReceiveListErrorModel> ();
1908
  blackList.clear ();
1909
  // Block ADDBA request 3 times (== maximum number of MAC frame transmissions in the addba response timeout interval)
1910
  blackList.push_back (4);
1911
  blackList.push_back (5);
1912
  blackList.push_back (6);
1913
  apPem->SetList (blackList);
1914
1915
  {
1916
    RunSubtest (PointerValue (apPem), PointerValue ());
1917
    NS_TEST_ASSERT_MSG_EQ (m_droppedActionCount, 3, "ADDBA response packet is not dropped correctly");
1918
    // Similar to subtest 1, we also expect to receive 6 normal MPDU packets and 4 A-MPDU packets.
1919
    NS_TEST_ASSERT_MSG_EQ (m_receivedNormalMpduCount, 6, "Receiving incorrect number of normal MPDU packet on subtest 2");
1920
    NS_TEST_ASSERT_MSG_EQ (m_receivedAmpduCount, 4, "Receiving incorrect number of A-MPDU packet on subtest 2");
1921
  }
1922
}
1923
1703
/**
1924
/**
1704
 * \ingroup wifi-test
1925
 * \ingroup wifi-test
1705
 * \ingroup tests
1926
 * \ingroup tests
 Lines 1725-1730   WifiTestSuite::WifiTestSuite () Link Here 
1725
  AddTestCase (new Bug2483TestCase, TestCase::QUICK); //Bug 2483
1946
  AddTestCase (new Bug2483TestCase, TestCase::QUICK); //Bug 2483
1726
  AddTestCase (new Bug2831TestCase, TestCase::QUICK); //Bug 2831
1947
  AddTestCase (new Bug2831TestCase, TestCase::QUICK); //Bug 2831
1727
  AddTestCase (new StaWifiMacScanningTestCase, TestCase::QUICK); //Bug 2399
1948
  AddTestCase (new StaWifiMacScanningTestCase, TestCase::QUICK); //Bug 2399
1949
  AddTestCase (new Bug2470TestCase, TestCase::QUICK); //Bug 2470
1728
}
1950
}
1729
1951
1730
static WifiTestSuite g_wifiTestSuite; ///< the test suite
1952
static WifiTestSuite g_wifiTestSuite; ///< the test suite

Return to bug 2470