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
76  {
77  if (m_compressed)
78  {
79  size += (2 + 2) * (m_tidInfo + 1); //Multi-tid block ack
80  }
81  else
82  {
83  NS_FATAL_ERROR ("Reserved configuration.");
84  }
85  }
86  return size;
87 }
88 
89 void
91 {
94  if (!m_multiTid)
95  {
97  }
98  else
99  {
100  if (m_compressed)
101  {
102  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
103  }
104  else
105  {
106  NS_FATAL_ERROR ("Reserved configuration.");
107  }
108  }
109 }
110 
111 uint32_t
113 {
116  if (!m_multiTid)
117  {
119  }
120  else
121  {
122  if (m_compressed)
123  {
124  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
125  }
126  else
127  {
128  NS_FATAL_ERROR ("Reserved configuration.");
129  }
130  }
131  return i.GetDistanceFrom (start);
132 }
133 
134 uint16_t
136 {
137  uint16_t res = 0;
138  if (m_barAckPolicy)
139  {
140  res |= 0x1;
141  }
142  if (m_multiTid)
143  {
144  res |= (0x1 << 1);
145  }
146  if (m_compressed)
147  {
148  res |= (0x1 << 2);
149  }
150  res |= (m_tidInfo << 12) & (0xf << 12);
151  return res;
152 }
153 
154 void
156 {
157  m_barAckPolicy = ((bar & 0x01) == 1) ? true : false;
158  m_multiTid = (((bar >> 1) & 0x01) == 1) ? true : false;
159  m_compressed = (((bar >> 2) & 0x01) == 1) ? true : false;
160  m_tidInfo = (bar >> 12) & 0x0f;
161 }
162 
163 uint16_t
165 {
166  return (m_startingSeq << 4) & 0xfff0;
167 }
168 
169 void
171 {
172  m_startingSeq = (seqControl >> 4) & 0x0fff;
173 }
174 
175 void
177 {
178  m_barAckPolicy = immediateAck;
179 }
180 
181 void
183 {
184  switch (type)
185  {
186  case BASIC_BLOCK_ACK:
187  m_multiTid = false;
188  m_compressed = false;
189  break;
191  m_multiTid = false;
192  m_compressed = true;
193  break;
194  case MULTI_TID_BLOCK_ACK:
195  m_multiTid = true;
196  m_compressed = true;
197  break;
198  default:
199  NS_FATAL_ERROR ("Invalid variant type");
200  break;
201  }
202 }
203 
204 void
206 {
207  m_tidInfo = static_cast<uint16_t> (tid);
208 }
209 
210 void
212 {
213  m_startingSeq = seq;
214 }
215 
216 bool
218 {
219  return m_barAckPolicy;
220 }
221 
222 uint8_t
224 {
225  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
226  return tid;
227 }
228 
229 uint16_t
231 {
232  return m_startingSeq;
233 }
234 
235 bool
237 {
238  return (!m_multiTid && !m_compressed) ? true : false;
239 }
240 
241 bool
243 {
244  return (!m_multiTid && m_compressed) ? true : false;
245 }
246 
247 bool
249 {
250  return (m_multiTid && m_compressed) ? true : false;
251 }
252 
253 
254 /***********************************
255  * Block ack response
256  ***********************************/
257 
259 
261  : m_baAckPolicy (false),
262  m_multiTid (false),
263  m_compressed (false)
264 {
265  memset (&bitmap, 0, sizeof (bitmap));
266 }
267 
269 {
270 }
271 
272 TypeId
274 {
275  static TypeId tid = TypeId ("ns3::CtrlBAckResponseHeader")
276  .SetParent<Header> ()
277  .SetGroupName ("Wifi")
278  .AddConstructor<CtrlBAckResponseHeader> ()
279  ;
280  return tid;
281 }
282 
283 TypeId
285 {
286  return GetTypeId ();
287 }
288 
289 void
290 CtrlBAckResponseHeader::Print (std::ostream &os) const
291 {
292  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
293 }
294 
295 uint32_t
297 {
298  uint32_t size = 0;
299  size += 2; //Bar control
300  if (!m_multiTid)
301  {
302  if (!m_compressed)
303  {
304  size += (2 + 128); //Basic block ack
305  }
306  else
307  {
308  size += (2 + 8); //Compressed block ack
309  }
310  }
311  else
312  {
313  if (m_compressed)
314  {
315  size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-tid block ack
316  }
317  else
318  {
319  NS_FATAL_ERROR ("Reserved configuration.");
320  }
321  }
322  return size;
323 }
324 
325 void
327 {
330  if (!m_multiTid)
331  {
333  i = SerializeBitmap (i);
334  }
335  else
336  {
337  if (m_compressed)
338  {
339  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
340  }
341  else
342  {
343  NS_FATAL_ERROR ("Reserved configuration.");
344  }
345  }
346 }
347 
348 uint32_t
350 {
353  if (!m_multiTid)
354  {
356  i = DeserializeBitmap (i);
357  }
358  else
359  {
360  if (m_compressed)
361  {
362  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
363  }
364  else
365  {
366  NS_FATAL_ERROR ("Reserved configuration.");
367  }
368  }
369  return i.GetDistanceFrom (start);
370 }
371 
372 void
374 {
375  m_baAckPolicy = immediateAck;
376 }
377 
378 void
380 {
381  switch (type)
382  {
383  case BASIC_BLOCK_ACK:
384  m_multiTid = false;
385  m_compressed = false;
386  break;
388  m_multiTid = false;
389  m_compressed = true;
390  break;
391  case MULTI_TID_BLOCK_ACK:
392  m_multiTid = true;
393  m_compressed = true;
394  break;
395  default:
396  NS_FATAL_ERROR ("Invalid variant type");
397  break;
398  }
399 }
400 
401 void
403 {
404  m_tidInfo = static_cast<uint16_t> (tid);
405 }
406 
407 void
409 {
410  m_startingSeq = seq;
411 }
412 
413 bool
415 {
416  return (m_baAckPolicy) ? true : false;
417 }
418 
419 uint8_t
421 {
422  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
423  return tid;
424 }
425 
426 uint16_t
428 {
429  return m_startingSeq;
430 }
431 
432 bool
434 {
435  return (!m_multiTid && !m_compressed) ? true : false;
436 }
437 
438 bool
440 {
441  return (!m_multiTid && m_compressed) ? true : false;
442 }
443 
444 bool
446 {
447  return (m_multiTid && m_compressed) ? true : false;
448 }
449 
450 uint16_t
452 {
453  uint16_t res = 0;
454  if (m_baAckPolicy)
455  {
456  res |= 0x1;
457  }
458  if (m_multiTid)
459  {
460  res |= (0x1 << 1);
461  }
462  if (m_compressed)
463  {
464  res |= (0x1 << 2);
465  }
466  res |= (m_tidInfo << 12) & (0xf << 12);
467  return res;
468 }
469 
470 void
472 {
473  m_baAckPolicy = ((ba & 0x01) == 1) ? true : false;
474  m_multiTid = (((ba >> 1) & 0x01) == 1) ? true : false;
475  m_compressed = (((ba >> 2) & 0x01) == 1) ? true : false;
476  m_tidInfo = (ba >> 12) & 0x0f;
477 }
478 
479 uint16_t
481 {
482  return (m_startingSeq << 4) & 0xfff0;
483 }
484 
485 void
487 {
488  m_startingSeq = (seqControl >> 4) & 0x0fff;
489 }
490 
493 {
495  if (!m_multiTid)
496  {
497  if (!m_compressed)
498  {
499  for (uint32_t j = 0; j < 64; j++)
500  {
501  i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
502  }
503  }
504  else
505  {
506  i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
507  }
508  }
509  else
510  {
511  if (m_compressed)
512  {
513  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
514  }
515  else
516  {
517  NS_FATAL_ERROR ("Reserved configuration.");
518  }
519  }
520  return i;
521 }
522 
525 {
527  if (!m_multiTid)
528  {
529  if (!m_compressed)
530  {
531  for (uint32_t j = 0; j < 64; j++)
532  {
533  bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
534  }
535  }
536  else
537  {
538  bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
539  }
540  }
541  else
542  {
543  if (m_compressed)
544  {
545  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
546  }
547  else
548  {
549  NS_FATAL_ERROR ("Reserved configuration.");
550  }
551  }
552  return i;
553 }
554 
555 void
557 {
558  if (!IsInBitmap (seq))
559  {
560  return;
561  }
562  if (!m_multiTid)
563  {
564  if (!m_compressed)
565  {
566  /* To set correctly basic block ack bitmap we need fragment number too.
567  So if it's not specified, we consider packet not fragmented. */
568  bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
569  }
570  else
571  {
572  bitmap.m_compressedBitmap |= (uint64_t (0x0000000000000001) << IndexInBitmap (seq));
573  }
574  }
575  else
576  {
577  if (m_compressed)
578  {
579  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
580  }
581  else
582  {
583  NS_FATAL_ERROR ("Reserved configuration.");
584  }
585  }
586 }
587 
588 void
590 {
591  NS_ASSERT (frag < 16);
592  if (!IsInBitmap (seq))
593  {
594  return;
595  }
596  if (!m_multiTid)
597  {
598  if (!m_compressed)
599  {
600  bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001 << frag);
601  }
602  else
603  {
604  /* We can ignore this...compressed block ack doesn't support
605  acknowledgement of single fragments */
606  }
607  }
608  else
609  {
610  if (m_compressed)
611  {
612  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
613  }
614  else
615  {
616  NS_FATAL_ERROR ("Reserved configuration.");
617  }
618  }
619 }
620 
621 bool
623 {
624  if (!IsInBitmap (seq))
625  {
626  return false;
627  }
628  if (!m_multiTid)
629  {
630  if (!m_compressed)
631  {
632  /*It's impossible to say if an entire packet was correctly received. */
633  return false;
634  }
635  else
636  {
637  uint64_t mask = uint64_t (0x0000000000000001);
638  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
639  }
640  }
641  else
642  {
643  if (m_compressed)
644  {
645  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
646  }
647  else
648  {
649  NS_FATAL_ERROR ("Reserved configuration.");
650  }
651  }
652  return false;
653 }
654 
655 bool
656 CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const
657 {
658  NS_ASSERT (frag < 16);
659  if (!IsInBitmap (seq))
660  {
661  return false;
662  }
663  if (!m_multiTid)
664  {
665  if (!m_compressed)
666  {
667  return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001 << frag)) != 0x0000) ? true : false;
668  }
669  else
670  {
671  /* Although this could make no sense, if packet with sequence number
672  equal to <i>seq</i> was correctly received, also all of its fragments
673  were correctly received. */
674  uint64_t mask = uint64_t (0x0000000000000001);
675  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
676  }
677  }
678  else
679  {
680  if (m_compressed)
681  {
682  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
683  }
684  else
685  {
686  NS_FATAL_ERROR ("Reserved configuration.");
687  }
688  }
689  return false;
690 }
691 
692 uint8_t
694 {
695  uint8_t index;
696  if (seq >= m_startingSeq)
697  {
698  index = seq - m_startingSeq;
699  }
700  else
701  {
702  index = 4096 - m_startingSeq + seq;
703  }
704  NS_ASSERT (index <= 63);
705  return index;
706 }
707 
708 bool
710 {
711  return (seq - m_startingSeq + 4096) % 4096 < 64;
712 }
713 
714 const uint16_t*
716 {
717  return bitmap.m_bitmap;
718 }
719 
720 uint64_t
722 {
723  return bitmap.m_compressedBitmap;
724 }
725 
726 void
728 {
729  memset (&bitmap, 0, sizeof (bitmap));
730 }
731 
732 } //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
#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:172
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
def start()
Definition: core.py:1790
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
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
void SetBarControl(uint16_t bar)
Set the Block ACK control.
bool IsPacketReceived(uint16_t seq) const
Check if the packet with the given sequence number was ACKed in this Block ACK response.
bool IsCompressed(void) const
Check if the current ACK policy is compressed ACK and not multiple TID.
#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.
BlockAckType
Enumeration for different block ACK policies.
Definition: ctrl-headers.h:31
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:403
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:786
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).
void Print(std::ostream &os) const
Definition: ctrl-headers.cc:61
union ns3::CtrlBAckResponseHeader::@72 bitmap
bitmap union type
void SetBaControl(uint16_t bar)
Set the block ACK control.
uint16_t GetBaControl(void) const
Return 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:170
uint32_t GetSerializedSize(void) const
Definition: ctrl-headers.cc:67
uint16_t m_startingSeq
starting seq
Definition: ctrl-headers.h:174
uint8_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...
Headers for Block ack response.
Definition: ctrl-headers.h:190
static TypeId GetTypeId(void)
Get the type ID.
Definition: ctrl-headers.cc:44
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
uint16_t m_tidInfo
TID info.
Definition: ctrl-headers.h:406
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...
uint32_t GetSerializedSize(void) const
Buffer::Iterator SerializeBitmap(Buffer::Iterator start) const
Serialize bitmap to the given buffer.
uint32_t Deserialize(Buffer::Iterator start)
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
uint16_t GetStartingSequence(void) const
Return the starting sequence number.
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.
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
void SetType(BlockAckType type)
Set the block ACK type.
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
void Serialize(Buffer::Iterator start) const
void ResetBitmap(void)
Reset the bitmap to 0.
bool IsInBitmap(uint16_t seq) const
Checks if sequence number seq can be acknowledged in the bitmap.
bool m_compressed
compressed
Definition: ctrl-headers.h:405
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:913
uint16_t m_startingSeq
starting seq
Definition: ctrl-headers.h:407
void SetReceivedFragment(uint16_t seq, uint8_t frag)
Set the bitmap that the packet with the given sequence number and fragment number was received...
void Serialize(Buffer::Iterator start) const
Definition: ctrl-headers.cc:90
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 MustSendHtImmediateAck(void) const
Check if the current ACK policy is immediate.
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:929
const uint16_t * GetBitmap(void) const
Return the bitmap from the block ACK response header.
uint32_t Deserialize(Buffer::Iterator start)
uint16_t m_tidInfo
TID info.
Definition: ctrl-headers.h:173
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate ACK.
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1068
void Print(std::ostream &os) const
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.
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1096
Headers for Block ack request.
Definition: ctrl-headers.h:50
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.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
uint64_t GetCompressedBitmap(void) const
Return the compressed bitmap from the block ACK response header.