A Discrete-Event Network Simulator
API
radiotap-header.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 CTTC
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, Include., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Nicola Baldo <nbaldo@cttc.es>
19  * Sébastien Deronne <sebastien.deronne@gmail.com>
20  */
21 
22 #include <iomanip>
23 #include <cmath>
24 #include "ns3/log.h"
25 #include "radiotap-header.h"
26 
27 namespace ns3 {
28 
29 NS_LOG_COMPONENT_DEFINE ("RadiotapHeader");
30 
31 NS_OBJECT_ENSURE_REGISTERED (RadiotapHeader);
32 
34  : m_length (8),
35  m_present (0),
36  m_tsft (0),
37  m_flags (FRAME_FLAG_NONE),
38  m_rate (0),
39  m_channelFreq (0),
40  m_channelFlags (CHANNEL_FLAG_NONE),
41  m_antennaSignal (0),
42  m_antennaNoise (0),
43  m_ampduStatusRef (0),
44  m_ampduStatusFlags (0),
45  m_ampduStatusCRC (0),
46  m_vhtPad (0),
47  m_vhtKnown (0),
48  m_vhtFlags (0),
49  m_vhtBandwidth (0),
50  m_vhtCoding (0),
51  m_vhtGroupId (0),
52  m_vhtPartialAid (0),
53  m_hePad (0),
54  m_heData1 (0),
55  m_heData2 (0),
56  m_heData3 (0),
57  m_heData4 (0),
58  m_heData5 (0),
59  m_heData6 (0),
60  m_heMuPad (0),
61  m_heMuFlags1 (0),
62  m_heMuFlags2 (0),
63  m_heMuOtherUserPad (0),
64  m_heMuPerUser1 (0),
65  m_heMuPerUser2 (0),
66  m_heMuPerUserPosition (0),
67  m_heMuPerUserKnown (0)
68 {
69  NS_LOG_FUNCTION (this);
70 }
71 
73 {
74  static TypeId tid = TypeId ("ns3::RadiotapHeader")
75  .SetParent<Header> ()
76  .SetGroupName ("Network")
77 
78  .AddConstructor<RadiotapHeader> ()
79  ;
80  return tid;
81 }
82 
83 TypeId
85 {
86  return GetTypeId ();
87 }
88 
89 uint32_t
91 {
92  NS_LOG_FUNCTION (this);
93  return m_length;
94 }
95 
96 void
98 {
99  NS_LOG_FUNCTION (this << &start);
100 
101  start.WriteU8 (0); // major version of radiotap header
102  start.WriteU8 (0); // pad field
103  start.WriteU16 (m_length); // entire length of radiotap data + header
104  start.WriteU32 (m_present); // bits describing which fields follow header
105 
106  //
107  // Time Synchronization Function Timer (when the first bit of the MPDU
108  // arrived at the MAC)
109  // Reference: https://www.radiotap.org/fields/TSFT.html
110  //
111  if (m_present & RADIOTAP_TSFT) // bit 0
112  {
113  start.WriteU64 (m_tsft);
114  }
115 
116  //
117  // Properties of transmitted and received frames.
118  // Reference: https://www.radiotap.org/fields/Flags.html
119  //
120  if (m_present & RADIOTAP_FLAGS) // bit 1
121  {
122  start.WriteU8 (m_flags);
123  }
124 
125  //
126  // TX/RX data rate in units of 500 kbps
127  // Reference: https://www.radiotap.org/fields/Rate.html
128  //
129  if (m_present & RADIOTAP_RATE) // bit 2
130  {
131  start.WriteU8 (m_rate);
132  }
133 
134  //
135  // Tx/Rx frequency in MHz, followed by flags.
136  // Reference: https://www.radiotap.org/fields/Channel.html
137  //
138  if (m_present & RADIOTAP_CHANNEL) // bit 3
139  {
140  start.WriteU8 (0, m_channelPad);
141  start.WriteU16 (m_channelFreq);
142  start.WriteU16 (m_channelFlags);
143  }
144 
145  //
146  // The hop set and pattern for frequency-hopping radios. We don't need it but
147  // still need to account for it.
148  // Reference: https://www.radiotap.org/fields/FHSS.html
149  //
150  if (m_present & RADIOTAP_FHSS) // bit 4
151  {
152  start.WriteU8 (0); //not yet implemented
153  }
154 
155  //
156  // RF signal power at the antenna, decibel difference from an arbitrary, fixed
157  // reference.
158  // Reference: https://www.radiotap.org/fields/Antenna%20signal.html
159  //
160  if (m_present & RADIOTAP_DBM_ANTSIGNAL) // bit 5
161  {
162  start.WriteU8 (m_antennaSignal);
163  }
164 
165  //
166  // RF noise power at the antenna, decibel difference from an arbitrary, fixed
167  // reference.
168  // Reference: https://www.radiotap.org/fields/Antenna%20noise.html
169  //
170  if (m_present & RADIOTAP_DBM_ANTNOISE) // bit 6
171  {
172  start.WriteU8 (m_antennaNoise);
173  }
174 
175  //
176  // Quality of Barker code lock.
177  // Reference: https://www.radiotap.org/fields/Lock%20quality.html
178  //
179  if (m_present & RADIOTAP_LOCK_QUALITY) // bit 7
180  {
181  start.WriteU16 (0); //not yet implemented
182  }
183 
184  //
185  // Transmit power expressed as unitless distance from max power
186  // set at factory calibration (0 is max power).
187  // Reference: https://www.radiotap.org/fields/TX%20attenuation.html
188  //
189  if (m_present & RADIOTAP_TX_ATTENUATION) // bit 8
190  {
191  start.WriteU16 (0); //not yet implemented
192  }
193 
194  //
195  // Transmit power expressed as decibel distance from max power
196  // set at factory calibration (0 is max power).
197  // Reference: https://www.radiotap.org/fields/dB%20TX%20attenuation.html
198  //
199  if (m_present & RADIOTAP_DB_TX_ATTENUATION) // bit 9
200  {
201  start.WriteU16 (0); //not yet implemented
202  }
203 
204  //
205  // Transmit power expressed as dBm (decibels from a 1 milliwatt reference).
206  // This is the absolute power level measured at the antenna port.
207  // Reference: https://www.radiotap.org/fields/dBm%20TX%20power.html
208  //
209  if (m_present & RADIOTAP_DBM_TX_POWER) // bit 10
210  {
211  start.WriteU8 (0); //not yet implemented
212  }
213 
214  //
215  // Unitless indication of the Rx/Tx antenna for this packet.
216  // The first antenna is antenna 0.
217  // Reference: https://www.radiotap.org/fields/Antenna.html
218  //
219  if (m_present & RADIOTAP_ANTENNA) // bit 11
220  {
221  start.WriteU8 (0); //not yet implemented
222  }
223 
224  //
225  // RF signal power at the antenna (decibel difference from an arbitrary fixed reference).
226  // Reference: https://www.radiotap.org/fields/dB%20antenna%20signal.html
227  //
228  if (m_present & RADIOTAP_DB_ANTSIGNAL) // bit 12
229  {
230  start.WriteU8 (0); //not yet implemented
231  }
232 
233  //
234  // RF noise power at the antenna (decibel difference from an arbitrary fixed reference).
235  // Reference: https://www.radiotap.org/fields/dB%20antenna%20noise.html
236  //
237  if (m_present & RADIOTAP_DB_ANTNOISE) // bit 13
238  {
239  start.WriteU8 (0); //not yet implemented
240  }
241 
242  //
243  // Properties of received frames.
244  // Reference: https://www.radiotap.org/fields/RX%20flags.html
245  //
246  if (m_present & RADIOTAP_RX_FLAGS) // bit 14
247  {
248  start.WriteU16 (0); //not yet implemented
249  }
250 
251  //
252  // MCS field.
253  // Reference: https://www.radiotap.org/fields/MCS.html
254  //
255  if (m_present & RADIOTAP_MCS) // bit 19
256  {
257  start.WriteU8 (m_mcsKnown);
258  start.WriteU8 (m_mcsFlags);
259  start.WriteU8 (m_mcsRate);
260  }
261 
262  //
263  // A-MPDU Status, information about the received or transmitted A-MPDU.
264  // Reference: https://www.radiotap.org/fields/A-MPDU%20status.html
265  //
266  if (m_present & RADIOTAP_AMPDU_STATUS) // bit 20
267  {
268  start.WriteU8 (0, m_ampduStatusPad);
269  start.WriteU32 (m_ampduStatusRef);
270  start.WriteU16 (m_ampduStatusFlags);
271  start.WriteU8 (m_ampduStatusCRC);
272  start.WriteU8 (0);
273  }
274 
275  //
276  // Information about the received or transmitted VHT frame.
277  // Reference: https://www.radiotap.org/fields/VHT.html
278  //
279  if (m_present & RADIOTAP_VHT) // bit 21
280  {
281  start.WriteU8 (0, m_vhtPad);
282  start.WriteU16 (m_vhtKnown);
283  start.WriteU8 (m_vhtFlags);
284  start.WriteU8 (m_vhtBandwidth);
285  for (uint8_t i = 0; i < 4; i++)
286  {
287  start.WriteU8 (m_vhtMcsNss[i]);
288  }
289  start.WriteU8 (m_vhtCoding);
290  start.WriteU8 (m_vhtGroupId);
291  start.WriteU16 (m_vhtPartialAid);
292  }
293 
294  //
295  // HE field.
296  // Reference: https://www.radiotap.org/fields/HE.html
297  //
298  if (m_present & RADIOTAP_HE) // bit 23
299  {
300  start.WriteU8 (0, m_hePad);
301  start.WriteU16 (m_heData1);
302  start.WriteU16 (m_heData2);
303  start.WriteU16 (m_heData3);
304  start.WriteU16 (m_heData4);
305  start.WriteU16 (m_heData5);
306  start.WriteU16 (m_heData6);
307  }
308 
309  //
310  // HE MU field.
311  // Reference: https://www.radiotap.org/fields/HE-MU.html
312  //
313  if (m_present & RADIOTAP_HE_MU) // bit 24
314  {
315  start.WriteU8 (0, m_heMuPad);
316  start.WriteU16 (m_heMuFlags1);
317  start.WriteU16 (m_heMuFlags2);
318  start.WriteU8 (0);
319  start.WriteU8 (0);
320  start.WriteU8 (0);
321  start.WriteU8 (0);
322  start.WriteU8 (0);
323  start.WriteU8 (0);
324  start.WriteU8 (0);
325  start.WriteU8 (0);
326  }
327 
328  //
329  // HE MU other user field.
330  // Reference: https://www.radiotap.org/fields/HE-MU-other-user.html
331  //
332  if (m_present & RADIOTAP_HE_MU_OTHER_USER) // bit 25
333  {
334  start.WriteU8 (0, m_heMuOtherUserPad);
335  start.WriteU16 (m_heMuPerUser1);
336  start.WriteU16 (m_heMuPerUser2);
337  start.WriteU8 (m_heMuPerUserPosition);
338  start.WriteU8 (m_heMuPerUserKnown);
339  }
340 }
341 
342 uint32_t
344 {
345  NS_LOG_FUNCTION (this << &start);
346 
347  uint8_t tmp = start.ReadU8 (); // major version of radiotap header
348  NS_ASSERT_MSG (tmp == 0x00, "RadiotapHeader::Deserialize(): Unexpected major version");
349  start.ReadU8 (); // pad field
350 
351  m_length = start.ReadU16 (); // entire length of radiotap data + header
352  m_present = start.ReadU32 (); // bits describing which fields follow header
353 
354  uint32_t bytesRead = 8;
355 
356  //
357  // Time Synchronization Function Timer (when the first bit of the MPDU arrived at the MAC)
358  // Reference: https://www.radiotap.org/fields/TSFT.html
359  //
360  if (m_present & RADIOTAP_TSFT) // bit 0
361  {
362  m_tsft = start.ReadU64 ();
363  bytesRead += 8;
364  }
365 
366  //
367  // Properties of transmitted and received frames.
368  // Reference: https://www.radiotap.org/fields/Flags.html
369  //
370  if (m_present & RADIOTAP_FLAGS) // bit 1
371  {
372  m_flags = start.ReadU8 ();
373  ++bytesRead;
374  }
375 
376  //
377  // TX/RX data rate in units of 500 kbps
378  // Reference: https://www.radiotap.org/fields/Rate.html
379  //
380  if (m_present & RADIOTAP_RATE) // bit 2
381  {
382  m_rate = start.ReadU8 ();
383  ++bytesRead;
384  }
385 
386  //
387  // Tx/Rx frequency in MHz, followed by flags.
388  // Reference: https://www.radiotap.org/fields/Channel.html
389  //
390  if (m_present & RADIOTAP_CHANNEL) // bit 3
391  {
392  m_channelPad = ((2 - bytesRead % 2) % 2);
393  start.Next (m_channelPad);
394  m_channelFreq = start.ReadU16 ();
395  m_channelFlags = start.ReadU16 ();
396  bytesRead += (4 + m_channelPad);
397  }
398 
399  //
400  // The hop set and pattern for frequency-hopping radios. We don't need it but
401  // still need to account for it.
402  // Reference: https://www.radiotap.org/fields/FHSS.html
403  //
404  if (m_present & RADIOTAP_FHSS) // bit 4
405  {
406  //not yet implemented
407  start.ReadU8 ();
408  ++bytesRead;
409  }
410 
411  //
412  // RF signal power at the antenna, decibel difference from an arbitrary, fixed
413  // reference.
414  // Reference: https://www.radiotap.org/fields/Antenna%20signal.html
415  //
416  if (m_present & RADIOTAP_DBM_ANTSIGNAL) // bit 5
417  {
418  m_antennaSignal = start.ReadU8 ();
419  ++bytesRead;
420  }
421 
422  //
423  // RF noise power at the antenna, decibel difference from an arbitrary, fixed
424  // reference.
425  // Reference: https://www.radiotap.org/fields/Antenna%20noise.html
426  //
427  if (m_present & RADIOTAP_DBM_ANTNOISE) // bit 6
428  {
429  m_antennaNoise = start.ReadU8 ();
430  ++bytesRead;
431  }
432 
433  //
434  // Quality of Barker code lock.
435  // Reference: https://www.radiotap.org/fields/Lock%20quality.html
436  //
437  if (m_present & RADIOTAP_LOCK_QUALITY) // bit 7
438  {
439  //not yet implemented
440  start.ReadU16 ();
441  bytesRead += 2;
442  }
443 
444  //
445  // Transmit power expressed as unitless distance from max power
446  // set at factory calibration (0 is max power).
447  // Reference: https://www.radiotap.org/fields/TX%20attenuation.html
448  //
449  if (m_present & RADIOTAP_TX_ATTENUATION) // bit 8
450  {
451  //not yet implemented
452  start.ReadU16 ();
453  bytesRead += 2;
454  }
455 
456  //
457  // Transmit power expressed as decibel distance from max power
458  // set at factory calibration (0 is max power).
459  // Reference: https://www.radiotap.org/fields/dB%20TX%20attenuation.html
460  //
461  if (m_present & RADIOTAP_DB_TX_ATTENUATION) // bit 9
462  {
463  //not yet implemented
464  start.ReadU16 ();
465  bytesRead += 2;
466  }
467 
468  //
469  // Transmit power expressed as dBm (decibels from a 1 milliwatt reference).
470  // This is the absolute power level measured at the antenna port.
471  // Reference: https://www.radiotap.org/fields/dBm%20TX%20power.html
472  //
473  if (m_present & RADIOTAP_DBM_TX_POWER) // bit 10
474  {
475  //not yet implemented
476  start.ReadU8 ();
477  ++bytesRead;
478  }
479 
480  //
481  // Unitless indication of the Rx/Tx antenna for this packet.
482  // The first antenna is antenna 0.
483  // Reference: https://www.radiotap.org/fields/Antenna.html
484  //
485  if (m_present & RADIOTAP_ANTENNA) // bit 11
486  {
487  //not yet implemented
488  start.ReadU8 ();
489  ++bytesRead;
490  }
491 
492  //
493  // RF signal power at the antenna (decibel difference from an arbitrary fixed reference).
494  // Reference: https://www.radiotap.org/fields/dB%20antenna%20signal.html
495  //
496  if (m_present & RADIOTAP_DB_ANTSIGNAL) // bit 12
497  {
498  //not yet implemented
499  start.ReadU8 ();
500  ++bytesRead;
501  }
502 
503  //
504  // RF noise power at the antenna (decibel difference from an arbitrary fixed reference).
505  // Reference: https://www.radiotap.org/fields/dB%20antenna%20noise.html
506  //
507  if (m_present & RADIOTAP_DB_ANTNOISE) // bit 13
508  {
509  //not yet implemented
510  start.ReadU8 ();
511  ++bytesRead;
512  }
513 
514  //
515  // Properties of received frames.
516  // Reference: https://www.radiotap.org/fields/RX%20flags.html
517  //
518  if (m_present & RADIOTAP_RX_FLAGS) // bit 14
519  {
520  //not yet implemented
521  start.ReadU16 ();
522  bytesRead += 2;
523  }
524 
525  //
526  // MCS field.
527  // Reference: https://www.radiotap.org/fields/MCS.html
528  //
529  if (m_present & RADIOTAP_MCS) // bit 19
530  {
531  m_mcsKnown = start.ReadU8 ();
532  m_mcsFlags = start.ReadU8 ();
533  m_mcsRate = start.ReadU8 ();
534  bytesRead += 3;
535  }
536 
537  //
538  // A-MPDU Status, information about the received or transmitted A-MPDU.
539  // Reference: https://www.radiotap.org/fields/A-MPDU%20status.html
540  //
541  if (m_present & RADIOTAP_AMPDU_STATUS) // bit 20
542  {
543  m_ampduStatusPad = ((4 - bytesRead % 4) % 4);
544  start.Next (m_ampduStatusPad);
545  m_ampduStatusRef = start.ReadU32 ();
546  m_ampduStatusFlags = start.ReadU16 ();
547  m_ampduStatusCRC = start.ReadU8 ();
548  start.ReadU8 ();
549  bytesRead += (8 + m_ampduStatusPad);
550  }
551 
552  //
553  // Information about the received or transmitted VHT frame.
554  // Reference: https://www.radiotap.org/fields/VHT.html
555  //
556  if (m_present & RADIOTAP_VHT) // bit 21
557  {
558  m_vhtPad = ((2 - bytesRead % 2) % 2);
559  start.Next (m_vhtPad);
560  m_vhtKnown = start.ReadU16 ();
561  m_vhtFlags = start.ReadU8 ();
562  m_vhtBandwidth = start.ReadU8 ();
563  for (uint8_t i = 0; i < 4; i++)
564  {
565  m_vhtMcsNss[i] = start.ReadU8 ();
566  }
567  m_vhtCoding = start.ReadU8 ();
568  m_vhtGroupId = start.ReadU8 ();
569  m_vhtPartialAid = start.ReadU16 ();
570  bytesRead += (12 + m_vhtPad);
571  }
572 
573  //
574  // HE field.
575  // Reference: https://www.radiotap.org/fields/HE.html
576  //
577  if (m_present & RADIOTAP_HE) // bit 23
578  {
579  m_hePad = ((2 - bytesRead % 2) % 2);
580  start.Next (m_hePad);
581  m_heData1 = start.ReadU16 ();
582  m_heData2 = start.ReadU16 ();
583  m_heData3 = start.ReadU16 ();
584  m_heData4 = start.ReadU16 ();
585  m_heData5 = start.ReadU16 ();
586  m_heData6 = start.ReadU16 ();
587  bytesRead += (12 + m_hePad);
588  }
589 
590  //
591  // HE MU field.
592  // Reference: https://www.radiotap.org/fields/HE-MU.html
593  //
594  if (m_present & RADIOTAP_HE_MU) // bit 24
595  {
596  m_heMuPad = ((2 - bytesRead % 2) % 2);
597  m_heMuFlags1 = start.ReadU16 ();
598  m_heMuFlags2 = start.ReadU16 ();
599  start.ReadU8 ();
600  start.ReadU8 ();
601  start.ReadU8 ();
602  start.ReadU8 ();
603  start.ReadU8 ();
604  start.ReadU8 ();
605  start.ReadU8 ();
606  start.ReadU8 ();
607  bytesRead += (12 + m_heMuPad);
608  }
609 
610  //
611  // HE MU other user field.
612  // Reference: https://www.radiotap.org/fields/HE-MU-other-user.html
613  //
614  if (m_present & RADIOTAP_HE_MU_OTHER_USER) // bit 25
615  {
616  m_heMuOtherUserPad = ((2 - bytesRead % 2) % 2);
617  m_heMuPerUser1 = start.ReadU16 ();
618  m_heMuPerUser2 = start.ReadU16 ();
619  m_heMuPerUserPosition = start.ReadU8 ();
620  m_heMuPerUserKnown = start.ReadU8 ();
621  bytesRead += (6 + m_heMuOtherUserPad);
622  }
623 
624  NS_ASSERT_MSG (m_length == bytesRead, "RadiotapHeader::Deserialize(): expected and actual lengths inconsistent");
625  return bytesRead;
626 }
627 
628 void
629 RadiotapHeader::Print (std::ostream &os) const
630 {
631  NS_LOG_FUNCTION (this << &os);
632  os << " tsft=" << m_tsft
633  << " flags=" << std::hex << m_flags << std::dec
634  << " rate=" << +m_rate
635  << " freq=" << m_channelFreq
636  << " chflags=" << std::hex << +m_channelFlags << std::dec
637  << " signal=" << +m_antennaSignal
638  << " noise=" << +m_antennaNoise
639  << " mcsKnown=" << m_mcsKnown
640  << " mcsFlags=" << m_mcsFlags
641  << " mcsRate=" << m_mcsRate
642  << " ampduStatusFlags=" << +m_ampduStatusFlags
643  << " vhtKnown=" << m_vhtKnown
644  << " vhtFlags=" << m_vhtFlags
645  << " vhtBandwidth=" << m_vhtBandwidth
646  << " vhtMcsNss for user 1=" << m_vhtMcsNss[0]
647  << " vhtMcsNss for user 2=" << m_vhtMcsNss[1]
648  << " vhtMcsNss for user 3=" << m_vhtMcsNss[2]
649  << " vhtMcsNss for user 4=" << m_vhtMcsNss[3]
650  << " vhtCoding=" << m_vhtCoding
651  << " vhtGroupId=" << m_vhtGroupId
652  << " vhtPartialAid=" << m_vhtPartialAid
653  << " heData1=" << m_heData1
654  << " heData2=" << m_heData2
655  << " heData3=" << m_heData3
656  << " heData4=" << m_heData4
657  << " heData5=" << m_heData5
658  << " heData6=" << m_heData6
659  << " heMuFlags1=" << m_heMuFlags1
660  << " heMuFlags2=" << m_heMuFlags2
661  << " heMuPerUser1=" << m_heMuPerUser1
662  << " heMuPerUser2=" << m_heMuPerUser2
663  << " heMuPerUserPosition=" << +m_heMuPerUserPosition
664  << " heMuPerUserKnown=" << +m_heMuPerUserKnown;
665 }
666 
667 void
668 RadiotapHeader::SetTsft (uint64_t value)
669 {
670  NS_LOG_FUNCTION (this << value);
671  m_tsft = value;
672 
673  if (!(m_present & RADIOTAP_TSFT))
674  {
676  m_length += 8;
677  }
678 
679  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
680 }
681 
682 void
684 {
685  NS_LOG_FUNCTION (this << +flags);
686  m_flags = flags;
687 
688  if (!(m_present & RADIOTAP_FLAGS))
689  {
691  m_length += 1;
692  }
693 
694  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
695 }
696 
697 void
699 {
700  NS_LOG_FUNCTION (this << +rate);
701  m_rate = rate;
702 
703  if (!(m_present & RADIOTAP_RATE))
704  {
706  m_length += 1;
707  }
708 
709  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
710 }
711 
712 void
713 RadiotapHeader::SetChannelFrequencyAndFlags (uint16_t frequency, uint16_t flags)
714 {
715  NS_LOG_FUNCTION (this << frequency << flags);
716  m_channelFreq = frequency;
717  m_channelFlags = flags;
718 
719  if (!(m_present & RADIOTAP_CHANNEL))
720  {
721  m_channelPad = ((2 - m_length % 2) % 2);
723  m_length += (4 + m_channelPad);
724  }
725 
726  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
727 }
728 
729 void
731 {
732  NS_LOG_FUNCTION (this << signal);
733 
735  {
737  m_length += 1;
738  }
739  if (signal > 127)
740  {
741  m_antennaSignal = 127;
742  }
743  else if (signal < -128)
744  {
745  m_antennaSignal = -128;
746  }
747  else
748  {
749  m_antennaSignal = static_cast<int8_t> (floor (signal + 0.5));
750  }
751 
752  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
753 }
754 
755 void
757 {
758  NS_LOG_FUNCTION (this << noise);
759 
761  {
763  m_length += 1;
764  }
765  if (noise > 127.0)
766  {
767  m_antennaNoise = 127;
768  }
769  else if (noise < -128.0)
770  {
771  m_antennaNoise = -128;
772  }
773  else
774  {
775  m_antennaNoise = static_cast<int8_t> (floor (noise + 0.5));
776  }
777 
778  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
779 }
780 
781 void
782 RadiotapHeader::SetMcsFields (uint8_t known, uint8_t flags, uint8_t mcs)
783 {
784  NS_LOG_FUNCTION (this << known << +flags << +mcs);
785  m_mcsKnown = known;
786  m_mcsFlags = flags;
787  m_mcsRate = mcs;
788  if (!(m_present & RADIOTAP_MCS))
789  {
791  m_length += 3;
792  }
793 
794  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
795 }
796 
797 void
798 RadiotapHeader::SetAmpduStatus (uint32_t referenceNumber, uint16_t flags, uint8_t crc)
799 {
800  NS_LOG_FUNCTION (this << referenceNumber << flags);
801  m_ampduStatusRef = referenceNumber;
802  m_ampduStatusFlags = flags;
803  m_ampduStatusCRC = crc;
805  {
806  m_ampduStatusPad = ((4 - m_length % 4) % 4);
808  m_length += (8 + m_ampduStatusPad);
809  }
810 
811  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
812 }
813 
814 void
815 RadiotapHeader::SetVhtFields (uint16_t known, uint8_t flags, uint8_t bandwidth, uint8_t mcs_nss[4], uint8_t coding, uint8_t group_id, uint16_t partial_aid)
816 {
817  NS_LOG_FUNCTION (this << known << flags << +mcs_nss[0] << +mcs_nss[1] << +mcs_nss[2] << +mcs_nss[3] << +coding << +group_id << +partial_aid);
818  m_vhtKnown = known;
819  m_vhtFlags = flags;
820  m_vhtBandwidth = bandwidth;
821  for (uint8_t i = 0; i < 4; i++)
822  {
823  m_vhtMcsNss[i] = mcs_nss[i];
824  }
825  m_vhtCoding = coding;
826  m_vhtGroupId = group_id;
827  m_vhtPartialAid = partial_aid;
828  if (!(m_present & RADIOTAP_VHT))
829  {
830  m_vhtPad = ((2 - m_length % 2) % 2);
832  m_length += (12 + m_vhtPad);
833  }
834 
835  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
836 }
837 
838 void
839 RadiotapHeader::SetHeFields (uint16_t data1, uint16_t data2, uint16_t data3, uint16_t data4, uint16_t data5, uint16_t data6)
840 {
841  NS_LOG_FUNCTION (this << data1 << data2 << data3 << data4 << data5 << data6);
842  m_heData1 = data1;
843  m_heData2 = data2;
844  m_heData3 = data3;
845  m_heData4 = data4;
846  m_heData5 = data5;
847  m_heData6 = data6;
848  if (!(m_present & RADIOTAP_HE))
849  {
850  m_hePad = ((2 - m_length % 2) % 2);
852  m_length += (12 + m_hePad);
853  }
854 
855  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
856 }
857 
858 void
859 RadiotapHeader::SetHeMuFields (uint16_t flags1, uint16_t flags2, const std::array<uint8_t, 4> &/*ruChannel1*/, const std::array<uint8_t, 4> &/*ruChannel2*/)
860 {
861  NS_LOG_FUNCTION (this << flags1 << flags2);
862  m_heMuFlags1 = flags1;
863  m_heMuFlags2 = flags2;
864  if (!(m_present & RADIOTAP_HE_MU))
865  {
866  m_heMuPad = ((2 - m_length % 2) % 2);
868  m_length += (12 + m_heMuPad);
869  }
870 
871  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
872 }
873 
874 void
875 RadiotapHeader::SetHeMuPerUserFields (uint16_t perUser1, uint16_t perUser2, uint8_t perUserPosition, uint8_t perUserKnown)
876 {
877  NS_LOG_FUNCTION (this << perUser1 << perUser2 << +perUserPosition << +perUserKnown);
878  m_heMuPerUser1 = perUser1;
879  m_heMuPerUser2 = perUser2;
880  m_heMuPerUserPosition = perUserPosition;
881  m_heMuPerUserKnown = perUserKnown;
883  {
884  m_heMuOtherUserPad = ((2 - m_length % 2) % 2);
886  m_length += (6 + m_heMuOtherUserPad);
887  }
888 
889  NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec);
890 }
891 
892 } // namespace ns3
iterator in a Buffer instance
Definition: buffer.h:99
Protocol header serialization and deserialization.
Definition: header.h:43
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
Radiotap header implementation.
uint8_t m_ampduStatusCRC
A-MPDU Status Flags, delimiter CRC value.
uint8_t m_rate
TX/RX data rate in units of 500 kbps.
uint16_t m_heMuPerUser1
HE MU per_user_1 field.
uint8_t m_mcsRate
MCS Flags, mcs rate index.
virtual uint32_t GetSerializedSize(void) const
This method is used by Packet::AddHeader to store the header into the byte buffer of a packet.
uint8_t m_vhtGroupId
VHT group_id field.
uint16_t m_ampduStatusFlags
A-MPDU Status Flags, information about the received A-MPDU.
uint8_t m_heMuPerUserPosition
HE MU per_user_position field.
uint8_t m_ampduStatusPad
A-MPDU Status Flags, padding before A-MPDU Status Field.
void SetMcsFields(uint8_t known, uint8_t flags, uint8_t mcs)
Set the MCS fields.
uint8_t m_mcsKnown
MCS Flags, known information field.
uint16_t m_heData4
HE data4 field.
uint16_t m_vhtPartialAid
VHT partial_aid field.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
uint16_t m_heMuFlags1
HE MU flags1 field.
void SetChannelFrequencyAndFlags(uint16_t frequency, uint16_t flags)
Set the transmit/receive channel frequency and flags.
uint8_t m_heMuPad
HE MU padding.
uint16_t m_heData1
HE data1 field.
uint8_t m_heMuOtherUserPad
HE MU other user padding.
uint8_t m_hePad
HE padding.
static TypeId GetTypeId(void)
Get the type ID.
void SetRate(uint8_t rate)
Set the transmit/receive channel frequency in units of megahertz.
uint16_t m_heMuPerUser2
HE MU per_user_2 field.
int8_t m_antennaSignal
RF signal power at the antenna, dB difference from an arbitrary, fixed reference.
void SetVhtFields(uint16_t known, uint8_t flags, uint8_t bandwidth, uint8_t mcs_nss[4], uint8_t coding, uint8_t group_id, uint16_t partial_aid)
Set the VHT fields.
void SetAntennaSignalPower(double signal)
Set the RF signal power at the antenna as a decibel difference from an arbitrary, fixed reference.
uint8_t m_vhtBandwidth
VHT bandwidth field.
void SetTsft(uint64_t tsft)
Set the Time Synchronization Function Timer (TSFT) value.
uint16_t m_length
entire length of radiotap data + header
uint16_t m_heData6
HE data6 field.
uint8_t m_vhtCoding
VHT coding field.
void SetHeFields(uint16_t data1, uint16_t data2, uint16_t data3, uint16_t data4, uint16_t data5, uint16_t data6)
Set the HE fields.
uint8_t m_vhtMcsNss[4]
VHT mcs_nss field.
uint16_t m_heData5
HE data5 field.
uint16_t m_channelFlags
Tx/Rx channel flags.
uint32_t m_present
bits describing which fields follow header
uint32_t m_ampduStatusRef
A-MPDU Status Flags, reference number.
void SetAmpduStatus(uint32_t referenceNumber, uint16_t flags, uint8_t crc)
Set the A-MPDU status fields.
uint16_t m_heData2
HE data2 field.
void SetHeMuPerUserFields(uint16_t perUser1, uint16_t perUser2, uint8_t perUserPosition, uint8_t perUserKnown)
Set the HE MU per user fields.
uint8_t m_mcsFlags
MCS Flags, flags field.
virtual void Print(std::ostream &os) const
This method is used by Packet::Print to print the content of the header as ascii data to a C++ output...
void SetHeMuFields(uint16_t flags1, uint16_t flags2, const std::array< uint8_t, 4 > &ruChannel1, const std::array< uint8_t, 4 > &ruChannel2)
Set the HE MU fields.
void SetAntennaNoisePower(double noise)
Set the RF noise power at the antenna as a decibel difference from an arbitrary, fixed reference.
uint16_t m_heMuFlags2
HE MU flags2 field.
uint16_t m_vhtKnown
VHT known field.
uint16_t m_heData3
HE data3 field.
uint8_t m_vhtFlags
VHT flags field.
uint8_t m_channelPad
Tx/Rx channel padding.
uint8_t m_vhtPad
VHT padding.
uint16_t m_channelFreq
Tx/Rx frequency in MHz.
uint8_t m_flags
Properties of transmitted and received frames.
uint8_t m_heMuPerUserKnown
HE MU per_user_known field.
void SetFrameFlags(uint8_t flags)
Set the frame flags of the transmitted or received frame.
virtual void Serialize(Buffer::Iterator start) const
This method is used by Packet::AddHeader to store the header into the byte buffer of a packet.
uint64_t m_tsft
Time Synchronization Function Timer (when the first bit of the MPDU arrived at the MAC)
int8_t m_antennaNoise
RF noise power at the antenna, dB difference from an arbitrary, fixed reference.
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Every class exported by the ns3 library is enclosed in the ns3 namespace.
def start()
Definition: core.py:1853