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

(-)a/RELEASE_NOTES (+1 lines)
 Lines 80-85   New user-visible features Link Here 
80
  This trace is fired whenever a new path loss value is calculated. It exports pointers
80
  This trace is fired whenever a new path loss value is calculated. It exports pointers
81
  to the mobility model of the transmitter and the receiver, Tx antenna gain, Rx antenna gain,
81
  to the mobility model of the transmitter and the receiver, Tx antenna gain, Rx antenna gain,
82
  propagation gain and the pathloss value.
82
  propagation gain and the pathloss value.
83
- (wifi) It is now possible to transmit A-MPDUs containing up to 256 MPDUs (802.11ax only)
83
84
84
Bugs fixed
85
Bugs fixed
85
----------
86
----------
(-)a/src/network/utils/queue.cc (-1 / +1 lines)
 Lines 37-43   QueueBase::GetTypeId (void) Link Here 
37
    .SetGroupName ("Network")
37
    .SetGroupName ("Network")
38
    .AddAttribute ("MaxSize",
38
    .AddAttribute ("MaxSize",
39
                   "The max queue size",
39
                   "The max queue size",
40
                   QueueSizeValue (QueueSize ("100p")),
40
                   QueueSizeValue (QueueSize ("300p")),
41
                   MakeQueueSizeAccessor (&QueueBase::SetMaxSize,
41
                   MakeQueueSizeAccessor (&QueueBase::SetMaxSize,
42
                                          &QueueBase::GetMaxSize),
42
                                          &QueueBase::GetMaxSize),
43
                   MakeQueueSizeChecker ())
43
                   MakeQueueSizeChecker ())
(-)a/src/wifi/doc/source/wifi-user.rst (+7 lines)
 Lines 790-795   attributes for 802.11ax devices. Link Here 
790
 Ptr<HeConfiguration> heConfiguration = wnd->GetHeConfiguration ();
790
 Ptr<HeConfiguration> heConfiguration = wnd->GetHeConfiguration ();
791
 heConfiguration->SetGuardInterval (NanoSeconds (1600));
791
 heConfiguration->SetGuardInterval (NanoSeconds (1600));
792
792
793
 802.11ax allows extended compressed Block ACKs containing a 256-bits bitmap, making possible transmissions of A-MPDUs containing up to 256 MPDUs,
794
 depending on the negotiated buffer size. In order to configure the buffer size of an 802.11ax device, the following line of code could be used::
795
796
 heConfiguration->SetMpduBufferSize (256);
797
798
 For transmitting large MPDUs, it might also be needed to increase the maximum aggregation size (see above).
799
793
Mobility configuration
800
Mobility configuration
794
======================
801
======================
795
802
(-)a/src/wifi/model/ampdu-tag.cc (-1 lines)
 Lines 51-57   AmpduTag::AmpduTag () Link Here 
51
void
51
void
52
AmpduTag::SetRemainingNbOfMpdus (uint8_t nbofmpdus)
52
AmpduTag::SetRemainingNbOfMpdus (uint8_t nbofmpdus)
53
{
53
{
54
  NS_ASSERT (nbofmpdus <= 64);
55
  m_nbOfMpdus = nbofmpdus;
54
  m_nbOfMpdus = nbofmpdus;
56
}
55
}
57
56
(-)a/src/wifi/model/block-ack-agreement.cc (-12 / +4 lines)
 Lines 26-39   namespace ns3 { Link Here 
26
NS_LOG_COMPONENT_DEFINE ("BlockAckAgreement");
26
NS_LOG_COMPONENT_DEFINE ("BlockAckAgreement");
27
27
28
BlockAckAgreement::BlockAckAgreement (Mac48Address peer, uint8_t tid)
28
BlockAckAgreement::BlockAckAgreement (Mac48Address peer, uint8_t tid)
29
  : m_amsduSupported (0),
29
  : m_peer (peer),
30
    m_amsduSupported (0),
30
    m_blockAckPolicy (1),
31
    m_blockAckPolicy (1),
32
    m_tid (tid),
31
    m_htSupported (0),
33
    m_htSupported (0),
32
    m_inactivityEvent ()
34
    m_inactivityEvent ()
33
{
35
{
34
  NS_LOG_FUNCTION (this << peer << +tid);
36
  NS_LOG_FUNCTION (this << peer << +tid);
35
  m_tid = tid;
36
  m_peer = peer;
37
}
37
}
38
38
39
BlockAckAgreement::~BlockAckAgreement ()
39
BlockAckAgreement::~BlockAckAgreement ()
 Lines 46-52   void Link Here 
46
BlockAckAgreement::SetBufferSize (uint16_t bufferSize)
46
BlockAckAgreement::SetBufferSize (uint16_t bufferSize)
47
{
47
{
48
  NS_LOG_FUNCTION (this << bufferSize);
48
  NS_LOG_FUNCTION (this << bufferSize);
49
  NS_ASSERT (bufferSize <= 1024);
49
  NS_ASSERT (bufferSize <= 256);
50
  NS_ASSERT (bufferSize % 16 == 0);
50
  NS_ASSERT (bufferSize % 16 == 0);
51
  m_bufferSize = bufferSize;
51
  m_bufferSize = bufferSize;
52
}
52
}
 Lines 98-104   BlockAckAgreement::SetAmsduSupport (bool supported) Link Here 
98
uint8_t
98
uint8_t
99
BlockAckAgreement::GetTid (void) const
99
BlockAckAgreement::GetTid (void) const
100
{
100
{
101
  NS_LOG_FUNCTION (this);
102
  return m_tid;
101
  return m_tid;
103
}
102
}
104
103
 Lines 112-139   BlockAckAgreement::GetPeer (void) const Link Here 
112
uint16_t
111
uint16_t
113
BlockAckAgreement::GetBufferSize (void) const
112
BlockAckAgreement::GetBufferSize (void) const
114
{
113
{
115
  NS_LOG_FUNCTION (this);
116
  return m_bufferSize;
114
  return m_bufferSize;
117
}
115
}
118
116
119
uint16_t
117
uint16_t
120
BlockAckAgreement::GetTimeout (void) const
118
BlockAckAgreement::GetTimeout (void) const
121
{
119
{
122
  NS_LOG_FUNCTION (this);
123
  return m_timeout;
120
  return m_timeout;
124
}
121
}
125
122
126
uint16_t
123
uint16_t
127
BlockAckAgreement::GetStartingSequence (void) const
124
BlockAckAgreement::GetStartingSequence (void) const
128
{
125
{
129
  NS_LOG_FUNCTION (this);
130
  return m_startingSeq;
126
  return m_startingSeq;
131
}
127
}
132
128
133
uint16_t
129
uint16_t
134
BlockAckAgreement::GetStartingSequenceControl (void) const
130
BlockAckAgreement::GetStartingSequenceControl (void) const
135
{
131
{
136
  NS_LOG_FUNCTION (this);
137
  uint16_t seqControl = (m_startingSeq << 4) & 0xfff0;
132
  uint16_t seqControl = (m_startingSeq << 4) & 0xfff0;
138
  return seqControl;
133
  return seqControl;
139
}
134
}
 Lines 141-154   BlockAckAgreement::GetStartingSequenceControl (void) const Link Here 
141
bool
136
bool
142
BlockAckAgreement::IsImmediateBlockAck (void) const
137
BlockAckAgreement::IsImmediateBlockAck (void) const
143
{
138
{
144
  NS_LOG_FUNCTION (this);
145
  return (m_blockAckPolicy == 1);
139
  return (m_blockAckPolicy == 1);
146
}
140
}
147
141
148
bool
142
bool
149
BlockAckAgreement::IsAmsduSupported (void) const
143
BlockAckAgreement::IsAmsduSupported (void) const
150
{
144
{
151
  NS_LOG_FUNCTION (this);
152
  return (m_amsduSupported == 1) ? true : false;
145
  return (m_amsduSupported == 1) ? true : false;
153
}
146
}
154
147
 Lines 174-180   BlockAckAgreement::SetHtSupported (bool htSupported) Link Here 
174
bool
167
bool
175
BlockAckAgreement::IsHtSupported (void) const
168
BlockAckAgreement::IsHtSupported (void) const
176
{
169
{
177
  NS_LOG_FUNCTION (this);
178
  return (m_htSupported == 1) ? true : false;
170
  return (m_htSupported == 1) ? true : false;
179
}
171
}
180
172
(-)a/src/wifi/model/block-ack-cache.cc (-2 / +2 lines)
 Lines 36-42   BlockAckCache::Init (uint16_t winStart, uint16_t winSize) Link Here 
36
{
36
{
37
  NS_LOG_FUNCTION (this << winStart << winSize);
37
  NS_LOG_FUNCTION (this << winStart << winSize);
38
  m_winStart = winStart;
38
  m_winStart = winStart;
39
  m_winSize = winSize <= 64 ? winSize : 64;
39
  m_winSize = winSize;
40
  m_winEnd = (m_winStart + m_winSize - 1) % 4096;
40
  m_winEnd = (m_winStart + m_winSize - 1) % 4096;
41
  memset (m_bitmap, 0, sizeof (m_bitmap));
41
  memset (m_bitmap, 0, sizeof (m_bitmap));
42
}
42
}
 Lines 119-125   BlockAckCache::FillBlockAckBitmap (CtrlBAckResponseHeader *blockAckHeader) Link Here 
119
    {
119
    {
120
      NS_FATAL_ERROR ("Basic block ack is only partially implemented.");
120
      NS_FATAL_ERROR ("Basic block ack is only partially implemented.");
121
    }
121
    }
122
  else if (blockAckHeader->IsCompressed ())
122
  else if (blockAckHeader->IsCompressed () || blockAckHeader->IsExtendedCompressed ())
123
    {
123
    {
124
      uint16_t i = blockAckHeader->GetStartingSequence ();
124
      uint16_t i = blockAckHeader->GetStartingSequence ();
125
      uint16_t end = (i + m_winSize - 1) % 4096;
125
      uint16_t end = (i + m_winSize - 1) % 4096;
(-)a/src/wifi/model/block-ack-manager.cc (-16 / +18 lines)
 Lines 122-128   BlockAckManager::CreateAgreement (const MgtAddBaRequestHeader *reqHdr, Mac48Addr Link Here 
122
  agreement.SetStartingSequence (reqHdr->GetStartingSequence ());
122
  agreement.SetStartingSequence (reqHdr->GetStartingSequence ());
123
  /* For now we assume that originator doesn't use this field. Use of this field
123
  /* For now we assume that originator doesn't use this field. Use of this field
124
     is mandatory only for recipient */
124
     is mandatory only for recipient */
125
  agreement.SetBufferSize (64);
125
  agreement.SetBufferSize (reqHdr->GetBufferSize());
126
  agreement.SetWinEnd ((agreement.GetStartingSequence () + agreement.GetBufferSize () - 1) % 4096);
126
  agreement.SetWinEnd ((agreement.GetStartingSequence () + agreement.GetBufferSize () - 1) % 4096);
127
  agreement.SetTimeout (reqHdr->GetTimeout ());
127
  agreement.SetTimeout (reqHdr->GetTimeout ());
128
  agreement.SetAmsduSupport (reqHdr->IsAmsduSupported ());
128
  agreement.SetAmsduSupport (reqHdr->IsAmsduSupported ());
 Lines 588-594   BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4 Link Here 
588
                    }
588
                    }
589
                }
589
                }
590
            }
590
            }
591
          else if (blockAck->IsCompressed ())
591
          else if (blockAck->IsCompressed () || blockAck->IsExtendedCompressed ())
592
            {
592
            {
593
              for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; )
593
              for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; )
594
                {
594
                {
 Lines 671-690   BlockAckManager::ScheduleBlockAckReqIfNeeded (Mac48Address recipient, uint8_t ti Link Here 
671
      agreement.CompleteExchange ();
671
      agreement.CompleteExchange ();
672
672
673
      CtrlBAckRequestHeader reqHdr;
673
      CtrlBAckRequestHeader reqHdr;
674
      if (m_blockAckType == BASIC_BLOCK_ACK || m_blockAckType == COMPRESSED_BLOCK_ACK)
674
      reqHdr.SetType (m_blockAckType);
675
        {
675
      reqHdr.SetTidInfo (agreement.GetTid ());
676
          reqHdr.SetType (m_blockAckType);
676
      reqHdr.SetStartingSequence (agreement.GetStartingSequence ());
677
          reqHdr.SetTidInfo (agreement.GetTid ());
677
678
          reqHdr.SetStartingSequence (agreement.GetStartingSequence ());
679
        }
680
      else if (m_blockAckType == MULTI_TID_BLOCK_ACK)
681
        {
682
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
683
        }
684
      else
685
        {
686
          NS_FATAL_ERROR ("Invalid block ack type.");
687
        }
688
      Ptr<Packet> bar = Create<Packet> ();
678
      Ptr<Packet> bar = Create<Packet> ();
689
      bar->AddHeader (reqHdr);
679
      bar->AddHeader (reqHdr);
690
      return bar;
680
      return bar;
 Lines 951-954   BlockAckManager::InsertInRetryQueue (PacketQueueI item) Link Here 
951
    }
941
    }
952
}
942
}
953
943
944
uint16_t
945
BlockAckManager::GetRecipientBufferSize (Mac48Address recipient, uint8_t tid) const
946
{
947
  uint16_t size = 0;
948
  AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid));
949
  if (it != m_agreements.end ())
950
    {
951
      size = it->second.first.GetBufferSize ();
952
    }
953
  return size;
954
}
955
954
} //namespace ns3
956
} //namespace ns3
(-)a/src/wifi/model/block-ack-manager.h (+9 lines)
 Lines 361-366   public: Link Here 
361
   * \returns true if BAR retransmission needed
361
   * \returns true if BAR retransmission needed
362
   */
362
   */
363
  bool NeedBarRetransmission (uint8_t tid, uint16_t seqNumber, Mac48Address recipient);
363
  bool NeedBarRetransmission (uint8_t tid, uint16_t seqNumber, Mac48Address recipient);
364
  /**
365
   * This function returns the buffer size negociated with the recipient.
366
   *
367
   * \param tid Traffic ID
368
   * \param recipient MAC address
369
   *
370
   * \returns the buffer size negociated with the recipient
371
   */
