diff --git a/src/network/utils/radiotap-header.cc b/src/network/utils/radiotap-header.cc old mode 100644 new mode 100755 --- a/src/network/utils/radiotap-header.cc +++ b/src/network/utils/radiotap-header.cc @@ -38,7 +38,10 @@ m_channelFreq (0), m_channelFlags (CHANNEL_FLAG_NONE), m_antennaSignal (0), - m_antennaNoise (0) + m_antennaNoise (0), + m_ampduStatusRef (0), + m_ampduStatusFlags (0), + m_ampduStatusCRC (0) { NS_LOG_FUNCTION (this); } @@ -128,6 +131,110 @@ { start.WriteU8 (m_antennaNoise); } + + // + // Quality of Barker code lock. + // + if (m_present & RADIOTAP_LOCK_QUALITY) // bit 7 + { + start.WriteU16 (0); + } + + // + // Transmit power expressed as unitless distance from max power + // set at factory calibration (0 is max power). + // + if (m_present & RADIOTAP_TX_ATTENUATION) // bit 8 + { + start.WriteU16 (0); + } + + // + // Transmit power expressed as decibel distance from max power + // set at factory calibration (0 is max power). + // + if (m_present & RADIOTAP_DB_TX_ATTENUATION) // bit 9 + { + start.WriteU16 (0); + } + + // + // Transmit power expressed as dBm (decibels from a 1 milliwatt reference). + // This is the absolute power level measured at the antenna port. + // + if (m_present & RADIOTAP_DBM_TX_POWER) // bit 10 + { + start.WriteU8 (0); + } + + // + // Unitless indication of the Rx/Tx antenna for this packet. + // The first antenna is antenna 0. + // + if (m_present & RADIOTAP_ANTENNA) // bit 11 + { + start.WriteU8 (0); + } + + // + // RF signal power at the antenna (decibel difference from an arbitrary fixed reference). + // + if (m_present & RADIOTAP_DB_ANTSIGNAL) // bit 12 + { + start.WriteU8 (0); + } + + // + // RF noise power at the antenna (decibel difference from an arbitrary fixed reference). + // + if (m_present & RADIOTAP_DB_ANTNOISE) // bit 13 + { + start.WriteU8 (0); + } + + // + // Properties of received frames. + // + if (m_present & RADIOTAP_RX_FLAGS) // bit 14 + { + start.WriteU16 (0); + } + + // + // MCS field. + // + if (m_present & RADIOTAP_MCS) // bit 19 + { + start.WriteU8 (m_mcsKnown); + start.WriteU8 (m_mcsFlags); + start.WriteU8 (m_mcsRate); + } + + // + // A-MPDU Status, information about the received or transmitted A-MPDU. + // + if (m_present & RADIOTAP_AMPDU_STATUS) // bit 20 + { + start.WriteU8(0, m_ampduStatusPad); + start.WriteU32 (m_ampduStatusRef); + start.WriteU16 (m_ampduStatusFlags); + start.WriteU8 (m_ampduStatusCRC); + start.WriteU8 (0); + } + + // + // Information about the received or transmitted VHT frame. + // + if (m_present & RADIOTAP_VHT) // bit 21 + { + start.WriteU16 (0); + start.WriteU8 (0); + start.WriteU8 (0); + start.WriteU8 (0); + start.WriteU8 (0); + start.WriteU8 (0); + start.WriteU16 (0); + } } uint32_t @@ -211,6 +318,121 @@ ++bytesRead; } + // + // Quality of Barker code lock. + // + if (m_present & RADIOTAP_LOCK_QUALITY) // bit 7 + { + start.ReadU16 (); + bytesRead += 2; + } + + // + // Transmit power expressed as unitless distance from max power + // set at factory calibration (0 is max power). + // + if (m_present & RADIOTAP_TX_ATTENUATION) // bit 8 + { + start.ReadU16 (); + bytesRead += 2; + } + + // + // Transmit power expressed as decibel distance from max power + // set at factory calibration (0 is max power). + // + if (m_present & RADIOTAP_DB_TX_ATTENUATION) // bit 9 + { + start.ReadU16 (); + bytesRead += 2; + } + + // + // Transmit power expressed as dBm (decibels from a 1 milliwatt reference). + // This is the absolute power level measured at the antenna port. + // + if (m_present & RADIOTAP_DBM_TX_POWER) // bit 10 + { + start.ReadU8 (); + ++bytesRead; + } + + // + // Unitless indication of the Rx/Tx antenna for this packet. + // The first antenna is antenna 0. + // + if (m_present & RADIOTAP_ANTENNA) // bit 11 + { + start.ReadU8 (); + ++bytesRead; + } + + // + // RF signal power at the antenna (decibel difference from an arbitrary fixed reference). + // + if (m_present & RADIOTAP_DB_ANTSIGNAL) // bit 12 + { + start.ReadU8 (); + ++bytesRead; + } + + // + // RF noise power at the antenna (decibel difference from an arbitrary fixed reference). + // + if (m_present & RADIOTAP_DB_ANTNOISE) // bit 13 + { + start.ReadU8 (); + ++bytesRead; + } + + // + // Properties of received frames. + // + if (m_present & RADIOTAP_RX_FLAGS) // bit 14 + { + start.ReadU16 (); + bytesRead += 2; + } + + // + // MCS field. + // + if (m_present & RADIOTAP_MCS) // bit 19 + { + m_mcsKnown = start.ReadU8 (); + m_mcsFlags = start.ReadU8 (); + m_mcsRate = start.ReadU8 (); + bytesRead += 3; + } + + // + // A-MPDU Status, information about the received or transmitted A-MPDU. + // + if (m_present & RADIOTAP_AMPDU_STATUS) // bit 20 + { + m_ampduStatusPad = ((4 - bytesRead % 4) % 4); + start.Next (m_ampduStatusPad); + m_ampduStatusRef = start.ReadU32 (); + m_ampduStatusFlags = start.ReadU16 (); + m_ampduStatusCRC = start.ReadU8 (); + start.ReadU8 (); + bytesRead += (8 + m_ampduStatusPad); + } + + // + // Information about the received or transmitted VHT frame. + // + if (m_present & RADIOTAP_VHT) // bit 21 + { + start.ReadU16 (); + start.ReadU8 (); + start.ReadU8 (); + start.ReadU8 (); + start.ReadU8 (); + start.ReadU8 (); + start.ReadU16 (); + } + NS_ASSERT_MSG (m_length == bytesRead, "RadiotapHeader::Deserialize(): expected and actual lengths inconsistent"); return bytesRead; } @@ -225,7 +447,11 @@ << " freq=" << m_channelFreq << " chflags=" << std::hex << (uint32_t)m_channelFlags << std::dec << " signal=" << (int16_t) m_antennaSignal - << " noise=" << (int16_t) m_antennaNoise; + << " noise=" << (int16_t) m_antennaNoise + << " mcsKnown=" << m_mcsKnown + << " mcsFlags=" << m_mcsFlags + << " mcsRate=" << m_mcsRate + << " ampduStatusFlags=" << (int16_t) m_ampduStatusFlags; } void @@ -390,4 +616,72 @@ return m_antennaNoise; } +void +RadiotapHeader::SetMcsFields (uint8_t known, uint8_t flags, uint8_t mcs) +{ + NS_LOG_FUNCTION (this << known << flags << mcs); + m_mcsKnown = known; + m_mcsFlags = flags; + m_mcsRate = mcs; + if (!(m_present & RADIOTAP_MCS)) + { + m_present |= RADIOTAP_MCS; + m_length += 3; + } + + NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec); +} + +uint8_t +RadiotapHeader::GetMcsKnown () const +{ + NS_LOG_FUNCTION (this); + return m_mcsKnown; +} + +uint8_t +RadiotapHeader::GetMcsFlags () const +{ + NS_LOG_FUNCTION (this); + return m_mcsFlags; +} + +uint8_t +RadiotapHeader::GetMcsRate () const +{ + NS_LOG_FUNCTION (this); + return m_mcsRate; +} + +void +RadiotapHeader::SetAmpduStatus (uint32_t referenceNumber, uint16_t flags, uint8_t crc) +{ + NS_LOG_FUNCTION (this << referenceNumber << flags); + m_ampduStatusRef = referenceNumber; + m_ampduStatusFlags = flags; + m_ampduStatusCRC = crc; + if (!(m_present & RADIOTAP_AMPDU_STATUS)) + { + m_ampduStatusPad = (4 - m_length % 4) % 4; + m_present |= RADIOTAP_AMPDU_STATUS; + m_length += 8 + m_ampduStatusPad; + } + + NS_LOG_LOGIC (this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present << std::dec); +} + +uint32_t +RadiotapHeader::GetAmpduStatusRef () const +{ + NS_LOG_FUNCTION (this); + return m_ampduStatusRef; +} + +uint16_t +RadiotapHeader::GetAmpduStatusFlags () const +{ + NS_LOG_FUNCTION (this); + return m_ampduStatusFlags; +} + } // namespace ns3 diff --git a/src/network/utils/radiotap-header.h b/src/network/utils/radiotap-header.h old mode 100644 new mode 100755 --- a/src/network/utils/radiotap-header.h +++ b/src/network/utils/radiotap-header.h @@ -226,6 +226,91 @@ * from an arbitrary, fixed reference. */ uint8_t GetAntennaNoisePower (void) const; + + enum { + MCS_KNOWN_NONE = 0x00, /**< No flags set */ + MCS_KNOWN_BANDWIDTH = 0x01, /**< Bandwidth */ + MCS_KNOWN_INDEX = 0x02, /**< MCS index known */ + MCS_KNOWN_GUARD_INTERVAL = 0x04, /**< Guard interval */ + MCS_KNOWN_HT_FORMAT = 0x08, /**< HT format */ + MCS_KNOWN_FEC_TYPE = 0x10, /**< FEC type */ + MCS_KNOWN_STBC = 0x20, /**< STBC known */ + MCS_KNOWN_NESS = 0x40, /**< Ness known (Number of extension spatial streams) */ + MCS_KNOWN_NESS_BIT_1 = 0x80, /**< Ness data - bit 1 (MSB) of Number of extension spatial streams */ + }; + + enum { + MCS_FLAGS_NONE = 0x00, /**< Default: 20 MHz, long guard interval, mixed HT format and BCC FEC type */ + MCS_FLAGS_BANDWIDTH_40 = 0x01, /**< 40 MHz */ + MCS_FLAGS_BANDWIDTH_20L = 0x02, /**< 20L (20 MHz in lower half of 40 MHz channel) */ + MCS_FLAGS_BANDWIDTH_20U = 0x03, /**< 20U (20 MHz in upper half of 40 MHz channel) */ + MCS_FLAGS_GUARD_INTERVAL = 0x04, /**< Short guard interval */ + MCS_FLAGS_HT_GREENFIELD = 0x08, /**< Greenfield HT format */ + MCS_FLAGS_FEC_TYPE = 0x10, /**< LDPC FEC type */ + MCS_FLAGS_STBC_STREAMS = 0x60, /**< STBC enabled */ + MCS_FLAGS_NESS_BIT_0 = 0x80, /**< Ness - bit 0 (LSB) of Number of extension spatial streams */ + }; + + /** + * @brief Set the MCS fields + * + * @param known The kwown flags. + * @param flags The flags to set. + * @param mcs The MCS index value. + */ + void SetMcsFields (uint8_t known, uint8_t flags, uint8_t mcs); + + /** + * @brief Get the MCS known bitmap. + * + * @returns The MCS known bitmap. + */ + uint8_t GetMcsKnown (void) const; + /** + * @brief Get the MCS flags. + * + * @returns The MCS flags. + */ + uint8_t GetMcsFlags (void) const; + /** + * @brief Get the MCS index value. + * + * @returns The MCS index value. + */ + uint8_t GetMcsRate (void) const; + + enum { + A_MPDU_STATUS_NONE = 0x00, /**< No flags set */ + A_MPDU_STATUS_REPORT_ZERO_LENGTH = 0x01, /**< Driver reports 0-length subframes */ + A_MPDU_STATUS_IS_ZERO_LENGTH = 0x02, /**< Frame is 0-length subframe (valid only if 0x0001 is set) */ + A_MPDU_STATUS_LAST_KNOWN = 0x04, /**< Last subframe is known (should be set for all subframes in an A-MPDU) */ + A_MPDU_STATUS_LAST = 0x08, /**< This frame is the last subframe */ + A_MPDU_STATUS_DELIMITER_CRC_ERROR = 0x10, /**< Delimiter CRC error */ + A_MPDU_STATUS_DELIMITER_CRC_KNOWN = 0x20 /**< Delimiter CRC value known: the delimiter CRC value field is valid */ + }; + + /** + * @brief Set the A-MPDU status fields + * + * @param referenceNumber The A-MPDU reference number to identify all subframes belonging to the same A-MPDU. + * @param flags The flags to set. + * @param crc The CRC value value. + */ + void SetAmpduStatus (uint32_t referenceNumber, uint16_t flags, uint8_t crc); + + /** + * @brief Get the A-MPDU reference number. + * + * @returns The A-MPDU reference number. + */ + uint32_t GetAmpduStatusRef (void) const; + /** + * @brief Get the A-MPDU status flags. + * + * @returns The A-MPDU status flags. + */ + uint16_t GetAmpduStatusFlags (void) const; + private: enum { @@ -239,10 +324,14 @@ RADIOTAP_LOCK_QUALITY = 0x00000080, RADIOTAP_TX_ATTENUATION = 0x00000100, RADIOTAP_DB_TX_ATTENUATION = 0x00000200, - RADIOTAP_DBM_TX_POWER = 0x00000200, - RADIOTAP_ANTENNA = 0x00000400, - RADIOTAP_DB_ANTSIGNAL = 0x00000800, - RADIOTAP_DB_ANTNOISE = 0x00001000, + RADIOTAP_DBM_TX_POWER = 0x00000400, + RADIOTAP_ANTENNA = 0x00000800, + RADIOTAP_DB_ANTSIGNAL = 0x00001000, + RADIOTAP_DB_ANTNOISE = 0x00002000, + RADIOTAP_RX_FLAGS = 0x00004000, + RADIOTAP_MCS = 0x00080000, + RADIOTAP_AMPDU_STATUS = 0x00100000, + RADIOTAP_VHT = 0x00200000, RADIOTAP_EXT = 0x10000000 }; @@ -256,6 +345,15 @@ uint16_t m_channelFlags; //!< Tx/Rx channel flags. int8_t m_antennaSignal; //!< RF signal power at the antenna, dB difference from an arbitrary, fixed reference. int8_t m_antennaNoise; //!< RF noise power at the antenna, dB difference from an arbitrary, fixed reference. + + uint8_t m_mcsKnown; //!< MCS Flags, known information field. + uint8_t m_mcsFlags; //!< MCS Flags, flags field. + uint8_t m_mcsRate; //!< MCS Flags, mcs rate index. + + uint8_t m_ampduStatusPad; //!< A-MPDU Status Flags, Padding before A-MPDU Status Field. + uint32_t m_ampduStatusRef; //!< A-MPDU Status Flags, reference number. + uint16_t m_ampduStatusFlags; //!< A-MPDU Status Flags, information about the received A-MPDU. + uint8_t m_ampduStatusCRC; //!< A-MPDU Status Flags, delimiter CRC value. }; } // namespace ns3 diff --git a/src/wifi/examples/test-interference-helper.cc b/src/wifi/examples/test-interference-helper.cc --- a/src/wifi/examples/test-interference-helper.cc +++ b/src/wifi/examples/test-interference-helper.cc @@ -106,7 +106,7 @@ WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevelA); txVector.SetMode (WifiMode (m_input.txModeA)); - m_txA->SendPacket (p, txVector, m_input.preamble, 0); + m_txA->SendPacket (p, txVector, m_input.preamble, 0, 0); } void @@ -116,7 +116,7 @@ WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevelB); txVector.SetMode (WifiMode (m_input.txModeB)); - m_txB->SendPacket (p, txVector, m_input.preamble, 0); + m_txB->SendPacket (p, txVector, m_input.preamble, 0, 0); } InterferenceExperiment::InterferenceExperiment () diff --git a/src/wifi/examples/wifi-phy-test.cc b/src/wifi/examples/wifi-phy-test.cc --- a/src/wifi/examples/wifi-phy-test.cc +++ b/src/wifi/examples/wifi-phy-test.cc @@ -74,7 +74,7 @@ WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevel); txVector.SetMode (mode); - m_tx->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, 0); + m_tx->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, 0, 0); } void @@ -182,7 +182,7 @@ WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevelA); txVector.SetMode (WifiMode (m_input.txModeA)); - m_txA->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, 0); + m_txA->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, 0, 0); } void @@ -193,7 +193,7 @@ WifiTxVector txVector; txVector.SetTxPowerLevel (m_input.txPowerLevelB); txVector.SetMode (WifiMode (m_input.txModeB)); - m_txB->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, 0); + m_txB->SendPacket (p, txVector, WIFI_PREAMBLE_LONG, 0, 0); } void diff --git a/src/wifi/helper/yans-wifi-helper.cc b/src/wifi/helper/yans-wifi-helper.cc --- a/src/wifi/helper/yans-wifi-helper.cc +++ b/src/wifi/helper/yans-wifi-helper.cc @@ -25,6 +25,7 @@ #include "ns3/propagation-delay-model.h" #include "ns3/yans-wifi-channel.h" #include "ns3/yans-wifi-phy.h" +#include "ns3/ampdu-subframe-header.h" #include "ns3/wifi-net-device.h" #include "ns3/radiotap-header.h" #include "ns3/pcap-file-wrapper.h" @@ -253,8 +254,9 @@ uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, - bool isShortPreamble, - WifiTxVector txvector) + WifiPreamble preamble, + WifiTxVector txvector, + struct mpduInfo aMpdu) { uint32_t dlt = file->GetDataLinkType (); @@ -278,7 +280,155 @@ //Our capture includes the FCS, so we set the flag to say so. frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED; - if (isShortPreamble) + if (preamble == WIFI_PREAMBLE_SHORT) + { + frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE; + } + + if (txvector.IsShortGuardInterval ()) + { + frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_GUARD; + } + + header.SetFrameFlags (frameFlags); + header.SetRate (rate); + + uint16_t channelFlags = 0; + switch (rate) + { + case 2: //1Mbps + case 4: //2Mbps + case 10: //5Mbps + case 22: //11Mbps + channelFlags |= RadiotapHeader::CHANNEL_FLAG_CCK; + break; + + default: + channelFlags |= RadiotapHeader::CHANNEL_FLAG_OFDM; + break; + } + + if (channelFreqMhz < 2500) + { + channelFlags |= RadiotapHeader::CHANNEL_FLAG_SPECTRUM_2GHZ; + } + else + { + channelFlags |= RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ; + } + + header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags); + + if (preamble == WIFI_PREAMBLE_HT_MF || preamble == WIFI_PREAMBLE_HT_GF || preamble == WIFI_PREAMBLE_NONE) + { + uint8_t mcsRate = 0; + uint8_t mcsKnown = RadiotapHeader::MCS_KNOWN_NONE; + uint8_t mcsFlags = RadiotapHeader::MCS_FLAGS_NONE; + + mcsKnown |= RadiotapHeader::MCS_KNOWN_INDEX; + mcsRate = rate - 128; + + mcsKnown |= RadiotapHeader::MCS_KNOWN_BANDWIDTH; + if (txvector.GetMode ().GetBandwidth () == 40000000) + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_BANDWIDTH_40; + } + + mcsKnown |= RadiotapHeader::MCS_KNOWN_GUARD_INTERVAL; + if (txvector.IsShortGuardInterval ()) + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_GUARD_INTERVAL; + } + + mcsKnown |= RadiotapHeader::MCS_KNOWN_HT_FORMAT; + if (preamble == WIFI_PREAMBLE_HT_GF) + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_HT_GREENFIELD; + } + + mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS; + if (txvector.GetNess () & 0x01) //bit 1 + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_NESS_BIT_0; + } + if (txvector.GetNess () & 0x02) //bit 2 + { + mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS_BIT_1; + } + + mcsKnown |= RadiotapHeader::MCS_KNOWN_FEC_TYPE; //TODO + + mcsKnown |= RadiotapHeader::MCS_KNOWN_STBC; + if (txvector.IsStbc ()) + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_STBC_STREAMS; + } + + header.SetMcsFields (mcsKnown, mcsFlags, mcsRate); + } + + if (txvector.IsAggregation ()) + { + uint16_t ampduStatusFlags = RadiotapHeader::A_MPDU_STATUS_NONE; + ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_DELIMITER_CRC_KNOWN; + ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN; + if (aMpdu.packetType == 2) + { + ampduStatusFlags |= RadiotapHeader::A_MPDU_STATUS_LAST; + } + /* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */ + AmpduSubframeHeader hdr; + uint32_t extractedLength; + p->RemoveHeader (hdr); + extractedLength = hdr.GetLength (); + p = p->CreateFragment (0, static_cast (extractedLength)); + header.SetAmpduStatus (aMpdu.referenceNumber, ampduStatusFlags, hdr.GetCrc ()); + } + + p->AddHeader (header); + file->Write (Simulator::Now (), p); + return; + } + default: + NS_ABORT_MSG ("PcapSniffTxEvent(): Unexpected data link type " << dlt); + } +} + +static void +PcapSniffRxEvent ( + Ptr file, + Ptr packet, + uint16_t channelFreqMhz, + uint16_t channelNumber, + uint32_t rate, + WifiPreamble preamble, + WifiTxVector txvector, + struct mpduInfo aMpdu, + struct snrDbm snr) +{ + uint32_t dlt = file->GetDataLinkType (); + + switch (dlt) + { + case PcapHelper::DLT_IEEE802_11: + file->Write (Simulator::Now (), packet); + return; + case PcapHelper::DLT_PRISM_HEADER: + { + NS_FATAL_ERROR ("PcapSniffRxEvent(): DLT_PRISM_HEADER not implemented"); + return; + } + case PcapHelper::DLT_IEEE802_11_RADIO: + { + Ptr p = packet->Copy (); + RadiotapHeader header; + uint8_t frameFlags = RadiotapHeader::FRAME_FLAG_NONE; + header.SetTsft (Simulator::Now ().GetMicroSeconds ()); + + //Our capture includes the FCS, so we set the flag to say so. + frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED; + + if (preamble == WIFI_PREAMBLE_SHORT) { frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE; } @@ -317,91 +467,75 @@ header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags); - p->AddHeader (header); - file->Write (Simulator::Now (), p); - return; - } - default: - NS_ABORT_MSG ("PcapSniffTxEvent(): Unexpected data link type " << dlt); - } -} + header.SetAntennaSignalPower (snr.signal); + header.SetAntennaNoisePower (snr.noise); + + if (preamble == WIFI_PREAMBLE_HT_MF || preamble == WIFI_PREAMBLE_HT_GF || preamble == WIFI_PREAMBLE_NONE) + { + uint8_t mcsRate = 0; + uint8_t mcsKnown = RadiotapHeader::MCS_KNOWN_NONE; + uint8_t mcsFlags = RadiotapHeader::MCS_FLAGS_NONE; + + mcsKnown |= RadiotapHeader::MCS_KNOWN_INDEX; + mcsRate = rate - 128; + + mcsKnown |= RadiotapHeader::MCS_KNOWN_BANDWIDTH; + if (txvector.GetMode ().GetBandwidth () == 40000000) + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_BANDWIDTH_40; + } + + mcsKnown |= RadiotapHeader::MCS_KNOWN_GUARD_INTERVAL; + if (txvector.IsShortGuardInterval ()) + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_GUARD_INTERVAL; + } -static void -PcapSniffRxEvent ( - Ptr file, - Ptr packet, - uint16_t channelFreqMhz, - uint16_t channelNumber, - uint32_t rate, - bool isShortPreamble, - WifiTxVector txvector, - double signalDbm, - double noiseDbm) -{ - uint32_t dlt = file->GetDataLinkType (); - - switch (dlt) - { - case PcapHelper::DLT_IEEE802_11: - file->Write (Simulator::Now (), packet); - return; - case PcapHelper::DLT_PRISM_HEADER: - { - NS_FATAL_ERROR ("PcapSniffRxEvent(): DLT_PRISM_HEADER not implemented"); - return; - } - case PcapHelper::DLT_IEEE802_11_RADIO: - { - Ptr p = packet->Copy (); - RadiotapHeader header; - uint8_t frameFlags = RadiotapHeader::FRAME_FLAG_NONE; - header.SetTsft (Simulator::Now ().GetMicroSeconds ()); - - //Our capture includes the FCS, so we set the flag to say so. - frameFlags |= RadiotapHeader::FRAME_FLAG_FCS_INCLUDED; - - if (isShortPreamble) + mcsKnown |= RadiotapHeader::MCS_KNOWN_HT_FORMAT; + if (preamble == WIFI_PREAMBLE_HT_GF) + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_HT_GREENFIELD; + } + + mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS; + if (txvector.GetNess () & 0x01) //bit 1 + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_NESS_BIT_0; + } + if (txvector.GetNess () & 0x02) //bit 2 + { + mcsKnown |= RadiotapHeader::MCS_KNOWN_NESS_BIT_1; + } + + mcsKnown |= RadiotapHeader::MCS_KNOWN_FEC_TYPE; //TODO + + mcsKnown |= RadiotapHeader::MCS_KNOWN_STBC; + if (txvector.IsStbc ()) + { + mcsFlags |= RadiotapHeader::MCS_FLAGS_STBC_STREAMS; + } + + header.SetMcsFields (mcsKnown, mcsFlags, mcsRate); + } + + if (txvector.IsAggregation()) { - frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE; + uint16_t ampduStatus_Flags = 0; + ampduStatus_Flags |= RadiotapHeader::A_MPDU_STATUS_DELIMITER_CRC_KNOWN; + ampduStatus_Flags |= RadiotapHeader::A_MPDU_STATUS_LAST_KNOWN; + if (aMpdu.packetType == 2) + { + ampduStatus_Flags |= RadiotapHeader::A_MPDU_STATUS_LAST; + } + /* For PCAP file, MPDU Delimiter and Padding should be removed by the MAC Driver */ + AmpduSubframeHeader hdr; + uint32_t extractedLength; + p->RemoveHeader (hdr); + extractedLength = hdr.GetLength (); + p = p->CreateFragment (0, static_cast (extractedLength)); + header.SetAmpduStatus (aMpdu.referenceNumber, ampduStatus_Flags, hdr.GetCrc ()); } - if (txvector.IsShortGuardInterval ()) - { - frameFlags |= RadiotapHeader::FRAME_FLAG_SHORT_GUARD; - } - - header.SetFrameFlags (frameFlags); - header.SetRate (rate); - - uint16_t channelFlags = 0; - switch (rate) - { - case 2: //1Mbps - case 4: //2Mbps - case 10: //5Mbps - case 22: //11Mbps - channelFlags |= RadiotapHeader::CHANNEL_FLAG_CCK; - break; - - default: - channelFlags |= RadiotapHeader::CHANNEL_FLAG_OFDM; - break; - } - - if (channelFreqMhz < 2500) - { - channelFlags |= RadiotapHeader::CHANNEL_FLAG_SPECTRUM_2GHZ; - } - else - { - channelFlags |= RadiotapHeader::CHANNEL_FLAG_SPECTRUM_5GHZ; - } - - header.SetChannelFrequencyAndFlags (channelFreqMhz, channelFlags); - - header.SetAntennaSignalPower (signalDbm); - header.SetAntennaNoisePower (noiseDbm); - p->AddHeader (header); file->Write (Simulator::Now (), p); return; diff --git a/src/wifi/model/aarf-wifi-manager.cc b/src/wifi/model/aarf-wifi-manager.cc --- a/src/wifi/model/aarf-wifi-manager.cc +++ b/src/wifi/model/aarf-wifi-manager.cc @@ -232,7 +232,7 @@ { NS_LOG_FUNCTION (this << st << size); AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -242,7 +242,7 @@ /// \todo we could/should implement the Aarf algorithm for /// RTS only by picking a single rate within the BasicRateSet. AarfWifiRemoteStation *station = (AarfWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/aarfcd-wifi-manager.cc b/src/wifi/model/aarfcd-wifi-manager.cc --- a/src/wifi/model/aarfcd-wifi-manager.cc +++ b/src/wifi/model/aarfcd-wifi-manager.cc @@ -304,7 +304,7 @@ { NS_LOG_FUNCTION (this << st << size); AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector AarfcdWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) @@ -313,7 +313,7 @@ /// \todo we could/should implement the Aarf algorithm for /// RTS only by picking a single rate within the BasicRateSet. AarfcdWifiRemoteStation *station = (AarfcdWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/amrr-wifi-manager.cc b/src/wifi/model/amrr-wifi-manager.cc --- a/src/wifi/model/amrr-wifi-manager.cc +++ b/src/wifi/model/amrr-wifi-manager.cc @@ -336,7 +336,7 @@ } } - return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -346,7 +346,7 @@ AmrrWifiRemoteStation *station = (AmrrWifiRemoteStation *)st; UpdateMode (station); /// \todo can we implement something smarter ? - return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/aparf-wifi-manager.cc b/src/wifi/model/aparf-wifi-manager.cc --- a/src/wifi/model/aparf-wifi-manager.cc +++ b/src/wifi/model/aparf-wifi-manager.cc @@ -322,7 +322,7 @@ NS_LOG_FUNCTION (this << st << size); AparfWifiRemoteStation *station = (AparfWifiRemoteStation *) st; CheckInit (station); - return WifiTxVector (GetSupported (station, station->m_rate), station->m_power, GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, station->m_rate), station->m_power, GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -332,7 +332,7 @@ /// \todo we could/should implement the Arf algorithm for /// RTS only by picking a single rate within the BasicRateSet. AparfWifiRemoteStation *station = (AparfWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/arf-wifi-manager.cc b/src/wifi/model/arf-wifi-manager.cc --- a/src/wifi/model/arf-wifi-manager.cc +++ b/src/wifi/model/arf-wifi-manager.cc @@ -208,7 +208,7 @@ { NS_LOG_FUNCTION (this << st << size); ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -218,7 +218,7 @@ /// \todo we could/should implement the Arf algorithm for /// RTS only by picking a single rate within the BasicRateSet. ArfWifiRemoteStation *station = (ArfWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/cara-wifi-manager.cc b/src/wifi/model/cara-wifi-manager.cc --- a/src/wifi/model/cara-wifi-manager.cc +++ b/src/wifi/model/cara-wifi-manager.cc @@ -183,7 +183,7 @@ { NS_LOG_FUNCTION (this << st << size); CaraWifiRemoteStation *station = (CaraWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -192,7 +192,7 @@ NS_LOG_FUNCTION (this << st); /// \todo we could/should implement the Arf algorithm for /// RTS only by picking a single rate within the BasicRateSet. - return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetStbc (st)); + return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetAggregation (st), GetStbc (st)); } bool diff --git a/src/wifi/model/constant-rate-wifi-manager.cc b/src/wifi/model/constant-rate-wifi-manager.cc --- a/src/wifi/model/constant-rate-wifi-manager.cc +++ b/src/wifi/model/constant-rate-wifi-manager.cc @@ -117,14 +117,14 @@ ConstantRateWifiManager::DoGetDataTxVector (WifiRemoteStation *st, uint32_t size) { NS_LOG_FUNCTION (this << st << size); - return WifiTxVector (m_dataMode, GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetStbc (st)); + return WifiTxVector (m_dataMode, GetDefaultTxPowerLevel (), GetLongRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetAggregation (st), GetStbc (st)); } WifiTxVector ConstantRateWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) { NS_LOG_FUNCTION (this << st); - return WifiTxVector (m_ctlMode, GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetStbc (st)); + return WifiTxVector (m_ctlMode, GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetAggregation (st), GetStbc (st)); } bool diff --git a/src/wifi/model/ideal-wifi-manager.cc b/src/wifi/model/ideal-wifi-manager.cc --- a/src/wifi/model/ideal-wifi-manager.cc +++ b/src/wifi/model/ideal-wifi-manager.cc @@ -169,7 +169,7 @@ maxMode = mode; } } - return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -192,7 +192,7 @@ maxMode = mode; } } - return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (maxMode, GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/mac-low.cc b/src/wifi/model/mac-low.cc --- a/src/wifi/model/mac-low.cc +++ b/src/wifi/model/mac-low.cc @@ -366,7 +366,8 @@ m_listener (0), m_phyMacLowListener (0), m_ctsToSelfSupported (false), - m_receivedAtLeastOneMpdu (false) + m_receivedAtLeastOneMpdu (false), + m_mpduReferenceNumber (0) { NS_LOG_FUNCTION (this); m_lastNavDuration = Seconds (0); @@ -1556,7 +1557,7 @@ ", seq=0x" << std::hex << m_currentHdr.GetSequenceControl () << std::dec); if (!m_ampdu || hdr->IsRts ()) { - m_phy->SendPacket (packet, txVector, preamble, 0); + m_phy->SendPacket (packet, txVector, preamble, 0, 0); } else { @@ -1571,6 +1572,10 @@ AmpduTag ampdutag; ampdutag.SetAmpdu (true); Time delay = Seconds (0); + if (queueSize > 1) + { + txVector.SetAggregation (true); + } for (; queueSize > 0; queueSize--) { dequeuedPacket = m_aggregateQueue->Dequeue (&newHdr); @@ -1591,11 +1596,11 @@ { NS_LOG_DEBUG ("Sending MPDU as part of A-MPDU"); packetType = 1; - m_phy->SendPacket (newPacket, txVector, preamble, packetType); + m_phy->SendPacket (newPacket, txVector, preamble, packetType, m_mpduReferenceNumber); } else { - Simulator::Schedule (delay, &MacLow::SendPacket, this, newPacket, txVector, preamble, packetType); + Simulator::Schedule (delay, &MacLow::SendPacket, this, newPacket, txVector, preamble, packetType, m_mpduReferenceNumber); } if (queueSize > 1) { @@ -1603,14 +1608,15 @@ } preamble = WIFI_PREAMBLE_NONE; } + m_mpduReferenceNumber = ((m_mpduReferenceNumber + 1) % 4294967296); } } void -MacLow::SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType) +MacLow::SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType, uint32_t mpduReferenceNumber) { NS_LOG_DEBUG ("Sending MPDU as part of A-MPDU"); - m_phy->SendPacket (packet, txVector, preamble, packetType); + m_phy->SendPacket (packet, txVector, preamble, packetType, mpduReferenceNumber); } void diff --git a/src/wifi/model/mac-low.h b/src/wifi/model/mac-low.h --- a/src/wifi/model/mac-low.h +++ b/src/wifi/model/mac-low.h @@ -886,8 +886,10 @@ * \param hdr * \param txVector * \param preamble + * \param packetType + * \param mpduReferenceNumber */ - void SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType); + void SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType, uint32_t mpduReferenceNumber); /** * Return a TXVECTOR for the RTS frame given the destination. * The function consults WifiRemoteStationManager, which controls the rate @@ -1367,6 +1369,7 @@ WifiTxVector m_currentTxVector; //!< TXVECTOR used for the current packet transmission bool m_receivedAtLeastOneMpdu; //!< Flag whether an MPDU has already been successfully received while receiving an A-MPDU std::vector m_txPackets; //!< Contain temporary items to be sent with the next A-MPDU transmission, once RTS/CTS exchange has succeeded. It is not used in other cases. + uint32_t m_mpduReferenceNumber; //!< A-MPDU reference number to identify all subframes belonging to the same A-MPDU }; } //namespace ns3 diff --git a/src/wifi/model/minstrel-wifi-manager.cc b/src/wifi/model/minstrel-wifi-manager.cc --- a/src/wifi/model/minstrel-wifi-manager.cc +++ b/src/wifi/model/minstrel-wifi-manager.cc @@ -482,7 +482,7 @@ station->m_txrate = m_nsupported / 2; } UpdateStats (station); - return WifiTxVector (GetSupported (station, station->m_txrate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, station->m_txrate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -491,7 +491,7 @@ MinstrelWifiRemoteStation *station = (MinstrelWifiRemoteStation *) st; NS_LOG_DEBUG ("DoGetRtsMode m_txrate=" << station->m_txrate); - return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station),GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/onoe-wifi-manager.cc b/src/wifi/model/onoe-wifi-manager.cc --- a/src/wifi/model/onoe-wifi-manager.cc +++ b/src/wifi/model/onoe-wifi-manager.cc @@ -278,7 +278,7 @@ rateIndex = station->m_txrate; } } - return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, rateIndex), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -287,7 +287,7 @@ OnoeWifiRemoteStation *station = (OnoeWifiRemoteStation *)st; UpdateMode (station); /// \todo can we implement something smarter ? - return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/parf-wifi-manager.cc b/src/wifi/model/parf-wifi-manager.cc --- a/src/wifi/model/parf-wifi-manager.cc +++ b/src/wifi/model/parf-wifi-manager.cc @@ -294,7 +294,7 @@ NS_LOG_FUNCTION (this << st << size); ParfWifiRemoteStation *station = (ParfWifiRemoteStation *) st; CheckInit (station); - return WifiTxVector (GetSupported (station, station->m_currentRate), station->m_currentPower, GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, station->m_currentRate), station->m_currentPower, GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetAggregation (station), GetStbc (station)); } WifiTxVector @@ -304,7 +304,7 @@ /// \todo we could/should implement the Arf algorithm for /// RTS only by picking a single rate within the BasicRateSet. ParfWifiRemoteStation *station = (ParfWifiRemoteStation *) st; - return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNumberOfTransmitAntennas (station), GetAggregation (station), GetStbc (station)); } bool diff --git a/src/wifi/model/rraa-wifi-manager.cc b/src/wifi/model/rraa-wifi-manager.cc --- a/src/wifi/model/rraa-wifi-manager.cc +++ b/src/wifi/model/rraa-wifi-manager.cc @@ -290,13 +290,13 @@ { ResetCountersBasic (station); } - return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetStbc (station)); + return WifiTxVector (GetSupported (station, station->m_rate), GetDefaultTxPowerLevel (), GetLongRetryCount (station), GetShortGuardInterval (station), Min (GetNumberOfReceiveAntennas (station), GetNumberOfTransmitAntennas ()), GetNess (station), GetAggregation (station), GetStbc (station)); } WifiTxVector RraaWifiManager::DoGetRtsTxVector (WifiRemoteStation *st) { - return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetStbc (st)); + return WifiTxVector (GetSupported (st, 0), GetDefaultTxPowerLevel (), GetShortRetryCount (st), GetShortGuardInterval (st), Min (GetNumberOfReceiveAntennas (st), GetNumberOfTransmitAntennas ()), GetNess (st), GetAggregation (st), GetStbc (st)); } bool diff --git a/src/wifi/model/wifi-phy.cc b/src/wifi/model/wifi-phy.cc --- a/src/wifi/model/wifi-phy.cc +++ b/src/wifi/model/wifi-phy.cc @@ -592,15 +592,15 @@ } void -WifiPhy::NotifyMonitorSniffRx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, WifiTxVector txvector, double signalDbm, double noiseDbm) +WifiPhy::NotifyMonitorSniffRx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, WifiTxVector txvector, struct mpduInfo aMpdu, struct snrDbm snr) { - m_phyMonitorSniffRxTrace (packet, channelFreqMhz, channelNumber, rate, isShortPreamble, txvector, signalDbm, noiseDbm); + m_phyMonitorSniffRxTrace (packet, channelFreqMhz, channelNumber, rate, preamble, txvector, aMpdu, snr); } void -WifiPhy::NotifyMonitorSniffTx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, bool isShortPreamble, WifiTxVector txvector) +WifiPhy::NotifyMonitorSniffTx (Ptr packet, uint16_t channelFreqMhz, uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, WifiTxVector txvector, struct mpduInfo aMpdu) { - m_phyMonitorSniffTxTrace (packet, channelFreqMhz, channelNumber, rate, isShortPreamble, txvector); + m_phyMonitorSniffTxTrace (packet, channelFreqMhz, channelNumber, rate, preamble, txvector, aMpdu); } diff --git a/src/wifi/model/wifi-phy.h b/src/wifi/model/wifi-phy.h --- a/src/wifi/model/wifi-phy.h +++ b/src/wifi/model/wifi-phy.h @@ -38,6 +38,18 @@ class WifiChannel; class NetDevice; +struct snrDbm +{ + double signal; + double noise; +}; + +struct mpduInfo +{ + uint8_t packetType; + uint32_t referenceNumber; +}; + /** * \brief receive notifications about phy events. */ @@ -209,8 +221,9 @@ * power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels * \param preamble the type of preamble to use to send this packet. * \param packetType the type of the packet 0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU + * \param mpduReferenceNumber the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) */ - virtual void SendPacket (Ptr packet, WifiTxVector txvector, enum WifiPreamble preamble, uint8_t packetType) = 0; + virtual void SendPacket (Ptr packet, WifiTxVector txvector, enum WifiPreamble preamble, uint8_t packetType, uint32_t mpduReferenceNumber) = 0; /** * \param listener the new listener @@ -997,15 +1010,15 @@ * \param channelNumber the channel on which the packet is received * \param rate the PHY data rate in units of 500kbps (i.e., the same * units used both for the radiotap and for the prism header) - * \param isShortPreamble true if short preamble is used, false otherwise + * \param preamble the preamble of the packet * \param txVector the txvector that holds rx parameters - * \param signalDbm signal power in dBm - * \param noiseDbm noise power in dBm + * \param aMpdu the type of the packet (0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU) + * and the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) + * \param snr signal power and noise power in dBm */ void NotifyMonitorSniffRx (Ptr packet, uint16_t channelFreqMhz, - uint16_t channelNumber, uint32_t rate, - bool isShortPreamble, WifiTxVector txvector, - double signalDbm, double noiseDbm); + uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, + WifiTxVector txvector, struct mpduInfo aMpdu, struct snrDbm snr); /** * TracedCallback signature for monitor mode receive events. @@ -1022,15 +1035,15 @@ * \param channelNumber the channel on which the packet is received * \param rate the PHY data rate in units of 500kbps (i.e., the same * units used both for the radiotap and for the prism header) - * \param isShortPreamble true if short preamble is used, false otherwise + * \param preamble the preamble of the packet * \param txVector the txvector that holds rx parameters - * \param signalDbm signal power in dBm - * \param noiseDbm noise power in dBm + * \param aMpdu the type of the packet (0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU) + * and the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) + * \param snr signal power and noise power in dBm */ typedef void (* MonitorSnifferRxCallback)(Ptr packet, uint16_t channelFreqMhz, - uint16_t channelNumber, uint32_t rate, - bool isShortPreamble, WifiTxVector txvector, - double signalDbm, double noiseDbm); + uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, + WifiTxVector txvector, struct mpduInfo aMpdu, struct snrDbm snr); /** * Public method used to fire a MonitorSniffer trace for a wifi packet being transmitted. @@ -1042,12 +1055,14 @@ * \param channelNumber the channel on which the packet is transmitted * \param rate the PHY data rate in units of 500kbps (i.e., the same * units used both for the radiotap and for the prism header) - * \param isShortPreamble true if short preamble is used, false otherwise + * \param preamble the preamble of the packet * \param txVector the txvector that holds tx parameters + * \param aMpdu the type of the packet (0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU) + * and the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) */ void NotifyMonitorSniffTx (Ptr packet, uint16_t channelFreqMhz, - uint16_t channelNumber, uint32_t rate, - bool isShortPreamble, WifiTxVector txvector); + uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, + WifiTxVector txvector, struct mpduInfo aMpdu); /** * TracedCallback signature for monitor mode transmit events. @@ -1058,12 +1073,14 @@ * \param channelNumber the channel on which the packet is transmitted * \param rate the PHY data rate in units of 500kbps (i.e., the same * units used both for the radiotap and for the prism header) - * \param isShortPreamble true if short preamble is used, false otherwise + * \param preamble the preamble of the packet * \param txVector the txvector that holds tx parameters + * \param aMpdu the type of the packet (0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU) + * and the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) */ typedef void (* MonitorSnifferTxCallback)(const Ptr packet, uint16_t channelFreqMhz, - uint16_t channelNumber, uint32_t rate, - bool isShortPreamble, WifiTxVector txvector); + uint16_t channelNumber, uint32_t rate, WifiPreamble preamble, + WifiTxVector txvector, struct mpduInfo aMpdu); /** * Assign a fixed random variable stream number to the random variables @@ -1199,7 +1216,7 @@ * * \see class CallBackTraceSource */ - TracedCallback, uint16_t, uint16_t, uint32_t, bool, WifiTxVector, double, double> m_phyMonitorSniffRxTrace; + TracedCallback, uint16_t, uint16_t, uint32_t, WifiPreamble, WifiTxVector, struct mpduInfo, struct snrDbm> m_phyMonitorSniffRxTrace; /** * A trace source that emulates a wifi device in monitor mode @@ -1211,7 +1228,7 @@ * * \see class CallBackTraceSource */ - TracedCallback, uint16_t, uint16_t, uint32_t, bool, WifiTxVector> m_phyMonitorSniffTxTrace; + TracedCallback, uint16_t, uint16_t, uint32_t, WifiPreamble, WifiTxVector, struct mpduInfo> m_phyMonitorSniffTxTrace; uint32_t m_totalAmpduNumSymbols; //!< Number of symbols previously transmitted for the MPDUs in an A-MPDU, used for the computation of the number of symbols needed for the last MPDU in the A-MPDU uint32_t m_totalAmpduSize; //!< Total size of the previously transmitted MPDUs in an A-MPDU, used for the computation of the number of symbols needed for the last MPDU in the A-MPDU diff --git a/src/wifi/model/wifi-remote-station-manager.cc b/src/wifi/model/wifi-remote-station-manager.cc --- a/src/wifi/model/wifi-remote-station-manager.cc +++ b/src/wifi/model/wifi-remote-station-manager.cc @@ -661,6 +661,7 @@ m_wifiPhy->GetGuardInterval (), GetNumberOfTransmitAntennas (), GetNumberOfTransmitAntennas (), + false, false); } @@ -1271,6 +1272,7 @@ state->m_rx = 1; state->m_tx = 1; state->m_ness = 0; + state->m_aggregation = false; state->m_stbc = false; const_cast (this)->m_states.push_back (state); NS_LOG_DEBUG ("WifiRemoteStationManager::LookupState returning new state"); @@ -1488,6 +1490,12 @@ } bool +WifiRemoteStationManager::GetAggregation (const WifiRemoteStation *station) const +{ + return station->m_state->m_aggregation; +} + +bool WifiRemoteStationManager::GetStbc (const WifiRemoteStation *station) const { return station->m_state->m_stbc; diff --git a/src/wifi/model/wifi-remote-station-manager.h b/src/wifi/model/wifi-remote-station-manager.h --- a/src/wifi/model/wifi-remote-station-manager.h +++ b/src/wifi/model/wifi-remote-station-manager.h @@ -636,6 +636,15 @@ */ bool GetShortGuardInterval (const WifiRemoteStation *station) const; /** + * Return whether the given station supports A-MPDU. + * + * \param station the station being queried + * + * \return true if the station supports MPDU aggregation, + * false otherwise + */ + bool GetAggregation (const WifiRemoteStation *station) const; + /** * Return whether the given station supports space-time block coding (STBC). * * \param station the station being queried @@ -1049,6 +1058,7 @@ uint32_t m_tx; //!< Number of TX antennas of the remote station uint32_t m_ness; //!< Number of streams in beamforming of the remote station bool m_stbc; //!< Flag if STBC is used by the remote station + bool m_aggregation; //!< Flag if MPDU aggregation is used by the remote station bool m_greenfield; //!< Flag if green field is used by the remote station }; diff --git a/src/wifi/model/wifi-tx-vector.cc b/src/wifi/model/wifi-tx-vector.cc --- a/src/wifi/model/wifi-tx-vector.cc +++ b/src/wifi/model/wifi-tx-vector.cc @@ -29,6 +29,7 @@ m_shortGuardInterval (false), m_nss (1), m_ness (0), + m_aggregation (false), m_stbc (false), m_modeInitialized (false), m_txPowerLevelInitialized (false) @@ -36,13 +37,15 @@ } WifiTxVector::WifiTxVector (WifiMode mode, uint8_t powerLevel, uint8_t retries, - bool shortGuardInterval, uint8_t nss, uint8_t ness, bool stbc) + bool shortGuardInterval, uint8_t nss, uint8_t ness, + bool aggregation, bool stbc) : m_mode (mode), m_txPowerLevel (powerLevel), m_retries (retries), m_shortGuardInterval (shortGuardInterval), m_nss (nss), m_ness (ness), + m_aggregation (aggregation), m_stbc (stbc), m_modeInitialized (true), m_txPowerLevelInitialized (true) @@ -94,6 +97,12 @@ } bool +WifiTxVector::IsAggregation (void) const +{ + return m_aggregation; +} + +bool WifiTxVector::IsStbc (void) const { return m_stbc; @@ -138,6 +147,12 @@ } void +WifiTxVector::SetAggregation (bool aggregation) +{ + m_aggregation = aggregation; +} + +void WifiTxVector::SetStbc (bool stbc) { m_stbc = stbc; @@ -151,6 +166,7 @@ " Short GI: " << v.IsShortGuardInterval () << " Nss: " << (uint32_t)v.GetNss () << " Ness: " << (uint32_t)v.GetNess () << + " MPDU aggregation" << v.IsAggregation () << " STBC: " << v.IsStbc (); return os; } diff --git a/src/wifi/model/wifi-tx-vector.h b/src/wifi/model/wifi-tx-vector.h --- a/src/wifi/model/wifi-tx-vector.h +++ b/src/wifi/model/wifi-tx-vector.h @@ -73,7 +73,14 @@ * \param ness the number of extension spatial streams (NESS) * \param stbc enable or disable STBC */ - WifiTxVector (WifiMode mode, uint8_t powerLevel, uint8_t retries, bool shortGuardInterval, uint8_t nss, uint8_t ness, bool stbc); + WifiTxVector (WifiMode mode, + uint8_t powerLevel, + uint8_t retries, + bool shortGuardInterval, + uint8_t nss, + uint8_t ness, + bool aggregation, + bool stbc); /** * \returns the txvector payload mode */ @@ -135,6 +142,18 @@ */ void SetNess (uint8_t ness); /** + * Checks whether the PSDU contains A-MPDU. + * \returns true if this PSDU has A-MPDU aggregation, + * false otherwise. + */ + bool IsAggregation (void) const; + /** + * Sets if PSDU contains A-MPDU. + * + * \param aggregated whether the PSDU contains A-MPDU or not. + */ + void SetAggregation(bool aggregation); + /** * Check if STBC is used or not * * \returns true if STBC is used, @@ -162,6 +181,7 @@ bool m_shortGuardInterval; /**< true if short GI is going to be used */ uint8_t m_nss; /**< number of streams */ uint8_t m_ness; /**< number of streams in beamforming */ + bool m_aggregation; /** Flag whether the PSDU contains A-MPDU. */ bool m_stbc; /**< STBC used or not */ bool m_modeInitialized; //*< Internal initialization flag */ diff --git a/src/wifi/model/yans-wifi-channel.cc b/src/wifi/model/yans-wifi-channel.cc --- a/src/wifi/model/yans-wifi-channel.cc +++ b/src/wifi/model/yans-wifi-channel.cc @@ -27,7 +27,6 @@ #include "ns3/pointer.h" #include "ns3/object-factory.h" #include "yans-wifi-channel.h" -#include "yans-wifi-phy.h" #include "ns3/propagation-loss-model.h" #include "ns3/propagation-delay-model.h" @@ -80,7 +79,7 @@ void YansWifiChannel::Send (Ptr sender, Ptr packet, double txPowerDbm, - WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType, Time duration) const + WifiTxVector txVector, WifiPreamble preamble, struct mpduInfo aMpdu, Time duration) const { Ptr senderMobility = sender->GetMobility ()->GetObject (); NS_ASSERT (senderMobility != 0); @@ -112,24 +111,24 @@ dstNode = dstNetDevice->GetObject ()->GetNode ()->GetId (); } - double *atts = new double[3]; - *atts = rxPowerDbm; - *(atts + 1) = packetType; - *(atts + 2) = duration.GetNanoSeconds (); + struct Parameters parameters; + parameters.rxPowerDbm = rxPowerDbm; + parameters.aMpdu = aMpdu; + parameters.duration = duration; + parameters.txVector = txVector; + parameters.preamble = preamble; Simulator::ScheduleWithContext (dstNode, delay, &YansWifiChannel::Receive, this, - j, copy, atts, txVector, preamble); + j, copy, parameters); } } } void -YansWifiChannel::Receive (uint32_t i, Ptr packet, double *atts, - WifiTxVector txVector, WifiPreamble preamble) const +YansWifiChannel::Receive (uint32_t i, Ptr packet, struct Parameters parameters) const { - m_phyList[i]->StartReceivePreambleAndHeader (packet, *atts, txVector, preamble, *(atts + 1), NanoSeconds (*(atts + 2))); - delete[] atts; + m_phyList[i]->StartReceivePreambleAndHeader (packet, parameters.rxPowerDbm, parameters.txVector, parameters.preamble, parameters.aMpdu, parameters.duration); } uint32_t diff --git a/src/wifi/model/yans-wifi-channel.h b/src/wifi/model/yans-wifi-channel.h --- a/src/wifi/model/yans-wifi-channel.h +++ b/src/wifi/model/yans-wifi-channel.h @@ -28,6 +28,7 @@ #include "wifi-mode.h" #include "wifi-preamble.h" #include "wifi-tx-vector.h" +#include "yans-wifi-phy.h" #include "ns3/nstime.h" namespace ns3 { @@ -35,7 +36,15 @@ class NetDevice; class PropagationLossModel; class PropagationDelayModel; -class YansWifiPhy; + +struct Parameters +{ + double rxPowerDbm; + struct mpduInfo aMpdu; + Time duration; + WifiTxVector txVector; + WifiPreamble preamble; +}; /** * \brief A Yans wifi channel @@ -83,7 +92,8 @@ * \param txPowerDbm the tx power associated to the packet * \param txVector the TXVECTOR associated to the packet * \param preamble the preamble associated to the packet - * \param packetType the type of packet, used for A-MPDU to say whether it's the last MPDU or not + * \param aMpdu the type of the packet (0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU) + * and the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) * \param duration the transmission duration associated to the packet * * This method should not be invoked by normal users. It is @@ -92,7 +102,7 @@ * e.g. PHYs that are operating on the same channel. */ void Send (Ptr sender, Ptr packet, double txPowerDbm, - WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType, Time duration) const; + WifiTxVector txVector, WifiPreamble preamble, struct mpduInfo aMpdu, Time duration) const; /** * Assign a fixed random variable stream number to the random variables @@ -111,6 +121,7 @@ * A vector of pointers to YansWifiPhy. */ typedef std::vector > PhyList; + /** * This method is scheduled by Send for each associated YansWifiPhy. * The method then calls the corresponding YansWifiPhy that the first @@ -122,9 +133,7 @@ * \param txVector the TXVECTOR of the packet * \param preamble the type of preamble being used to send the packet */ - void Receive (uint32_t i, Ptr packet, double *atts, - WifiTxVector txVector, WifiPreamble preamble) const; - + void Receive (uint32_t i, Ptr packet, struct Parameters parameters) const; PhyList m_phyList; //!< List of YansWifiPhys connected to this YansWifiChannel Ptr m_loss; //!< Propagation loss model diff --git a/src/wifi/model/yans-wifi-phy.cc b/src/wifi/model/yans-wifi-phy.cc --- a/src/wifi/model/yans-wifi-phy.cc +++ b/src/wifi/model/yans-wifi-phy.cc @@ -562,11 +562,11 @@ double rxPowerDbm, WifiTxVector txVector, enum WifiPreamble preamble, - uint8_t packetType, Time rxDuration) + struct mpduInfo aMpdu, Time rxDuration) { //This function should be later split to check separately wether plcp preamble and plcp header can be successfully received. //Note: plcp preamble reception is not yet modeled. - NS_LOG_FUNCTION (this << packet << rxPowerDbm << txVector.GetMode () << preamble << (uint32_t)packetType); + NS_LOG_FUNCTION (this << packet << rxPowerDbm << txVector.GetMode () << preamble << (uint32_t)aMpdu.packetType); AmpduTag ampduTag; rxPowerDbm += m_rxGainDb; double rxPowerW = DbmToW (rxPowerDbm); @@ -674,12 +674,12 @@ { NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); m_endPlcpRxEvent = Simulator::Schedule (preambleAndHeaderDuration, &YansWifiPhy::StartReceivePacket, this, - packet, txVector, preamble, packetType, event); + packet, txVector, preamble, aMpdu, event); } NS_ASSERT (m_endRxEvent.IsExpired ()); m_endRxEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndReceive, this, - packet, preamble, packetType, event); + packet, preamble, aMpdu, event); } else { @@ -716,10 +716,10 @@ YansWifiPhy::StartReceivePacket (Ptr packet, WifiTxVector txVector, enum WifiPreamble preamble, - uint8_t packetType, + struct mpduInfo aMpdu, Ptr event) { - NS_LOG_FUNCTION (this << packet << txVector.GetMode () << preamble << (uint32_t)packetType); + NS_LOG_FUNCTION (this << packet << txVector.GetMode () << preamble << (uint32_t)aMpdu.packetType); NS_ASSERT (IsStateRx ()); NS_ASSERT (m_endPlcpRxEvent.IsExpired ()); AmpduTag ampduTag; @@ -753,7 +753,7 @@ } void -YansWifiPhy::SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType) +YansWifiPhy::SendPacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, uint8_t packetType, uint32_t mpduReferenceNumber) { NS_LOG_FUNCTION (this << packet << txVector.GetMode () << preamble << (uint32_t)txVector.GetTxPowerLevel () << (uint32_t)packetType); /* Transmission can happen if: @@ -788,10 +788,12 @@ { dataRate500KbpsUnits = txVector.GetMode ().GetDataRate () * txVector.GetNss () / 500000; } - bool isShortPreamble = (WIFI_PREAMBLE_SHORT == preamble); - NotifyMonitorSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, txVector); + struct mpduInfo aMpdu; + aMpdu.packetType = packetType; + aMpdu.referenceNumber = mpduReferenceNumber; + NotifyMonitorSniffTx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, preamble, txVector, aMpdu); m_state->SwitchToTx (txDuration, packet, GetPowerDbm (txVector.GetTxPowerLevel ()), txVector, preamble); - m_channel->Send (this, packet, GetPowerDbm (txVector.GetTxPowerLevel ()) + m_txGainDb, txVector, preamble, packetType, txDuration); + m_channel->Send (this, packet, GetPowerDbm (txVector.GetTxPowerLevel ()) + m_txGainDb, txVector, preamble, aMpdu, txDuration); } uint32_t @@ -1079,7 +1081,7 @@ } void -YansWifiPhy::EndReceive (Ptr packet, enum WifiPreamble preamble, uint8_t packetType, Ptr event) +YansWifiPhy::EndReceive (Ptr packet, enum WifiPreamble preamble, struct mpduInfo aMpdu, Ptr event) { NS_LOG_FUNCTION (this << packet << event); NS_ASSERT (IsStateRx ()); @@ -1106,10 +1108,10 @@ { dataRate500KbpsUnits = event->GetPayloadMode ().GetDataRate () * event->GetTxVector ().GetNss () / 500000; } - bool isShortPreamble = (WIFI_PREAMBLE_SHORT == event->GetPreambleType ()); - double signalDbm = RatioToDb (event->GetRxPowerW ()) + 30; - double noiseDbm = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30; - NotifyMonitorSniffRx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, isShortPreamble, event->GetTxVector (), signalDbm, noiseDbm); + struct snrDbm snr; + snr.signal = RatioToDb (event->GetRxPowerW ()) + 30; + snr.noise = RatioToDb (event->GetRxPowerW () / snrPer.snr) - GetRxNoiseFigure () + 30; + NotifyMonitorSniffRx (packet, (uint16_t)GetChannelFrequencyMhz (), GetChannelNumber (), dataRate500KbpsUnits, event->GetPreambleType (), event->GetTxVector (), aMpdu, snr); m_state->SwitchFromRxEndOk (packet, snrPer.snr, event->GetTxVector (), event->GetPreambleType ()); } else @@ -1125,7 +1127,7 @@ m_state->SwitchFromRxEndError (packet, snrPer.snr); } - if (preamble == WIFI_PREAMBLE_NONE && packetType == 2) + if (preamble == WIFI_PREAMBLE_NONE && aMpdu.packetType == 2) { m_plcpSuccess = false; } diff --git a/src/wifi/model/yans-wifi-phy.h b/src/wifi/model/yans-wifi-phy.h --- a/src/wifi/model/yans-wifi-phy.h +++ b/src/wifi/model/yans-wifi-phy.h @@ -105,14 +105,15 @@ * \param rxPowerDbm the receive power in dBm * \param txVector the TXVECTOR of the arriving packet * \param preamble the preamble of the arriving packet - * \param packetType The type of the received packet (values: 0 not an A-MPDU, 1 corresponds to any packets in an A-MPDU except the last one, 2 is the last packet in an A-MPDU) + * \param aMpdu the type of the packet (0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU) + * and the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) * \param rxDuration the duration needed for the reception of the packet */ void StartReceivePreambleAndHeader (Ptr packet, double rxPowerDbm, WifiTxVector txVector, WifiPreamble preamble, - uint8_t packetType, + struct mpduInfo aMpdu, Time rxDuration); /** * Starting receiving the payload of a packet (i.e. the first bit of the packet has arrived). @@ -120,13 +121,14 @@ * \param packet the arriving packet * \param txVector the TXVECTOR of the arriving packet * \param preamble the preamble of the arriving packet - * \param packetType The type of the received packet (values: 0 not an A-MPDU, 1 corresponds to any packets in an A-MPDU except the last one, 2 is the last packet in an A-MPDU) + * \param aMpdu the type of the packet (0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU) + * and the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) * \param event the corresponding event of the first time the packet arrives */ void StartReceivePacket (Ptr packet, WifiTxVector txVector, WifiPreamble preamble, - uint8_t packetType, + struct mpduInfo aMpdu, Ptr event); /** @@ -277,7 +279,7 @@ virtual void SetReceiveOkCallback (WifiPhy::RxOkCallback callback); virtual void SetReceiveErrorCallback (WifiPhy::RxErrorCallback callback); - virtual void SendPacket (Ptr packet, WifiTxVector txvector, enum WifiPreamble preamble, uint8_t packetType); + virtual void SendPacket (Ptr packet, WifiTxVector txvector, enum WifiPreamble preamble, uint8_t packetType, uint32_t mpduReferenceNumber); virtual void RegisterListener (WifiPhyListener *listener); virtual void UnregisterListener (WifiPhyListener *listener); virtual void SetSleepMode (void); @@ -496,10 +498,11 @@ * * \param packet the packet that the last bit has arrived * \param preamble the preamble of the arriving packet - * \param packetType The type of the received packet (values: 0 not an A-MPDU, 1 corresponds to any packets in an A-MPDU except the last one, 2 is the last packet in an A-MPDU) + * \param aMpdu the type of the packet (0 is not A-MPDU, 1 is a MPDU that is part of an A-MPDU and 2 is the last MPDU in an A-MPDU) + * and the A-MPDU reference number (must be a different value for each A-MPDU but the same for each subframe within one A-MPDU) * \param event the corresponding event of the first time the packet arrives */ - void EndReceive (Ptr packet, enum WifiPreamble preamble, uint8_t packetType, Ptr event); + void EndReceive (Ptr packet, enum WifiPreamble preamble, struct mpduInfo aMpdu, Ptr event); bool m_initialized; //!< Flag for runtime initialization double m_edThresholdW; //!< Energy detection threshold in watts