src/wifi/helper/yans-wifi-helper.cc
changeset 11479 a3dcf66928f3
parent 11451 36f951da53ac
child 11481 6189e8edc765
equal deleted inserted replaced
11478:f743110af92e 11479:a3dcf66928f3
    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       }