372
  uint16_t GetRecipientBufferSize (Mac48Address recipient, uint8_t tid) const;
364
373
365
  /**
374
  /**
366
   * typedef for a callback to invoke when a
375
   * typedef for a callback to invoke when a
(-)a/src/wifi/model/block-ack-type.h (-1 / +2 lines)
 Lines 31-37   enum BlockAckType Link Here 
31
{
31
{
32
  BASIC_BLOCK_ACK,
32
  BASIC_BLOCK_ACK,
33
  COMPRESSED_BLOCK_ACK,
33
  COMPRESSED_BLOCK_ACK,
34
  MULTI_TID_BLOCK_ACK
34
  EXTENDED_COMPRESSED_BLOCK_ACK,
35
  MULTI_TID_BLOCK_ACK,
35
};
36
};
36
37
37
} //namespace ns3
38
} //namespace ns3
(-)a/src/wifi/model/ctrl-headers.cc (-230 / +298 lines)
 Lines 31-38   NS_OBJECT_ENSURE_REGISTERED (CtrlBAckRequestHeader); Link Here 
31
31
32
CtrlBAckRequestHeader::CtrlBAckRequestHeader ()
32
CtrlBAckRequestHeader::CtrlBAckRequestHeader ()
33
  : m_barAckPolicy (false),
33
  : m_barAckPolicy (false),
34
    m_multiTid (false),
34
    m_baType (BASIC_BLOCK_ACK)
35
    m_compressed (false)
36
{
35
{
37
}
36
}
38
37
 Lines 68-84   CtrlBAckRequestHeader::GetSerializedSize () const Link Here 
68
{
67
{
69
  uint32_t size = 0;
68
  uint32_t size = 0;
70
  size += 2; //Bar control
69
  size += 2; //Bar control
71
  if (!m_multiTid)
70
  switch (m_baType)
72
    {
71
    {
73
      size += 2; //Starting sequence control
72
      case BASIC_BLOCK_ACK:
74
    }
73
      case COMPRESSED_BLOCK_ACK:
75
  else if (m_compressed)
74
      case EXTENDED_COMPRESSED_BLOCK_ACK:
76
    {
75
        size += 2;
77
      size += (2 + 2) * (m_tidInfo + 1);  //Multi-tid block ack
76
        break;
78
    }
77
      case MULTI_TID_BLOCK_ACK:
79
  else
78
        size += (2 + 2) * (m_tidInfo + 1);
80
    {
79
        break;
81
      NS_FATAL_ERROR ("Reserved configuration.");
80
      default:
81
        NS_FATAL_ERROR ("Invalid BA type");
82
        break;
82
    }
83
    }
83
  return size;
84
  return size;
84
}
85
}
 Lines 88-104   CtrlBAckRequestHeader::Serialize (Buffer::Iterator start) const Link Here 
88
{
89
{
89
  Buffer::Iterator i = start;
90
  Buffer::Iterator i = start;
90
  i.WriteHtolsbU16 (GetBarControl ());
91
  i.WriteHtolsbU16 (GetBarControl ());
91
  if (!m_multiTid)
92
  switch (m_baType)
92
    {
93
      i.WriteHtolsbU16 (GetStartingSequenceControl ());
94
    }
95
  else if (m_compressed)
96
    {
97
      NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
98
    }
99
  else
100
    {
93
    {
101
      NS_FATAL_ERROR ("Reserved configuration.");
94
      case BASIC_BLOCK_ACK:
95
      case COMPRESSED_BLOCK_ACK:
96
      case EXTENDED_COMPRESSED_BLOCK_ACK:
97
        i.WriteHtolsbU16 (GetStartingSequenceControl ());
98
        break;
99
      case MULTI_TID_BLOCK_ACK:
100
        NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
101
        break;
102
      default:
103
        NS_FATAL_ERROR ("Invalid BA type");
104
        break;
102
    }
105
    }
103
}
106
}
104
107
 Lines 107-123   CtrlBAckRequestHeader::Deserialize (Buffer::Iterator start) Link Here 
107
{
110
{
108
  Buffer::Iterator i = start;
111
  Buffer::Iterator i = start;
109
  SetBarControl (i.ReadLsbtohU16 ());
112
  SetBarControl (i.ReadLsbtohU16 ());
110
  if (!m_multiTid)
113
  switch (m_baType)
111
    {
114
    {
112
      SetStartingSequenceControl (i.ReadLsbtohU16 ());
115
      case BASIC_BLOCK_ACK:
113
    }
116
      case COMPRESSED_BLOCK_ACK:
114
  else if (m_compressed)
117
      case EXTENDED_COMPRESSED_BLOCK_ACK:
115
    {
118
        SetStartingSequenceControl (i.ReadLsbtohU16 ());
116
      NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
119
        break;
117
    }
120
      case MULTI_TID_BLOCK_ACK:
118
  else
121
        NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
119
    {
122
        break;
120
      NS_FATAL_ERROR ("Reserved configuration.");
123
      default:
124
        NS_FATAL_ERROR ("Invalid BA type");
125
        break;
121
    }
126
    }
122
  return i.GetDistanceFrom (start);
127
  return i.GetDistanceFrom (start);
123
}
128
}
 Lines 126-142   uint16_t Link Here 
126
CtrlBAckRequestHeader::GetBarControl (void) const
131
CtrlBAckRequestHeader::GetBarControl (void) const
127
{
132
{
128
  uint16_t res = 0;
133
  uint16_t res = 0;
129
  if (m_barAckPolicy)
134
  switch (m_baType)
130
    {
135
    {
131
      res |= 0x1;
136
      case BASIC_BLOCK_ACK:
132
    }
137
        break;
133
  if (m_multiTid)
138
      case COMPRESSED_BLOCK_ACK:
134
    {
139
        res |= (0x02 << 1);
135
      res |= (0x1 << 1);
140
        break;
136
    }
141
      case EXTENDED_COMPRESSED_BLOCK_ACK:
137
  if (m_compressed)
142
        res |= (0x01 << 1);
138
    {
143
        break;
139
      res |= (0x1 << 2);
144
      case MULTI_TID_BLOCK_ACK:
145
        res |= (0x03 << 1);
146
        break;
147
      default:
148
        NS_FATAL_ERROR ("Invalid BA type");
149
        break;
140
    }
150
    }
141
  res |= (m_tidInfo << 12) & (0xf << 12);
151
  res |= (m_tidInfo << 12) & (0xf << 12);
142
  return res;
152
  return res;
 Lines 146-153   void Link Here 
146
CtrlBAckRequestHeader::SetBarControl (uint16_t bar)
156
CtrlBAckRequestHeader::SetBarControl (uint16_t bar)
147
{
157
{
148
  m_barAckPolicy = ((bar & 0x01) == 1) ? true : false;
158
  m_barAckPolicy = ((bar & 0x01) == 1) ? true : false;
149
  m_multiTid = (((bar >> 1) & 0x01) == 1) ? true : false;
159
  if (((bar >> 1) & 0x0f) == 0x03)
150
  m_compressed = (((bar >> 2) & 0x01) == 1) ? true : false;
160
    {
161
      m_baType = MULTI_TID_BLOCK_ACK;
162
    }
163
  else if (((bar >> 1) & 0x0f) == 0x01)
164
    {
165
      m_baType = EXTENDED_COMPRESSED_BLOCK_ACK;
166
    }
167
  else if (((bar >> 1) & 0x0f) == 0x02)
168
    {
169
      m_baType = COMPRESSED_BLOCK_ACK;
170
    }
171
  else
172
    {
173
      m_baType = BASIC_BLOCK_ACK;
174
    }
151
  m_tidInfo = (bar >> 12) & 0x0f;
175
  m_tidInfo = (bar >> 12) & 0x0f;
152
}
176
}
153
177
 Lines 172-195   CtrlBAckRequestHeader::SetHtImmediateAck (bool immediateAck) Link Here 
172
void
196
void
173
CtrlBAckRequestHeader::SetType (BlockAckType type)
197
CtrlBAckRequestHeader::SetType (BlockAckType type)
174
{
198
{
175
  switch (type)
199
  m_baType = type;
176
    {
200
}
177
    case BASIC_BLOCK_ACK:
201
178
      m_multiTid = false;
202
BlockAckType
179
      m_compressed = false;
203
CtrlBAckRequestHeader::GetType (void) const
180
      break;
204
{
181
    case COMPRESSED_BLOCK_ACK:
205
  return m_baType;
182
      m_multiTid = false;
183
      m_compressed = true;
184
      break;
185
    case MULTI_TID_BLOCK_ACK:
186
      m_multiTid = true;
187
      m_compressed = true;
188
      break;
189
    default:
190
      NS_FATAL_ERROR ("Invalid variant type");
191
      break;
192
    }
193
}
206
}
194
207
195
void
208
void
 Lines 226-244   CtrlBAckRequestHeader::GetStartingSequence (void) const Link Here 
226
bool
239
bool
227
CtrlBAckRequestHeader::IsBasic (void) const
240
CtrlBAckRequestHeader::IsBasic (void) const
228
{
241
{
229
  return (!m_multiTid && !m_compressed) ? true : false;
242
  return (m_baType == BASIC_BLOCK_ACK) ? true : false;
230
}
243
}
231
244
232
bool
245
bool
233
CtrlBAckRequestHeader::IsCompressed (void) const
246
CtrlBAckRequestHeader::IsCompressed (void) const
234
{
247
{
235
  return (!m_multiTid && m_compressed) ? true : false;
248
  return (m_baType == COMPRESSED_BLOCK_ACK) ? true : false;
249
}
250
251
bool
252
CtrlBAckRequestHeader::IsExtendedCompressed (void) const
253
{
254
  return (m_baType == EXTENDED_COMPRESSED_BLOCK_ACK) ? true : false;
236
}
255
}
237
256
238
bool
257
bool
239
CtrlBAckRequestHeader::IsMultiTid (void) const
258
CtrlBAckRequestHeader::IsMultiTid (void) const
240
{
259
{
241
  return (m_multiTid && m_compressed) ? true : false;
260
  return (m_baType == MULTI_TID_BLOCK_ACK) ? true : false;
242
}
261
}
243
262
244
263
 Lines 250-257   NS_OBJECT_ENSURE_REGISTERED (CtrlBAckResponseHeader); Link Here 
250
269
251
CtrlBAckResponseHeader::CtrlBAckResponseHeader ()
270
CtrlBAckResponseHeader::CtrlBAckResponseHeader ()
252
  : m_baAckPolicy (false),
271
  : m_baAckPolicy (false),
253
    m_multiTid (false),
272
    m_baType (BASIC_BLOCK_ACK)
254
    m_compressed (false)
255
{
273
{
256
  memset (&bitmap, 0, sizeof (bitmap));
274
  memset (&bitmap, 0, sizeof (bitmap));
257
}
275
}
 Lines 288-314   CtrlBAckResponseHeader::GetSerializedSize (void) const Link Here 
288
{
306
{
289
  uint32_t size = 0;
307
  uint32_t size = 0;
290
  size += 2; //Bar control
308
  size += 2; //Bar control
291
  if (!m_multiTid)
309
  switch (m_baType)
292
    {
310
    {
293
      if (!m_compressed)
311
      case BASIC_BLOCK_ACK:
294
        {
312
        size += (2 + 128);
295
          size += (2 + 128); //Basic block ack
313
        break;
296
        }
314
      case COMPRESSED_BLOCK_ACK:
297
      else
315
        size += (2 + 8);
298
        {
316
        break;
299
          size += (2 + 8); //Compressed block ack
317
      case EXTENDED_COMPRESSED_BLOCK_ACK:
300
        }
318
        size += (2 + 32);
301
    }
319
        break;
302
  else
320
      case MULTI_TID_BLOCK_ACK:
303
    {
321
        size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-tid block ack
304
      if (m_compressed)
322
        break;
305
        {
323
      default:
306
          size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-tid block ack
324
        NS_FATAL_ERROR ("Invalid BA type");
307
        }
325
        break;
308
      else
309
        {
310
          NS_FATAL_ERROR ("Reserved configuration.");
311
        }
312
    }
326
    }
313
  return size;
327
  return size;
314
}
328
}
 Lines 318-335   CtrlBAckResponseHeader::Serialize (Buffer::Iterator start) const Link Here 
318
{
332
{
319
  Buffer::Iterator i = start;
333
  Buffer::Iterator i = start;
320
  i.WriteHtolsbU16 (GetBaControl ());
334
  i.WriteHtolsbU16 (GetBaControl ());
321
  if (!m_multiTid)
335
  switch (m_baType)
322
    {
323
      i.WriteHtolsbU16 (GetStartingSequenceControl ());
324
      i = SerializeBitmap (i);
325
    }
326
  else if (m_compressed)
327
    {
328
      NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
329
    }
330
  else
331
    {
336
    {
332
      NS_FATAL_ERROR ("Reserved configuration.");
337
      case BASIC_BLOCK_ACK:
338
      case COMPRESSED_BLOCK_ACK:
339
      case EXTENDED_COMPRESSED_BLOCK_ACK:
340
        i.WriteHtolsbU16 (GetStartingSequenceControl ());
341
        i = SerializeBitmap (i);
342
        break;
343
      case MULTI_TID_BLOCK_ACK:
344
        NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
345
        break;
346
      default:
347
        NS_FATAL_ERROR ("Invalid BA type");
348
        break;
333
    }
349
    }
334
}
350
}
335
351
 Lines 338-355   CtrlBAckResponseHeader::Deserialize (Buffer::Iterator start) Link Here 
338
{
354
{
339
  Buffer::Iterator i = start;
355
  Buffer::Iterator i = start;
340
  SetBaControl (i.ReadLsbtohU16 ());
356
  SetBaControl (i.ReadLsbtohU16 ());
341
  if (!m_multiTid)
357
  switch (m_baType)
342
    {
358
    {
343
      SetStartingSequenceControl (i.ReadLsbtohU16 ());
359
      case BASIC_BLOCK_ACK:
344
      i = DeserializeBitmap (i);
360
      case COMPRESSED_BLOCK_ACK:
345
    }
361
      case EXTENDED_COMPRESSED_BLOCK_ACK:
346
  else if (m_compressed)
362
        SetStartingSequenceControl (i.ReadLsbtohU16 ());
347
    {
363
        i = DeserializeBitmap (i);
348
      NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
364
        break;
349
    }
365
      case MULTI_TID_BLOCK_ACK:
350
  else
366
        NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
351
    {
367
        break;
352
      NS_FATAL_ERROR ("Reserved configuration.");
368
      default:
369
        NS_FATAL_ERROR ("Invalid BA type");
370
        break;
353
    }
371
    }
354
  return i.GetDistanceFrom (start);
372
  return i.GetDistanceFrom (start);
355
}
373
}
 Lines 363-386   CtrlBAckResponseHeader::SetHtImmediateAck (bool immediateAck) Link Here 
363
void
381
void
364
CtrlBAckResponseHeader::SetType (BlockAckType type)
382
CtrlBAckResponseHeader::SetType (BlockAckType type)
365
{
383
{
366
  switch (type)
384
  m_baType = type;
367
    {
385
}
368
    case BASIC_BLOCK_ACK:
386
369
      m_multiTid = false;
387
BlockAckType
370
      m_compressed = false;
388
CtrlBAckResponseHeader::GetType (void) const
371
      break;
389
{
372
    case COMPRESSED_BLOCK_ACK:
390
  return m_baType;
373
      m_multiTid = false;
374
      m_compressed = true;
375
      break;
376
    case MULTI_TID_BLOCK_ACK:
377
      m_multiTid = true;
378
      m_compressed = true;
379
      break;
380
    default:
381
      NS_FATAL_ERROR ("Invalid variant type");
382
      break;
383
    }
384
}
391
}
385
392
386
void
393
void
 Lines 417-435   CtrlBAckResponseHeader::GetStartingSequence (void) const Link Here 
417
bool
424
bool
418
CtrlBAckResponseHeader::IsBasic (void) const
425
CtrlBAckResponseHeader::IsBasic (void) const
419
{
426
{
420
  return (!m_multiTid && !m_compressed) ? true : false;
427
  return (m_baType == BASIC_BLOCK_ACK) ? true : false;
421
}
428
}
422
429
423
bool
430
bool
424
CtrlBAckResponseHeader::IsCompressed (void) const
431
CtrlBAckResponseHeader::IsCompressed (void) const
425
{
432
{
426
  return (!m_multiTid && m_compressed) ? true : false;
433
  return (m_baType == COMPRESSED_BLOCK_ACK) ? true : false;
434
}
435
436
bool
437
CtrlBAckResponseHeader::IsExtendedCompressed (void) const
438
{
439
  return (m_baType == EXTENDED_COMPRESSED_BLOCK_ACK) ? true : false;
427
}
440
}
428
441
429
bool
442
bool
430
CtrlBAckResponseHeader::IsMultiTid (void) const
443
CtrlBAckResponseHeader::IsMultiTid (void) const
431
{
444
{
432
  return (m_multiTid && m_compressed) ? true : false;
445
  return (m_baType == MULTI_TID_BLOCK_ACK) ? true : false;
433
}
446
}
434
447
435
uint16_t
448
uint16_t
 Lines 440-452   CtrlBAckResponseHeader::GetBaControl (void) const Link Here 
440
    {
453
    {
441
      res |= 0x1;
454
      res |= 0x1;
442
    }
455
    }
443
  if (m_multiTid)
456
  switch (m_baType)
444
    {
457
    {
445
      res |= (0x1 << 1);
458
      case BASIC_BLOCK_ACK:
446
    }
459
        break;
447
  if (m_compressed)
460
      case COMPRESSED_BLOCK_ACK:
448
    {
461
        res |= (0x02 << 1);
449
      res |= (0x1 << 2);
462
        break;
463
      case EXTENDED_COMPRESSED_BLOCK_ACK:
464
        res |= (0x01 << 1);
465
        break;
466
      case MULTI_TID_BLOCK_ACK:
467
        res |= (0x03 << 1);
468
        break;
469
      default:
470
        NS_FATAL_ERROR ("Invalid BA type");
471
        break;
450
    }
472
    }
451
  res |= (m_tidInfo << 12) & (0xf << 12);
473
  res |= (m_tidInfo << 12) & (0xf << 12);
452
  return res;
474
  return res;
 Lines 456-463   void Link Here 
456
CtrlBAckResponseHeader::SetBaControl (uint16_t ba)
478
CtrlBAckResponseHeader::SetBaControl (uint16_t ba)
457
{
479
{
458
  m_baAckPolicy = ((ba & 0x01) == 1) ? true : false;
480
  m_baAckPolicy = ((ba & 0x01) == 1) ? true : false;
459
  m_multiTid = (((ba >> 1) & 0x01) == 1) ? true : false;
481
  if (((ba >> 1) & 0x0f) == 0x03)
460
  m_compressed = (((ba >> 2) & 0x01) == 1) ? true : false;
482
    {
483
      m_baType = MULTI_TID_BLOCK_ACK;
484
    }
485
  else if (((ba >> 1) & 0x0f) == 0x01)
486
    {
487
      m_baType = EXTENDED_COMPRESSED_BLOCK_ACK;
488
    }
489
  else if (((ba >> 1) & 0x0f) == 0x02)
490
    {
491
      m_baType = COMPRESSED_BLOCK_ACK;
492
    }
493
  else
494
    {
495
      m_baType = BASIC_BLOCK_ACK;
496
    }
461
  m_tidInfo = (ba >> 12) & 0x0f;
497
  m_tidInfo = (ba >> 12) & 0x0f;
462
}
498
}
463
499
 Lines 477-506   Buffer::Iterator Link Here 
477
CtrlBAckResponseHeader::SerializeBitmap (Buffer::Iterator start) const
513
CtrlBAckResponseHeader::SerializeBitmap (Buffer::Iterator start) const
478
{
514
{
479
  Buffer::Iterator i = start;
515
  Buffer::Iterator i = start;
480
  if (!m_multiTid)
516
  switch (m_baType)
481
    {
517
    {
482
      if (!m_compressed)
518
      case BASIC_BLOCK_ACK:
483
        {
484
          for (uint8_t j = 0; j < 64; j++)
519
          for (uint8_t j = 0; j < 64; j++)
485
            {
520
            {
486
              i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
521
              i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
487
            }
522
            }
488
        }
523
          break;
489
      else
524
      case COMPRESSED_BLOCK_ACK:
490
        {
491
          i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
525
          i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
492
        }
526
          break;
493
    }
527
      case EXTENDED_COMPRESSED_BLOCK_ACK:
494
  else
528
          i.WriteHtolsbU64 (bitmap.m_extendedCompressedBitmap[0]);
495
    {
529
          i.WriteHtolsbU64 (bitmap.m_extendedCompressedBitmap[1]);
496
      if (m_compressed)
530
          i.WriteHtolsbU64 (bitmap.m_extendedCompressedBitmap[2]);
497
        {
531
          i.WriteHtolsbU64 (bitmap.m_extendedCompressedBitmap[3]);
498
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
532
          break;
499
        }
533
      case MULTI_TID_BLOCK_ACK:
500
      else
534
        NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
501
        {
535
        break;
502
          NS_FATAL_ERROR ("Reserved configuration.");
536
      default:
503
        }
537
        NS_FATAL_ERROR ("Invalid BA type");
538
        break;
504
    }
539
    }
505
  return i;
540
  return i;
506
}
541
}
 Lines 509-538   Buffer::Iterator Link Here 
509
CtrlBAckResponseHeader::DeserializeBitmap (Buffer::Iterator start)
544
CtrlBAckResponseHeader::DeserializeBitmap (Buffer::Iterator start)
510
{
545
{
511
  Buffer::Iterator i = start;
546
  Buffer::Iterator i = start;
512
  if (!m_multiTid)
547
  switch (m_baType)
513
    {
548
    {
514
      if (!m_compressed)
549
      case BASIC_BLOCK_ACK:
515
        {
516
          for (uint8_t j = 0; j < 64; j++)
550
          for (uint8_t j = 0; j < 64; j++)
517
            {
551
            {
518
              bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
552
              bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
519
            }
553
            }
520
        }
554
          break;
521
      else
555
      case COMPRESSED_BLOCK_ACK:
522
        {
523
          bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
556
          bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
524
        }
557
          break;
525
    }
558
      case EXTENDED_COMPRESSED_BLOCK_ACK:
526
  else
559
          bitmap.m_extendedCompressedBitmap[0] = i.ReadLsbtohU64 ();
527
    {
560
          bitmap.m_extendedCompressedBitmap[1] = i.ReadLsbtohU64 ();
528
      if (m_compressed)
561
          bitmap.m_extendedCompressedBitmap[2] = i.ReadLsbtohU64 ();
529
        {
562
          bitmap.m_extendedCompressedBitmap[3] = i.ReadLsbtohU64 ();
530
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
563
          break;
531
        }
564
      case MULTI_TID_BLOCK_ACK:
532
      else
565
        NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
533
        {
566
        break;
534
          NS_FATAL_ERROR ("Reserved configuration.");
567
      default:
535
        }
568
        NS_FATAL_ERROR ("Invalid BA type");
569
        break;
536
    }
570
    }
537
  return i;
571
  return i;
538
}
572
}
 Lines 544-571   CtrlBAckResponseHeader::SetReceivedPacket (uint16_t seq) Link Here 
544
    {
578
    {
545
      return;
579
      return;
546
    }
580
    }
547
  if (!m_multiTid)
581
  switch (m_baType)
548
    {
582
    {
549
      if (!m_compressed)
583
      case BASIC_BLOCK_ACK:
550
        {
584
        {
551
          /* To set correctly basic block ack bitmap we need fragment number too.
585
          /* To set correctly basic block ack bitmap we need fragment number too.
552
             So if it's not specified, we consider packet not fragmented. */
