A Discrete-Event Network Simulator
API
ctrl-headers.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 MIRKO BANCHI
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mirko Banchi <mk.banchi@gmail.com>
19  */
20 
21 #include "ctrl-headers.h"
22 
23 namespace ns3 {
24 
25 
26 /***********************************
27  * Block ack request
28  ***********************************/
29 
30 NS_OBJECT_ENSURE_REGISTERED (CtrlBAckRequestHeader);
31 
33  : m_barAckPolicy (false),
34  m_baType (BASIC_BLOCK_ACK)
35 {
36 }
37 
39 {
40 }
41 
42 TypeId
44 {
45  static TypeId tid = TypeId ("ns3::CtrlBAckRequestHeader")
46  .SetParent<Header> ()
47  .SetGroupName ("Wifi")
48  .AddConstructor<CtrlBAckRequestHeader> ()
49  ;
50  return tid;
51 }
52 
53 TypeId
55 {
56  return GetTypeId ();
57 }
58 
59 void
60 CtrlBAckRequestHeader::Print (std::ostream &os) const
61 {
62  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
63 }
64 
65 uint32_t
67 {
68  uint32_t size = 0;
69  size += 2; //Bar control
70  switch (m_baType)
71  {
72  case BASIC_BLOCK_ACK:
75  size += 2;
76  break;
78  size += (2 + 2) * (m_tidInfo + 1);
79  break;
80  default:
81  NS_FATAL_ERROR ("Invalid BA type");
82  break;
83  }
84  return size;
85 }
86 
87 void
89 {
92  switch (m_baType)
93  {
94  case BASIC_BLOCK_ACK:
98  break;
100  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
101  break;
102  default:
103  NS_FATAL_ERROR ("Invalid BA type");
104  break;
105  }
106 }
107 
108 uint32_t
110 {
113  switch (m_baType)
114  {
115  case BASIC_BLOCK_ACK:
119  break;
120  case MULTI_TID_BLOCK_ACK:
121  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
122  break;
123  default:
124  NS_FATAL_ERROR ("Invalid BA type");
125  break;
126  }
127  return i.GetDistanceFrom (start);
128 }
129 
130 uint16_t
132 {
133  uint16_t res = 0;
134  switch (m_baType)
135  {
136  case BASIC_BLOCK_ACK:
137  break;
139  res |= (0x02 << 1);
140  break;
142  res |= (0x01 << 1);
143  break;
144  case MULTI_TID_BLOCK_ACK:
145  res |= (0x03 << 1);
146  break;
147  default:
148  NS_FATAL_ERROR ("Invalid BA type");
149  break;
150  }
151  res |= (m_tidInfo << 12) & (0xf << 12);
152  return res;
153 }
154 
155 void
157 {
158  m_barAckPolicy = ((bar & 0x01) == 1) ? true : false;
159  if (((bar >> 1) & 0x0f) == 0x03)
160  {
162  }
163  else if (((bar >> 1) & 0x0f) == 0x01)
164  {
166  }
167  else if (((bar >> 1) & 0x0f) == 0x02)
168  {
170  }
171  else
172  {
174  }
175  m_tidInfo = (bar >> 12) & 0x0f;
176 }
177 
178 uint16_t
180 {
181  return (m_startingSeq << 4) & 0xfff0;
182 }
183 
184 void
186 {
187  m_startingSeq = (seqControl >> 4) & 0x0fff;
188 }
189 
190 void
192 {
193  m_barAckPolicy = immediateAck;
194 }
195 
196 void
198 {
199  m_baType = type;
200 }
201 
204 {
205  return m_baType;
206 }
207 
208 void
210 {
211  m_tidInfo = static_cast<uint16_t> (tid);
212 }
213 
214 void
216 {
217  m_startingSeq = seq;
218 }
219 
220 bool
222 {
223  return m_barAckPolicy;
224 }
225 
226 uint8_t
228 {
229  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
230  return tid;
231 }
232 
233 uint16_t
235 {
236  return m_startingSeq;
237 }
238 
239 bool
241 {
242  return (m_baType == BASIC_BLOCK_ACK) ? true : false;
243 }
244 
245 bool
247 {
248  return (m_baType == COMPRESSED_BLOCK_ACK) ? true : false;
249 }
250 
251 bool
253 {
254  return (m_baType == EXTENDED_COMPRESSED_BLOCK_ACK) ? true : false;
255 }
256 
257 bool
259 {
260  return (m_baType == MULTI_TID_BLOCK_ACK) ? true : false;
261 }
262 
263 
264 /***********************************
265  * Block ack response
266  ***********************************/
267 
269 
271  : m_baAckPolicy (false),
272  m_baType (BASIC_BLOCK_ACK)
273 {
274  memset (&bitmap, 0, sizeof (bitmap));
275 }
276 
278 {
279 }
280 
281 TypeId
283 {
284  static TypeId tid = TypeId ("ns3::CtrlBAckResponseHeader")
285  .SetParent<Header> ()
286  .SetGroupName ("Wifi")
287  .AddConstructor<CtrlBAckResponseHeader> ()
288  ;
289  return tid;
290 }
291 
292 TypeId
294 {
295  return GetTypeId ();
296 }
297 
298 void
299 CtrlBAckResponseHeader::Print (std::ostream &os) const
300 {
301  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
302 }
303 
304 uint32_t
306 {
307  uint32_t size = 0;
308  size += 2; //Bar control
309  switch (m_baType)
310  {
311  case BASIC_BLOCK_ACK:
312  size += (2 + 128);
313  break;
315  size += (2 + 8);
316  break;
318  size += (2 + 32);
319  break;
320  case MULTI_TID_BLOCK_ACK:
321  size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-TID block ack
322  break;
323  default:
324  NS_FATAL_ERROR ("Invalid BA type");
325  break;
326  }
327  return size;
328 }
329 
330 void
332 {
335  switch (m_baType)
336  {
337  case BASIC_BLOCK_ACK:
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;
349  }
350 }
351 
352 uint32_t
354 {
357  switch (m_baType)
358  {
359  case BASIC_BLOCK_ACK:
363  i = DeserializeBitmap (i);
364  break;
365  case MULTI_TID_BLOCK_ACK:
366  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
367  break;
368  default:
369  NS_FATAL_ERROR ("Invalid BA type");
370  break;
371  }
372  return i.GetDistanceFrom (start);
373 }
374 
375 void
377 {
378  m_baAckPolicy = immediateAck;
379 }
380 
381 void
383 {
384  m_baType = type;
385 }
386 
389 {
390  return m_baType;
391 }
392 
393 void
395 {
396  m_tidInfo = static_cast<uint16_t> (tid);
397 }
398 
399 void
401 {
402  m_startingSeq = seq;
403 }
404 
405 bool
407 {
408  return (m_baAckPolicy) ? true : false;
409 }
410 
411 uint8_t
413 {
414  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
415  return tid;
416 }
417 
418 uint16_t
420 {
421  return m_startingSeq;
422 }
423 
424 bool
426 {
427  return (m_baType == BASIC_BLOCK_ACK) ? true : false;
428 }
429 
430 bool
432 {
433  return (m_baType == COMPRESSED_BLOCK_ACK) ? true : false;
434 }
435 
436 bool
438 {
439  return (m_baType == EXTENDED_COMPRESSED_BLOCK_ACK) ? true : false;
440 }
441 
442 bool
444 {
445  return (m_baType == MULTI_TID_BLOCK_ACK) ? true : false;
446 }
447 
448 uint16_t
450 {
451  uint16_t res = 0;
452  if (m_baAckPolicy)
453  {
454  res |= 0x1;
455  }
456  switch (m_baType)
457  {
458  case BASIC_BLOCK_ACK:
459  break;
461  res |= (0x02 << 1);
462  break;
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;
472  }
473  res |= (m_tidInfo << 12) & (0xf << 12);
474  return res;
475 }
476 
477 void
479 {
480  m_baAckPolicy = ((ba & 0x01) == 1) ? true : false;
481  if (((ba >> 1) & 0x0f) == 0x03)
482  {
484  }
485  else if (((ba >> 1) & 0x0f) == 0x01)
486  {
488  }
489  else if (((ba >> 1) & 0x0f) == 0x02)
490  {
492  }
493  else
494  {
496  }
497  m_tidInfo = (ba >> 12) & 0x0f;
498 }
499 
500 uint16_t
502 {
503  return (m_startingSeq << 4) & 0xfff0;
504 }
505 
506 void
508 {
509  m_startingSeq = (seqControl >> 4) & 0x0fff;
510 }
511 
514 {
516  switch (m_baType)
517  {
518  case BASIC_BLOCK_ACK:
519  for (uint8_t j = 0; j < 64; j++)
520  {
521  i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
522  }
523  break;
525  i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
526  break;
528  i.WriteHtolsbU64 (bitmap.m_extendedCompressedBitmap[0]);
529  i.WriteHtolsbU64 (bitmap.m_extendedCompressedBitmap[1]);
530  i.WriteHtolsbU64 (bitmap.m_extendedCompressedBitmap[2]);
531  i.WriteHtolsbU64 (bitmap.m_extendedCompressedBitmap[3]);
532  break;
533  case MULTI_TID_BLOCK_ACK:
534  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
535  break;
536  default:
537  NS_FATAL_ERROR ("Invalid BA type");
538  break;
539  }
540  return i;
541 }
542 
545 {
547  switch (m_baType)
548  {
549  case BASIC_BLOCK_ACK:
550  for (uint8_t j = 0; j < 64; j++)
551  {
552  bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
553  }
554  break;
556  bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
557  break;
559  bitmap.m_extendedCompressedBitmap[0] = i.ReadLsbtohU64 ();
560  bitmap.m_extendedCompressedBitmap[1] = i.ReadLsbtohU64 ();
561  bitmap.m_extendedCompressedBitmap[2] = i.ReadLsbtohU64 ();
562  bitmap.m_extendedCompressedBitmap[3] = i.ReadLsbtohU64 ();
563  break;
564  case MULTI_TID_BLOCK_ACK:
565  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
566  break;
567  default:
568  NS_FATAL_ERROR ("Invalid BA type");
569  break;
570  }
571  return i;
572 }
573 
574 void
576 {
577  if (!IsInBitmap (seq))
578  {
579  return;
580  }
581  switch (m_baType)
582  {
583  case BASIC_BLOCK_ACK:
584  {
585  /* To set correctly basic block ack bitmap we need fragment number too.
586  So if it's not specified, we consider packet not fragmented. */
587  bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
588  break;
589  }
591  {
592  bitmap.m_compressedBitmap |= (uint64_t (0x0000000000000001) << IndexInBitmap (seq));
593  break;
594  }
596  {
597  uint16_t index = IndexInBitmap (seq);
598  bitmap.m_extendedCompressedBitmap[index/64] |= (uint64_t (0x0000000000000001) << index);
599  break;
600  }
601  case MULTI_TID_BLOCK_ACK:
602  {
603  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
604  break;
605  }
606  default:
607  {
608  NS_FATAL_ERROR ("Invalid BA type");
609  break;
610  }
611  }
612 }
613 
614 void
616 {
617  NS_ASSERT (frag < 16);
618  if (!IsInBitmap (seq))
619  {
620  return;
621  }
622  switch (m_baType)
623  {
624  case BASIC_BLOCK_ACK:
625  bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001 << frag);
626  break;
629  /* We can ignore this...compressed block ack doesn't support
630  acknowledgment of single fragments */
631  break;
632  case MULTI_TID_BLOCK_ACK:
633  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
634  break;
635  default:
636  NS_FATAL_ERROR ("Invalid BA type");
637  break;
638  }
639 }
640 
641 bool
643 {
644  if (!IsInBitmap (seq))
645  {
646  return false;
647  }
648  switch (m_baType)
649  {
650  case BASIC_BLOCK_ACK:
651  {
652  /*It's impossible to say if an entire packet was correctly received. */
653  return false;
654  }
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. */
660  uint64_t mask = uint64_t (0x0000000000000001);
661  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
662  }
664  {
665  uint64_t mask = uint64_t (0x0000000000000001);
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:
670  {
671  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
672  break;
673  }
674  default:
675  {
676  NS_FATAL_ERROR ("Invalid BA type");
677  break;
678  }
679  }
680  return false;
681 }
682 
683 bool
684 CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const
685 {
686  NS_ASSERT (frag < 16);
687  if (!IsInBitmap (seq))
688  {
689  return false;
690  }
691  switch (m_baType)
692  {
693  case BASIC_BLOCK_ACK:
694  {
695  return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001 << frag)) != 0x0000) ? true : false;
696  }
698  {
699  /* Although this could make no sense, if packet with sequence number
700  equal to <i>seq</i> was correctly received, also all of its fragments
701  were correctly received. */
702  uint64_t mask = uint64_t (0x0000000000000001);
703  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
704  }
706  {
707  uint64_t mask = uint64_t (0x0000000000000001);
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:
712  {
713  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
714  break;
715  }
716  default:
717  {
718  NS_FATAL_ERROR ("Invalid BA type");
719  break;
720  }
721  }
722  return false;
723 }
724 
725 uint16_t
727 {
728  uint16_t index;
729  if (seq >= m_startingSeq)
730  {
731  index = seq - m_startingSeq;
732  }
733  else
734  {
735  index = 4096 - m_startingSeq + seq;
736  }
738  {
739  NS_ASSERT (index <= 255);
740  }
741  else
742  {
743  NS_ASSERT (index <= 63);
744  }
745  return index;
746 }
747 
748 bool
750 {
752  {
753  return (seq - m_startingSeq + 4096) % 4096 < 256;
754  }
755  else
756  {
757  return (seq - m_startingSeq + 4096) % 4096 < 64;
758  }
759 }
760 
761 const uint16_t*
763 {
764  return bitmap.m_bitmap;
765 }
766 
767 uint64_t
769 {
770  return bitmap.m_compressedBitmap;
771 }
772 
773 const uint64_t*
775 {
776  return bitmap.m_extendedCompressedBitmap;
777 }
778 
779 void
781 {
782  memset (&bitmap, 0, sizeof (bitmap));
783 }
784 
785 } //namespace ns3
Protocol header serialization and deserialization.
Definition: header.h:42
TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: ctrl-headers.cc:54
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
Buffer::Iterator SerializeBitmap(Buffer::Iterator start) const
Serialize bitmap to the given buffer.
uint16_t GetBaControl(void) const
Return the Block Ack control.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
def start()
Definition: core.py:1855
uint32_t GetSerializedSize(void) const
void SetStartingSequenceControl(uint16_t seqControl)
Set the starting sequence control with the given sequence control value.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
void SetBarControl(uint16_t bar)
Set the Block Ack control.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate Ack.
bool m_baAckPolicy
The LSB bit of the BA control field is used only for the HT (High Throughput) delayed block ack confi...
Definition: ctrl-headers.h:423
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
void Serialize(Buffer::Iterator start) const
bool IsExtendedCompressed(void) const
Check if the current BA policy is Extended Compressed Block Ack.
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
bool IsBasic(void) const
Check if the current BA policy is Basic Block Ack.
void SetType(BlockAckType type)
Set the block ack type.
iterator in a Buffer instance
Definition: buffer.h:98
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:783
union ns3::CtrlBAckResponseHeader::@72 bitmap
bitmap union type
bool IsCompressed(void) const
Check if the current BA policy is Compressed Block Ack.
bool MustSendHtImmediateAck(void) const
Check if the current Ack Policy is immediate.
bool m_barAckPolicy
The LSB bit of the BAR control field is used only for the HT (High Throughput) delayed block ack conf...
Definition: ctrl-headers.h:174
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
void Print(std::ostream &os) const
Definition: ctrl-headers.cc:60
uint64_t GetCompressedBitmap(void) const
Return the compressed bitmap from the BlockAck response header.
uint16_t m_startingSeq
starting sequence number
Definition: ctrl-headers.h:177
bool IsPacketReceived(uint16_t seq) const
Check if the packet with the given sequence number was acknowledged in this BlockAck response...
Headers for BlockAck response.
Definition: ctrl-headers.h:193
uint32_t GetSerializedSize(void) const
Definition: ctrl-headers.cc:66
static TypeId GetTypeId(void)
Get the type ID.
Definition: ctrl-headers.cc:43
uint16_t m_tidInfo
TID info.
Definition: ctrl-headers.h:425
bool IsCompressed(void) const
Check if the current Ack Policy is Compressed Block Ack and not multi-TID.
bool IsExtendedCompressed(void) const
Check if the current Ack Policy is Extended Compressed Block Ack.
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
uint16_t IndexInBitmap(uint16_t seq) const
This function is used to correctly index in both bitmap and compressed bitmap, one bit or one block o...
const uint16_t * GetBitmap(void) const
Return the bitmap from the BlockAck response header.
uint32_t Deserialize(Buffer::Iterator start)
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Buffer::Iterator DeserializeBitmap(Buffer::Iterator start)
Deserialize bitmap from the given buffer.
const uint64_t * GetExtendedCompressedBitmap(void) const
Return the extended compressed bitmap from the BlockAck response header.
static TypeId GetTypeId(void)
Get the type ID.
BlockAckType GetType(void) const
Return the Block Ack type ID.
void SetType(BlockAckType type)
Set the block ack type.
bool IsMultiTid(void) const
Check if the current Ack Policy has Multi-TID Block Ack.
bool IsBasic(void) const
Check if the current Ack Policy is Basic Block Ack (i.e.
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
BlockAckType m_baType
BA type.
Definition: ctrl-headers.h:424
void ResetBitmap(void)
Reset the bitmap to 0.
bool IsFragmentReceived(uint16_t seq, uint8_t frag) const
Check if the packet with the given sequence number and fragment number was acknowledged in this Block...
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:910
uint16_t m_startingSeq
starting sequence number
Definition: ctrl-headers.h:426
void SetReceivedFragment(uint16_t seq, uint8_t frag)
Set the bitmap that the packet with the given sequence number and fragment number was received...
TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
void SetStartingSequenceControl(uint16_t seqControl)
Set the starting sequence control with the given sequence control value.
void SetReceivedPacket(uint16_t seq)
Set the bitmap that the packet with the given sequence number was received.
uint16_t GetBarControl(void) const
Return the Block Ack control.
bool IsInBitmap(uint16_t seq) const
Checks if sequence number seq can be acknowledged in the bitmap.
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:926
uint32_t Deserialize(Buffer::Iterator start)
uint16_t m_tidInfo
TID info.
Definition: ctrl-headers.h:176
bool IsMultiTid(void) const
Check if the current BA policy is Multi-TID Block Ack.
BlockAckType m_baType
BA type.
Definition: ctrl-headers.h:175
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate Ack.
void Print(std::ostream &os) const
BlockAckType GetType(void) const
Return the block ack type ID.
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1065
void Serialize(Buffer::Iterator start) const
Definition: ctrl-headers.cc:88
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1093
Headers for BlockAckRequest.
Definition: ctrl-headers.h:41
a unique identifier for an interface.
Definition: type-id.h:58
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
bool MustSendHtImmediateAck(void) const
Check if the current Ack Policy is immediate.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
void SetBaControl(uint16_t ba)
Set the Block Ack control.
BlockAckType
The different block ack policies.