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