586
             So if it's not specified, we consider packet not fragmented. */
553
          bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
587
          bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
588
          break;
554
        }
589
        }
555
      else
590
      case COMPRESSED_BLOCK_ACK:
556
        {
591
        {
557
          bitmap.m_compressedBitmap |= (uint64_t (0x0000000000000001) << IndexInBitmap (seq));
592
          bitmap.m_compressedBitmap |= (uint64_t (0x0000000000000001) << IndexInBitmap (seq));
593
          break;
558
        }
594
        }
559
    }
595
      case EXTENDED_COMPRESSED_BLOCK_ACK:
560
  else
596
        {
561
    {
597
          uint16_t index = IndexInBitmap (seq);
562
      if (m_compressed)
598
          bitmap.m_extendedCompressedBitmap[index/64] |= (uint64_t (0x0000000000000001) << index);
599
          break;
600
        }
601
      case MULTI_TID_BLOCK_ACK:
563
        {
602
        {
564
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
603
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
604
          break;
565
        }
605
        }
566
      else
606
      default:
567
        {
607
        {
568
          NS_FATAL_ERROR ("Reserved configuration.");
608
          NS_FATAL_ERROR ("Invalid BA type");
609
          break;
569
        }
610
        }
570
    }
611
    }
571
}
612
}
 Lines 578-605   CtrlBAckResponseHeader::SetReceivedFragment (uint16_t seq, uint8_t frag) Link Here 
578
    {
619
    {
579
      return;
620
      return;
580
    }
621
    }
581
  if (!m_multiTid)
622
  switch (m_baType)
582
    {
623
    {
583
      if (!m_compressed)
624
      case BASIC_BLOCK_ACK:
584
        {
625
        bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001 << frag);
585
          bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001 << frag);
626
        break;
586
        }
627
      case COMPRESSED_BLOCK_ACK:
587
      else
628
      case EXTENDED_COMPRESSED_BLOCK_ACK:
588
        {
629
        /* We can ignore this...compressed block ack doesn't support
589
          /* We can ignore this...compressed block ack doesn't support
630
           acknowledgement of single fragments */
590
             acknowledgement of single fragments */
631
        break;
591
        }
632
      case MULTI_TID_BLOCK_ACK:
592
    }
633
        NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
593
  else
634
        break;
594
    {
635
      default:
595
      if (m_compressed)
636
        NS_FATAL_ERROR ("Invalid BA type");
596
        {
637
        break;
597
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
598
        }
599
      else
600
        {
601
          NS_FATAL_ERROR ("Reserved configuration.");
602
        }
603
    }
638
    }
604
}
639
}
605
640
 Lines 610-637   CtrlBAckResponseHeader::IsPacketReceived (uint16_t seq) const Link Here 
610
    {
645
    {
611
      return false;
646
      return false;
612
    }
647
    }
613
  if (!m_multiTid)
648
  switch (m_baType)
614
    {
649
    {
615
      if (!m_compressed)
650
      case BASIC_BLOCK_ACK:
616
        {
651
        {
617
          /*It's impossible to say if an entire packet was correctly received. */
652
          /*It's impossible to say if an entire packet was correctly received. */
618
          return false;
653
          return false;
619
        }
654
        }
620
      else
655
      case COMPRESSED_BLOCK_ACK:
621
        {
656
        {
657
          /* Although this could make no sense, if packet with sequence number
658
             equal to <i>seq</i> was correctly received, also all of its fragments
659
             were correctly received. */
622
          uint64_t mask = uint64_t (0x0000000000000001);
660
          uint64_t mask = uint64_t (0x0000000000000001);
623
          return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
661
          return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
624
        }
662
        }
625
    }
663
      case EXTENDED_COMPRESSED_BLOCK_ACK:
626
  else
664
        {
627
    {
665
          uint64_t mask = uint64_t (0x0000000000000001);
628
      if (m_compressed)
666
          uint16_t index = IndexInBitmap (seq);
667
          return (((bitmap.m_extendedCompressedBitmap[index/64] >> index) & mask) == 1) ? true : false;
668
        }
669
      case MULTI_TID_BLOCK_ACK:
629
        {
670
        {
630
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
671
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
672
          break;
631
        }
673
        }
632
      else
674
      default:
633
        {
675
        {
634
          NS_FATAL_ERROR ("Reserved configuration.");
676
          NS_FATAL_ERROR ("Invalid BA type");
677
          break;
635
        }
678
        }
636
    }
679
    }
