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_multiTid (false),
35  m_compressed (false)
36 {
37 }
38 
40 {
41 }
42 
43 TypeId
45 {
46  static TypeId tid = TypeId ("ns3::CtrlBAckRequestHeader")
47  .SetParent<Header> ()
48  .SetGroupName ("Wifi")
49  .AddConstructor<CtrlBAckRequestHeader> ()
50  ;
51  return tid;
52 }
53 
54 TypeId
56 {
57  return GetTypeId ();
58 }
59 
60 void
61 CtrlBAckRequestHeader::Print (std::ostream &os) const
62 {
63  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
64 }
65 
66 uint32_t
68 {
69  uint32_t size = 0;
70  size += 2; //Bar control
71  if (!m_multiTid)
72  {
73  size += 2; //Starting sequence control
74  }
75  else if (m_compressed)
76  {
77  size += (2 + 2) * (m_tidInfo + 1); //Multi-tid block ack
78  }
79  else
80  {
81  NS_FATAL_ERROR ("Reserved configuration.");
82  }
83  return size;
84 }
85 
86 void
88 {
91  if (!m_multiTid)
92  {
94  }
95  else if (m_compressed)
96  {
97  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
98  }
99  else
100  {
101  NS_FATAL_ERROR ("Reserved configuration.");
102  }
103 }
104 
105 uint32_t
107 {
110  if (!m_multiTid)
111  {
113  }
114  else if (m_compressed)
115  {
116  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
117  }
118  else
119  {
120  NS_FATAL_ERROR ("Reserved configuration.");
121  }
122  return i.GetDistanceFrom (start);
123 }
124 
125 uint16_t
127 {
128  uint16_t res = 0;
129  if (m_barAckPolicy)
130  {
131  res |= 0x1;
132  }
133  if (m_multiTid)
134  {
135  res |= (0x1 << 1);
136  }
137  if (m_compressed)
138  {
139  res |= (0x1 << 2);
140  }
141  res |= (m_tidInfo << 12) & (0xf << 12);
142  return res;
143 }
144 
145 void
147 {
148  m_barAckPolicy = ((bar & 0x01) == 1) ? true : false;
149  m_multiTid = (((bar >> 1) & 0x01) == 1) ? true : false;
150  m_compressed = (((bar >> 2) & 0x01) == 1) ? true : false;
151  m_tidInfo = (bar >> 12) & 0x0f;
152 }
153 
154 uint16_t
156 {
157  return (m_startingSeq << 4) & 0xfff0;
158 }
159 
160 void
162 {
163  m_startingSeq = (seqControl >> 4) & 0x0fff;
164 }
165 
166 void
168 {
169  m_barAckPolicy = immediateAck;
170 }
171 
172 void
174 {
175  switch (type)
176  {
177  case BASIC_BLOCK_ACK:
178  m_multiTid = false;
179  m_compressed = false;
180  break;
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 }
194 
195 void
197 {
198  m_tidInfo = static_cast<uint16_t> (tid);
199 }
200 
201 void
203 {
204  m_startingSeq = seq;
205 }
206 
207 bool
209 {
210  return m_barAckPolicy;
211 }
212 
213 uint8_t
215 {
216  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
217  return tid;
218 }
219 
220 uint16_t
222 {
223  return m_startingSeq;
224 }
225 
226 bool
228 {
229  return (!m_multiTid && !m_compressed) ? true : false;
230 }
231 
232 bool
234 {
235  return (!m_multiTid && m_compressed) ? true : false;
236 }
237 
238 bool
240 {
241  return (m_multiTid && m_compressed) ? true : false;
242 }
243 
244 
245 /***********************************
246  * Block ack response
247  ***********************************/
248 
250 
252  : m_baAckPolicy (false),
253  m_multiTid (false),
254  m_compressed (false)
255 {
256  memset (&bitmap, 0, sizeof (bitmap));
257 }
258 
260 {
261 }
262 
263 TypeId
265 {
266  static TypeId tid = TypeId ("ns3::CtrlBAckResponseHeader")
267  .SetParent<Header> ()
268  .SetGroupName ("Wifi")
269  .AddConstructor<CtrlBAckResponseHeader> ()
270  ;
271  return tid;
272 }
273 
274 TypeId
276 {
277  return GetTypeId ();
278 }
279 
280 void
281 CtrlBAckResponseHeader::Print (std::ostream &os) const
282 {
283  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
284 }
285 
286 uint32_t
288 {
289  uint32_t size = 0;
290  size += 2; //Bar control
291  if (!m_multiTid)
292  {
293  if (!m_compressed)
294  {
295  size += (2 + 128); //Basic block ack
296  }
297  else
298  {
299  size += (2 + 8); //Compressed block ack
300  }
301  }
302  else
303  {
304  if (m_compressed)
305  {
306  size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-tid block ack
307  }
308  else
309  {
310  NS_FATAL_ERROR ("Reserved configuration.");
311  }
312  }
313  return size;
314 }
315 
316 void
318 {
321  if (!m_multiTid)
322  {
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  {
332  NS_FATAL_ERROR ("Reserved configuration.");
333  }
334 }
335 
336 uint32_t
338 {
341  if (!m_multiTid)
342  {
344  i = DeserializeBitmap (i);
345  }
346  else if (m_compressed)
347  {
348  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
349  }
350  else
351  {
352  NS_FATAL_ERROR ("Reserved configuration.");
353  }
354  return i.GetDistanceFrom (start);
355 }
356 
357 void
359 {
360  m_baAckPolicy = immediateAck;
361 }
362 
363 void
365 {
366  switch (type)
367  {
368  case BASIC_BLOCK_ACK:
369  m_multiTid = false;
370  m_compressed = false;
371  break;
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 }
385 
386 void
388 {
389  m_tidInfo = static_cast<uint16_t> (tid);
390 }
391 
392 void
394 {
395  m_startingSeq = seq;
396 }
397 
398 bool
400 {
401  return (m_baAckPolicy) ? true : false;
402 }
403 
404 uint8_t
406 {
407  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
408  return tid;
409 }
410 
411 uint16_t
413 {
414  return m_startingSeq;
415 }
416 
417 bool
419 {
420  return (!m_multiTid && !m_compressed) ? true : false;
421 }
422 
423 bool
425 {
426  return (!m_multiTid && m_compressed) ? true : false;
427 }
428 
429 bool
431 {
432  return (m_multiTid && m_compressed) ? true : false;
433 }
434 
435 uint16_t
437 {
438  uint16_t res = 0;
439  if (m_baAckPolicy)
440  {
441  res |= 0x1;
442  }
443  if (m_multiTid)
444  {
445  res |= (0x1 << 1);
446  }
447  if (m_compressed)
448  {
449  res |= (0x1 << 2);
450  }
451  res |= (m_tidInfo << 12) & (0xf << 12);
452  return res;
453 }
454 
455 void
457 {
458  m_baAckPolicy = ((ba & 0x01) == 1) ? true : false;
459  m_multiTid = (((ba >> 1) & 0x01) == 1) ? true : false;
460  m_compressed = (((ba >> 2) & 0x01) == 1) ? true : false;
461  m_tidInfo = (ba >> 12) & 0x0f;
462 }
463 
464 uint16_t
466 {
467  return (m_startingSeq << 4) & 0xfff0;
468 }
469 
470 void
472 {
473  m_startingSeq = (seqControl >> 4) & 0x0fff;
474 }
475 
478 {
480  if (!m_multiTid)
481  {
482  if (!m_compressed)
483  {
484  for (uint8_t j = 0; j < 64; j++)
485  {
486  i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
487  }
488  }
489  else
490  {
491  i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
492  }
493  }
494  else
495  {
496  if (m_compressed)
497  {
498  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
499  }
500  else
501  {
502  NS_FATAL_ERROR ("Reserved configuration.");
503  }
504  }
505  return i;
506 }
507 
510 {
512  if (!m_multiTid)
513  {
514  if (!m_compressed)
515  {
516  for (uint8_t j = 0; j < 64; j++)
517  {
518  bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
519  }
520  }
521  else
522  {
523  bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
524  }
525  }
526  else
527  {
528  if (m_compressed)
529  {
530  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
531  }
532  else
533  {
534  NS_FATAL_ERROR ("Reserved configuration.");
535  }
536  }
537  return i;
538 }
539 
540 void
542 {
543  if (!IsInBitmap (seq))
544  {
545  return;
546  }
547  if (!m_multiTid)
548  {
549  if (!m_compressed)
550  {
551  /* To set correctly basic block ack bitmap we need fragment number too.
552  So if it's not specified, we consider packet not fragmented. */
553  bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
554  }
555  else
556  {
557  bitmap.m_compressedBitmap |= (uint64_t (0x0000000000000001) << IndexInBitmap (seq));
558  }
559  }
560  else
561  {
562  if (m_compressed)
563  {
564  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
565  }
566  else
567  {
568  NS_FATAL_ERROR ("Reserved configuration.");
569  }
570  }
571 }
572 
573 void
575 {
576  NS_ASSERT (frag < 16);
577  if (!IsInBitmap (seq))
578  {
579  return;
580  }
581  if (!m_multiTid)
582  {
583  if (!m_compressed)
584  {
585  bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001 << frag);
586  }
587  else
588  {
589  /* We can ignore this...compressed block ack doesn't support
590  acknowledgement of single fragments */
591  }
592  }
593  else
594  {
595  if (m_compressed)
596  {
597  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
598  }
599  else
600  {
601  NS_FATAL_ERROR ("Reserved configuration.");
602  }
603  }
604 }
605 
606 bool
608 {
609  if (!IsInBitmap (seq))
610  {
611  return false;
612  }
613  if (!m_multiTid)
614  {
615  if (!m_compressed)
616  {
617  /*It's impossible to say if an entire packet was correctly received. */
618  return false;
619  }
620  else
621  {
622  uint64_t mask = uint64_t (0x0000000000000001);
623  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
624  }
625  }
626  else
627  {
628  if (m_compressed)
629  {
630  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
631  }
632  else
633  {
634  NS_FATAL_ERROR ("Reserved configuration.");
635  }
636  }
637  return false;
638 }
639 
640 bool
641 CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const
642 {
643  NS_ASSERT (frag < 16);
644  if (!IsInBitmap (seq))
645  {
646  return false;
647  }
648  if (!m_multiTid)
649  {
650  if (!m_compressed)
651  {
652  return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001 << frag)) != 0x0000) ? true : false;
653  }
654  else
655  {
656  /* 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
658  were correctly received. */
659  uint64_t mask = uint64_t (0x0000000000000001);
660  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
661  }
662  }
663  else
664  {
665  if (m_compressed)
666  {
667  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
668  }
669  else
670  {
671  NS_FATAL_ERROR ("Reserved configuration.");
672  }
673  }
674  return false;
675 }
676 
677 uint16_t
679 {
680  uint16_t index;
681  if (seq >= m_startingSeq)
682  {
683  index = seq - m_startingSeq;
684  }
685  else
686  {
687  index = 4096 - m_startingSeq + seq;
688  }
689  NS_ASSERT (index <= 63);
690  return index;
691 }
692 
693 bool
695 {
696  return (seq - m_startingSeq + 4096) % 4096 < 64;
697 }
698 
699 const uint16_t*
701 {
702  return bitmap.m_bitmap;
703 }
704 
705 uint64_t
707 {
708  return bitmap.m_compressedBitmap;
709 }
710 
711 void
713 {
714  memset (&bitmap, 0, sizeof (bitmap));
715 }
716 
717 } //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:55
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
bool m_compressed
compressed
Definition: ctrl-headers.h:163
def start()
Definition: core.py:1844
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:162
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:394
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
void Serialize(Buffer::Iterator start) const
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
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 ACK policy is compressed ACK and not multiple TID.
bool MustSendHtImmediateAck(void) const
Check if the current ACK policy is immediate.
void SetBaControl(uint16_t bar)
Set the block ACK control.
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:161
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
void Print(std::ostream &os) const
Definition: ctrl-headers.cc:61
uint64_t GetCompressedBitmap(void) const
Return the compressed bitmap from the block ACK response header.
uint16_t m_startingSeq
starting seq
Definition: ctrl-headers.h:165
bool IsPacketReceived(uint16_t seq) const
Check if the packet with the given sequence number was ACKed in this Block ACK response.
Headers for Block ack response.
Definition: ctrl-headers.h:181
uint32_t GetSerializedSize(void) const
Definition: ctrl-headers.cc:67
static TypeId GetTypeId(void)
Get the type ID.
Definition: ctrl-headers.cc:44
uint16_t m_tidInfo
TID info.
Definition: ctrl-headers.h:397
bool IsCompressed(void) const
Check if the current ACK policy is compressed ACK and not multiple TID.
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 block ACK 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.
static TypeId GetTypeId(void)
Get the type ID.
void SetType(BlockAckType type)
Set the block ACK type.
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
void ResetBitmap(void)
Reset the bitmap to 0.
bool m_compressed
compressed
Definition: ctrl-headers.h:396
bool IsFragmentReceived(uint16_t seq, uint8_t frag) const
Check if the packet with the given sequence number and fragment number was ACKed in this Block ACK re...
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:910
uint16_t m_startingSeq
starting seq
Definition: ctrl-headers.h:398
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:164
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate ACK.
void Print(std::ostream &os) const
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1065
void Serialize(Buffer::Iterator start) const
Definition: ctrl-headers.cc:87
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1093
Headers for Block ack request.
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:915
BlockAckType
The different block ACK policies.