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 #include "wifi-tx-vector.h"
23 #include "ns3/he-phy.h"
24 #include "wifi-utils.h"
25 #include <algorithm>
26 
27 namespace ns3 {
28 
29 
30 /***********************************
31  * Block ack request
32  ***********************************/
33 
34 NS_OBJECT_ENSURE_REGISTERED (CtrlBAckRequestHeader);
35 
37  : m_barAckPolicy (false),
38  m_barType (BlockAckReqType::BASIC)
39 {
40 }
41 
43 {
44 }
45 
46 TypeId
48 {
49  static TypeId tid = TypeId ("ns3::CtrlBAckRequestHeader")
50  .SetParent<Header> ()
51  .SetGroupName ("Wifi")
52  .AddConstructor<CtrlBAckRequestHeader> ()
53  ;
54  return tid;
55 }
56 
57 TypeId
59 {
60  return GetTypeId ();
61 }
62 
63 void
64 CtrlBAckRequestHeader::Print (std::ostream &os) const
65 {
66  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
67 }
68 
69 uint32_t
71 {
72  uint32_t size = 0;
73  size += 2; //Bar control
74  switch (m_barType.m_variant)
75  {
79  size += 2;
80  break;
82  size += (2 + 2) * (m_tidInfo + 1);
83  break;
84  default:
85  NS_FATAL_ERROR ("Invalid BA type");
86  break;
87  }
88  return size;
89 }
90 
91 void
93 {
96  switch (m_barType.m_variant)
97  {
102  break;
104  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
105  break;
106  default:
107  NS_FATAL_ERROR ("Invalid BA type");
108  break;
109  }
110 }
111 
112 uint32_t
114 {
117  switch (m_barType.m_variant)
118  {
123  break;
125  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
126  break;
127  default:
128  NS_FATAL_ERROR ("Invalid BA type");
129  break;
130  }
131  return i.GetDistanceFrom (start);
132 }
133 
134 uint16_t
136 {
137  uint16_t res = 0;
138  switch (m_barType.m_variant)
139  {
141  break;
143  res |= (0x02 << 1);
144  break;
146  res |= (0x01 << 1);
147  break;
149  res |= (0x03 << 1);
150  break;
151  default:
152  NS_FATAL_ERROR ("Invalid BA type");
153  break;
154  }
155  res |= (m_tidInfo << 12) & (0xf << 12);
156  return res;
157 }
158 
159 void
161 {
162  m_barAckPolicy = ((bar & 0x01) == 1) ? true : false;
163  if (((bar >> 1) & 0x0f) == 0x03)
164  {
166  }
167  else if (((bar >> 1) & 0x0f) == 0x01)
168  {
170  }
171  else if (((bar >> 1) & 0x0f) == 0x02)
172  {
174  }
175  else
176  {
178  }
179  m_tidInfo = (bar >> 12) & 0x0f;
180 }
181 
182 uint16_t
184 {
185  return (m_startingSeq << 4) & 0xfff0;
186 }
187 
188 void
190 {
191  m_startingSeq = (seqControl >> 4) & 0x0fff;
192 }
193 
194 void
196 {
197  m_barAckPolicy = immediateAck;
198 }
199 
200 void
202 {
203  m_barType = type;
204 }
205 
208 {
209  return m_barType;
210 }
211 
212 void
214 {
215  m_tidInfo = static_cast<uint16_t> (tid);
216 }
217 
218 void
220 {
221  m_startingSeq = seq;
222 }
223 
224 bool
226 {
227  return m_barAckPolicy;
228 }
229 
230 uint8_t
232 {
233  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
234  return tid;
235 }
236 
237 uint16_t
239 {
240  return m_startingSeq;
241 }
242 
243 bool
245 {
246  return (m_barType.m_variant == BlockAckReqType::BASIC) ? true : false;
247 }
248 
249 bool
251 {
252  return (m_barType.m_variant == BlockAckReqType::COMPRESSED) ? true : false;
253 }
254 
255 bool
257 {
258  return (m_barType.m_variant == BlockAckReqType::EXTENDED_COMPRESSED) ? true : false;
259 }
260 
261 bool
263 {
264  return (m_barType.m_variant == BlockAckReqType::MULTI_TID) ? true : false;
265 }
266 
267 
268 /***********************************
269  * Block ack response
270  ***********************************/
271 
273 
275  : m_baAckPolicy (false),
276  m_tidInfo (0),
277  m_startingSeq (0)
278 {
280 }
281 
283 {
284 }
285 
286 TypeId
288 {
289  static TypeId tid = TypeId ("ns3::CtrlBAckResponseHeader")
290  .SetParent<Header> ()
291  .SetGroupName ("Wifi")
292  .AddConstructor<CtrlBAckResponseHeader> ()
293  ;
294  return tid;
295 }
296 
297 TypeId
299 {
300  return GetTypeId ();
301 }
302 
303 void
304 CtrlBAckResponseHeader::Print (std::ostream &os) const
305 {
306  os << "TID_INFO=" << m_tidInfo << ", StartingSeq=" << std::hex << m_startingSeq << std::dec;
307 }
308 
309 uint32_t
311 {
312  uint32_t size = 0;
313  size += 2; //Bar control
314  switch (m_baType.m_variant)
315  {
316  case BlockAckType::BASIC:
319  size += (2 + m_baType.m_bitmapLen[0]);
320  break;
322  size += (2 + 2 + 8) * (m_tidInfo + 1); //Multi-TID block ack
323  break;
324  default:
325  NS_FATAL_ERROR ("Invalid BA type");
326  break;
327  }
328  return size;
329 }
330 
331 void
333 {
336  switch (m_baType.m_variant)
337  {
338  case BlockAckType::BASIC:
342  i = SerializeBitmap (i);
343  break;
345  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
346  break;
347  default:
348  NS_FATAL_ERROR ("Invalid BA type");
349  break;
350  }
351 }
352 
353 uint32_t
355 {
358  switch (m_baType.m_variant)
359  {
360  case BlockAckType::BASIC:
364  i = DeserializeBitmap (i);
365  break;
367  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
368  break;
369  default:
370  NS_FATAL_ERROR ("Invalid BA type");
371  break;
372  }
373  return i.GetDistanceFrom (start);
374 }
375 
376 void
378 {
379  m_baAckPolicy = immediateAck;
380 }
381 
382 void
384 {
385  m_baType = type;
386  m_bitmap.resize (m_baType.m_bitmapLen[0]);
387  m_bitmap.assign (m_baType.m_bitmapLen[0], 0);
388 }
389 
392 {
393  return m_baType;
394 }
395 
396 void
398 {
399  m_tidInfo = static_cast<uint16_t> (tid);
400 }
401 
402 void
404 {
405  m_startingSeq = seq;
406 }
407 
408 bool
410 {
411  return (m_baAckPolicy) ? true : false;
412 }
413 
414 uint8_t
416 {
417  uint8_t tid = static_cast<uint8_t> (m_tidInfo);
418  return tid;
419 }
420 
421 uint16_t
423 {
424  return m_startingSeq;
425 }
426 
427 bool
429 {
430  return (m_baType.m_variant == BlockAckType::BASIC) ? true : false;
431 }
432 
433 bool
435 {
436  return (m_baType.m_variant == BlockAckType::COMPRESSED) ? true : false;
437 }
438 
439 bool
441 {
442  return (m_baType.m_variant == BlockAckType::EXTENDED_COMPRESSED) ? true : false;
443 }
444 
445 bool
447 {
448  return (m_baType.m_variant == BlockAckType::MULTI_TID) ? true : false;
449 }
450 
451 uint16_t
453 {
454  uint16_t res = 0;
455  if (m_baAckPolicy)
456  {
457  res |= 0x1;
458  }
459  switch (m_baType.m_variant)
460  {
461  case BlockAckType::BASIC:
462  break;
464  res |= (0x02 << 1);
465  break;
467  res |= (0x01 << 1);
468  break;
470  res |= (0x03 << 1);
471  break;
472  default:
473  NS_FATAL_ERROR ("Invalid BA type");
474  break;
475  }
476  res |= (m_tidInfo << 12) & (0xf << 12);
477  return res;
478 }
479 
480 void
482 {
483  m_baAckPolicy = ((ba & 0x01) == 1) ? true : false;
484  if (((ba >> 1) & 0x0f) == 0x03)
485  {
487  }
488  else if (((ba >> 1) & 0x0f) == 0x01)
489  {
491  }
492  else if (((ba >> 1) & 0x0f) == 0x02)
493  {
495  }
496  else if (((ba >> 1) & 0x0f) == 0)
497  {
499  }
500  else
501  {
502  NS_FATAL_ERROR ("Invalid BA type");
503  }
504  m_tidInfo = (ba >> 12) & 0x0f;
505 }
506 
507 uint16_t
509 {
510  uint16_t ret = (m_startingSeq << 4) & 0xfff0;
511 
513  && m_baType.m_bitmapLen[0] == 32)
514  {
515  ret |= 0x0004;
516  }
517  return ret;
518 }
519 
520 void
522 {
524  {
525  if ((seqControl & 0x0001) == 1)
526  {
527  NS_FATAL_ERROR ("Fragmentation Level 3 unsupported");
528  }
529  if (((seqControl >> 3) & 0x0001) == 0 && ((seqControl >> 1) & 0x0003) == 0)
530  {
532  }
533  else if (((seqControl >> 3) & 0x0001) == 0 && ((seqControl >> 1) & 0x0003) == 2)
534  {
536  }
537  else
538  {
539  NS_FATAL_ERROR ("Reserved configurations");
540  }
541  }
542  m_startingSeq = (seqControl >> 4) & 0x0fff;
543 }
544 
547 {
549  switch (m_baType.m_variant)
550  {
551  case BlockAckType::BASIC:
554  for (auto& byte : m_bitmap)
555  {
556  i.WriteU8 (byte);
557  }
558  break;
560  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
561  break;
562  default:
563  NS_FATAL_ERROR ("Invalid BA type");
564  break;
565  }
566  return i;
567 }
568 
571 {
573  switch (m_baType.m_variant)
574  {
575  case BlockAckType::BASIC:
578  for (uint8_t j = 0; j < m_baType.m_bitmapLen[0]; j++)
579  {
580  m_bitmap[j] = i.ReadU8 ();
581  }
582  break;
584  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
585  break;
586  default:
587  NS_FATAL_ERROR ("Invalid BA type");
588  break;
589  }
590  return i;
591 }
592 
593 void
595 {
596  if (!IsInBitmap (seq))
597  {
598  return;
599  }
600  switch (m_baType.m_variant)
601  {
602  case BlockAckType::BASIC:
603  /* To set correctly basic block ack bitmap we need fragment number too.
604  So if it's not specified, we consider packet not fragmented. */
605  m_bitmap[IndexInBitmap (seq) * 2] |= 0x01;
606  break;
609  {
610  uint16_t index = IndexInBitmap (seq);
611  m_bitmap[index / 8] |= (uint8_t (0x01) << (index % 8));
612  break;
613  }
615  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
616  break;
617  default:
618  NS_FATAL_ERROR ("Invalid BA type");
619  break;
620  }
621 }
622 
623 void
625 {
626  NS_ASSERT (frag < 16);
627  if (!IsInBitmap (seq))
628  {
629  return;
630  }
631  switch (m_baType.m_variant)
632  {
633  case BlockAckType::BASIC:
634  m_bitmap[IndexInBitmap (seq) * 2 + frag / 8] |= (0x01 << (frag % 8));
635  break;
638  /* We can ignore this...compressed block ack doesn't support
639  acknowledgment of single fragments */
640  break;
642  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
643  break;
644  default:
645  NS_FATAL_ERROR ("Invalid BA type");
646  break;
647  }
648 }
649 
650 bool
652 {
653  if (!IsInBitmap (seq))
654  {
655  return false;
656  }
657  switch (m_baType.m_variant)
658  {
659  case BlockAckType::BASIC:
660  /*It's impossible to say if an entire packet was correctly received. */
661  return false;
664  {
665  uint16_t index = IndexInBitmap (seq);
666  uint8_t mask = uint8_t (0x01) << (index % 8) ;
667  return ((m_bitmap[index / 8] & mask) != 0) ? true : false;
668  }
670  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
671  break;
672  default:
673  NS_FATAL_ERROR ("Invalid BA type");
674  break;
675  }
676  return false;
677 }
678 
679 bool
680 CtrlBAckResponseHeader::IsFragmentReceived (uint16_t seq, uint8_t frag) const
681 {
682  NS_ASSERT (frag < 16);
683  if (!IsInBitmap (seq))
684  {
685  return false;
686  }
687  switch (m_baType.m_variant)
688  {
689  case BlockAckType::BASIC:
690  return ((m_bitmap[IndexInBitmap (seq) * 2 + frag / 8] & (0x01 << (frag % 8))) != 0) ? true : false;
693  /* We can ignore this...compressed block ack doesn't support
694  acknowledgement of single fragments */
695  return false;
697  {
698  NS_FATAL_ERROR ("Multi-tid block ack is not supported.");
699  break;
700  }
701  default:
702  {
703  NS_FATAL_ERROR ("Invalid BA type");
704  break;
705  }
706  }
707  return false;
708 }
709 
710 uint16_t
712 {
713  uint16_t index;
714  if (seq >= m_startingSeq)
715  {
716  index = seq - m_startingSeq;
717  }
718  else
719  {
720  index = SEQNO_SPACE_SIZE - m_startingSeq + seq;
721  }
723  {
724  NS_ASSERT (index <= 255);
725  }
726  else
727  {
728  NS_ASSERT (index <= 63);
729  }
730  return index;
731 }
732 
733 bool
735 {
737  {
738  return (seq - m_startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE < 256;
739  }
740  else
741  {
742  return (seq - m_startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE < 64;
743  }
744 }
745 
746 const std::vector<uint8_t>&
748 {
749  return m_bitmap;
750 }
751 
752 void
754 {
755  m_bitmap.assign (m_baType.m_bitmapLen[0], 0);
756 }
757 
758 
759 /***********************************
760  * Trigger frame - User Info field
761  ***********************************/
762 
764  : m_aid12 (0),
765  m_ruAllocation (0),
766  m_ulFecCodingType (false),
767  m_ulMcs (0),
768  m_ulDcm (false),
769  m_ulTargetRssi (0),
770  m_triggerType (triggerType),
771  m_basicTriggerDependentUserInfo (0)
772 {
773  memset (&m_bits26To31, 0, sizeof (m_bits26To31));
774 }
775 
777 {
778 }
779 
782 {
783  NS_ABORT_MSG_IF (m_triggerType != userInfo.m_triggerType, "Trigger Frame type mismatch");
784 
785  // check for self-assignment
786  if (&userInfo == this)
787  {
788  return *this;
789  }
790 
791  m_aid12 = userInfo.m_aid12;
792  m_ruAllocation = userInfo.m_ruAllocation;
794  m_ulMcs = userInfo.m_ulMcs;
795  m_ulDcm = userInfo.m_ulDcm;
796  m_bits26To31 = userInfo.m_bits26To31;
797  m_ulTargetRssi = userInfo.m_ulTargetRssi;
800  return *this;
801 }
802 
803 void
804 CtrlTriggerUserInfoField::Print (std::ostream &os) const
805 {
806  os << ", USER_INFO AID=" << m_aid12 << ", RU_Allocation=" << +m_ruAllocation << ", MCS=" << +m_ulMcs;
807 }
808 
809 uint32_t
811 {
812  uint32_t size = 0;
813  size += 5; // User Info (excluding Trigger Dependent User Info)
814 
815  switch (m_triggerType)
816  {
817  case BASIC_TRIGGER:
818  case BFRP_TRIGGER:
819  size += 1;
820  break;
821  case MU_BAR_TRIGGER:
822  size += m_muBarTriggerDependentUserInfo.GetSerializedSize (); // BAR Control and BAR Information
823  break;
824  // The Trigger Dependent User Info subfield is not present in the other variants
825  }
826 
827  return size;
828 }
829 
832 {
833  NS_ABORT_MSG_IF (m_triggerType == BFRP_TRIGGER, "BFRP Trigger frame is not supported");
834  NS_ABORT_MSG_IF (m_triggerType == GCR_MU_BAR_TRIGGER, "GCR-MU-BAR Trigger frame is not supported");
835  NS_ABORT_MSG_IF (m_triggerType == NFRP_TRIGGER, "NFRP Trigger frame is not supported");
836 
838 
839  uint32_t userInfo = 0; // User Info except the MSB
840  userInfo |= (m_aid12 & 0x0fff);
841  userInfo |= (m_ruAllocation << 12);
842  userInfo |= (m_ulFecCodingType ? 1 << 20 : 0);
843  userInfo |= (m_ulMcs & 0x0f) << 21;
844  userInfo |= (m_ulDcm ? 1 << 25 : 0);
845 
846  if (m_aid12 != 0 && m_aid12 != 2045)
847  {
848  userInfo |= (m_bits26To31.ssAllocation.startingSs & 0x07) << 26;
849  userInfo |= (m_bits26To31.ssAllocation.nSs & 0x07) << 29;
850  }
851  else
852  {
853  userInfo |= (m_bits26To31.raRuInformation.nRaRu & 0x1f) << 26;
854  userInfo |= (m_bits26To31.raRuInformation.moreRaRu ? 1 << 31 : 0);
855  }
856 
857  i.WriteHtolsbU32 (userInfo);
858  // Here we need to write 8 bits covering the UL Target RSSI (7 bits) and the
859  // Reserved bit. Given how m_ulTargetRssi is set, writing m_ulTargetRssi
860  // leads to setting the Reserved bit to zero
862 
864  {
866  }
867  else if (m_triggerType == MU_BAR_TRIGGER)
868  {
871  }
872 
873  return i;
874 }
875 
878 {
879  NS_ABORT_MSG_IF (m_triggerType == BFRP_TRIGGER, "BFRP Trigger frame is not supported");
880  NS_ABORT_MSG_IF (m_triggerType == GCR_MU_BAR_TRIGGER, "GCR-MU-BAR Trigger frame is not supported");
881  NS_ABORT_MSG_IF (m_triggerType == NFRP_TRIGGER, "NFRP Trigger frame is not supported");
882 
884 
885  uint32_t userInfo = i.ReadLsbtohU32 ();
886 
887  m_aid12 = userInfo & 0x0fff;
888  NS_ABORT_MSG_IF (m_aid12 == 4095, "Cannot deserialize a Padding field");
889  m_ruAllocation = (userInfo >> 12) & 0xff;
890  m_ulFecCodingType = (userInfo >> 20) & 0x01;
891  m_ulMcs = (userInfo >> 21) & 0x0f;
892  m_ulDcm = (userInfo >> 25) & 0x01;
893 
894  if (m_aid12 != 0 && m_aid12 != 2045)
895  {
896  m_bits26To31.ssAllocation.startingSs = (userInfo >> 26) & 0x07;
897  m_bits26To31.ssAllocation.nSs = (userInfo >> 29) & 0x07;
898  }
899  else
900  {
901  m_bits26To31.raRuInformation.nRaRu = (userInfo >> 26) & 0x1f;
902  m_bits26To31.raRuInformation.moreRaRu = (userInfo >> 31) & 0x01;
903  }
904 
905  m_ulTargetRssi = i.ReadU8 () & 0x7f; // B39 is reserved
906 
908  {
910  }
911  else if (m_triggerType == MU_BAR_TRIGGER)
912  {
913  uint32_t len = m_muBarTriggerDependentUserInfo.Deserialize (i);
914  i.Next (len);
915  }
916 
917  return i;
918 }
919 
922 {
923  return static_cast<TriggerFrameType> (m_triggerType);
924 }
925 
926 void
928 {
929  m_aid12 = aid & 0x0fff;
930 }
931 
932 uint16_t
934 {
935  return m_aid12;
936 }
937 
938 bool
940 {
941  return (m_aid12 == 0);
942 }
943 
944 bool
946 {
947  return (m_aid12 == 2045);
948 }
949 
950 void
952 {
953  NS_ABORT_MSG_IF (ru.index == 0, "Valid indices start at 1");
954 
955  switch (ru.ruType)
956  {
957  case HeRu::RU_26_TONE:
958  m_ruAllocation = ru.index - 1;
959  break;
960  case HeRu::RU_52_TONE:
961  m_ruAllocation = ru.index + 36;
962  break;
963  case HeRu::RU_106_TONE:
964  m_ruAllocation = ru.index + 52;
965  break;
966  case HeRu::RU_242_TONE:
967  m_ruAllocation = ru.index + 60;
968  break;
969  case HeRu::RU_484_TONE:
970  m_ruAllocation = ru.index + 64;
971  break;
972  case HeRu::RU_996_TONE:
973  m_ruAllocation = 67;
974  break;
975  case HeRu::RU_2x996_TONE:
976  m_ruAllocation = 68;
977  break;
978  default:
979  NS_FATAL_ERROR ("RU type unknown.");
980  break;
981  }
982 
983  NS_ABORT_MSG_IF (m_ruAllocation > 68, "Reserved value.");
984 
985  m_ruAllocation += (ru.primary80MHz ? 0 : 0x80);
986 }
987 
990 {
991  HeRu::RuSpec ru;
992 
993  ru.primary80MHz = ((m_ruAllocation & 0x80) == 0);
994 
995  uint8_t val = m_ruAllocation & 0x7f;
996 
997  if (val < 37)
998  {
1000  ru.index = val + 1;
1001  }
1002  else if (val < 53)
1003  {
1004  ru.ruType = HeRu::RU_52_TONE;
1005  ru.index = val - 36;
1006  }
1007  else if (val < 61)
1008  {
1010  ru.index = val - 52;
1011  }
1012  else if (val < 65)
1013  {
1015  ru.index = val - 60;
1016  }
1017  else if (val < 67)
1018  {
1020  ru.index = val - 64;
1021  }
1022  else if (val == 67)
1023  {
1025  ru.index = 1;
1026  }
1027  else if (val == 68)
1028  {
1030  ru.index = 1;
1031  }
1032  else
1033  {
1034  NS_FATAL_ERROR ("Reserved value.");
1035  }
1036 
1037  return ru;
1038 }
1039 
1040 void
1042 {
1043  m_ulFecCodingType = ldpc;
1044 }
1045 
1046 bool
1048 {
1049  return m_ulFecCodingType;
1050 }
1051 
1052 void
1054 {
1055  NS_ABORT_MSG_IF (mcs > 11, "Invalid MCS index");
1056  m_ulMcs = mcs;
1057 }
1058 
1059 uint8_t
1061 {
1062  return m_ulMcs;
1063 }
1064 
1065 void
1067 {
1068  m_ulDcm = dcm;
1069 }
1070 
1071 bool
1073 {
1074  return m_ulDcm;
1075 }
1076 
1077 void
1078 CtrlTriggerUserInfoField::SetSsAllocation (uint8_t startingSs, uint8_t nSs)
1079 {
1080  NS_ABORT_MSG_IF (m_aid12 == 0 || m_aid12 == 2045, "SS Allocation subfield not present");
1081  NS_ABORT_MSG_IF (!startingSs || startingSs > 8, "Starting SS must be from 1 to 8");
1082  NS_ABORT_MSG_IF (!nSs || nSs > 8, "Number of SS must be from 1 to 8");
1083 
1084  m_bits26To31.ssAllocation.startingSs = startingSs - 1;
1085  m_bits26To31.ssAllocation.nSs = nSs - 1;
1086 }
1087 
1088 uint8_t
1090 {
1091  if (m_aid12 == 0 || m_aid12 == 2045)
1092  {
1093  return 1;
1094  }
1095  return m_bits26To31.ssAllocation.startingSs + 1;
1096 }
1097 
1098 uint8_t
1100 {
1101  if (m_aid12 == 0 || m_aid12 == 2045)
1102  {
1103  return 1;
1104  }
1105  return m_bits26To31.ssAllocation.nSs + 1;
1106 }
1107 
1108 void
1109 CtrlTriggerUserInfoField::SetRaRuInformation (uint8_t nRaRu, bool moreRaRu)
1110 {
1111  NS_ABORT_MSG_IF (m_aid12 != 0 && m_aid12 != 2045, "RA-RU Information subfield not present");
1112  NS_ABORT_MSG_IF (!nRaRu || nRaRu > 32, "Number of contiguous RA-RUs must be from 1 to 32");
1113 
1114  m_bits26To31.raRuInformation.nRaRu = nRaRu - 1;
1115  m_bits26To31.raRuInformation.moreRaRu = moreRaRu;
1116 }
1117 
1118 uint8_t
1120 {
1121  NS_ABORT_MSG_IF (m_aid12 != 0 && m_aid12 != 2045, "RA-RU Information subfield not present");
1122 
1123  return m_bits26To31.raRuInformation.nRaRu + 1;
1124 }
1125 
1126 bool
1128 {
1129  NS_ABORT_MSG_IF (m_aid12 != 0 && m_aid12 != 2045, "RA-RU Information subfield not present");
1130 
1131  return m_bits26To31.raRuInformation.moreRaRu;
1132 }
1133 
1134 void
1136 {
1137  m_ulTargetRssi = 127; // see Table 9-25i of 802.11ax amendment D3.0
1138 }
1139 
1140 void
1142 {
1143  NS_ABORT_MSG_IF (dBm < -110 || dBm > -20, "Invalid values for signal power");
1144 
1145  m_ulTargetRssi = static_cast<uint8_t> (110 + dBm);
1146 }
1147 
1148 bool
1150 {
1151  return (m_ulTargetRssi == 127);
1152 }
1153 
1154 int8_t
1156 {
1157  NS_ABORT_MSG_IF (m_ulTargetRssi == 127, "STA must use its max TX power");
1158 
1159  return static_cast<int8_t> (m_ulTargetRssi) - 110;
1160 }
1161 
1162 void
1163 CtrlTriggerUserInfoField::SetBasicTriggerDepUserInfo (uint8_t spacingFactor, uint8_t tidLimit, AcIndex prefAc)
1164 {
1165  NS_ABORT_MSG_IF (m_triggerType != BASIC_TRIGGER, "Not a Basic Trigger Frame");
1166 
1167  m_basicTriggerDependentUserInfo = (spacingFactor & 0x03)
1168  | (tidLimit & 0x07) << 2
1169  // B5 is reserved
1170  | (prefAc & 0x03) << 6;
1171 }
1172 
1173 uint8_t
1175 {
1176  NS_ABORT_MSG_IF (m_triggerType != BASIC_TRIGGER, "Not a Basic Trigger Frame");
1177 
1178  return m_basicTriggerDependentUserInfo & 0x03;
1179 }
1180 
1181 uint8_t
1183 {
1184  NS_ABORT_MSG_IF (m_triggerType != BASIC_TRIGGER, "Not a Basic Trigger Frame");
1185 
1186  return (m_basicTriggerDependentUserInfo & 0x1c) >> 2;
1187 }
1188 
1189 AcIndex
1191 {
1192  NS_ABORT_MSG_IF (m_triggerType != BASIC_TRIGGER, "Not a Basic Trigger Frame");
1193 
1194  return AcIndex ((m_basicTriggerDependentUserInfo & 0xc0) >> 6);
1195 }
1196 
1197 void
1199 {
1200  NS_ABORT_MSG_IF (m_triggerType != MU_BAR_TRIGGER, "Not a MU-BAR Trigger frame");
1203  "BAR Control indicates it is neither the Compressed nor the Multi-TID variant");
1205 }
1206 
1207 const CtrlBAckRequestHeader&
1209 {
1210  NS_ABORT_MSG_IF (m_triggerType != MU_BAR_TRIGGER, "Not a MU-BAR Trigger frame");
1211 
1213 }
1214 
1215 /***********************************
1216  * Trigger frame
1217  ***********************************/
1218 
1220 
1222  : m_triggerType (0),
1223  m_ulLength (0),
1224  m_moreTF (false),
1225  m_csRequired (false),
1226  m_ulBandwidth (0),
1227  m_giAndLtfType (0),
1228  m_apTxPower (0),
1229  m_ulSpatialReuse (0)
1230 {
1231 }
1232 
1234  : CtrlTriggerHeader ()
1235 {
1236  m_triggerType = type;
1237  SetUlBandwidth (txVector.GetChannelWidth ());
1238  SetUlLength (txVector.GetLength ());
1239  uint16_t gi = txVector.GetGuardInterval ();
1240  if (gi == 800 || gi == 1600)
1241  {
1242  m_giAndLtfType = 1;
1243  }
1244  else
1245  {
1246  m_giAndLtfType = 2;
1247  }
1248  for (auto& userInfo : txVector.GetHeMuUserInfoMap ())
1249  {
1251  ui.SetAid12 (userInfo.first);
1252  ui.SetRuAllocation (userInfo.second.ru);
1253  ui.SetUlMcs (userInfo.second.mcs.GetMcsValue ());
1254  ui.SetSsAllocation (1, userInfo.second.nss); // MU-MIMO is not supported
1255  }
1256 }
1257 
1259 {
1260 }
1261 
1264 {
1265  // check for self-assignment
1266  if (&trigger == this)
1267  {
1268  return *this;
1269  }
1270 
1271  m_triggerType = trigger.m_triggerType;
1272  m_ulLength = trigger.m_ulLength;
1273  m_moreTF = trigger.m_moreTF;
1274  m_csRequired = trigger.m_csRequired;
1275  m_ulBandwidth = trigger.m_ulBandwidth;
1276  m_giAndLtfType = trigger.m_giAndLtfType;
1277  m_apTxPower = trigger.m_apTxPower;
1279  m_userInfoFields.clear ();
1281  return *this;
1282 }
1283 
1284 TypeId
1286 {
1287  static TypeId tid = TypeId ("ns3::CtrlTriggerHeader")
1288  .SetParent<Header> ()
1289  .SetGroupName ("Wifi")
1290  .AddConstructor<CtrlTriggerHeader> ()
1291  ;
1292  return tid;
1293 }
1294 
1295 TypeId
1297 {
1298  return GetTypeId ();
1299 }
1300 
1301 void
1302 CtrlTriggerHeader::Print (std::ostream &os) const
1303 {
1304  os << "TriggerType=" << GetTypeString () << ", Bandwidth=" << +GetUlBandwidth ()
1305  << ", UL Length=" << m_ulLength;
1306 
1307  for (auto& ui : m_userInfoFields)
1308  {
1309  ui.Print (os);
1310  }
1311 }
1312 
1313 uint32_t
1315 {
1316  uint32_t size = 0;
1317  size += 8; // Common Info (excluding Trigger Dependent Common Info)
1318 
1319  // Add the size of the Trigger Dependent Common Info subfield
1321  {
1322  size += 4;
1323  }
1324 
1325  for (auto& ui : m_userInfoFields)
1326  {
1327  size += ui.GetSerializedSize ();
1328  }
1329 
1330  size += 2; // Padding field
1331 
1332  return size;
1333 }
1334 
1335 void
1337 {
1338  NS_ABORT_MSG_IF (m_triggerType == BFRP_TRIGGER, "BFRP Trigger frame is not supported");
1339  NS_ABORT_MSG_IF (m_triggerType == GCR_MU_BAR_TRIGGER, "GCR-MU-BAR Trigger frame is not supported");
1340  NS_ABORT_MSG_IF (m_triggerType == NFRP_TRIGGER, "NFRP Trigger frame is not supported");
1341 
1342  Buffer::Iterator i = start;
1343 
1344  uint64_t commonInfo = 0;
1345  commonInfo |= (m_triggerType & 0x0f);
1346  commonInfo |= (m_ulLength & 0x0fff) << 4;
1347  commonInfo |= (m_moreTF ? 1 << 16 : 0);
1348  commonInfo |= (m_csRequired ? 1 << 17 : 0);
1349  commonInfo |= (m_ulBandwidth & 0x03) << 18;
1350  commonInfo |= (m_giAndLtfType & 0x03) << 20;
1351  commonInfo |= static_cast<uint64_t> (m_apTxPower & 0x3f) << 28;
1352  commonInfo |= static_cast<uint64_t> (m_ulSpatialReuse) << 37;
1353 
1354  i.WriteHtolsbU64 (commonInfo);
1355 
1356  for (auto& ui : m_userInfoFields)
1357  {
1358  i = ui.Serialize (i);
1359  }
1360 
1361  i.WriteHtolsbU16 (0xffff); // Padding field, used as delimiter
1362 }
1363 
1364 uint32_t
1366 {
1367  Buffer::Iterator i = start;
1368 
1369  uint64_t commonInfo = i.ReadLsbtohU64 ();
1370 
1371  m_triggerType = (commonInfo & 0x0f);
1372  m_ulLength = (commonInfo >> 4) & 0x0fff;
1373  m_moreTF = (commonInfo >> 16) & 0x01;
1374  m_csRequired = (commonInfo >> 17) & 0x01;
1375  m_ulBandwidth = (commonInfo >> 18) & 0x03;
1376  m_giAndLtfType = (commonInfo >> 20) & 0x03;
1377  m_apTxPower = (commonInfo >> 28) & 0x3f;
1378  m_ulSpatialReuse = (commonInfo >> 37) & 0xffff;
1379  m_userInfoFields.clear ();
1380 
1381  NS_ABORT_MSG_IF (m_triggerType == BFRP_TRIGGER, "BFRP Trigger frame is not supported");
1382  NS_ABORT_MSG_IF (m_triggerType == GCR_MU_BAR_TRIGGER, "GCR-MU-BAR Trigger frame is not supported");
1383  NS_ABORT_MSG_IF (m_triggerType == NFRP_TRIGGER, "NFRP Trigger frame is not supported");
1384 
1385  bool isPadding = false;
1386 
1387  // We always add a Padding field (of two octets of all 1s) as delimiter
1388  while (!isPadding)
1389  {
1390  // read the first 2 bytes to check if we encountered the Padding field
1391  if (i.ReadU16 () == 0xffff)
1392  {
1393  isPadding = true;
1394  }
1395  else
1396  {
1397  // go back 2 bytes to deserialize the User Info field from the beginning
1398  i.Prev (2);
1400  i = ui.Deserialize (i);
1401  }
1402  }
1403 
1404  return i.GetDistanceFrom (start);
1405 }
1406 
1407 void
1409 {
1410  m_triggerType = type;
1411 }
1412 
1415 {
1416  return static_cast<TriggerFrameType> (m_triggerType);
1417 }
1418 
1419 const char *
1421 {
1422  return GetTypeString (GetType ());
1423 }
1424 
1425 const char *
1427 {
1428 #define FOO(x) \
1429 case x: \
1430  return # x; \
1431  break;
1432 
1433  switch (type)
1434  {
1435  FOO (BASIC_TRIGGER);
1436  FOO (BFRP_TRIGGER);
1437  FOO (MU_BAR_TRIGGER);
1438  FOO (MU_RTS_TRIGGER);
1439  FOO (BSRP_TRIGGER);
1441  FOO (BQRP_TRIGGER);
1442  FOO (NFRP_TRIGGER);
1443  default:
1444  return "ERROR";
1445  }
1446 #undef FOO
1447 }
1448 
1449 bool
1451 {
1452  return (m_triggerType == BASIC_TRIGGER);
1453 }
1454 
1455 bool
1457 {
1458  return (m_triggerType == BFRP_TRIGGER);
1459 }
1460 
1461 bool
1463 {
1464  return (m_triggerType == MU_BAR_TRIGGER);
1465 }
1466 
1467 bool
1469 {
1470  return (m_triggerType == MU_RTS_TRIGGER);
1471 }
1472 
1473 bool
1475 {
1476  return (m_triggerType == BSRP_TRIGGER);
1477 }
1478 
1479 bool
1481 {
1482  return (m_triggerType == GCR_MU_BAR_TRIGGER);
1483 }
1484 
1485 bool
1487 {
1488  return (m_triggerType == BQRP_TRIGGER);
1489 }
1490 
1491 bool
1493 {
1494  return (m_triggerType == NFRP_TRIGGER);
1495 }
1496 
1497 void
1499 {
1500  m_ulLength = (len & 0x0fff);
1501 }
1502 
1503 uint16_t
1505 {
1506  return m_ulLength;
1507 }
1508 
1511 {
1512  auto userInfoIt = FindUserInfoWithAid (staId);
1513  NS_ASSERT (userInfoIt != end ());
1514 
1515  WifiTxVector v;
1519  v.SetLength (GetUlLength ());
1520  v.SetHeMuUserInfo (staId, {userInfoIt->GetRuAllocation (),
1521  HePhy::GetHeMcs (userInfoIt->GetUlMcs ()),
1522  userInfoIt->GetNss ()});
1523  return v;
1524 }
1525 
1526 void
1528 {
1529  m_moreTF = more;
1530 }
1531 
1532 bool
1534 {
1535  return m_moreTF;
1536 }
1537 
1538 void
1540 {
1541  m_csRequired = cs;
1542 }
1543 
1544 bool
1546 {
1547  return m_csRequired;
1548 }
1549 
1550 void
1552 {
1553  switch (bw)
1554  {
1555  case 20:
1556  m_ulBandwidth = 0;
1557  break;
1558  case 40:
1559  m_ulBandwidth = 1;
1560  break;
1561  case 80:
1562  m_ulBandwidth = 2;
1563  break;
1564  case 160:
1565  m_ulBandwidth = 3;
1566  break;
1567  default:
1568  NS_FATAL_ERROR ("Bandwidth value not allowed.");
1569  break;
1570  }
1571 }
1572 
1573 uint16_t
1575 {
1576  return (1 << m_ulBandwidth) * 20;
1577 }
1578 
1579 void
1580 CtrlTriggerHeader::SetGiAndLtfType (uint16_t guardInterval, uint8_t ltfType)
1581 {
1582  if (ltfType == 1 && guardInterval == 1600)
1583  {
1584  m_giAndLtfType = 0;
1585  }
1586  else if (ltfType == 2 && guardInterval == 1600)
1587  {
1588  m_giAndLtfType = 1;
1589  }
1590  else if (ltfType == 4 && guardInterval == 3200)
1591  {
1592  m_giAndLtfType = 2;
1593  }
1594  else
1595  {
1596  NS_FATAL_ERROR ("Invalid combination of GI and LTF type");
1597  }
1598 }
1599 
1600 uint16_t
1602 {
1603  if (m_giAndLtfType == 0 || m_giAndLtfType == 1)
1604  {
1605  return 1600;
1606  }
1607  else if (m_giAndLtfType == 2)
1608  {
1609  return 3200;
1610  }
1611  else
1612  {
1613  NS_FATAL_ERROR ("Invalid value for GI And LTF Type subfield");
1614  }
1615 }
1616 
1617 uint8_t
1619 {
1620  if (m_giAndLtfType == 0)
1621  {
1622  return 1;
1623  }
1624  else if (m_giAndLtfType == 1)
1625  {
1626  return 2;
1627  }
1628  else if (m_giAndLtfType == 2)
1629  {
1630  return 4;
1631  }
1632  else
1633  {
1634  NS_FATAL_ERROR ("Invalid value for GI And LTF Type subfield");
1635  }
1636 }
1637 
1638 void
1640 {
1641  // see Table 9-25f "AP Tx Power subfield encoding" of 802.11ax amendment D3.0
1642  NS_ABORT_MSG_IF (power < -20 || power > 40, "Out of range power values");
1643 
1644  m_apTxPower = static_cast<uint8_t> (power + 20);
1645 }
1646 
1647 int8_t
1649 {
1650  // see Table 9-25f "AP Tx Power subfield encoding" of 802.11ax amendment D3.0
1651  return static_cast<int8_t> (m_apTxPower) - 20;
1652 }
1653 
1654 void
1656 {
1657  m_ulSpatialReuse = sr;
1658 }
1659 
1660 uint16_t
1662 {
1663  return m_ulSpatialReuse;
1664 }
1665 
1668 {
1669  // make a copy of this Trigger Frame and remove the User Info fields from the copy
1670  CtrlTriggerHeader trigger (*this);
1671  trigger.m_userInfoFields.clear ();
1672  return trigger;
1673 }
1674 
1677 {
1678  m_userInfoFields.emplace_back (m_triggerType);
1679  return m_userInfoFields.back ();
1680 }
1681 
1684 {
1685  NS_ABORT_MSG_IF (userInfo.GetType () != m_triggerType,
1686  "Trying to add a User Info field of a type other than the type of the Trigger Frame");
1687  m_userInfoFields.push_back (userInfo);
1688  return m_userInfoFields.back ();
1689 }
1690 
1693 {
1694  return m_userInfoFields.begin ();
1695 }
1696 
1699 {
1700  return m_userInfoFields.end ();
1701 }
1702 
1705 {
1706  return m_userInfoFields.begin ();
1707 }
1708 
1711 {
1712  return m_userInfoFields.end ();
1713 }
1714 
1715 std::size_t
1717 {
1718  return m_userInfoFields.size ();
1719 }
1720 
1723 {
1724  // the lambda function returns true if a User Info field has the AID12 subfield
1725  // equal to the given aid12 value
1726  return std::find_if (start, end (), [aid12] (const CtrlTriggerUserInfoField& ui) -> bool
1727  { return (ui.GetAid12 () == aid12); });
1728 }
1729 
1732 {
1733  return FindUserInfoWithAid (m_userInfoFields.begin (), aid12);
1734 }
1735 
1738 {
1739  return FindUserInfoWithAid (start, 0);
1740 }
1741 
1744 {
1745  return FindUserInfoWithAid (0);
1746 }
1747 
1750 {
1751  return FindUserInfoWithAid (start, 2045);
1752 }
1753 
1756 {
1757  return FindUserInfoWithAid (2045);
1758 }
1759 
1760 bool
1762 {
1763  // check that allocated RUs do not overlap
1764  // TODO This is not a problem in case of UL MU-MIMO
1765  std::vector<HeRu::RuSpec> prevRus;
1766 
1767  for (auto& ui : m_userInfoFields)
1768  {
1769  if (HeRu::DoesOverlap (GetUlBandwidth (), ui.GetRuAllocation (), prevRus))
1770  {
1771  return false;
1772  }
1773  prevRus.push_back (ui.GetRuAllocation ());
1774  }
1775  return true;
1776 }
1777 
1778 } //namespace ns3
uint16_t ReadU16(void)
Definition: buffer.h:1029
Protocol header serialization and deserialization.
Definition: header.h:42
CtrlTriggerUserInfoField(uint8_t triggerType)
Constructor.
TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Definition: ctrl-headers.cc:58
ConstIterator FindUserInfoWithRaRuUnassociated(void) const
Get a const iterator pointing to the first User Info field found which allocates a Random Access RU f...
uint8_t m_ulBandwidth
UL BW subfield.
bool GetCsRequired(void) const
Get the CS Required subfield of the Common Info field.
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
RuType ruType
RU type.
Definition: he-ru.h:67
Buffer::Iterator SerializeBitmap(Buffer::Iterator start) const
Serialize bitmap to the given buffer.
#define FOO(x)
bool IsUlTargetRssiMaxTxPower(void) const
Return true if the UL Target RSSI subfield indicates to the station to transmit an HE TB PPDU respons...
void SetType(TriggerFrameType type)
Set the Trigger frame type.
uint8_t nRaRu
Number of Random Access RUs.
Definition: ctrl-headers.h:717
const char * GetTypeString(void) const
Return a string corresponding to the Trigger Frame type.
enum Variant m_variant
Block Ack Request variant.
uint16_t GetBaControl(void) const
Return the Block Ack control.
Headers for Trigger frames.
Definition: ctrl-headers.h:751
uint8_t m_ulTargetRssi
Expected receive signal power.
Definition: ctrl-headers.h:721
This class mimics the TXVECTOR which is to be passed to the PHY in order to define the parameters whi...
void SetMoreTF(bool more)
Set the More TF subfield of the Common Info field.
uint8_t m_ulMcs
MCS to be used by the addressed station.
Definition: ctrl-headers.h:706
uint8_t GetNRaRus(void) const
Get the number of contiguous RUs for Random Access.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
void SetChannelWidth(uint16_t channelWidth)
Sets the selected channelWidth (in MHz)
uint8_t m_triggerType
Common Info field.
uint16_t m_aid12
Association ID of the addressed station.
Definition: ctrl-headers.h:703
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:57
CtrlBAckRequestHeader m_muBarTriggerDependentUserInfo
MU-BAR variant of Trigger Dependent User Info subfield.
Definition: ctrl-headers.h:724
bool IsMuRts(void) const
Check if this is a MU-RTS Trigger frame.
uint8_t startingSs
Starting spatial stream.
Definition: ctrl-headers.h:712
def start()
Definition: core.py:1855
uint32_t GetSerializedSize(void) const
void SetGiAndLtfType(uint16_t guardInterval, uint8_t ltfType)
Set the GI And LTF Type subfield of the Common Info field.
void SetStartingSequenceControl(uint16_t seqControl)
Set the starting sequence control with the given sequence control value.
uint8_t GetUlMcs(void) const
Get the UL MCS subfield, which indicates the MCS of the solicited HE TB PPDU.
#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 GetUlFecCodingType(void) const
Get the UL FEC Coding Type subfield, which indicates whether BCC or LDPC is used. ...
bool primary80MHz
true if the RU is allocated in the primary 80MHz channel
Definition: he-ru.h:66
uint8_t m_apTxPower
Tx Power used by AP to transmit the Trigger Frame.
void Print(std::ostream &os) const
Print the content of this User Info field.
void SetBarControl(uint16_t bar)
Set the Block Ack control.
bool HasRaRuForUnassociatedSta(void) const
Check if this User Info field allocates a Random Access RU for stations not associated with the AP th...
uint16_t GetAid12(void) const
Get the value of the AID12 subfield.
bool IsValid(void) const
Check the validity of this Trigger frame.
std::list< CtrlTriggerUserInfoField > m_userInfoFields
List of User Info fields.
uint32_t GetSerializedSize(void) const
Get the expected size of this User Info field.
void SetRaRuInformation(uint8_t nRaRu, bool moreRaRu)
Set the RA-RU Information subfield, which is present when the AID12 subfield is 0 or 2045...
#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.
void SetUlTargetRssi(int8_t dBm)
Set the UL Target RSSI subfield to indicate the expected receive signal power in dBm.
uint16_t GetGuardInterval(void) const
uint8_t m_basicTriggerDependentUserInfo
Basic Trigger variant of Trigger Dependent User Info subfield.
Definition: ctrl-headers.h:723
std::list< CtrlTriggerUserInfoField >::const_iterator ConstIterator
User Info fields list const iterator.
bool IsGcrMuBar(void) const
Check if this is a Groupcast with Retries (GCR) MU-BAR Trigger frame.
bool GetMoreTF(void) const
Get the More TF subfield of the Common Info field.
void SetCsRequired(bool cs)
Set the CS Required subfield of the Common Info field.
The different BlockAckRequest variants.
void SetUlFecCodingType(bool ldpc)
Set the UL FEC Coding Type subfield, which indicates whether BCC or LDPC is used. ...
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:417
void SetStartingSequence(uint16_t seq)
Set the starting sequence number from the given raw sequence control field.
void Serialize(Buffer::Iterator start) const
static WifiMode GetHeMcs(uint8_t index)
Return the HE MCS corresponding to the provided index.
Definition: he-phy.cc:983
bool IsExtendedCompressed(void) const
Check if the current BA policy is Extended Compressed Block Ack.
uint8_t m_triggerType
Trigger frame type.
Definition: ctrl-headers.h:722
static bool DoesOverlap(uint16_t bw, RuSpec ru, const std::vector< RuSpec > &v)
Check whether the given RU overlaps with the given set of RUs.
Definition: he-ru.cc:211
CtrlTriggerUserInfoField & operator=(const CtrlTriggerUserInfoField &userInfo)
Copy assignment operator.
enum Variant m_variant
Block Ack variant.
uint8_t GetStartingSs(void) const
Get the starting spatial stream.
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
bool IsBasic(void) const
Check if the current BA policy is Basic Block Ack.
iterator in a Buffer instance
Definition: buffer.h:98
uint8_t GetTidInfo(void) const
Return the Traffic ID (TID).
void SetMuBarTriggerDepUserInfo(const CtrlBAckRequestHeader &bar)
Set the Trigger Dependent User Info subfield for the MU-BAR variant of Trigger frames, which includes a BAR Control subfield and a BAR Information subfield.
void SetBasicTriggerDepUserInfo(uint8_t spacingFactor, uint8_t tidLimit, AcIndex prefAc)
Set the Trigger Dependent User Info subfield for Basic Trigger frames.
uint32_t GetDistanceFrom(Iterator const &o) const
Definition: buffer.cc:783
uint32_t GetSerializedSize(void) const
static TypeId GetTypeId(void)
Get the type ID.
bool m_csRequired
Carrier Sense required.
TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
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.
TriggerFrameType
The different Trigger frame types.
Definition: ctrl-headers.h:429
bool GetMoreRaRu(void) const
Return true if more RA-RUs are allocated in subsequent Trigger frames that are sent before the end of...
RU Specification.
Definition: he-ru.h:64
uint8_t GetMpduMuSpacingFactor(void) const
Get the MPDU MU spacing factor.
void SetUlTargetRssiMaxTxPower(void)
Set the UL Target RSSI subfield to indicate to the station to transmit an HE TB PPDU response at its ...
uint16_t GetGuardInterval(void) const
Get the guard interval duration (in nanoseconds) of the solicited HE TB PPDU.
void Prev(void)
go backward by one byte
Definition: buffer.h:851
bool m_ulDcm
whether or not to use Dual Carrier Modulation
Definition: ctrl-headers.h:707
bool m_moreTF
True if a subsequent Trigger frame follows.
void SetGuardInterval(uint16_t guardInterval)
Sets the guard interval duration (in nanoseconds)
void SetType(BlockAckReqType type)
Set the BlockAckRequest type.
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:180
uint16_t GetStartingSequenceControl(void) const
Return the starting sequence control.
void Print(std::ostream &os) const
Definition: ctrl-headers.cc:64
uint16_t m_startingSeq
starting seq
Definition: ctrl-headers.h:183
uint8_t GetLtfType(void) const
Get the LTF type of the solicited HE TB PPDU.
void SetAid12(uint16_t aid)
Set the AID12 subfield, which carries the 12 LSBs of the AID of the station for which this User Info ...
bool IsPacketReceived(uint16_t seq) const
Check if the packet with the given sequence number was acknowledged in this BlockAck response...
void Print(std::ostream &os) const
void Next(void)
go forward by one byte
Definition: buffer.h:845
bool HasRaRuForAssociatedSta(void) const
Check if this User Info field allocates a Random Access RU for stations associated with the AP that t...
const std::vector< uint8_t > & GetBitmap(void) const
Return a const reference to the bitmap from the BlockAck response header.
CtrlTriggerHeader & operator=(const CtrlTriggerHeader &trigger)
Copy assignment operator.
BlockAckReqType m_barType
BAR type.
Definition: ctrl-headers.h:181
const CtrlBAckRequestHeader & GetMuBarTriggerDepUserInfo(void) const
Get the Trigger Dependent User Info subfield for the MU-BAR variant of Trigger frames, which includes a BAR Control subfield and a BAR Information subfield.
Headers for BlockAck response.
Definition: ctrl-headers.h:199
uint32_t GetSerializedSize(void) const
Definition: ctrl-headers.cc:70
static TypeId GetTypeId(void)
Get the type ID.
Definition: ctrl-headers.cc:47
uint32_t Deserialize(Buffer::Iterator start)
uint16_t m_tidInfo
TID info.
Definition: ctrl-headers.h:419
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.
Buffer::Iterator Deserialize(Buffer::Iterator start)
Deserialize the User Info field from the given buffer.
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...
TriggerFrameType GetType(void) const
Get the Trigger Frame type.
BlockAckReqType GetType(void) const
Return the BlockAckRequest type.
void SetHeMuUserInfo(uint16_t staId, HeMuUserInfo userInfo)
Set the HE MU user-specific transmission information for the given STA-ID.
uint16_t GetUlBandwidth(void) const
Get the bandwidth of the solicited HE TB PPDU.
uint32_t Deserialize(Buffer::Iterator start)
bool IsNfrp(void) const
Check if this is a NDP Feedback Report Poll Trigger frame.
void SetTidInfo(uint8_t tid)
Set Traffic ID (TID).
ConstIterator begin(void) const
Get a const iterator pointing to the first User Info field in the list.
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.
void SetPreambleType(WifiPreamble preamble)
Sets the preamble type.
bool moreRaRu
More RA-RU in subsequent Trigger frames.
Definition: ctrl-headers.h:718
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 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.
void SetUlBandwidth(uint16_t bw)
Set the bandwidth of the solicited HE TB PPDU.
uint8_t m_ruAllocation
RU Allocation.
Definition: ctrl-headers.h:704
BlockAckType m_baType
BA type.
Definition: ctrl-headers.h:418
void ResetBitmap(void)
Reset the bitmap to 0.
uint8_t nSs
Number of spatial streams.
Definition: ctrl-headers.h:713
uint8_t GetTidAggregationLimit(void) const
Get the TID Aggregation Limit.
bool IsBqrp(void) const
Check if this is a Bandwidth Query Report Poll Trigger frame.
ConstIterator FindUserInfoWithRaRuAssociated(void) const
Get a const iterator pointing to the first User Info field found which allocates a Random Access RU f...
User Info field of Trigger frames.
Definition: ctrl-headers.h:450
uint8_t GetNss(void) const
Get the number of spatial streams.
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
std::size_t GetNUserInfoFields(void) const
Get the number of User Info fields in this Trigger Frame.
void SetUlSpatialReuse(uint16_t sr)
Set the UL Spatial Reuse subfield of the Common Info field.
uint16_t m_startingSeq
starting seq
Definition: ctrl-headers.h:420
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.
bool IsMuBar(void) const
Check if this is a MU-BAR Trigger frame.
bool IsBsrp(void) const
Check if this is a Buffer Status Report Poll Trigger frame.
std::vector< uint8_t > m_bitmapLen
Length (bytes) of included bitmaps.
TriggerFrameType GetType(void) const
Get the type of the Trigger Frame this User Info field belongs to.
void SetApTxPower(int8_t power)
Set the AP TX Power subfield of the Common Info field.
void SetRuAllocation(HeRu::RuSpec ru)
Set the RU Allocation subfield according to the specified RU.
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 GetLength(void) const
Get the LENGTH field of the L-SIG.
uint16_t GetBarControl(void) const
Return the Block Ack control.
The different BlockAck variants.
void WriteU8(uint8_t data)
Definition: buffer.h:869
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
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
std::vector< uint8_t > m_bitmap
block ack bitmap
Definition: ctrl-headers.h:421
bool GetUlDcm(void) const
Get the UL DCM subfield, which indicates whether or not DCM is used.
CtrlTriggerHeader GetCommonInfoField(void) const
Get a copy of the Common Info field of this Trigger frame.
void SetSsAllocation(uint8_t startingSs, uint8_t nSs)
Set the SS Allocation subfield, which is present when the AID12 subfield is neither 0 nor 2045...
CtrlTriggerUserInfoField & AddUserInfoField(void)
Append a new User Info field to this Trigger frame and return a non-const reference to it...
uint32_t Deserialize(Buffer::Iterator start)
uint16_t m_tidInfo
TID info.
Definition: ctrl-headers.h:182
std::size_t index
index (starting at 1)
Definition: he-ru.h:68
std::list< CtrlTriggerUserInfoField >::iterator Iterator
User Info fields list iterator.
bool IsMultiTid(void) const
Check if the current BA policy is Multi-TID Block Ack.
void SetHtImmediateAck(bool immediateAck)
Enable or disable HT immediate Ack.
const uint16_t SEQNO_SPACE_SIZE
Size of the space of sequence numbers.
Definition: wifi-utils.h:222
uint8_t ReadU8(void)
Definition: buffer.h:1021
void Print(std::ostream &os) const
Buffer::Iterator Serialize(Buffer::Iterator start) const
Serialize the User Info field to the given buffer.
ConstIterator FindUserInfoWithAid(ConstIterator start, uint16_t aid12) const
Get a const iterator pointing to the first User Info field found (starting from the one pointed to by...
WifiTxVector GetHeTbTxVector(uint16_t staId) const
Get the TX vector that the station with the given STA-ID will use to send the HE TB PPDU solicited by...
BlockAckType GetType(void) const
Return the block ack type ID.
bool IsBfrp(void) const
Check if this is a Beamforming Report Poll Trigger frame.
uint8_t m_giAndLtfType
GI And LTF Type subfield.
uint16_t ReadLsbtohU16(void)
Definition: buffer.cc:1065
uint16_t GetUlSpatialReuse(void) const
Get the UL Spatial Reuse subfield of the Common Info field.
void SetUlMcs(uint8_t mcs)
Set the UL MCS subfield, which indicates the MCS of the solicited HE TB PPDU.
void Serialize(Buffer::Iterator start) const
Definition: ctrl-headers.cc:92
uint16_t GetChannelWidth(void) const
void SetUlLength(uint16_t len)
Set the UL Length subfield of the Common Info field.
void SetLength(uint16_t length)
Set the LENGTH field of the L-SIG.
int8_t GetApTxPower(void) const
Get the power value (dBm) indicated by the AP TX Power subfield of the Common Info field...
ConstIterator end(void) const
Get a const iterator indicating past-the-last User Info field in the list.
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1093
uint16_t GetUlLength(void) const
Get the UL Length subfield of the Common Info field.
Headers for BlockAckRequest.
Definition: ctrl-headers.h:47
const HeMuUserInfoMap & GetHeMuUserInfoMap(void) const
Get the map HE MU user-specific transmission information indexed by STA-ID.
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.
union ns3::CtrlTriggerUserInfoField::@72 m_bits26To31
Fields occupying bits 26-31 in the User Info 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
HeRu::RuSpec GetRuAllocation(void) const
Get the RU specified by the RU Allocation subfield.
uint32_t ReadLsbtohU32(void)
Definition: buffer.cc:1076
bool IsBasic(void) const
Check if this is a Basic Trigger frame.
~CtrlTriggerUserInfoField()
Destructor.
uint16_t m_ulLength
Value for the L-SIG Length field.
uint16_t m_ulSpatialReuse
Value for the Spatial Reuse field in HE-SIG-A.
AcIndex GetPreferredAc(void) const
Get the Preferred AC subfield.
bool m_ulFecCodingType
UL FEC Coding Type.
Definition: ctrl-headers.h:705
void SetUlDcm(bool dcm)
Set the UL DCM subfield, which indicates whether or not DCM is used.
void SetBaControl(uint16_t ba)
Set the Block Ack control.
void WriteHtolsbU32(uint32_t data)
Definition: buffer.cc:917
void Serialize(Buffer::Iterator start) const
int8_t GetUlTargetRssi(void) const
Get the expected receive signal power for the solicited HE TB PPDU.