637
  return false;
680
  return false;
 Lines 645-657   CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const Link Here 
645
    {
688
    {
646
      return false;
689
      return false;
647
    }
690
    }
648
  if (!m_multiTid)
691
  switch (m_baType)
649
    {
692
    {
650
      if (!m_compressed)
693
      case BASIC_BLOCK_ACK:
651
        {
694
        {
652
          return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001 << frag)) != 0x0000) ? true : false;
695
          return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001 << frag)) != 0x0000) ? true : false;
653
        }
696
        }
654
      else
697
      case COMPRESSED_BLOCK_ACK:
655
        {
698
        {
656
          /* Although this could make no sense, if packet with sequence number
699
          /* Although this could make no sense, if packet with sequence number
657
             equal to <i>seq</i> was correctly received, also all of its fragments
700
             equal to <i>seq</i> was correctly received, also all of its fragments
 Lines 659-674   CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const Link Here 
659
          uint64_t mask = uint64_t (0x0000000000000001);
702
          uint64_t mask = uint64_t (0x0000000000000001);
660
          return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
703
          return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
661
        }
704
        }
662
    }
705
      case EXTENDED_COMPRESSED_BLOCK_ACK:
663
  else
706
        {
664
    {
707
          uint64_t mask = uint64_t (0x0000000000000001);
665
      if (m_compressed)
708
          uint16_t index = IndexInBitmap (seq);
709
          return (((bitmap.m_extendedCompressedBitmap[index/64] >> index) & mask) == 1) ? true : false;
710
        }
711
      case MULTI_TID_BLOCK_ACK:
666
        {
712
        {
667
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
713
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
714
          break;
668
        }
715
        }
669
      else
716
      default:
670
        {
717
        {
671
          NS_FATAL_ERROR ("Reserved configuration.");
718
          NS_FATAL_ERROR ("Invalid BA type");
719
          break;
672
        }
720
        }
673
    }
721
    }
674
  return false;
722
  return false;
 Lines 686-699   CtrlBAckResponseHeader::IndexInBitmap (uint16_t seq) const Link Here 
686
    {
734
    {
687
      index = 4096 - m_startingSeq + seq;
735
      index = 4096 - m_startingSeq + seq;
688
    }
736
    }
689
  NS_ASSERT (index <= 63);
737
  if (m_baType == EXTENDED_COMPRESSED_BLOCK_ACK)
738
    {
739
      NS_ASSERT (index <= 255);
740
    }
741
  else
742
    {
743
      NS_ASSERT (index <= 63);
744
    }
690
  return index;
745
  return index;
691
}
746
}
692
747
693
bool
748
bool
694
CtrlBAckResponseHeader::IsInBitmap (uint16_t seq) const
749
CtrlBAckResponseHeader::IsInBitmap (uint16_t seq) const
695
{
750
{
696
  return (seq - m_startingSeq + 4096) % 4096 < 64;
751
  if (m_baType == EXTENDED_COMPRESSED_BLOCK_ACK)
752
    {
753
      return (seq - m_startingSeq + 4096) % 4096 < 256;
754
    }
755
  else
756
    {
757
      return (seq - m_startingSeq + 4096) % 4096 < 64;
758
    }
697
}
759
}
698
760
699
const uint16_t*
761
const uint16_t*
 Lines 708-713   CtrlBAckResponseHeader::GetCompressedBitmap (void) const Link Here 
708
  return bitmap.m_compressedBitmap;
770
  return bitmap.m_compressedBitmap;
709
}
771
}
710
772
773
const uint64_t*
774
CtrlBAckResponseHeader::GetExtendedCompressedBitmap (void) const
775
{
776
  return bitmap.m_extendedCompressedBitmap;
777
}
778
711
void
779
void
712
CtrlBAckResponseHeader::ResetBitmap (void)
780
CtrlBAckResponseHeader::ResetBitmap (void)
713
{
781
{
(-)a/src/wifi/model/ctrl-headers.h (-16 / +46 lines)
 Lines 88-93   public: Link Here 
88
   */
88
   */
89
  bool MustSendHtImmediateAck (void) const;
89
  bool MustSendHtImmediateAck (void) const;
90
  /**
90
  /**
91
   * Return the block ACK type ID.
92
   *
93
   * \return type
94
   */
95
  BlockAckType GetType (void) const;
96
  /**
91
   * Return the Traffic ID (TID).
97
   * Return the Traffic ID (TID).
92
   *
98
   *
93
   * \return TID
99
   * \return TID
 Lines 116-121   public: Link Here 
116
   */
122
   */
117
  bool IsCompressed (void) const;
123
  bool IsCompressed (void) const;
118
  /**
124
  /**
125
   * Check if the current BA policy is extended compressed block ACK.
126
   *
127
   * \return true if the current BA policy is extended compressed block ACK,
128
   *         false otherwise
129
   */
130
  bool IsExtendedCompressed (void) const;
131
  /**
119
   * Check if the current ACK policy has multiple TID.
132
   * Check if the current ACK policy has multiple TID.
120
   *
133
   *
121
   * \return true if the current ACK policy has multiple TID,
134
   * \return true if the current ACK policy has multiple TID,
 Lines 158-167   private: Link Here 
158
   * For now only non HT immediate block ack is implemented so this field
171
   * For now only non HT immediate block ack is implemented so this field
159
   * is here only for a future implementation of HT delayed variant.
172
   * is here only for a future implementation of HT delayed variant.
160
   */
173
   */
161
  bool m_barAckPolicy; ///< bar ack policy
174
  bool m_barAckPolicy;    ///< bar ack policy
162
  bool m_multiTid; ///< multi TID
175
  BlockAckType m_baType;  ///< BA type
163
  bool m_compressed; ///< compressed
176
  uint16_t m_tidInfo;     ///< TID info
164
  uint16_t m_tidInfo; ///< TID info
165
  uint16_t m_startingSeq; ///< starting seq
177
  uint16_t m_startingSeq; ///< starting seq
166
};
178
};
167
179
 Lines 228-233   public: Link Here 
228
   */
240
   */
229
  bool MustSendHtImmediateAck (void) const;
241
  bool MustSendHtImmediateAck (void) const;
230
  /**
242
  /**
243
   * Return the block ACK type ID.
244
   *
245
   * \return type
246
   */
247
  BlockAckType GetType (void) const;
248
  /**
231
   * Return the Traffic ID (TID).
249
   * Return the Traffic ID (TID).
232
   *
250
   *
233
   * \return TID
251
   * \return TID
 Lines 240-264   public: Link Here 
240
   */
258
   */
241
  uint16_t GetStartingSequence (void) const;
259
  uint16_t GetStartingSequence (void) const;
242
  /**
260
  /**
243
   * Check if the current ACK policy is basic
261
   * Check if the current BA policy is basic block ACK.
244
   * (i.e. not multiple TID and not compressed ACK).
245
   *
262
   *
246
   * \return true if the current ACK policy is basic,
263
   * \return true if the current BA policy is basic block ACK,
247
   *         false otherwise
264
   *         false otherwise
248
   */
265
   */
249
  bool IsBasic (void) const;
266
  bool IsBasic (void) const;
250
  /**
267
  /**
251
   * Check if the current ACK policy is compressed ACK
268
   * Check if the current BA policy is compressed block ACK.
252
   * and not multiple TID.
253
   *
269
   *
254
   * \return true if the current ACK policy is compressed ACK,
270
   * \return true if the current BA policy is compressed block ACK,
255
   *         false otherwise
271
   *         false otherwise
256
   */
272
   */
257
  bool IsCompressed (void) const;
273
  bool IsCompressed (void) const;
258
  /**
274
  /**
259
   * Check if the current ACK policy has multiple TID.
275
   * Check if the current BA policy is extended compressed block ACK.
260
   *
276
   *
261
   * \return true if the current ACK policy has multiple TID,
277
   * \return true if the current BA policy is extended compressed block ACK,
278
   *         false otherwise
279
   */
280
  bool IsExtendedCompressed (void) const;
281
  /**
282
   * Check if the current BA policy is multi-TID block ACK.
283
   *
284
   * \return true if the current BA policy is multi-TID block ACK,
262
   *         false otherwise
285
   *         false otherwise
263
   */
286
   */
264
  bool IsMultiTid (void) const;
287
  bool IsMultiTid (void) const;
 Lines 317-322   public: Link Here 
317
   *
340
   *
318
   * \return the bitmap from the block ACK response header
341
   * \return the bitmap from the block ACK response header
319
   */
342
   */
343
320
  const uint16_t* GetBitmap (void) const;
344
  const uint16_t* GetBitmap (void) const;
321
  /**
345
  /**
322
   * Return the compressed bitmap from the block ACK response header.
346
   * Return the compressed bitmap from the block ACK response header.
 Lines 324-329   public: Link Here 
324
   * \return the compressed bitmap from the block ACK response header
348
   * \return the compressed bitmap from the block ACK response header
325
   */
349
   */
326
  uint64_t GetCompressedBitmap (void) const;
350
  uint64_t GetCompressedBitmap (void) const;
351
  /**
352
   * Return the extended compressed bitmap from the block ACK response header.
353
   *
354
   * \return the extended compressed bitmap from the block ACK response header
355
   */
356
  const uint64_t* GetExtendedCompressedBitmap (void) const;
327
357
328
  /**
358
  /**
329
   * Reset the bitmap to 0.
359
   * Reset the bitmap to 0.
 Lines 391-406   private: Link Here 
391
   * For now only non HT immediate block ack is implemented so this field
421
   * For now only non HT immediate block ack is implemented so this field
392
   * is here only for a future implementation of HT delayed variant.
422
   * is here only for a future implementation of HT delayed variant.
393
   */
423
   */
394
  bool m_baAckPolicy; ///< BA ack policy
424
  bool m_baAckPolicy;     ///< BA ack policy
395
  bool m_multiTid; ///< multi TID
425
  BlockAckType m_baType;  ///< BA type
396
  bool m_compressed; ///< compressed
426
  uint16_t m_tidInfo;     ///< TID info
397
  uint16_t m_tidInfo; ///< TID info
398
  uint16_t m_startingSeq; ///< starting seq
427
  uint16_t m_startingSeq; ///< starting seq
399
428
400
  union
429
  union
401
  {
430
  {
402
    uint16_t m_bitmap[64]; ///< the block ack bitmap
431
    uint16_t m_bitmap[64]; ///< the block ack bitmap
403
    uint64_t m_compressedBitmap; ///< the compressed block ack bitmap
432
    uint64_t m_compressedBitmap; ///< the compressed block ack bitmap
433
    uint64_t m_extendedCompressedBitmap[4]; ///< the extended compressed block ack bitmap
404
  } bitmap; ///< bitmap union type
434
  } bitmap; ///< bitmap union type
405
};
435
};
406
436
(-)a/src/wifi/model/he-configuration.cc (-1 / +21 lines)
 Lines 46-55   HeConfiguration::GetTypeId (void) Link Here 
46
                   MakeTimeAccessor (&HeConfiguration::GetGuardInterval,
46
                   MakeTimeAccessor (&HeConfiguration::GetGuardInterval,
47
                                     &HeConfiguration::SetGuardInterval),
47
                                     &HeConfiguration::SetGuardInterval),
48
                   MakeTimeChecker (NanoSeconds (800), NanoSeconds (3200)))
48
                   MakeTimeChecker (NanoSeconds (800), NanoSeconds (3200)))
49
    .AddAttribute ("BssColor", "BSS color",
49
    .AddAttribute ("BssColor",
50
                   "The BSS color",
50
                   UintegerValue (0),
51
                   UintegerValue (0),
51
                   MakeUintegerAccessor (&HeConfiguration::m_bssColor),
52
                   MakeUintegerAccessor (&HeConfiguration::m_bssColor),
52
                   MakeUintegerChecker<uint8_t> ())
53
                   MakeUintegerChecker<uint8_t> ())
54
    .AddAttribute ("MpduBufferSize",
55
                   "The MPDU buffer size for receiving A-MPDUs",
56
                   UintegerValue (64),
57
                   MakeUintegerAccessor (&HeConfiguration::GetMpduBufferSize,
58
                                         &HeConfiguration::SetMpduBufferSize),
59
                   MakeUintegerChecker<uint16_t> (64, 256))
53
    ;
60
    ;
54
    return tid;
61
    return tid;
55
}
62
}
 Lines 68-71   HeConfiguration::GetGuardInterval (void) const Link Here 
68
  return m_guardInterval;
75
  return m_guardInterval;
69
}
76
}
70
77
78
void
79
HeConfiguration::SetMpduBufferSize (uint16_t size)
80
{
81
  NS_LOG_FUNCTION (this << size);
82
  m_mpduBufferSize = size;
83
}
84
85
uint16_t
86
HeConfiguration::GetMpduBufferSize (void) const
87
{
88
  return m_mpduBufferSize;
89
}
90
71
} //namespace ns3
91
} //namespace ns3
(-)a/src/wifi/model/he-configuration.h (-2 / +11 lines)
 Lines 46-56   public: Link Here 
46
   * \return the supported HE guard interval
46
   * \return the supported HE guard interval
47
   */
47
   */
48
  Time GetGuardInterval (void) const;
48
  Time GetGuardInterval (void) const;
49
  /**
50
   * \param size the MPDU buffer size to receive A-MPDUs
51
   */
52
  void SetMpduBufferSize (uint16_t size);
53
  /**
54
   * \return the MPDU buffer size to receive A-MPDUs
55
   */
56
  uint16_t GetMpduBufferSize (void) const;
49
57
50
58
51
private:
59
private:
52
  Time m_guardInterval; //!< Supported HE guard interval
60
  Time m_guardInterval;      //!< Supported HE guard interval
53
  uint8_t m_bssColor;   //!< BSS color
61
  uint8_t m_bssColor;        //!< BSS color
62
  uint16_t m_mpduBufferSize; //!< MPDU buffer size
54
};
63
};
55
64
56
} //namespace ns3
65
} //namespace ns3
(-)a/src/wifi/model/mac-low-transmission-parameters.cc (+15 lines)
 Lines 56-61   MacLowTransmissionParameters::EnableCompressedBlockAck (void) Link Here 
