A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 #include "ns3/fatal-error.h"
21 #include "ns3/log.h"
22 
23 #include "ctrl-headers.h"
24 
25 NS_LOG_COMPONENT_DEFINE ("CtrlHeaders");
26 
27 namespace ns3 {
28 
29 /***********************************
30  * Block ack request
31  ***********************************/
32 
33 NS_OBJECT_ENSURE_REGISTERED (CtrlBAckRequestHeader);
34 
36  : m_barAckPolicy (false),
37  m_multiTid (false),
38  m_compressed (false)
39 {
40  NS_LOG_FUNCTION (this);
41 }
42 
44 {
45  NS_LOG_FUNCTION (this);
46 }
47 
48 TypeId
50 {
52  static TypeId tid = TypeId ("ns3::CtrlBAckRequestHeader")
53  .SetParent<Header> ()
54  .AddConstructor<CtrlBAckRequestHeader> ()
55  ;
56  return tid;
57 }
58 
59 TypeId
61 {
62  NS_LOG_FUNCTION (this);
63  return GetTypeId ();
64 }
65 
66 void
67 CtrlBAckRequestHeader::Print (std::ostream &os) const
68 {
69  NS_LOG_FUNCTION (this << &os);
70  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
71 }
72 
73 uint32_t
75 {
76  NS_LOG_FUNCTION (this);
77  uint32_t size = 0;
78  size += 2; //Bar control
79  if (!m_multiTid)
80  {
81  size += 2; //Starting sequence control
82  }
83  else
84  {
85  if (m_compressed)
86  {
87  size += (2 + 2) * (m_tidInfo + 1); //Multi-tid block ack
88  }
89  else
90  {
91  NS_FATAL_ERROR ("Reserved configuration.");
92  }
93  }
94  return size;
95 }
96 
97 void
99 {
100  NS_LOG_FUNCTION (this << &start);
103  if (!m_multiTid)
104  {
106  }
107  else
108  {
109  if (m_compressed)
110  {
111  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
112  }
113  else
114  {
115  NS_FATAL_ERROR ("Reserved configuration.");
116  }
117  }
118 }
119 
120 uint32_t
122 {
123  NS_LOG_FUNCTION (this << &start);
126  if (!m_multiTid)
127  {
129  }
130  else
131  {
132  if (m_compressed)
133  {
134  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
135  }
136  else
137  {
138  NS_FATAL_ERROR ("Reserved configuration.");
139  }
140  }
141  return i.GetDistanceFrom (start);
142 }
143 
144 uint16_t
146 {
147  NS_LOG_FUNCTION (this);
148  uint16_t res = 0;
149  if (m_barAckPolicy)
150  {
151  res |= 0x1;
152  }
153  if (m_multiTid)
154  {
155  res |= (0x1 << 1);
156  }
157  if (m_compressed)
158  {
159  res |= (0x1 << 2);
160  }
161  res |= (m_tidInfo << 12) & (0xf << 12);
162  return res;
163 }
164 
165 void
167 {
168  NS_LOG_FUNCTION (this << bar);
169  m_barAckPolicy = ((bar & 0x01) == 1) ? true : false;
170  m_multiTid = (((bar >> 1) & 0x01) == 1) ? true : false;
171  m_compressed = (((bar >> 2) & 0x01) == 1) ? true : false;
172  m_tidInfo = (bar >> 12) & 0x0f;
173 }
174 
175 uint16_t
177 {
178  NS_LOG_FUNCTION (this);
179  return (m_startingSeq << 4) & 0xfff0;
180 }
181 
182 void
184 {
185  NS_LOG_FUNCTION (this << seqControl);
186  m_startingSeq = (seqControl >> 4) & 0x0fff;
187 }
188 
189 void
191 {
192  NS_LOG_FUNCTION (this << immediateAck);
193  m_barAckPolicy = immediateAck;
194 }
195 
196 void
198 {
199  NS_LOG_FUNCTION (this << type);
200  switch (type)
201  {
202  case BASIC_BLOCK_ACK:
203  m_multiTid = false;
204  m_compressed = false;
205  break;
207  m_multiTid = false;
208  m_compressed = true;
209  break;
210  case MULTI_TID_BLOCK_ACK:
211  m_multiTid = true;
212  m_compressed = true;
213  break;
214  default:
215  NS_FATAL_ERROR ("Invalid variant type");
216  break;
217  }
218 }
219 
220 void
222 {
223  NS_LOG_FUNCTION (this << static_cast<uint32_t> (tid));
224  m_tidInfo = static_cast<uint16_t> (tid);
225 }
226 
227 void
229 {
230  NS_LOG_FUNCTION (this << seq);
231  m_startingSeq = seq;
232 }
233 
234 bool
236 {
237  NS_LOG_FUNCTION (this);
238  return m_barAckPolicy;
239 }
240 
241 uint8_t
243 {
244  NS_LOG_FUNCTION (this);
245  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
246  return tid;
247 }
248 
249 uint16_t
251 {
252  NS_LOG_FUNCTION (this);
253  return m_startingSeq;
254 }
255 
256 bool
258 {
259  NS_LOG_FUNCTION (this);
260  return (!m_multiTid && !m_compressed) ? true : false;
261 }
262 
263 bool
265 {
266  NS_LOG_FUNCTION (this);
267  return (!m_multiTid && m_compressed) ? true : false;
268 }
269 
270 bool
272 {
273  NS_LOG_FUNCTION (this);
274  return (m_multiTid && m_compressed) ? true : false;
275 }
276 
277 /***********************************
278  * Block ack response
279  ***********************************/
280 
282 
284  : m_baAckPolicy (false),
285  m_multiTid (false),
286  m_compressed (false)
287 {
288  NS_LOG_FUNCTION (this);
289  memset (&bitmap, 0, sizeof (bitmap));
290 }
291 
293 {
294  NS_LOG_FUNCTION (this);
295 }
296 
297 TypeId
299 {
300  static TypeId tid = TypeId ("ns3::CtrlBAckResponseHeader")
301  .SetParent<Header> ()
302  .AddConstructor<CtrlBAckResponseHeader> ()
303  ;
304  return tid;
305 }
306 
307 TypeId
309 {
310  return GetTypeId ();
311 }
312 
313 void
314 CtrlBAckResponseHeader::Print (std::ostream &os) const
315 {
316  NS_LOG_FUNCTION (this << &os);
317  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
318 }
319 
320 uint32_t
322 {
323  NS_LOG_FUNCTION (this);
324  uint32_t size = 0;
325  size += 2; //Bar control
326  if (!m_multiTid)
327  {
328  if (!m_compressed)
329  {
330  size += (2 + 128); //Basic block ack
331  }
332  else
333  {
334  size += (2 + 8); //Compressed block ack
335  }
336  }
337  else
338  {
339  if (m_compressed)
340  {
341  size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-tid block ack
342  }
343  else
344  {
345  NS_FATAL_ERROR ("Reserved configuration.");
346  }
347  }
348  return size;
349 }
350 
351 void
353 {
354  NS_LOG_FUNCTION (this << &start);
357  if (!m_multiTid)
358  {
360  i = SerializeBitmap (i);
361  }
362  else
363  {
364  if (m_compressed)
365  {
366  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
367  }
368  else
369  {
370  NS_FATAL_ERROR ("Reserved configuration.");
371  }
372  }
373 }
374 
375 uint32_t
377 {
378  NS_LOG_FUNCTION (this << &start);
381  if (!m_multiTid)
382  {
384  i = DeserializeBitmap (i);
385  }
386  else
387  {
388  if (m_compressed)
389  {
390  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
391  }
392  else
393  {
394  NS_FATAL_ERROR ("Reserved configuration.");
395  }
396  }
397  return i.GetDistanceFrom (start);
398 }
399 
400 void
402 {
403  NS_LOG_FUNCTION (this << immediateAck);
404  m_baAckPolicy = immediateAck;
405 }
406 
407 void
409 {
410  NS_LOG_FUNCTION (this << type);
411  switch (type)
412  {
413  case BASIC_BLOCK_ACK:
414  m_multiTid = false;
415  m_compressed = false;
416  break;
418  m_multiTid = false;
419  m_compressed = true;
420  break;
421  case MULTI_TID_BLOCK_ACK:
422  m_multiTid = true;
423  m_compressed = true;
424  break;
425  default:
426  NS_FATAL_ERROR ("Invalid variant type");
427  break;
428  }
429 }
430 
431 void
433 {
434  NS_LOG_FUNCTION (this << static_cast<uint32_t> (tid));
435  m_tidInfo = static_cast<uint16_t> (tid);
436 }
437 
438 void
440 {
441  NS_LOG_FUNCTION (this << seq);
442  m_startingSeq = seq;
443 }
444 
445 bool
447 {
448  NS_LOG_FUNCTION (this);
449  return (m_baAckPolicy) ? true : false;
450 }
451 
452 uint8_t
454 {
455  NS_LOG_FUNCTION (this);
456  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
457  return tid;
458 }
459 
460 uint16_t
462 {
463  NS_LOG_FUNCTION (this);
464  return m_startingSeq;
465 }
466 
467 bool
469 {
470  NS_LOG_FUNCTION (this);
471  return (!m_multiTid && !m_compressed) ? true : false;
472 }
473 
474 bool
476 {
477  NS_LOG_FUNCTION (this);
478  return (!m_multiTid && m_compressed) ? true : false;
479 }
480 
481 bool
483 {
484  NS_LOG_FUNCTION (this);
485  return (m_multiTid && m_compressed) ? true : false;
486 }
487 
488 uint16_t
490 {
491  NS_LOG_FUNCTION (this);
492  uint16_t res = 0;
493  if (m_baAckPolicy)
494  {
495  res |= 0x1;
496  }
497  if (m_multiTid)
498  {
499  res |= (0x1 << 1);
500  }
501  if (m_compressed)
502  {
503  res |= (0x1 << 2);
504  }
505  res |= (m_tidInfo << 12) & (0xf << 12);
506  return res;
507 }
508 
509 void
511 {
512  NS_LOG_FUNCTION (this << ba);
513  m_baAckPolicy = ((ba & 0x01) == 1) ? true : false;
514  m_multiTid = (((ba >> 1) & 0x01) == 1) ? true : false;
515  m_compressed = (((ba >> 2) & 0x01) == 1) ? true : false;
516  m_tidInfo = (ba >> 12) & 0x0f;
517 }
518 
519 uint16_t
521 {
522  NS_LOG_FUNCTION (this);
523  return (m_startingSeq << 4) & 0xfff0;
524 }
525 
526 void
528 {
529  NS_LOG_FUNCTION (this << seqControl);
530  m_startingSeq = (seqControl >> 4) & 0x0fff;
531 }
532 
535 {
536  NS_LOG_FUNCTION (this << &start);
538  if (!m_multiTid)
539  {
540  if (!m_compressed)
541  {
542  for (uint32_t j = 0; j < 64; j++)
543  {
544  i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
545  }
546  }
547  else
548  {
549  i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
550  }
551  }
552  else
553  {
554  if (m_compressed)
555  {
556  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
557  }
558  else
559  {
560  NS_FATAL_ERROR ("Reserved configuration.");
561  }
562  }
563  return i;
564 }
565 
568 {
569  NS_LOG_FUNCTION (this << &start);
571  if (!m_multiTid)
572  {
573  if (!m_compressed)
574  {
575  for (uint32_t j = 0; j < 64; j++)
576  {
577  bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
578  }
579  }
580  else
581  {
582  bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
583  }
584  }
585  else
586  {
587  if (m_compressed)
588  {
589  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
590  }
591  else
592  {
593  NS_FATAL_ERROR ("Reserved configuration.");
594  }
595  }
596  return i;
597 }
598 
599 void
601 {
602  NS_LOG_FUNCTION (this << seq);
603  if (!IsInBitmap (seq))
604  {
605  return;
606  }
607  if (!m_multiTid)
608  {
609  if (!m_compressed)
610  {
611  /* To set correctly basic block ack bitmap we need fragment number too.
612  So if it's not specified, we consider packet not fragmented. */
613  bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
614  }
615  else
616  {
617  bitmap.m_compressedBitmap |= (uint64_t (0x0000000000000001) << IndexInBitmap (seq));
618  }
619  }
620  else
621  {
622  if (m_compressed)
623  {
624  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
625  }
626  else
627  {
628  NS_FATAL_ERROR ("Reserved configuration.");
629  }
630  }
631 }
632 
633 void
635 {
636  NS_LOG_FUNCTION (this << seq << static_cast<uint32_t> (frag));
637  NS_ASSERT (frag < 16);
638  if (!IsInBitmap (seq))
639  {
640  return;
641  }
642  if (!m_multiTid)
643  {
644  if (!m_compressed)
645  {
646  bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001 << frag);
647  }
648  else
649  {
650  /* We can ignore this...compressed block ack doesn't support
651  acknowledgement of single fragments */
652  }
653  }
654  else
655  {
656  if (m_compressed)
657  {
658  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
659  }
660  else
661  {
662  NS_FATAL_ERROR ("Reserved configuration.");
663  }
664  }
665 }
666 
667 bool
669 {
670  NS_LOG_FUNCTION (this << seq);
671  if (!IsInBitmap (seq))
672  {
673  return false;
674  }
675  if (!m_multiTid)
676  {
677  if (!m_compressed)
678  {
679  /*It's impossible to say if an entire packet was correctly received. */
680  return false;
681  }
682  else
683  {
684  uint64_t mask = uint64_t (0x0000000000000001);
685  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
686  }
687  }
688  else
689  {
690  if (m_compressed)
691  {
692  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
693  }
694  else
695  {
696  NS_FATAL_ERROR ("Reserved configuration.");
697  }
698  }
699  return false;
700 }
701 
702 bool
703 CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const
704 {
705  NS_LOG_FUNCTION (this << seq << static_cast<uint32_t> (frag));
706  NS_ASSERT (frag < 16);
707  if (!IsInBitmap (seq))
708  {
709  return false;
710  }
711  if (!m_multiTid)
712  {
713  if (!m_compressed)
714  {
715  return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001 << frag)) != 0x0000) ? true : false;
716  }
717  else
718  {
719  /* Although this could make no sense, if packet with sequence number
720  equal to <i>seq</i> was correctly received, also all of its fragments
721  were correctly received. */
722  uint64_t mask = uint64_t (0x0000000000000001);
723  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
724  }
725  }
726  else
727  {
728  if (m_compressed)
729  {
730  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
731  }
732  else
733  {
734  NS_FATAL_ERROR ("Reserved configuration.");
735  }
736  }
737  return false;
738 }
739 
740 uint8_t
742 {
743  NS_LOG_FUNCTION (this << seq);
744  uint8_t index;
745  if (seq >= m_startingSeq)
746  {
747  index = seq - m_startingSeq;
748  }
749  else
750  {
751  index = 4096 - m_startingSeq + seq;
752  }
753  NS_ASSERT (index <= 63);
754  return index;
755 }
756 
757 bool
759 {
760  NS_LOG_FUNCTION (this << seq);
761  return (seq - m_startingSeq + 4096) % 4096 < 64;
762 }
763 
764 const uint16_t*
766 {
767  NS_LOG_FUNCTION (this);
768  return bitmap.m_bitmap;
769 }
770 
771 uint64_t
773 {
774  NS_LOG_FUNCTION (this);
775  return bitmap.m_compressedBitmap;
776 }
777 
778 void
780 {
781  NS_LOG_FUNCTION (this);
782  memset (&bitmap, 0, sizeof (bitmap));
783 }
784 
785 } // namespace ns3
Protocol header serialization and deserialization.
Definition: header.h:42
void SetType(enum BlockAckType type)
Set the block ACK type.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
virtual TypeId GetInstanceTypeId(void) const
Definition: ctrl-headers.cc:60
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
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 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:61
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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)
fatal error handling
Definition: fatal-error.h:95
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate ACK.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
BlockAckType
Enumeration for different block ACK policies.
Definition: ctrl-headers.h:30
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:391
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:811
iterator in a Buffer instance
Definition: buffer.h:98
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
virtual void Print(std::ostream &os) const
Definition: ctrl-headers.cc:67
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:164
virtual uint32_t GetSerializedSize(void) const
Definition: ctrl-headers.cc:74
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:183
static TypeId GetTypeId(void)
Definition: ctrl-headers.cc:49
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
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...
virtual uint32_t GetSerializedSize(void) const
Buffer::Iterator SerializeBitmap(Buffer::Iterator start) const
Serialize bitmap to the given buffer.
virtual 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.
Buffer::Iterator DeserializeBitmap(Buffer::Iterator start)
Deserialize bitmap from the given buffer.
static TypeId GetTypeId(void)
void SetType(enum BlockAckType type)
Set the block ACK type.
bool IsBasic(void) const
Check if the current ACK policy is basic (i.e.
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
virtual 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.
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
void WriteHtolsbU16(uint16_t data)
Definition: buffer.cc:939
void SetReceivedFragment(uint16_t seq, uint8_t frag)
Set the bitmap that the packet with the given sequence number and fragment number was received...
virtual void Serialize(Buffer::Iterator start) const
Definition: ctrl-headers.cc:98
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:955
const uint16_t * GetBitmap(void) const
Return the bitmap from the block ACK response header.
virtual uint32_t Deserialize(Buffer::Iterator start)
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate ACK.
union ns3::CtrlBAckResponseHeader::@88 bitmap
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1094
virtual 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:1122
a unique identifier for an interface.
Definition: type-id.h:49
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
bool IsMultiTid(void) const
Check if the current ACK policy has multiple TID.
virtual TypeId GetInstanceTypeId(void) const
uint64_t GetCompressedBitmap(void) const
Return the compressed bitmap from the block ACK response header.