13 * |
13 * |
14 * You should have received a copy of the GNU General Public License |
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 |
15 * along with this program; if not, write to the Free Software |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 * |
17 * |
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
18 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
|
19 * Sébastien Deronne <sebastien.deronne@gmail.com> |
19 */ |
20 */ |
20 |
21 |
21 #include "ns3/trace-helper.h" |
22 #include "ns3/trace-helper.h" |
22 #include "yans-wifi-helper.h" |
23 #include "yans-wifi-helper.h" |
23 #include "ns3/error-rate-model.h" |
24 #include "ns3/error-rate-model.h" |
24 #include "ns3/propagation-loss-model.h" |
25 #include "ns3/propagation-loss-model.h" |
25 #include "ns3/propagation-delay-model.h" |
26 #include "ns3/propagation-delay-model.h" |
26 #include "ns3/yans-wifi-channel.h" |
27 #include "ns3/yans-wifi-channel.h" |
27 #include "ns3/yans-wifi-phy.h" |
28 #include "ns3/yans-wifi-phy.h" |
|
29 #include "ns3/ampdu-subframe-header.h" |
28 #include "ns3/wifi-net-device.h" |
30 #include "ns3/wifi-net-device.h" |
29 #include "ns3/radiotap-header.h" |
31 #include "ns3/radiotap-header.h" |
30 #include "ns3/pcap-file-wrapper.h" |
32 #include "ns3/pcap-file-wrapper.h" |
31 #include "ns3/simulator.h" |
33 #include "ns3/simulator.h" |
32 #include "ns3/config.h" |
34 #include "ns3/config.h" |
251 Ptr<PcapFileWrapper> file, |
253 Ptr<PcapFileWrapper> file, |
252 Ptr<const Packet> packet, |
254 Ptr<const Packet> packet, |
253 uint16_t channelFreqMhz, |
255 uint16_t channelFreqMhz, |
254 uint16_t channelNumber, |
256 uint16_t channelNumber, |
255 uint32_t rate, |
257 uint32_t rate, |
256 bool isShortPreamble, |
258 WifiPreamble preamble, |
257 WifiTxVector txvector) |
259 WifiTxVector txvector, |
|
260 struct mpduInfo aMpdu) |
258 { |
261 { |
259 uint32_t dlt = file->GetDataLinkType (); |
262 uint32_t dlt = file->GetDataLinkType (); |
260 |
263 |
261 switch (dlt) |
264 switch (dlt) |
262 { |
265 { |
276 header.SetTsft (Simulator::Now ().GetMicroSeconds ()); |
279 header.SetTsft (Simulator::Now ().GetMicroSeconds ()); |
277 |
280 |
278 //Our capture includes the FCS, so we set the flag to say so. |
281 //Our capture includes the FCS, so we set the flag to say so. |
279 frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED; |
282 frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED; |
280 |
283 |
281 if (isShortPreamble) |
284 if (preamble == WIFI_PREAMBLE_SHORT) |
282 { |
285 { |
283 frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE; |
286 frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE; |
284 } |
287 } |
285 |
288 |
286 if (txvector.IsShortGuardInterval ()) |
289 if (txvector.IsShortGuardInterval ()) |
314 { |
317 { |
315 channelFlags |= RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ; |
318 channelFlags |= RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ; |
316 } |
319 } |
317 |
320 |
318 header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags); |
321 header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags); |
|
322 |
|
323 if (preamble == WIFI_PREAMBLE_HT_MF || preamble == WIFI_PREAMBLE_HT_GF || preamble == WIFI_PREAMBLE_NONE) |
|
324 { |
|
325 uint8_t mcsRate = 0; |
|
326 uint8_t mcsKnown = RadiotapHeader::MCS_KNOWN_NONE; |
|
327 uint8_t mcsFlags = RadiotapHeader::MCS_FLAGS_NONE; |
|
328 |
|
329 mcsKnown |= RadiotapHeader::MCS_KNOWN_INDEX; |
|
330 mcsRate = rate - 128; |
|
331 |
|
332 mcsKnown |= RadiotapHeader::MCS_KNOWN_BANDWIDTH; |
|
333 if (txvector.GetMode ().GetBandwidth () == 40000000) |
|
334 { |
|
335 mcsFlags |= RadiotapHeader::MCS_FLAGS_BANDWIDTH_40; |
|
336 } |
|
337 |
|
338 mcsKnown |= RadiotapHeader::MCS_KNOWN_GUARD_INTERVAL; |
|
339 if (txvector.IsShortGuardInterval ()) |
|
340 { |
|
341 mcsFlags |= RadiotapHeader::MCS_FLAGS_GUARD_INTERVAL; |
|
342 } |
|
343 |
|
344 mcsKnown |= RadiotapHeader::MCS_KNOWN_HT_FORMAT; |
|
345 if (preamble == WIFI_PREAMBLE_HT_GF) |
|
346 { |
|
347 mcsFlags |= RadiotapHeader::MCS_FLAGS_HT_GREENFIELD; |
|
348 } |
|
349 |
|
350 mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS; |
|
351 if (txvector.GetNess () & 0x01) //bit 1 |
|
352 { |
|
353 mcsFlags |= RadiotapHeader::MCS_FLAGS_NESS_BIT_0; |
|
354 } |
|
355 if (txvector.GetNess () & 0x02) //bit 2 |
|
356 { |
|
357 mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS_BIT_1; |
|
358 } |
|
359 |
|
360 mcsKnown |= RadiotapHeader::MCS_KNOWN_FEC_TYPE; //only BCC is currently supported |
|
361 |
|
362 mcsKnown |= RadiotapHeader::MCS_KNOWN_STBC; |
|
363 if (txvector.IsStbc ()) |
|
364 { |
|
365 mcsFlags |= RadiotapHeader::MCS_FLAGS_STBC_STREAMS; |
|
366 } |
|
367 |
|
368 header.SetMcsFields (mcsKnown, mcsFlags, mcsRate); |
|
369 } |
|
370 |
|
371 if (txvector.IsAggregation ()) |
|
372 { |
|
373 uint16_t ampduStatusFlags = RadiotapHeader::A_MPDU_STATUS_NONE; |
|
374 ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_DELIMITER_CRC_KNOWN; |
|
375 ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN; |
|
376 if (aMpdu.packetType == 2) |
|
377 { |
|
378 ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST; |
|
379 } |
|
380 /* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */ |
|
381 AmpduSubframeHeader hdr; |
|
382 uint32_t extractedLength; |
|
383 p->RemoveHeader (hdr); |
|
384 extractedLength = hdr.GetLength (); |
|
385 p = p->CreateFragment (0, static_cast<uint32_t> (extractedLength)); |
|
386 header.SetAmpduStatus (aMpdu.referenceNumber, ampduStatusFlags, hdr.GetCrc ()); |
|
387 } |
319 |
388 |
320 p->AddHeader (header); |
389 p->AddHeader (header); |
321 file->Write (Simulator::Now (), p); |
390 file->Write (Simulator::Now (), p); |
322 return; |
391 return; |
323 } |
392 } |
331 Ptr<PcapFileWrapper> file, |
400 Ptr<PcapFileWrapper> file, |
332 Ptr<const Packet> packet, |
401 Ptr<const Packet> packet, |
333 uint16_t channelFreqMhz, |
402 uint16_t channelFreqMhz, |
334 uint16_t channelNumber, |
403 uint16_t channelNumber, |
335 uint32_t rate, |
404 uint32_t rate, |
336 bool isShortPreamble, |
405 WifiPreamble preamble, |
337 WifiTxVector txvector, |
406 WifiTxVector txvector, |
338 double signalDbm, |
407 struct mpduInfo aMpdu, |
339 double noiseDbm) |
408 struct snrDbm snr) |
340 { |
409 { |
341 uint32_t dlt = file->GetDataLinkType (); |
410 uint32_t dlt = file->GetDataLinkType (); |
342 |
411 |
343 switch (dlt) |
412 switch (dlt) |
344 { |
413 { |
358 header.SetTsft (Simulator::Now ().GetMicroSeconds ()); |
427 header.SetTsft (Simulator::Now ().GetMicroSeconds ()); |
359 |
428 |
360 //Our capture includes the FCS, so we set the flag to say so. |
429 //Our capture includes the FCS, so we set the flag to say so. |
361 frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED; |
430 frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED; |
362 |
431 |
363 if (isShortPreamble) |
432 if (preamble == WIFI_PREAMBLE_SHORT) |
364 { |
433 { |
365 frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE; |
434 frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE; |
366 } |
435 } |
367 |
436 |
368 if (txvector.IsShortGuardInterval ()) |
437 if (txvector.IsShortGuardInterval ()) |
397 channelFlags |= RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ; |
466 channelFlags |= RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ; |
398 } |
467 } |
399 |
468 |
400 header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags); |
469 header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags); |
401 |
470 |
402 header.SetAntennaSignalPower (signalDbm); |
471 header.SetAntennaSignalPower (snr.signal); |
403 header.SetAntennaNoisePower (noiseDbm); |
472 header.SetAntennaNoisePower (snr.noise); |
|
473 |
|
474 if (preamble == WIFI_PREAMBLE_HT_MF || preamble == WIFI_PREAMBLE_HT_GF || preamble == WIFI_PREAMBLE_NONE) |
|
475 { |
|
476 uint8_t mcsRate = 0; |
|
477 uint8_t mcsKnown = RadiotapHeader::MCS_KNOWN_NONE; |
|
478 uint8_t mcsFlags = RadiotapHeader::MCS_FLAGS_NONE; |
|
479 |
|
480 mcsKnown |= RadiotapHeader::MCS_KNOWN_INDEX; |
|
481 mcsRate = rate - 128; |
|
482 |
|
483 mcsKnown |= RadiotapHeader::MCS_KNOWN_BANDWIDTH; |
|
484 if (txvector.GetMode ().GetBandwidth () == 40000000) |
|
485 { |
|
486 mcsFlags |= RadiotapHeader::MCS_FLAGS_BANDWIDTH_40; |
|
487 } |
|
488 |
|
489 mcsKnown |= RadiotapHeader::MCS_KNOWN_GUARD_INTERVAL; |
|
490 if (txvector.IsShortGuardInterval ()) |
|
491 { |
|
492 mcsFlags |= RadiotapHeader::MCS_FLAGS_GUARD_INTERVAL; |
|
493 } |
|
494 |
|
495 mcsKnown |= RadiotapHeader::MCS_KNOWN_HT_FORMAT; |
|
496 if (preamble == WIFI_PREAMBLE_HT_GF) |
|
497 { |
|
498 mcsFlags |= RadiotapHeader::MCS_FLAGS_HT_GREENFIELD; |
|
499 } |
|
500 |
|
501 mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS; |
|
502 if (txvector.GetNess () & 0x01) //bit 1 |
|
503 { |
|
504 mcsFlags |= RadiotapHeader::MCS_FLAGS_NESS_BIT_0; |
|
505 } |
|
506 if (txvector.GetNess () & 0x02) //bit 2 |
|
507 { |
|
508 mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS_BIT_1; |
|
509 } |
|
510 |
|
511 mcsKnown |= RadiotapHeader::MCS_KNOWN_FEC_TYPE; //only BCC is currently supported |
|
512 |
|
513 mcsKnown |= RadiotapHeader::MCS_KNOWN_STBC; |
|
514 if (txvector.IsStbc ()) |
|
515 { |
|
516 mcsFlags |= RadiotapHeader::MCS_FLAGS_STBC_STREAMS; |
|
517 } |
|
518 |
|
519 header.SetMcsFields (mcsKnown, mcsFlags, mcsRate); |
|
520 } |
|
521 |
|
522 if (txvector.IsAggregation ()) |
|
523 { |
|
524 uint16_t ampduStatusFlags = 0; |
|
525 ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_DELIMITER_CRC_KNOWN; |
|
526 ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN; |
|
527 if (aMpdu.packetType == 2) |
|
528 { |
|
529 ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST; |
|
530 } |
|
531 /* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */ |
|
532 AmpduSubframeHeader hdr; |
|
533 uint32_t extractedLength; |
|
534 p->RemoveHeader (hdr); |
|
535 extractedLength = hdr.GetLength (); |
|
536 p = p->CreateFragment (0, static_cast<uint32_t> (extractedLength)); |
|
537 header.SetAmpduStatus (aMpdu.referenceNumber, ampduStatusFlags, hdr.GetCrc ()); |
|
538 } |
404 |
539 |
405 p->AddHeader (header); |
540 p->AddHeader (header); |
406 file->Write (Simulator::Now (), p); |
541 file->Write (Simulator::Now (), p); |
407 return; |
542 return; |
408 } |
543 } |