56
}
56
}
57
57
58
void
58
void
59
MacLowTransmissionParameters::EnableExtendedCompressedBlockAck (void)
60
{
61
  m_waitAck = EXTENDED_BLOCK_ACK_COMPRESSED;
62
}
63
64
void
59
MacLowTransmissionParameters::EnableMultiTidBlockAck (void)
65
MacLowTransmissionParameters::EnableMultiTidBlockAck (void)
60
{
66
{
61
  m_waitAck = BLOCK_ACK_MULTI_TID;
67
  m_waitAck = BLOCK_ACK_MULTI_TID;
 Lines 104-109   MacLowTransmissionParameters::MustWaitCompressedBlockAck (void) const Link Here 
104
}
110
}
105
111
106
bool
112
bool
113
MacLowTransmissionParameters::MustWaitExtendedCompressedBlockAck (void) const
114
{
115
  return (m_waitAck == EXTENDED_BLOCK_ACK_COMPRESSED) ? true : false;
116
}
117
118
bool
107
MacLowTransmissionParameters::MustWaitMultiTidBlockAck (void) const
119
MacLowTransmissionParameters::MustWaitMultiTidBlockAck (void) const
108
{
120
{
109
  return (m_waitAck == BLOCK_ACK_MULTI_TID) ? true : false;
121
  return (m_waitAck == BLOCK_ACK_MULTI_TID) ? true : false;
 Lines 148-153   std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters Link Here 
148
    case MacLowTransmissionParameters::BLOCK_ACK_COMPRESSED:
160
    case MacLowTransmissionParameters::BLOCK_ACK_COMPRESSED:
149
      os << "compressed-block-ack";
161
      os << "compressed-block-ack";
150
      break;
162
      break;
163
    case MacLowTransmissionParameters::EXTENDED_BLOCK_ACK_COMPRESSED:
164
      os << "extended-compressed-block-ack";
165
      break;
151
    case MacLowTransmissionParameters::BLOCK_ACK_MULTI_TID:
166
    case MacLowTransmissionParameters::BLOCK_ACK_MULTI_TID:
152
      os << "multi-tid-block-ack";
167
      os << "multi-tid-block-ack";
153
      break;
168
      break;
(-)a/src/wifi/model/mac-low-transmission-parameters.h (+11 lines)
 Lines 55-60   public: Link Here 
55
   */
55
   */
56
  void EnableCompressedBlockAck (void);
56
  void EnableCompressedBlockAck (void);
57
  /**
57
  /**
58
   * Wait COMPRESSEDBLOCKACKTimeout for an Extended Compressed Block Ack Response frame.
59
   */
60
  void EnableExtendedCompressedBlockAck (void);
61
  /**
58
   * NOT IMPLEMENTED FOR NOW
62
   * NOT IMPLEMENTED FOR NOW
59
   */
63
   */
60
  void EnableMultiTidBlockAck (void);
64
  void EnableMultiTidBlockAck (void);
 Lines 108-113   public: Link Here 
108
   */
112
   */
109
  bool MustWaitCompressedBlockAck (void) const;
113
  bool MustWaitCompressedBlockAck (void) const;
110
  /**
114
  /**
115
   * \returns true if extended compressed block ack mechanism is used, false otherwise.
116
   *
117
   * \sa EnableExtendedCompressedBlockAck
118
   */
119
  bool MustWaitExtendedCompressedBlockAck (void) const;
120
  /**
111
   * \returns true if multi-tid block ack mechanism is used, false otherwise.
121
   * \returns true if multi-tid block ack mechanism is used, false otherwise.
112
   *
122
   *
113
   * \sa EnableMultiTidBlockAck
123
   * \sa EnableMultiTidBlockAck
 Lines 137-142   private: Link Here 
137
    ACK_NORMAL,
147
    ACK_NORMAL,
138
    BLOCK_ACK_BASIC,
148
    BLOCK_ACK_BASIC,
139
    BLOCK_ACK_COMPRESSED,
149
    BLOCK_ACK_COMPRESSED,
150
    EXTENDED_BLOCK_ACK_COMPRESSED,
140
    BLOCK_ACK_MULTI_TID
151
    BLOCK_ACK_MULTI_TID
141
  } m_waitAck; //!< wait ack
152
  } m_waitAck; //!< wait ack
142
  bool m_sendRts; //!< send an RTS?
153
  bool m_sendRts; //!< send an RTS?
(-)a/src/wifi/model/mac-low.cc (-39 / +88 lines)
 Lines 534-540   MacLow::StartTransmission (Ptr<const Packet> packet, Link Here 
534
      //In that case, we transmit the same A-MPDU as previously.
534
      //In that case, we transmit the same A-MPDU as previously.
535
      uint32_t sentMpdus = m_aggregateQueue[GetTid (packet, *hdr)]->GetNPackets ();
535
      uint32_t sentMpdus = m_aggregateQueue[GetTid (packet, *hdr)]->GetNPackets ();
536
      m_ampdu = true;
536
      m_ampdu = true;
537
      if (sentMpdus > 1)
537
      if (sentMpdus > 64)
538
        {
539
          m_txParams.EnableExtendedCompressedBlockAck ();
540
        }
541
      else if (sentMpdus > 1)
538
        {
542
        {
539
          m_txParams.EnableCompressedBlockAck ();
543
          m_txParams.EnableCompressedBlockAck ();
540
        }
544
        }
 Lines 565-571   MacLow::StartTransmission (Ptr<const Packet> packet, Link Here 
565
        {
569
        {
566
          AmpduTag ampdu;
570
          AmpduTag ampdu;
567
          m_currentPacket->PeekPacketTag (ampdu);
571
          m_currentPacket->PeekPacketTag (ampdu);
568
          if (ampdu.GetRemainingNbOfMpdus () > 0)
572
          if (ampdu.GetRemainingNbOfMpdus () > 63)
573
            {
574
              m_txParams.EnableExtendedCompressedBlockAck ();
575
            }
576
          else if (ampdu.GetRemainingNbOfMpdus () > 0)
569
            {
577
            {
570
              m_txParams.EnableCompressedBlockAck ();
578
              m_txParams.EnableCompressedBlockAck ();
571
            }
579
            }
 Lines 815-821   MacLow::ReceiveOk (Ptr<Packet> packet, double rxSnr, WifiTxVector txVector, bool Link Here 
815
        }
823
        }
816
    }
824
    }
817
  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
825
  else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self
818
           && (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck ())
826
           && (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ())
819
           && m_blockAckTimeoutEvent.IsRunning ())
827
           && m_blockAckTimeoutEvent.IsRunning ())
820
    {
828
    {
821
      NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
829
      NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ());
 Lines 1573-1582   MacLow::SendRtsForPacket (void) Link Here 
1573
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1581
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1574
      duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
1582
      duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
1575
    }
1583
    }
1576
  else if (m_txParams.MustWaitCompressedBlockAck ())
1584
  else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ())
1577
    {
1585
    {
1578
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1586
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1579
      duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1587
        if (m_txParams.MustWaitExtendedCompressedBlockAck ())
1588
          {
1589
            duration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK);
1590
          }
1591
        else
1592
          {
1593
            duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1594
          }
1580
    }
1595
    }
1581
  else if (m_txParams.MustWaitNormalAck ())
1596
  else if (m_txParams.MustWaitNormalAck ())
1582
    {
1597
    {
 Lines 1626-1632   MacLow::StartDataTxTimers (WifiTxVector dataTxVector) Link Here 
1626
      NotifyAckTimeoutStartNow (timerDelay);
1641
      NotifyAckTimeoutStartNow (timerDelay);
1627
      m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
1642
      m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this);
1628
    }
1643
    }
1629
  else if (m_txParams.MustWaitCompressedBlockAck ())
1644
  else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ())
1630
    {
1645
    {
1631
      Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1646
      Time timerDelay = txDuration + GetCompressedBlockAckTimeout ();
1632
      NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
1647
      NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ());
 Lines 1683-1693   MacLow::SendDataPacket (void) Link Here 
1683
          WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1698
          WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1684
          duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
1699
          duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
1685
        }
1700
        }
1686
      else if (m_txParams.MustWaitCompressedBlockAck ())
1701
      else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ())
1687
        {
1702
        {
1688
          duration += GetSifs ();
1703
          duration += GetSifs ();
1689
          WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1704
          WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1690
          duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1705
          if (m_txParams.MustWaitExtendedCompressedBlockAck ())
1706
            {
1707
              duration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK);
1708
            }
1709
          else
1710
            {
1711
              duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1712
            }
1691
        }
1713
        }
1692
      else if (m_txParams.MustWaitNormalAck ())
1714
      else if (m_txParams.MustWaitNormalAck ())
1693
        {
1715
        {
 Lines 1807-1817   MacLow::SendCtsToSelf (void) Link Here 
1807
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1829
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1808
      duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
1830
      duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
1809
    }
1831
    }
1810
  else if (m_txParams.MustWaitCompressedBlockAck ())
1832
  else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ())
1811
    {
1833
    {
1812
      duration += GetSifs ();
1834
      duration += GetSifs ();
1813
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1835
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1814
      duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1836
      if (m_txParams.MustWaitExtendedCompressedBlockAck ())
1837
        {
1838
          duration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK);
1839
        }
1840
      else
1841
        {
1842
          duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1843
        }
1815
    }
1844
    }
1816
  else if (m_txParams.MustWaitNormalAck ())
1845
  else if (m_txParams.MustWaitNormalAck ())
1817
    {
1846
    {
 Lines 1823-1833   MacLow::SendCtsToSelf (void) Link Here 
1823
      duration += GetSifs ();
1852
      duration += GetSifs ();
1824
      duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
1853
      duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (),
1825
                                              m_currentTxVector, m_phy->GetFrequency ());
1854
                                              m_currentTxVector, m_phy->GetFrequency ());
1826
      if (m_txParams.MustWaitCompressedBlockAck ())
1855
      if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ())
1827
        {
1856
        {
1828
          duration += GetSifs ();
1857
          duration += GetSifs ();
1829
          WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1858
          WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1830
          duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1859
          if (m_txParams.MustWaitExtendedCompressedBlockAck ())
1860
            {
1861
              duration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK);
1862
            }
1863
          else
1864
            {
1865
              duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1866
            }
1831
        }
1867
        }
1832
      else if (m_txParams.MustWaitNormalAck ())
1868
      else if (m_txParams.MustWaitNormalAck ())
1833
        {
1869
        {
 Lines 1916-1926   MacLow::SendDataAfterCts (Time duration) Link Here 
1916
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1952
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1917
      newDuration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
1953
      newDuration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
1918
    }
1954
    }
1919
  else if (m_txParams.MustWaitCompressedBlockAck ())
1955
  else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ())
1920
    {
1956
    {
1921
      newDuration += GetSifs ();
1957
      newDuration += GetSifs ();
1922
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1958
      WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1923
      newDuration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1959
      if (m_txParams.MustWaitExtendedCompressedBlockAck ())
1960
        {
1961
          newDuration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK);
1962
        }
1963
      else
1964
        {
1965
          newDuration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1966
        }
1924
    }
1967
    }
1925
  else if (m_txParams.MustWaitNormalAck ())
1968
  else if (m_txParams.MustWaitNormalAck ())
1926
    {
1969
    {
 Lines 1938-1948   MacLow::SendDataAfterCts (Time duration) Link Here 
1938
          newDuration += GetSifs ();
1981
          newDuration += GetSifs ();
1939
        }
1982
        }
1940
      newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), m_currentTxVector, m_phy->GetFrequency ());
1983
      newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), m_currentTxVector, m_phy->GetFrequency ());
1941
      if (m_txParams.MustWaitCompressedBlockAck ())
1984
      if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ())
1942
        {
1985
        {
1943
          newDuration += GetSifs ();
1986
          newDuration += GetSifs ();
1944
          WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1987
          WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentHdr.GetAddr2 (), m_currentTxVector.GetMode ());
1945
          newDuration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1988
          if (m_txParams.MustWaitExtendedCompressedBlockAck ())
1989
            {
1990
              newDuration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK);
1991
            }
1992
          else
1993
            {
1994
              newDuration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
1995
            }
1946
        }
1996
        }
1947
      else if (m_txParams.MustWaitNormalAck ())
1997
      else if (m_txParams.MustWaitNormalAck ())
1948
        {
1998
        {
 Lines 2282-2299   MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Addre Link Here 
2282
    {
2332
    {
2283
      m_txParams.DisableAck ();
2333
      m_txParams.DisableAck ();
2284
      duration -= GetSifs ();
2334
      duration -= GetSifs ();
2285
      if (blockAck->IsBasic ())
2335
      duration -= GetBlockAckDuration (blockAckReqTxVector, blockAck->GetType ());
2286
        {
2287
          duration -= GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK);
2288
        }
2289
      else if (blockAck->IsCompressed ())
2290
        {
2291
          duration -= GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK);
2292
        }
2293
      else if (blockAck->IsMultiTid ())
2294
        {
2295
          NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
2296
        }
2297
    }
2336
    }
2298
  else
2337
  else
2299
    {
2338
    {
 Lines 2321-2327   MacLow::SendBlockAckResponse (const CtrlBAckResponseHeader* blockAck, Mac48Addre Link Here 
2321
}
2360
}
2322
2361
2323
void
2362
void
2324
MacLow::SendBlockAckAfterAmpdu (uint8_t tid, Mac48Address originator, Time duration, WifiTxVector blockAckReqTxVector, double rxSnr)
2363
MacLow::SendBlockAckAfterAmpdu (uint8_t tid, Mac48Address originator, Time duration, WifiTxVector blockAckReqTxVector, double rxSnr, uint8_t nMpdus)
2325
{
2364
{
2326
  NS_LOG_FUNCTION (this);
2365
  NS_LOG_FUNCTION (this);
2327
  if (!m_phy->IsStateTx () && !m_phy->IsStateRx ())
2366
  if (!m_phy->IsStateTx () && !m_phy->IsStateRx ())
 Lines 2338-2344   MacLow::SendBlockAckAfterAmpdu (uint8_t tid, Mac48Address originator, Time durat Link Here 
2338
      blockAck.SetStartingSequence (seqNumber);
2377
      blockAck.SetStartingSequence (seqNumber);
2339
      blockAck.SetTidInfo (tid);
2378
      blockAck.SetTidInfo (tid);
2340
      immediate = (*it).second.first.IsImmediateBlockAck ();
2379
      immediate = (*it).second.first.IsImmediateBlockAck ();
2341
      blockAck.SetType (COMPRESSED_BLOCK_ACK);
2380
      if (nMpdus > 64)
2381
        {
2382
          blockAck.SetType (EXTENDED_COMPRESSED_BLOCK_ACK);
2383
        }
2384
      else
2385
        {
2386
          blockAck.SetType (COMPRESSED_BLOCK_ACK);
2387
        }
2342
      NS_LOG_DEBUG ("Got Implicit block Ack Req with seq " << seqNumber);
2388
      NS_LOG_DEBUG ("Got Implicit block Ack Req with seq " << seqNumber);
2343
      (*i).second.FillBlockAckBitmap (&blockAck);
2389
      (*i).second.FillBlockAckBitmap (&blockAck);
2344
2390
 Lines 2375-2380   MacLow::SendBlockAckAfterBlockAckRequest (const CtrlBAckRequestHeader reqHdr, Ma Link Here 
2375
            {
2421
            {
2376
              blockAck.SetType (COMPRESSED_BLOCK_ACK);
2422
              blockAck.SetType (COMPRESSED_BLOCK_ACK);
2377
            }
2423
            }
2424
          else if (reqHdr.IsExtendedCompressed ())
2425
            {
2426
              blockAck.SetType (EXTENDED_COMPRESSED_BLOCK_ACK);
2427
            }
2378
          BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2428
          BlockAckCachesI i = m_bAckCaches.find (std::make_pair (originator, tid));
2379
          NS_ASSERT (i != m_bAckCaches.end ());
2429
          NS_ASSERT (i != m_bAckCaches.end ());
2380
          (*i).second.FillBlockAckBitmap (&blockAck);
2430
          (*i).second.FillBlockAckBitmap (&blockAck);
 Lines 2470-2477   MacLow::DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr, Link Here 
2470
                                                    firsthdr.GetQosTid (),
2520
                                                    firsthdr.GetQosTid (),
2471
                                                    firsthdr.GetAddr2 (),
2521
                                                    firsthdr.GetAddr2 (),
2472
                                                    firsthdr.GetDuration (),
2522
                                                    firsthdr.GetDuration (),
2473
                                                    txVector,
2523
                                                    txVector, rxSnr,
2474
                                                    rxSnr);
2524
                                                    ampdu.GetRemainingNbOfMpdus () + 1);
2475
            }
2525
            }
2476
2526
2477
          if (firsthdr.IsAck () || firsthdr.IsBlockAck () || firsthdr.IsBlockAckReq ())
2527
          if (firsthdr.IsAck () || firsthdr.IsBlockAck () || firsthdr.IsBlockAckReq ())
 Lines 2594-2600   MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr) Link Here 
2594
2644
2595
      if (!hdr.GetAddr1 ().IsBroadcast () && edcaIt->second->GetMpduAggregator () != 0)
2645
      if (!hdr.GetAddr1 ().IsBroadcast () && edcaIt->second->GetMpduAggregator () != 0)
2596
        {
2646
        {
2597
          //Have to make sure that their exist a block Ack agreement before sending an AMPDU (BlockAck Manager)
2647
          //Have to make sure that their exist a block Ack agreement before sending an A-MPDU
2598
          if (edcaIt->second->GetBaAgreementExists (hdr.GetAddr1 (), tid))
2648
          if (edcaIt->second->GetBaAgreementExists (hdr.GetAddr1 (), tid))
2599
            {
2649
            {
2600
              /* here is performed mpdu aggregation */
2650
              /* here is performed mpdu aggregation */
 Lines 2606-2612   MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr) Link Here 
2606
              uint8_t qosPolicy = 0;
2656
              uint8_t qosPolicy = 0;
2607
              uint8_t blockAckSize = 0;
2657
              uint8_t blockAckSize = 0;
2608
              bool aggregated = false;
2658
              bool aggregated = false;
2609
              uint8_t i = 0;
2659
              uint16_t i = 0;
2610
              aggPacket = newPacket->Copy ();
2660
              aggPacket = newPacket->Copy ();
2611
2661
2612
              if (!hdr.IsBlockAckReq ())
2662
              if (!hdr.IsBlockAckReq ())
 Lines 2668-2674   MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr) Link Here 
