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  ;
35 
37  : m_barAckPolicy (false),
38  m_multiTid (false),
39  m_compressed (false)
40 {
41  NS_LOG_FUNCTION (this);
42 }
43 
45 {
46  NS_LOG_FUNCTION (this);
47 }
48 
49 TypeId
51 {
53  static TypeId tid = TypeId ("ns3::CtrlBAckRequestHeader")
54  .SetParent<Header> ()
55  .AddConstructor<CtrlBAckRequestHeader> ()
56  ;
57  return tid;
58 }
59 
60 TypeId
62 {
63  NS_LOG_FUNCTION (this);
64  return GetTypeId ();
65 }
66 
67 void
68 CtrlBAckRequestHeader::Print (std::ostream &os) const
69 {
70  NS_LOG_FUNCTION (this << &os);
71  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
72 }
73 
74 uint32_t
76 {
77  NS_LOG_FUNCTION (this);
78  uint32_t size = 0;
79  size += 2; //Bar control
80  if (!m_multiTid)
81  {
82  size += 2; //Starting sequence control
83  }
84  else
85  {
86  if (m_compressed)
87  {
88  size += (2 + 2) * (m_tidInfo + 1); //Multi-tid block ack
89  }
90  else
91  {
92  NS_FATAL_ERROR ("Reserved configuration.");
93  }
94  }
95  return size;
96 }
97 
98 void
100 {
101  NS_LOG_FUNCTION (this << &start);
104  if (!m_multiTid)
105  {
107  }
108  else
109  {
110  if (m_compressed)
111  {
112  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
113  }
114  else
115  {
116  NS_FATAL_ERROR ("Reserved configuration.");
117  }
118  }
119 }
120 
121 uint32_t
123 {
124  NS_LOG_FUNCTION (this << &start);
127  if (!m_multiTid)
128  {
130  }
131  else
132  {
133  if (m_compressed)
134  {
135  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
136  }
137  else
138  {
139  NS_FATAL_ERROR ("Reserved configuration.");
140  }
141  }
142  return i.GetDistanceFrom (start);
143 }
144 
145 uint16_t
147 {
148  NS_LOG_FUNCTION (this);
149  uint16_t res = 0;
150  if (m_barAckPolicy)
151  {
152  res |= 0x1;
153  }
154  if (m_multiTid)
155  {
156  res |= (0x1 << 1);
157  }
158  if (m_compressed)
159  {
160  res |= (0x1 << 2);
161  }
162  res |= (m_tidInfo << 12) & (0xf << 12);
163  return res;
164 }
165 
166 void
168 {
169  NS_LOG_FUNCTION (this << bar);
170  m_barAckPolicy = ((bar & 0x01) == 1) ? true : false;
171  m_multiTid = (((bar >> 1) & 0x01) == 1) ? true : false;
172  m_compressed = (((bar >> 2) & 0x01) == 1) ? true : false;
173  m_tidInfo = (bar >> 12) & 0x0f;
174 }
175 
176 uint16_t
178 {
179  NS_LOG_FUNCTION (this);
180  return (m_startingSeq << 4) & 0xfff0;
181 }
182 
183 void
185 {
186  NS_LOG_FUNCTION (this << seqControl);
187  m_startingSeq = (seqControl >> 4) & 0x0fff;
188 }
189 
190 void
192 {
193  NS_LOG_FUNCTION (this << immediateAck);
194  m_barAckPolicy = immediateAck;
195 }
196 
197 void
199 {
200  NS_LOG_FUNCTION (this << type);
201  switch (type)
202  {
203  case BASIC_BLOCK_ACK:
204  m_multiTid = false;
205  m_compressed = false;
206  break;
208  m_multiTid = false;
209  m_compressed = true;
210  break;
211  case MULTI_TID_BLOCK_ACK:
212  m_multiTid = true;
213  m_compressed = true;
214  break;
215  default:
216  NS_FATAL_ERROR ("Invalid variant type");
217  break;
218  }
219 }
220 
221 void
223 {
224  NS_LOG_FUNCTION (this << static_cast<uint32_t> (tid));
225  m_tidInfo = static_cast<uint16_t> (tid);
226 }
227 
228 void
230 {
231  NS_LOG_FUNCTION (this << seq);
232  m_startingSeq = seq;
233 }
234 
235 bool
237 {
238  NS_LOG_FUNCTION (this);
239  return m_barAckPolicy;
240 }
241 
242 uint8_t
244 {
245  NS_LOG_FUNCTION (this);
246  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
247  return tid;
248 }
249 
250 uint16_t
252 {
253  NS_LOG_FUNCTION (this);
254  return m_startingSeq;
255 }
256 
257 bool
259 {
260  NS_LOG_FUNCTION (this);
261  return (!m_multiTid && !m_compressed) ? true : false;
262 }
263 
264 bool
266 {
267  NS_LOG_FUNCTION (this);
268  return (!m_multiTid && m_compressed) ? true : false;
269 }
270 
271 bool
273 {
274  NS_LOG_FUNCTION (this);
275  return (m_multiTid && m_compressed) ? true : false;
276 }
277 
278 /***********************************
279  * Block ack response
280  ***********************************/
281 
283  ;
284 
286  : m_baAckPolicy (false),
287  m_multiTid (false),
288  m_compressed (false)
289 {
290  NS_LOG_FUNCTION (this);
291  memset (&bitmap, 0, sizeof (bitmap));
292 }
293 
295 {
296  NS_LOG_FUNCTION (this);
297 }
298 
299 TypeId
301 {
302  static TypeId tid = TypeId ("ns3::CtrlBAckResponseHeader")
303  .SetParent<Header> ()
304  .AddConstructor<CtrlBAckResponseHeader> ()
305  ;
306  return tid;
307 }
308 
309 TypeId
311 {
312  return GetTypeId ();
313 }
314 
315 void
316 CtrlBAckResponseHeader::Print (std::ostream &os) const
317 {
318  NS_LOG_FUNCTION (this << &os);
319  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
320 }
321 
322 uint32_t
324 {
325  NS_LOG_FUNCTION (this);
326  uint32_t size = 0;
327  size += 2; //Bar control
328  if (!m_multiTid)
329  {
330  if (!m_compressed)
331  {
332  size += (2 + 128); //Basic block ack
333  }
334  else
335  {
336  size += (2 + 8); //Compressed block ack
337  }
338  }
339  else
340  {
341  if (m_compressed)
342  {
343  size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-tid block ack
344  }
345  else
346  {
347  NS_FATAL_ERROR ("Reserved configuration.");
348  }
349  }
350  return size;
351 }
352 
353 void
355 {
356  NS_LOG_FUNCTION (this << &start);
359  if (!m_multiTid)
360  {
362  i = SerializeBitmap (i);
363  }
364  else
365  {
366  if (m_compressed)
367  {
368  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
369  }
370  else
371  {
372  NS_FATAL_ERROR ("Reserved configuration.");
373  }
374  }
375 }
376 
377 uint32_t
379 {
380  NS_LOG_FUNCTION (this << &start);
383  if (!m_multiTid)
384  {
386  i = DeserializeBitmap (i);
387  }
388  else
389  {
390  if (m_compressed)
391  {
392  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
393  }
394  else
395  {
396  NS_FATAL_ERROR ("Reserved configuration.");
397  }
398  }
399  return i.GetDistanceFrom (start);
400 }
401 
402 void
404 {
405  NS_LOG_FUNCTION (this << immediateAck);
406  m_baAckPolicy = immediateAck;
407 }
408 
409 void
411 {
412  NS_LOG_FUNCTION (this << type);
413  switch (type)
414  {
415  case BASIC_BLOCK_ACK:
416  m_multiTid = false;
417  m_compressed = false;
418  break;
420  m_multiTid = false;
421  m_compressed = true;
422  break;
423  case MULTI_TID_BLOCK_ACK:
424  m_multiTid = true;
425  m_compressed = true;
426  break;
427  default:
428  NS_FATAL_ERROR ("Invalid variant type");
429  break;
430  }
431 }
432 
433 void
435 {
436  NS_LOG_FUNCTION (this << static_cast<uint32_t> (tid));
437  m_tidInfo = static_cast<uint16_t> (tid);
438 }
439 
440 void
442 {
443  NS_LOG_FUNCTION (this << seq);
444  m_startingSeq = seq;
445 }
446 
447 bool
449 {
450  NS_LOG_FUNCTION (this);
451  return (m_baAckPolicy) ? true : false;
452 }
453 
454 uint8_t
456 {
457  NS_LOG_FUNCTION (this);
458  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
459  return tid;
460 }
461 
462 uint16_t
464 {
465  NS_LOG_FUNCTION (this);
466  return m_startingSeq;
467 }
468 
469 bool
471 {
472  NS_LOG_FUNCTION (this);
473  return (!m_multiTid && !m_compressed) ? true : false;
474 }
475 
476 bool
478 {
479  NS_LOG_FUNCTION (this);
480  return (!m_multiTid && m_compressed) ? true : false;
481 }
482 
483 bool
485 {
486  NS_LOG_FUNCTION (this);
487  return (m_multiTid && m_compressed) ? true : false;
488 }
489 
490 uint16_t
492 {
493  NS_LOG_FUNCTION (this);
494  uint16_t res = 0;
495  if (m_baAckPolicy)
496  {
497  res |= 0x1;
498  }
499  if (m_multiTid)
500  {
501  res |= (0x1 << 1);
502  }
503  if (m_compressed)
504  {
505  res |= (0x1 << 2);
506  }
507  res |= (m_tidInfo << 12) & (0xf << 12);
508  return res;
509 }
510 
511 void
513 {
514  NS_LOG_FUNCTION (this << ba);
515  m_baAckPolicy = ((ba & 0x01) == 1) ? true : false;
516  m_multiTid = (((ba >> 1) & 0x01) == 1) ? true : false;
517  m_compressed = (((ba >> 2) & 0x01) == 1) ? true : false;
518  m_tidInfo = (ba >> 12) & 0x0f;
519 }
520 
521 uint16_t
523 {
524  NS_LOG_FUNCTION (this);
525  return (m_startingSeq << 4) & 0xfff0;
526 }
527 
528 void
530 {
531  NS_LOG_FUNCTION (this << seqControl);
532  m_startingSeq = (seqControl >> 4) & 0x0fff;
533 }
534 
537 {
538  NS_LOG_FUNCTION (this << &start);
540  if (!m_multiTid)
541  {
542  if (!m_compressed)
543  {
544  for (uint32_t j = 0; j < 64; j++)
545  {
546  i.WriteHtolsbU16 (bitmap.m_bitmap[j]);
547  }
548  }
549  else
550  {
551  i.WriteHtolsbU64 (bitmap.m_compressedBitmap);
552  }
553  }
554  else
555  {
556  if (m_compressed)
557  {
558  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
559  }
560  else
561  {
562  NS_FATAL_ERROR ("Reserved configuration.");
563  }
564  }
565  return i;
566 }
567 
570 {
571  NS_LOG_FUNCTION (this << &start);
573  if (!m_multiTid)
574  {
575  if (!m_compressed)
576  {
577  for (uint32_t j = 0; j < 64; j++)
578  {
579  bitmap.m_bitmap[j] = i.ReadLsbtohU16 ();
580  }
581  }
582  else
583  {
584  bitmap.m_compressedBitmap = i.ReadLsbtohU64 ();
585  }
586  }
587  else
588  {
589  if (m_compressed)
590  {
591  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
592  }
593  else
594  {
595  NS_FATAL_ERROR ("Reserved configuration.");
596  }
597  }
598  return i;
599 }
600 
601 void
603 {
604  NS_LOG_FUNCTION (this << seq);
605  if (!IsInBitmap (seq))
606  {
607  return;
608  }
609  if (!m_multiTid)
610  {
611  if (!m_compressed)
612  {
613  /* To set correctly basic block ack bitmap we need fragment number too.
614  So if it's not specified, we consider packet not fragmented. */
615  bitmap.m_bitmap[IndexInBitmap (seq)] |= 0x0001;
616  }
617  else
618  {
619  bitmap.m_compressedBitmap |= (uint64_t (0x0000000000000001) << IndexInBitmap (seq));
620  }
621  }
622  else
623  {
624  if (m_compressed)
625  {
626  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
627  }
628  else
629  {
630  NS_FATAL_ERROR ("Reserved configuration.");
631  }
632  }
633 }
634 
635 void
637 {
638  NS_LOG_FUNCTION (this << seq << static_cast<uint32_t> (frag));
639  NS_ASSERT (frag < 16);
640  if (!IsInBitmap (seq))
641  {
642  return;
643  }
644  if (!m_multiTid)
645  {
646  if (!m_compressed)
647  {
648  bitmap.m_bitmap[IndexInBitmap (seq)] |= (0x0001 << frag);
649  }
650  else
651  {
652  /* We can ignore this...compressed block ack doesn't support
653  acknowledgement of single fragments */
654  }
655  }
656  else
657  {
658  if (m_compressed)
659  {
660  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
661  }
662  else
663  {
664  NS_FATAL_ERROR ("Reserved configuration.");
665  }
666  }
667 }
668 
669 bool
671 {
672  NS_LOG_FUNCTION (this << seq);
673  if (!IsInBitmap (seq))
674  {
675  return false;
676  }
677  if (!m_multiTid)
678  {
679  if (!m_compressed)
680  {
681  /*It's impossible to say if an entire packet was correctly received. */
682  return false;
683  }
684  else
685  {
686  uint64_t mask = uint64_t (0x0000000000000001);
687  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
688  }
689  }
690  else
691  {
692  if (m_compressed)
693  {
694  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
695  }
696  else
697  {
698  NS_FATAL_ERROR ("Reserved configuration.");
699  }
700  }
701  return false;
702 }
703 
704 bool
705 CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const
706 {
707  NS_LOG_FUNCTION (this << seq << static_cast<uint32_t> (frag));
708  NS_ASSERT (frag < 16);
709  if (!IsInBitmap (seq))
710  {
711  return false;
712  }
713  if (!m_multiTid)
714  {
715  if (!m_compressed)
716  {
717  return ((bitmap.m_bitmap[IndexInBitmap (seq)] & (0x0001 << frag)) != 0x0000) ? true : false;
718  }
719  else
720  {
721  /* Although this could make no sense, if packet with sequence number
722  equal to <i>seq</i> was correctly received, also all of its fragments
723  were correctly received. */
724  uint64_t mask = uint64_t (0x0000000000000001);
725  return (((bitmap.m_compressedBitmap >> IndexInBitmap (seq)) & mask) == 1) ? true : false;
726  }
727  }
728  else
729  {
730  if (m_compressed)
731  {
732  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
733  }
734  else
735  {
736  NS_FATAL_ERROR ("Reserved configuration.");
737  }
738  }
739  return false;
740 }
741 
742 uint8_t
744 {
745  NS_LOG_FUNCTION (this << seq);
746  uint8_t index;
747  if (seq >= m_startingSeq)
748  {
749  index = seq - m_startingSeq;
750  }
751  else
752  {
753  index = 4096 - m_startingSeq + seq;
754  }
755  NS_ASSERT (index <= 63);
756  return index;
757 }
758 
759 bool
761 {
762  NS_LOG_FUNCTION (this << seq);
763  return (seq - m_startingSeq + 4096) % 4096 < 64;
764 }
765 
766 const uint16_t*
768 {
769  NS_LOG_FUNCTION (this);
770  return bitmap.m_bitmap;
771 }
772 
773 uint64_t
775 {
776  NS_LOG_FUNCTION (this);
777  return bitmap.m_compressedBitmap;
778 }
779 
780 void
782 {
783  NS_LOG_FUNCTION (this);
784  memset (&bitmap, 0, sizeof (bitmap));
785 }
786 
787 } // namespace ns3
Protocol header serialization and deserialization.
Definition: header.h:42
void SetType(enum BlockAckType type)
Set the block ACK type.
union ns3::CtrlBAckResponseHeader::@86 bitmap
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
virtual TypeId GetInstanceTypeId(void) const
Definition: ctrl-headers.cc:61
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)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
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.
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate ACK.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
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).
NS_LOG_COMPONENT_DEFINE("CtrlHeaders")
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:807
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
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:68
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:75
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:50
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:935
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:99
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:951
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.
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1090
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:1118
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:611
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.