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