2668
                  currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2718
                  currentSequenceNumber = peekedHdr.GetSequenceNumber ();
2669
                }
2719
                }
2670
2720
2671
              while (IsInWindow (currentSequenceNumber, startingSequenceNumber, 64) && !StopMpduAggregation (peekedPacket, peekedHdr, currentAggregatedPacket, blockAckSize))
2721
              uint16_t maxMpdus = edcaIt->second->GetBaBufferSize (hdr.GetAddr1 (), tid);
2722
              while (IsInWindow (currentSequenceNumber, startingSequenceNumber, maxMpdus) && !StopMpduAggregation (peekedPacket, peekedHdr, currentAggregatedPacket, blockAckSize))
2672
                {
2723
                {
2673
                  //for now always send AMPDU with normal ACK
2724
                  //for now always send AMPDU with normal ACK
2674
                  if (retry == false)
2725
                  if (retry == false)
 Lines 2747-2753   MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr) Link Here 
2747
                              peekedPacket = item->GetPacket ();
2798
                              peekedPacket = item->GetPacket ();
2748
                              peekedHdr = item->GetHeader ();
2799
                              peekedHdr = item->GetHeader ();
2749
                              tstamp = item->GetTimeStamp ();
2800
                              tstamp = item->GetTimeStamp ();
2750
                              //find what will the sequence number be so that we don't send more than 64 packets apart
2751
                              currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2801
                              currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2752
2802
2753
                              if (edcaIt->second->GetMsduAggregator () != 0)
2803
                              if (edcaIt->second->GetMsduAggregator () != 0)
 Lines 2774-2783   MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr) Link Here 
2774
                          peekedPacket = item->GetPacket ();
2824
                          peekedPacket = item->GetPacket ();
2775
                          peekedHdr = item->GetHeader ();
2825
                          peekedHdr = item->GetHeader ();
2776
                          tstamp = item->GetTimeStamp ();
2826
                          tstamp = item->GetTimeStamp ();
2777
                          //find what will the sequence number be so that we don't send more than 64 packets apart
2778
                          currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2827
                          currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&peekedHdr);
2779
2828
2780
                          if (edcaIt->second->GetMsduAggregator () != 0 && IsInWindow (currentSequenceNumber, startingSequenceNumber, 64))
2829
                          if (edcaIt->second->GetMsduAggregator () != 0 && IsInWindow (currentSequenceNumber, startingSequenceNumber, maxMpdus))
2781
                            {
2830
                            {
2782
                              tempPacket = PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2831
                              tempPacket = PerformMsduAggregation (peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, blockAckSize);
2783
                              if (tempPacket != 0) //MSDU aggregation
2832
                              if (tempPacket != 0) //MSDU aggregation
 Lines 2818-2824   MacLow::AggregateToAmpdu (Ptr<const Packet> packet, const WifiMacHeader hdr) Link Here 
2818
                  newPacket = currentAggregatedPacket;
2867
                  newPacket = currentAggregatedPacket;
2819
                  newPacket->AddPacketTag (ampdutag);
2868
                  newPacket->AddPacketTag (ampdutag);
2820
2869
2821
                  NS_LOG_DEBUG ("tx unicast A-MPDU");
2870
                  NS_LOG_DEBUG ("tx unicast A-MPDU containing " << +i << " MPDUs");
2822
                  edcaIt->second->SetAmpduExist (hdr.GetAddr1 (), true);
2871
                  edcaIt->second->SetAmpduExist (hdr.GetAddr1 (), true);
2823
                }
2872
                }
2824
              else
2873
              else
(-)a/src/wifi/model/mac-low.h (-14 / +17 lines)
 Lines 37-42    Link Here 
37
37
38
class TwoLevelAggregationTest;
38
class TwoLevelAggregationTest;
39
class AmpduAggregationTest;
39
class AmpduAggregationTest;
40
class HeAggregationTest;
40
41
41
namespace ns3 {
42
namespace ns3 {
42
43
 Lines 60-67   class MacLow : public Object Link Here 
60
public:
61
public:
61
  /// Allow test cases to access private members
62
  /// Allow test cases to access private members
62
  friend class ::TwoLevelAggregationTest;
63
  friend class ::TwoLevelAggregationTest;
63
  /// Allow test cases to access private members
64
  friend class ::AmpduAggregationTest;
64
  friend class ::AmpduAggregationTest;
65
  friend class ::HeAggregationTest;
66
65
  /**
67
  /**
66
   * typedef for a callback for MacLowRx
68
   * typedef for a callback for MacLowRx
67
   */
69
   */
 Lines 403-419   public: Link Here 
403
   */
405
   */
404
  void DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr, WifiTxVector txVector);
406
  void DeaggregateAmpduAndReceive (Ptr<Packet> aggregatedPacket, double rxSnr, WifiTxVector txVector);
405
  /**
407
  /**
406
   * \param peekedPacket the packet to be aggregated
407
   * \param peekedHdr the WifiMacHeader for the packet.
408
   * \param aggregatedPacket the current A-MPDU
409
   * \param blockAckSize the size of a piggybacked block ack request
410
   * \return false if the given packet can be added to an A-MPDU, true otherwise
411
   *
412
   * This function decides if a given packet can be added to an A-MPDU or not
413
   *
414
   */
415
  bool StopMpduAggregation (Ptr<const Packet> peekedPacket, WifiMacHeader peekedHdr, Ptr<Packet> aggregatedPacket, uint8_t blockAckSize) const;
416
  /**
417
   *
408
   *
418
   * This function is called to flush the aggregate queue, which is used for A-MPDU
409
   * This function is called to flush the aggregate queue, which is used for A-MPDU
419
   * \param tid the Traffic ID
410
   * \param tid the Traffic ID
 Lines 477-482   private: Link Here 
477
   */
468
   */
478
  void SendMpdu (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype);
469
  void SendMpdu (Ptr<const Packet> packet, WifiTxVector txVector, MpduType mpdutype);
479
  /**
470
  /**
471
   * \param peekedPacket the packet to be aggregated
472
   * \param peekedHdr the WifiMacHeader for the packet.
473
   * \param aggregatedPacket the current A-MPDU
474
   * \param blockAckSize the size of a piggybacked block ack request
475
   * \return false if the given packet can be added to an A-MPDU, true otherwise
476
   *
477
   * This function decides if a given packet can be added to an A-MPDU or not
478
   *
479
   */
480
  bool StopMpduAggregation (Ptr<const Packet> peekedPacket, WifiMacHeader peekedHdr, Ptr<Packet> aggregatedPacket, uint8_t blockAckSize) const;
481
  /**
480
   * Return a TXVECTOR for the RTS frame given the destination.
482
   * Return a TXVECTOR for the RTS frame given the destination.
481
   * The function consults WifiRemoteStationManager, which controls the rate
483
   * The function consults WifiRemoteStationManager, which controls the rate
482
   * to different destinations.
484
   * to different destinations.
 Lines 788-796   private: Link Here 
788
   * \param duration the remaining NAV duration
790
   * \param duration the remaining NAV duration
789
   * \param blockAckReqTxVector the transmit vector
791
   * \param blockAckReqTxVector the transmit vector
790
   * \param rxSnr the receive SNR
792
   * \param rxSnr the receive SNR
793
   * \param nMpdus the number of received MPDUs
791
   */
794
   */
792
  void SendBlockAckAfterAmpdu (uint8_t tid, Mac48Address originator,
795
  void SendBlockAckAfterAmpdu (uint8_t tid, Mac48Address originator, Time duration,
793
                               Time duration, WifiTxVector blockAckReqTxVector, double rxSnr);
796
                               WifiTxVector blockAckReqTxVector, double rxSnr, uint8_t nMpdus);
794
  /**
797
  /**
795
   * This method creates block ack frame with header equals to <i>blockAck</i> and start its transmission.
798
   * This method creates block ack frame with header equals to <i>blockAck</i> and start its transmission.
796
   *
799
   *
(-)a/src/wifi/model/mpdu-aggregator.cc (-2 / +2 lines)
 Lines 49-60   MpduAggregator::~MpduAggregator () Link Here 
49
}
49
}
50
50
51
void
51
void
52
MpduAggregator::SetMaxAmpduSize (uint16_t maxSize)
52
MpduAggregator::SetMaxAmpduSize (uint32_t maxSize)
53
{
53
{
54
  m_maxAmpduLength = maxSize;
54
  m_maxAmpduLength = maxSize;
55
}
55
}
56
56
57
uint16_t
57
uint32_t
58
MpduAggregator::GetMaxAmpduSize (void) const
58
MpduAggregator::GetMaxAmpduSize (void) const
59
{
59
{
60
  return m_maxAmpduLength;
60
  return m_maxAmpduLength;
(-)a/src/wifi/model/mpdu-aggregator.h (-3 / +3 lines)
 Lines 60-73   public: Link Here 
60
   *
60
   *
61
   * \param maxSize the maximum A-MPDU size in bytes.
61
   * \param maxSize the maximum A-MPDU size in bytes.
62
   */
62
   */
63
  void SetMaxAmpduSize (uint16_t maxSize);
63
  void SetMaxAmpduSize (uint32_t maxSize);
64
  /**
64
  /**
65
   * Returns the maximum A-MPDU size in bytes.
65
   * Returns the maximum A-MPDU size in bytes.
66
   * Value 0 means that MPDU aggregation is disabled.
66
   * Value 0 means that MPDU aggregation is disabled.
67
   *
67
   *
68
   * \return the maximum A-MPDU size in bytes.
68
   * \return the maximum A-MPDU size in bytes.
69
   */
69
   */
70
  uint16_t GetMaxAmpduSize (void) const;
70
  uint32_t GetMaxAmpduSize (void) const;
71
71
72
  /**
72
  /**
73
   * \param packet Packet we have to insert into <i>aggregatedPacket</i>.
73
   * \param packet Packet we have to insert into <i>aggregatedPacket</i>.
 Lines 124-130   private: Link Here 
124
   */
124
   */
125
  uint8_t CalculatePadding (Ptr<const Packet> packet) const;
125
  uint8_t CalculatePadding (Ptr<const Packet> packet) const;
126
126
127
  uint16_t m_maxAmpduLength; //!< Maximum length in bytes of A-MPDUs
127
  uint32_t m_maxAmpduLength; //!< Maximum length in bytes of A-MPDUs
128
};
128
};
129
129
130
}  //namespace ns3
130
}  //namespace ns3
(-)a/src/wifi/model/originator-block-ack-agreement.cc (-2 / +1 lines)
 Lines 76-83   OriginatorBlockAckAgreement::NotifyMpduTransmission (uint16_t nextSeqNumber) Link Here 
76
  NS_ASSERT (m_sentMpdus < m_bufferSize);
76
  NS_ASSERT (m_sentMpdus < m_bufferSize);
77
  m_sentMpdus++;
77
  m_sentMpdus++;
78
  uint16_t delta = (nextSeqNumber - m_startingSeq + 4096) % 4096;
78
  uint16_t delta = (nextSeqNumber - m_startingSeq + 4096) % 4096;
79
  uint16_t min = m_bufferSize < 64 ? m_bufferSize : 64;
79
  if (delta >= m_bufferSize || m_sentMpdus == m_bufferSize)
80
  if (delta >= min || m_sentMpdus == m_bufferSize)
81
    {
80
    {
82
      m_needBlockAckReq = true;
81
      m_needBlockAckReq = true;
83
    }
82
    }
(-)a/src/wifi/model/qos-txop.cc (+6 lines)
 Lines 117-122   QosTxop::CompleteAmpduTransfer (Mac48Address recipient, uint8_t tid) Link Here 
117
  m_baManager->CompleteAmpduExchange (recipient, tid);
117
  m_baManager->CompleteAmpduExchange (recipient, tid);
118
}
118
}
119
119
120
uint16_t
121
QosTxop::GetBaBufferSize (Mac48Address address, uint8_t tid) const
122
{
123
  return m_baManager->GetRecipientBufferSize (address, tid);
124
}
125
120
void
126
void
121
QosTxop::SetWifiRemoteStationManager (const Ptr<WifiRemoteStationManager> remoteManager)
127
QosTxop::SetWifiRemoteStationManager (const Ptr<WifiRemoteStationManager> remoteManager)
122
{
128
{
(-)a/src/wifi/model/qos-txop.h (+12 lines)
 Lines 29-34    Link Here 
29
#include "qos-utils.h"
29
#include "qos-utils.h"
30
30
31
class AmpduAggregationTest;
31
class AmpduAggregationTest;
32
class HeAggregationTest;
32
33
33
namespace ns3 {
34
namespace ns3 {
34
35
 Lines 92-97   class QosTxop : public Txop Link Here 
92
public:
93
public:
93
  /// Allow test cases to access private members
94
  /// Allow test cases to access private members
94
  friend class ::AmpduAggregationTest;
95
  friend class ::AmpduAggregationTest;
96
  friend class ::HeAggregationTest;
95
97
96
  std::map<Mac48Address, bool> m_aMpduEnabled; //!< list containing flags whether A-MPDU is enabled for a given destination address
98
  std::map<Mac48Address, bool> m_aMpduEnabled; //!< list containing flags whether A-MPDU is enabled for a given destination address
97
99
 Lines 161-166   public: Link Here 
161
   * of an A-MPDU with ImmediateBlockAck policy (i.e. no BAR is scheduled).
163
   * of an A-MPDU with ImmediateBlockAck policy (i.e. no BAR is scheduled).
162
   */
164
   */
163
  void CompleteAmpduTransfer (Mac48Address recipient, uint8_t tid);
165
  void CompleteAmpduTransfer (Mac48Address recipient, uint8_t tid);
166
  /**
167
   * \param address recipient address of the peer station
168
   * \param tid traffic ID.
169
   *
170
   * \return the negociated buffer size during ADDBA handshake.
171
   *
172
   * Returns the negociated buffer size during ADDBA handshake with station addressed by
173
   * <i>recipient</i> for tid <i>tid</i>.
174
   */
175
  uint16_t GetBaBufferSize (Mac48Address address, uint8_t tid) const;
164
176
165
  /* dcf notifications forwarded here */
177
  /* dcf notifications forwarded here */
166
  /**
178
  /**
(-)a/src/wifi/model/regular-wifi-mac.cc (-15 / +19 lines)
 Lines 367-373   RegularWifiMac::SetBkMaxAmsduSize (uint16_t size) Link Here 
367
}
367
}
368
368
369
void
369
void
370
RegularWifiMac::SetVoMaxAmpduSize (uint16_t size)
370
RegularWifiMac::SetVoMaxAmpduSize (uint32_t size)
371
{
371
{
372
  NS_LOG_FUNCTION (this << size);
372
  NS_LOG_FUNCTION (this << size);
373
  m_voMaxAmpduSize = size;
373
  m_voMaxAmpduSize = size;
 Lines 375-381   RegularWifiMac::SetVoMaxAmpduSize (uint16_t size) Link Here 
375
}
375
}
376
376
377
void
377
void
378
RegularWifiMac::SetViMaxAmpduSize (uint16_t size)
378
RegularWifiMac::SetViMaxAmpduSize (uint32_t size)
379
{
379
{
380
  NS_LOG_FUNCTION (this << size);
380
  NS_LOG_FUNCTION (this << size);
381
  m_viMaxAmpduSize = size;
381
  m_viMaxAmpduSize = size;
 Lines 383-389   RegularWifiMac::SetViMaxAmpduSize (uint16_t size) Link Here 
383
}
383
}
384
384
385
void
385
void
386
RegularWifiMac::SetBeMaxAmpduSize (uint16_t size)
386
RegularWifiMac::SetBeMaxAmpduSize (uint32_t size)
387
{
387
{
388
  NS_LOG_FUNCTION (this << size);
388
  NS_LOG_FUNCTION (this << size);
389
  m_beMaxAmpduSize = size;
389
  m_beMaxAmpduSize = size;
 Lines 391-397   RegularWifiMac::SetBeMaxAmpduSize (uint16_t size) Link Here 
391
}
391
}
392
392
393
void
393
void
394
RegularWifiMac::SetBkMaxAmpduSize (uint16_t size)
394
RegularWifiMac::SetBkMaxAmpduSize (uint32_t size)
395
{
395
{
396
  NS_LOG_FUNCTION (this << size);
396
  NS_LOG_FUNCTION (this << size);
397
  m_bkMaxAmpduSize = size;
397
  m_bkMaxAmpduSize = size;
 Lines 1036-1048   RegularWifiMac::SendAddBaResponse (const MgtAddBaRequestHeader *reqHdr, Link Here 
1036
      respHdr.SetDelayedBlockAck ();
1036
      respHdr.SetDelayedBlockAck ();
1037
    }
1037
    }
1038
  respHdr.SetTid (reqHdr->GetTid ());
1038
  respHdr.SetTid (reqHdr->GetTid ());
1039
  //For now there's not no control about limit of reception. We
1039
1040
  //assume that receiver has no limit on reception. However we assume
1040
  Ptr<WifiNetDevice> device = DynamicCast<WifiNetDevice> (GetDevice ());
1041
  //that a receiver sets a bufferSize in order to satisfy next
1041
  Ptr<HeConfiguration> heConfiguration = device->GetHeConfiguration ();
1042
  //equation: (bufferSize + 1) % 16 = 0 So if a recipient is able to
1042
  if (heConfiguration && heConfiguration->GetMpduBufferSize () > 64)
1043
  //buffer a packet, it should be also able to buffer all possible
1043
    {
1044
  //packet's fragments. See section 7.3.1.14 in IEEE802.11e for more details.
1044
      respHdr.SetBufferSize (255);
1045
  respHdr.SetBufferSize (1023);
1045
    }
1046
  else
1047
    {
1048
      respHdr.SetBufferSize (63);
1049
    }
1046
  respHdr.SetTimeout (reqHdr->GetTimeout ());
1050
  respHdr.SetTimeout (reqHdr->GetTimeout ());
1047
1051
1048
  WifiActionHeader actionHdr;
1052
  WifiActionHeader actionHdr;
 Lines 1132-1156   RegularWifiMac::GetTypeId (void) Link Here 
1132
                   "Value 0 means A-MPDU is disabled for that AC.",
1136
                   "Value 0 means A-MPDU is disabled for that AC.",
1133
                   UintegerValue (0),
1137
                   UintegerValue (0),
1134
                   MakeUintegerAccessor (&RegularWifiMac::SetVoMaxAmpduSize),
1138
                   MakeUintegerAccessor (&RegularWifiMac::SetVoMaxAmpduSize),
1135
                   MakeUintegerChecker<uint16_t> ())
1139
                   MakeUintegerChecker<uint32_t> ())
1136
    .AddAttribute ("VI_MaxAmpduSize",
1140
    .AddAttribute ("VI_MaxAmpduSize",
1137
                   "Maximum length in bytes of an A-MPDU for AC_VI access class."
1141
                   "Maximum length in bytes of an A-MPDU for AC_VI access class."
1138
                   "Value 0 means A-MPDU is disabled for that AC.",
1142
                   "Value 0 means A-MPDU is disabled for that AC.",
1139
                   UintegerValue (65535),
1143
                   UintegerValue (65535),
1140
                   MakeUintegerAccessor (&RegularWifiMac::SetViMaxAmpduSize),
1144
                   MakeUintegerAccessor (&RegularWifiMac::SetViMaxAmpduSize),
1141
                   MakeUintegerChecker<uint16_t> ())
1145
                   MakeUintegerChecker<uint32_t> ())
1142
    .AddAttribute ("BE_MaxAmpduSize",
1146
    .AddAttribute ("BE_MaxAmpduSize",
1143
                   "Maximum length in bytes of an A-MPDU for AC_BE access class."
1147
                   "Maximum length in bytes of an A-MPDU for AC_BE access class."
1144
                   "Value 0 means A-MPDU is disabled for that AC.",
1148
                   "Value 0 means A-MPDU is disabled for that AC.",
1145
                   UintegerValue (65535),
1149
                   UintegerValue (65535),
1146
                   MakeUintegerAccessor (&RegularWifiMac::SetBeMaxAmpduSize),
1150
                   MakeUintegerAccessor (&RegularWifiMac::SetBeMaxAmpduSize),
1147
                   MakeUintegerChecker<uint16_t> ())
1151
                   MakeUintegerChecker<uint32_t> ())
1148
    .AddAttribute ("BK_MaxAmpduSize",
1152
    .AddAttribute ("BK_MaxAmpduSize",
1149
                   "Maximum length in bytes of an A-MPDU for AC_BK access class."
1153
                   "Maximum length in bytes of an A-MPDU for AC_BK access class."
1150
                   "Value 0 means A-MPDU is disabled for that AC.",
1154
                   "Value 0 means A-MPDU is disabled for that AC.",
1151
                   UintegerValue (0),
1155
                   UintegerValue (0),
1152
                   MakeUintegerAccessor (&RegularWifiMac::SetBkMaxAmpduSize),
1156
                   MakeUintegerAccessor (&RegularWifiMac::SetBkMaxAmpduSize),
1153
                   MakeUintegerChecker<uint16_t> ())
1157
                   MakeUintegerChecker<uint32_t> ())
1154
    .AddAttribute ("VO_BlockAckThreshold",
1158
    .AddAttribute ("VO_BlockAckThreshold",
1155
                   "If number of packets in VO queue reaches this value, "
1159
                   "If number of packets in VO queue reaches this value, "
1156
                   "block ack mechanism is used. If this value is 0, block ack is never used."
1160
                   "block ack mechanism is used. If this value is 0, block ack is never used."
(-)a/src/wifi/model/regular-wifi-mac.h (-8 / +8 lines)
 Lines 565-589   private: Link Here 
565
   *
565
   *
566
   * \param size the maximum A-MPDU size for AC_VO.
566
   * \param size the maximum A-MPDU size for AC_VO.
567
   */
567
   */
568
  void SetVoMaxAmpduSize (uint16_t size);
568
  void SetVoMaxAmpduSize (uint32_t size);
569
  /**
569
  /**
570
   * Set the maximum A-MPDU size for AC_VI.
570
   * Set the maximum A-MPDU size for AC_VI.
571
   *
571
   *
572
   * \param size the maximum A-MPDU size for AC_VI.
572
   * \param size the maximum A-MPDU size for AC_VI.
573
   */
573
   */
574
  void SetViMaxAmpduSize (uint16_t size);
574
  void SetViMaxAmpduSize (uint32_t size);
575
  /**
575
  /**
576
   * Set the maximum A-MPDU size for AC_BE.
576
   * Set the maximum A-MPDU size for AC_BE.
577
   *
577
   *
578
   * \param size the maximum A-MPDU size for AC_BE.
578
   * \param size the maximum A-MPDU size for AC_BE.
579
   */
579
   */
580
  void SetBeMaxAmpduSize (uint16_t size);
580
  void SetBeMaxAmpduSize (uint32_t size);
581
  /**
581
  /**
582
   * Set the maximum A-MPDU size for AC_BK.
582
   * Set the maximum A-MPDU size for AC_BK.
583
   *
583
   *
584
   * \param size the maximum A-MPDU size for AC_BK.
584
   * \param size the maximum A-MPDU size for AC_BK.
585
   */
585
   */
586
  void SetBkMaxAmpduSize (uint16_t size);
586
  void SetBkMaxAmpduSize (uint32_t size);
587
587
588
  /**
588
  /**
589
   * Set the Block ACK threshold for AC_VO.
589
   * Set the Block ACK threshold for AC_VO.
 Lines 672-681   private: Link Here 
672
  uint16_t m_beMaxAmsduSize; ///< maximum A-MSDU size for AC_BE
672
  uint16_t m_beMaxAmsduSize; ///< maximum A-MSDU size for AC_BE
673
  uint16_t m_bkMaxAmsduSize; ///< maximum A-MSDU size for AC_BK
673
  uint16_t m_bkMaxAmsduSize; ///< maximum A-MSDU size for AC_BK
674
674
675
  uint16_t m_voMaxAmpduSize; ///< maximum A-MPDU size for AC_VO
675
  uint32_t m_voMaxAmpduSize; ///< maximum A-MPDU size for AC_VO
676
  uint16_t m_viMaxAmpduSize; ///< maximum A-MPDU size for AC_VI
676
  uint32_t m_viMaxAmpduSize; ///< maximum A-MPDU size for AC_VI
677
  uint16_t m_beMaxAmpduSize; ///< maximum A-MPDU size for AC_BE
677
  uint32_t m_beMaxAmpduSize; ///< maximum A-MPDU size for AC_BE
678
  uint16_t m_bkMaxAmpduSize; ///< maximum A-MPDU size for AC_BK
678
  uint32_t m_bkMaxAmpduSize; ///< maximum A-MPDU size for AC_BK
679
679
680
  TracedCallback<const WifiMacHeader &> m_txOkCallback; ///< transmit OK callback
680
  TracedCallback<const WifiMacHeader &> m_txOkCallback; ///< transmit OK callback
681
  TracedCallback<const WifiMacHeader &> m_txErrCallback; ///< transmit error callback
681
  TracedCallback<const WifiMacHeader &> m_txErrCallback; ///< transmit error callback
(-)a/src/wifi/model/sta-wifi-mac.h (-1 / +3 lines)
 Lines 28-33    Link Here 
28
28
29
class TwoLevelAggregationTest;
29
class TwoLevelAggregationTest;
30
class AmpduAggregationTest;
30
class AmpduAggregationTest;
31
class HeAggregationTest;
31
32
32
namespace ns3  {
33
namespace ns3  {
33
34
 Lines 109-115   public: Link Here 
109
  friend class ::TwoLevelAggregationTest;
110
  friend class ::TwoLevelAggregationTest;
110
  /// Allow test cases to access private members
111
  /// Allow test cases to access private members
111
  friend class ::AmpduAggregationTest;
112
  friend class ::AmpduAggregationTest;
112
113
  /// Allow test cases to access private members
114
  friend class ::HeAggregationTest;
113
  /**
115
  /**
114
   * \brief Get the type ID.
116
   * \brief Get the type ID.
115
   * \return the object TypeId
117
   * \return the object TypeId
(-)a/src/wifi/model/wifi-utils.cc (-13 / +1 lines)
 Lines 118-136   GetBlockAckSize (BlockAckType type) Link Here 
118
  WifiMacHeader hdr;
118
  WifiMacHeader hdr;
119
  hdr.SetType (WIFI_MAC_CTL_BACKRESP);
119
  hdr.SetType (WIFI_MAC_CTL_BACKRESP);
120
  CtrlBAckResponseHeader blockAck;
120
  CtrlBAckResponseHeader blockAck;
121
  if (type == BASIC_BLOCK_ACK)
121
  blockAck.SetType (type);
122
    {
123
      blockAck.SetType (BASIC_BLOCK_ACK);
124
    }
125
  else if (type == COMPRESSED_BLOCK_ACK)
126
    {
127
      blockAck.SetType (COMPRESSED_BLOCK_ACK);
128
    }
129
  else if (type == MULTI_TID_BLOCK_ACK)
130
    {
131
      //Not implemented
132
      NS_ASSERT (false);
133
    }
134
  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
122
  return hdr.GetSize () + blockAck.GetSerializedSize () + 4;
135
}
123
}
136
124
(-)a/src/wifi/model/wifi-utils.h (-1 / +1 lines)
 Lines 120-126   uint32_t GetCtsSize (void); Link Here 
120
/**
120
/**
121
 * \param seq MPDU sequence number
121
 * \param seq MPDU sequence number
122
 * \param winstart sequence number window start
122
 * \param winstart sequence number window start
123
 * \param winsize the size of the sequence number window (currently default is 64)
123
 * \param winsize the size of the sequence number window
124
 * \returns true if in the window
124
 * \returns true if in the window
125
 *
125
 *
126
 * This method checks if the MPDU's sequence number is inside the scoreboard boundaries or not
126
 * This method checks if the MPDU's sequence number is inside the scoreboard boundaries or not
(-)a/src/wifi/test/wifi-aggregation-test.cc (-1 / +155 lines)
 Lines 30-35    Link Here 
30
#include "ns3/mpdu-aggregator.h"
30
#include "ns3/mpdu-aggregator.h"
31
#include "ns3/wifi-net-device.h"
31
#include "ns3/wifi-net-device.h"
32
#include "ns3/ht-configuration.h"
32
#include "ns3/ht-configuration.h"
33
#include "ns3/vht-configuration.h"
34
#include "ns3/he-configuration.h"
33
35
34
using namespace ns3;
36
using namespace ns3;
35
37
 Lines 124-130   AmpduAggregationTest::DoRun (void) Link Here 
124
  MgtAddBaRequestHeader reqHdr;
126
  MgtAddBaRequestHeader reqHdr;
125
  reqHdr.SetImmediateBlockAck ();
127
  reqHdr.SetImmediateBlockAck ();
126
  reqHdr.SetTid (0);
128
  reqHdr.SetTid (0);
127
  reqHdr.SetBufferSize (0);
129
  reqHdr.SetBufferSize (64);
128
  reqHdr.SetTimeout (0);
130
  reqHdr.SetTimeout (0);
129
  reqHdr.SetStartingSequence (0);
131
  reqHdr.SetStartingSequence (0);
130
  m_mac->GetBEQueue ()->m_baManager->CreateAgreement (&reqHdr, hdr.GetAddr1 ());
132
  m_mac->GetBEQueue ()->m_baManager->CreateAgreement (&reqHdr, hdr.GetAddr1 ());
 Lines 388-393   TwoLevelAggregationTest::DoRun (void) Link Here 
388
 * \ingroup wifi-test
390
 * \ingroup wifi-test
389
 * \ingroup tests
391
 * \ingroup tests
390
 *
392
 *
393
 * \brief 802.11ax aggregation test which permits 64 or 256 MPDUs in A-MPDU according to the negociated buffer size.
394
 */
395
class HeAggregationTest : public TestCase
396
{
397
public:
398
  HeAggregationTest ();
399
400
private:
401
  void DoRun (void);
402
  void DoRunSubTest (uint16_t bufferSize);
403
  Ptr<WifiNetDevice> m_device; ///<WifiNetDevice
404
  Ptr<StaWifiMac> m_mac; ///< Mac
405
  Ptr<YansWifiPhy> m_phy; ///< Phy
406
  Ptr<WifiRemoteStationManager> m_manager; ///< remote station manager
407
  ObjectFactory m_factory; ///< factory
408
};
409
410
HeAggregationTest::HeAggregationTest ()
411
  : TestCase ("Check the correctness of 802.11ax aggregation operations")
412
{
413
}
414
415
void
416
HeAggregationTest::DoRunSubTest (uint16_t bufferSize)
417
{
418
  /*
419
   * Create device and attach configurations.
420
   */
421
  m_device = CreateObject<WifiNetDevice> ();
422
  Ptr<HtConfiguration> htConfiguration = CreateObject<HtConfiguration> ();
423
  m_device->SetHtConfiguration (htConfiguration);
424
  Ptr<VhtConfiguration> vhtConfiguration = CreateObject<VhtConfiguration> ();
425
  m_device->SetVhtConfiguration (vhtConfiguration);
426
  Ptr<HeConfiguration> heConfiguration = CreateObject<HeConfiguration> ();
427
  m_device->SetHeConfiguration (heConfiguration);
428
429
  /*
430
   * Create and configure phy layer.
431
   */
432
  m_phy = CreateObject<YansWifiPhy> ();
433
  m_phy->SetDevice (m_device);
434
  m_phy->ConfigureStandard (WIFI_PHY_STANDARD_80211ax_5GHZ);
435
  m_device->SetPhy (m_phy);
436
437
  /*
438
   * Create and configure manager.
439
   */
440
  m_factory = ObjectFactory ();
441
  m_factory.SetTypeId ("ns3::ConstantRateWifiManager");
442
  m_factory.Set ("DataMode", StringValue ("HeMcs11"));
443
  m_manager = m_factory.Create<WifiRemoteStationManager> ();
444
  m_manager->SetupPhy (m_phy);
445
  m_device->SetRemoteStationManager (m_manager);
446
447
  /*
448
   * Create and configure mac layer.
449
   */
450
  m_mac = CreateObject<StaWifiMac> ();
451
  m_mac->SetDevice (m_device);
452
  m_mac->SetWifiPhy (m_phy);
453
  m_mac->SetWifiRemoteStationManager (m_manager);
454
  m_mac->SetAddress (Mac48Address ("00:00:00:00:00:01"));
455
  m_mac->ConfigureStandard (WIFI_PHY_STANDARD_80211ax_5GHZ);
456
  m_device->SetMac (m_mac);
457
458
  /*
459
   * Configure MPDU aggregation.
460
   */
461
  m_mac->GetBEQueue ()->GetMpduAggregator ()->SetMaxAmpduSize (4194304); //Maximum size allowed by 802.11ax
462
463
  /*
464
   * Create a dummy packet of 100 bytes and fill mac header fields.
465
   */
466
  Ptr<const Packet> pkt = Create<Packet> (100);
467
  Ptr<Packet> currentAggregatedPacket = Create<Packet> ();
468
  WifiMacHeader hdr;
469
  hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
470
  hdr.SetAddr2 (Mac48Address ("00:00:00:00:00:01"));
471
  hdr.SetType (WIFI_MAC_QOSDATA);
472
  hdr.SetQosTid (0);
473
  uint16_t sequence = m_mac->m_txMiddle->GetNextSequenceNumberFor (&hdr);
474
  hdr.SetSequenceNumber (sequence);
475
  hdr.SetFragmentNumber (0);
476
  hdr.SetNoMoreFragments ();
477
  hdr.SetNoRetry ();
478
479
  /*
480
   * Establish agreement.
481
   */
482
  MgtAddBaRequestHeader reqHdr;
483
  reqHdr.SetImmediateBlockAck ();
484
  reqHdr.SetTid (0);
485
  reqHdr.SetBufferSize (bufferSize);
486
  reqHdr.SetTimeout (0);
487
  reqHdr.SetStartingSequence (0);
488
  m_mac->GetBEQueue ()->m_baManager->CreateAgreement (&reqHdr, hdr.GetAddr1 ());
489
490
  /*
491
   * Prepare MacLow for transmission
492
   */
493
  m_mac->GetBEQueue ()->GetLow ()->m_currentHdr = hdr;
494
  m_mac->GetBEQueue ()->GetLow ()->m_currentPacket = pkt->Copy ();
495
  m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector = m_mac->GetBEQueue ()->GetLow ()->GetDataTxVector (m_mac->GetBEQueue ()->GetLow ()->m_currentPacket, &m_mac->GetBEQueue ()->GetLow ()->m_currentHdr);
496
497
  /*
498
   * Test behavior when 300 packets are ready for transmission but negociated buffer size is 64
499
   */
500
  for (uint16_t i = 0; i < 300; i++)
501
    {
502
      Ptr<const Packet> pkt = Create<Packet> (100);
503
      WifiMacHeader hdr;
504
505
      hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:02"));
506
      hdr.SetAddr2 (Mac48Address ("00:00:00:00:00:01"));
507
      hdr.SetType (WIFI_MAC_QOSDATA);
508
      hdr.SetQosTid (0);
509
510
      m_mac->GetBEQueue ()->GetWifiMacQueue ()->Enqueue (Create<WifiMacQueueItem> (pkt, hdr));
511
  }
512
513
  bool isAmpdu = m_mac->GetBEQueue ()->GetLow ()->IsAmpdu (pkt, hdr);
514
  NS_TEST_EXPECT_MSG_EQ (isAmpdu, true, "MPDU aggregation failed");
515
  uint32_t aggregationQueueSize = m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->GetNPackets ();
516
  NS_TEST_EXPECT_MSG_EQ (aggregationQueueSize, bufferSize, "aggregation queue should countain " << bufferSize << " MPDUs");
517
  uint16_t expectedRemainingPacketsInQueue = 300 - bufferSize + 1;
518
  NS_TEST_EXPECT_MSG_EQ (m_mac->GetBEQueue ()->GetWifiMacQueue ()->GetNPackets (), expectedRemainingPacketsInQueue, "queue should contain 300 - "<< bufferSize - 1 << " = "<< expectedRemainingPacketsInQueue << " packets");
519
520
  Simulator::Destroy ();
521
522
  m_manager->Dispose ();
523
  m_manager = 0;
524
525
  m_device->Dispose ();
526
  m_device = 0;
527
528
  htConfiguration = 0;
529
  vhtConfiguration = 0;
530
  heConfiguration = 0;
531
}
532
533
void
534
HeAggregationTest::DoRun ()
535
{
536
  DoRunSubTest (64);
537
  DoRunSubTest (256);
538
}
539
540
/**
541
 * \ingroup wifi-test
542
 * \ingroup tests
543
 *
391
 * \brief Wifi Aggregation Test Suite
544
 * \brief Wifi Aggregation Test Suite
392
 */
545
 */
393
class WifiAggregationTestSuite : public TestSuite
546
class WifiAggregationTestSuite : public TestSuite
 Lines 401-406   WifiAggregationTestSuite::WifiAggregationTestSuite () Link Here 
401
{
554
{
402
  AddTestCase (new AmpduAggregationTest, TestCase::QUICK);
555
  AddTestCase (new AmpduAggregationTest, TestCase::QUICK);
403
  AddTestCase (new TwoLevelAggregationTest, TestCase::QUICK);
556
  AddTestCase (new TwoLevelAggregationTest, TestCase::QUICK);
557
  AddTestCase (new HeAggregationTest, TestCase::QUICK);
404
}
558
}
405
559
406
static WifiAggregationTestSuite g_wifiAggregationTestSuite; ///< the test suite
560
static WifiAggregationTestSuite g_wifiAggregationTestSuite; ///< the test suite

Return to bug 3010