diff --git a/src/network/utils/radiotap-header.cc b/src/network/utils/radiotap-header.cc index 0cd2597f2..78aec2ae0 100644 --- a/src/network/utils/radiotap-header.cc +++ b/src/network/utils/radiotap-header.cc @@ -56,13 +56,13 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const { NS_LOG_FUNCTION(this << &start); - start.WriteU8(0); // major version of radiotap header - start.WriteU8(0); // pad field - start.WriteU16(m_length); // entire length of radiotap data + header - start.WriteU32(m_present); // bits describing which fields follow header - if (m_presentExt) + start.WriteU8(0); // major version of radiotap header + start.WriteU8(0); // pad field + start.WriteU16(m_length); // entire length of radiotap data + header + NS_ASSERT(!m_present.empty()); + for (const auto present : m_present) { - start.WriteU32(*m_presentExt); // extended bitmasks + start.WriteU32(present); // bits describing which fields follow header } // @@ -70,7 +70,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // arrived at the MAC) // Reference: https://www.radiotap.org/fields/TSFT.html // - if (m_present & RADIOTAP_TSFT) // bit 0 + if (m_present.at(0) & RADIOTAP_TSFT) // bit 0 { SerializeTsft(start); } @@ -79,7 +79,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // Properties of transmitted and received frames. // Reference: https://www.radiotap.org/fields/Flags.html // - if (m_present & RADIOTAP_FLAGS) // bit 1 + if (m_present.at(0) & RADIOTAP_FLAGS) // bit 1 { start.WriteU8(m_flags); } @@ -88,7 +88,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // TX/RX data rate in units of 500 kbps // Reference: https://www.radiotap.org/fields/Rate.html // - if (m_present & RADIOTAP_RATE) // bit 2 + if (m_present.at(0) & RADIOTAP_RATE) // bit 2 { start.WriteU8(m_rate); } @@ -97,7 +97,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // Tx/Rx frequency in MHz, followed by flags. // Reference: https://www.radiotap.org/fields/Channel.html // - if (m_present & RADIOTAP_CHANNEL) // bit 3 + if (m_present.at(0) & RADIOTAP_CHANNEL) // bit 3 { SerializeChannel(start); } @@ -107,7 +107,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // still need to account for it. // Reference: https://www.radiotap.org/fields/FHSS.html // - if (m_present & RADIOTAP_FHSS) // bit 4 + if (m_present.at(0) & RADIOTAP_FHSS) // bit 4 { NS_ASSERT(false); // not yet implemented } @@ -117,7 +117,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // reference. // Reference: https://www.radiotap.org/fields/Antenna%20signal.html // - if (m_present & RADIOTAP_DBM_ANTSIGNAL) // bit 5 + if (m_present.at(0) & RADIOTAP_DBM_ANTSIGNAL) // bit 5 { start.WriteU8(m_antennaSignal); } @@ -127,7 +127,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // reference. // Reference: https://www.radiotap.org/fields/Antenna%20noise.html // - if (m_present & RADIOTAP_DBM_ANTNOISE) // bit 6 + if (m_present.at(0) & RADIOTAP_DBM_ANTNOISE) // bit 6 { start.WriteU8(m_antennaNoise); } @@ -136,7 +136,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // Quality of Barker code lock. // Reference: https://www.radiotap.org/fields/Lock%20quality.html // - if (m_present & RADIOTAP_LOCK_QUALITY) // bit 7 + if (m_present.at(0) & RADIOTAP_LOCK_QUALITY) // bit 7 { NS_ASSERT(false); // not yet implemented } @@ -146,7 +146,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // set at factory calibration (0 is max power). // Reference: https://www.radiotap.org/fields/TX%20attenuation.html // - if (m_present & RADIOTAP_TX_ATTENUATION) // bit 8 + if (m_present.at(0) & RADIOTAP_TX_ATTENUATION) // bit 8 { NS_ASSERT(false); // not yet implemented } @@ -156,7 +156,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // set at factory calibration (0 is max power). // Reference: https://www.radiotap.org/fields/dB%20TX%20attenuation.html // - if (m_present & RADIOTAP_DB_TX_ATTENUATION) // bit 9 + if (m_present.at(0) & RADIOTAP_DB_TX_ATTENUATION) // bit 9 { NS_ASSERT(false); // not yet implemented } @@ -166,7 +166,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // This is the absolute power level measured at the antenna port. // Reference: https://www.radiotap.org/fields/dBm%20TX%20power.html // - if (m_present & RADIOTAP_DBM_TX_POWER) // bit 10 + if (m_present.at(0) & RADIOTAP_DBM_TX_POWER) // bit 10 { NS_ASSERT(false); // not yet implemented } @@ -176,7 +176,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // The first antenna is antenna 0. // Reference: https://www.radiotap.org/fields/Antenna.html // - if (m_present & RADIOTAP_ANTENNA) // bit 11 + if (m_present.at(0) & RADIOTAP_ANTENNA) // bit 11 { NS_ASSERT(false); // not yet implemented } @@ -185,7 +185,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // RF signal power at the antenna (decibel difference from an arbitrary fixed reference). // Reference: https://www.radiotap.org/fields/dB%20antenna%20signal.html // - if (m_present & RADIOTAP_DB_ANTSIGNAL) // bit 12 + if (m_present.at(0) & RADIOTAP_DB_ANTSIGNAL) // bit 12 { NS_ASSERT(false); // not yet implemented } @@ -194,7 +194,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // RF noise power at the antenna (decibel difference from an arbitrary fixed reference). // Reference: https://www.radiotap.org/fields/dB%20antenna%20noise.html // - if (m_present & RADIOTAP_DB_ANTNOISE) // bit 13 + if (m_present.at(0) & RADIOTAP_DB_ANTNOISE) // bit 13 { NS_ASSERT(false); // not yet implemented } @@ -203,7 +203,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // Properties of received frames. // Reference: https://www.radiotap.org/fields/RX%20flags.html // - if (m_present & RADIOTAP_RX_FLAGS) // bit 14 + if (m_present.at(0) & RADIOTAP_RX_FLAGS) // bit 14 { NS_ASSERT(false); // not yet implemented } @@ -212,7 +212,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // MCS field. // Reference: https://www.radiotap.org/fields/MCS.html // - if (m_present & RADIOTAP_MCS) // bit 19 + if (m_present.at(0) & RADIOTAP_MCS) // bit 19 { SerializeMcs(start); } @@ -221,7 +221,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // A-MPDU Status, information about the received or transmitted A-MPDU. // Reference: https://www.radiotap.org/fields/A-MPDU%20status.html // - if (m_present & RADIOTAP_AMPDU_STATUS) // bit 20 + if (m_present.at(0) & RADIOTAP_AMPDU_STATUS) // bit 20 { SerializeAmpduStatus(start); } @@ -230,7 +230,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // Information about the received or transmitted VHT frame. // Reference: https://www.radiotap.org/fields/VHT.html // - if (m_present & RADIOTAP_VHT) // bit 21 + if (m_present.at(0) & RADIOTAP_VHT) // bit 21 { SerializeVht(start); } @@ -239,7 +239,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // HE field. // Reference: https://www.radiotap.org/fields/HE.html // - if (m_present & RADIOTAP_HE) // bit 23 + if (m_present.at(0) & RADIOTAP_HE) // bit 23 { SerializeHe(start); } @@ -248,7 +248,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // HE MU field. // Reference: https://www.radiotap.org/fields/HE-MU.html // - if (m_present & RADIOTAP_HE_MU) // bit 24 + if (m_present.at(0) & RADIOTAP_HE_MU) // bit 24 { SerializeHeMu(start); } @@ -257,7 +257,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // HE MU other user field. // Reference: https://www.radiotap.org/fields/HE-MU-other-user.html // - if (m_present & RADIOTAP_HE_MU_OTHER_USER) // bit 25 + if (m_present.at(0) & RADIOTAP_HE_MU_OTHER_USER) // bit 25 { SerializeHeMuOtherUser(start); } @@ -266,7 +266,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // U-SIG field. // Reference: https://www.radiotap.org/fields/U-SIG.html // - if (m_presentExt && (*m_presentExt & RADIOTAP_USIG)) // bit 33 + if ((m_present.size() > 1) && m_present.at(1) & RADIOTAP_USIG) // bit 33 { SerializeUsig(start); } @@ -275,7 +275,7 @@ RadiotapHeader::Serialize(Buffer::Iterator start) const // EHT field. // Reference: https://www.radiotap.org/fields/EHT.html // - if (m_presentExt && (*m_presentExt & RADIOTAP_EHT_SIG)) // bit 34 + if ((m_present.size() > 1) && m_present.at(1) & RADIOTAP_EHT_SIG) // bit 34 { SerializeEht(start); } @@ -290,14 +290,15 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) NS_ASSERT_MSG(tmp == 0x00, "RadiotapHeader::Deserialize(): Unexpected major version"); start.ReadU8(); // pad field - m_length = start.ReadU16(); // entire length of radiotap data + header - m_present = start.ReadU32(); // bits describing which fields follow header - uint32_t bytesRead = 8; + m_length = start.ReadU16(); // entire length of radiotap data + header + m_present.emplace_back(start.ReadU32()); // bits describing which fields follow header + uint32_t bytesRead = MIN_HEADER_SIZE; - if (m_present & RADIOTAP_EXT) + std::size_t index{0}; + while (m_present.at(index++) & RADIOTAP_EXT) { - // If bit 31 of the it_present field is set, an extended it_present bitmask is present. - m_presentExt = start.ReadU32(); + // If bit 31 of the it_present field is set, another it_present bitmask is present. + m_present.emplace_back(start.ReadU32()); bytesRead += 4; } @@ -305,7 +306,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // Time Synchronization Function Timer (when the first bit of the MPDU arrived at the MAC) // Reference: https://www.radiotap.org/fields/TSFT.html // - if (m_present & RADIOTAP_TSFT) // bit 0 + if (m_present.at(0) & RADIOTAP_TSFT) // bit 0 { bytesRead += DeserializeTsft(start, bytesRead); } @@ -314,7 +315,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // Properties of transmitted and received frames. // Reference: https://www.radiotap.org/fields/Flags.html // - if (m_present & RADIOTAP_FLAGS) // bit 1 + if (m_present.at(0) & RADIOTAP_FLAGS) // bit 1 { m_flags = start.ReadU8(); ++bytesRead; @@ -324,7 +325,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // TX/RX data rate in units of 500 kbps // Reference: https://www.radiotap.org/fields/Rate.html // - if (m_present & RADIOTAP_RATE) // bit 2 + if (m_present.at(0) & RADIOTAP_RATE) // bit 2 { m_rate = start.ReadU8(); ++bytesRead; @@ -334,7 +335,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // Tx/Rx frequency in MHz, followed by flags. // Reference: https://www.radiotap.org/fields/Channel.html // - if (m_present & RADIOTAP_CHANNEL) // bit 3 + if (m_present.at(0) & RADIOTAP_CHANNEL) // bit 3 { bytesRead += DeserializeChannel(start, bytesRead); } @@ -344,7 +345,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // still need to account for it. // Reference: https://www.radiotap.org/fields/FHSS.html // - if (m_present & RADIOTAP_FHSS) // bit 4 + if (m_present.at(0) & RADIOTAP_FHSS) // bit 4 { NS_ASSERT(false); // not yet implemented } @@ -354,7 +355,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // reference. // Reference: https://www.radiotap.org/fields/Antenna%20signal.html // - if (m_present & RADIOTAP_DBM_ANTSIGNAL) // bit 5 + if (m_present.at(0) & RADIOTAP_DBM_ANTSIGNAL) // bit 5 { m_antennaSignal = start.ReadU8(); ++bytesRead; @@ -365,7 +366,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // reference. // Reference: https://www.radiotap.org/fields/Antenna%20noise.html // - if (m_present & RADIOTAP_DBM_ANTNOISE) // bit 6 + if (m_present.at(0) & RADIOTAP_DBM_ANTNOISE) // bit 6 { m_antennaNoise = start.ReadU8(); ++bytesRead; @@ -375,7 +376,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // Quality of Barker code lock. // Reference: https://www.radiotap.org/fields/Lock%20quality.html // - if (m_present & RADIOTAP_LOCK_QUALITY) // bit 7 + if (m_present.at(0) & RADIOTAP_LOCK_QUALITY) // bit 7 { NS_ASSERT(false); // not yet implemented } @@ -385,7 +386,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // set at factory calibration (0 is max power). // Reference: https://www.radiotap.org/fields/TX%20attenuation.html // - if (m_present & RADIOTAP_TX_ATTENUATION) // bit 8 + if (m_present.at(0) & RADIOTAP_TX_ATTENUATION) // bit 8 { NS_ASSERT(false); // not yet implemented } @@ -395,7 +396,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // set at factory calibration (0 is max power). // Reference: https://www.radiotap.org/fields/dB%20TX%20attenuation.html // - if (m_present & RADIOTAP_DB_TX_ATTENUATION) // bit 9 + if (m_present.at(0) & RADIOTAP_DB_TX_ATTENUATION) // bit 9 { NS_ASSERT(false); // not yet implemented } @@ -405,7 +406,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // This is the absolute power level measured at the antenna port. // Reference: https://www.radiotap.org/fields/dBm%20TX%20power.html // - if (m_present & RADIOTAP_DBM_TX_POWER) // bit 10 + if (m_present.at(0) & RADIOTAP_DBM_TX_POWER) // bit 10 { NS_ASSERT(false); // not yet implemented } @@ -415,7 +416,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // The first antenna is antenna 0. // Reference: https://www.radiotap.org/fields/Antenna.html // - if (m_present & RADIOTAP_ANTENNA) // bit 11 + if (m_present.at(0) & RADIOTAP_ANTENNA) // bit 11 { NS_ASSERT(false); // not yet implemented } @@ -424,7 +425,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // RF signal power at the antenna (decibel difference from an arbitrary fixed reference). // Reference: https://www.radiotap.org/fields/dB%20antenna%20signal.html // - if (m_present & RADIOTAP_DB_ANTSIGNAL) // bit 12 + if (m_present.at(0) & RADIOTAP_DB_ANTSIGNAL) // bit 12 { NS_ASSERT(false); // not yet implemented } @@ -433,7 +434,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // RF noise power at the antenna (decibel difference from an arbitrary fixed reference). // Reference: https://www.radiotap.org/fields/dB%20antenna%20noise.html // - if (m_present & RADIOTAP_DB_ANTNOISE) // bit 13 + if (m_present.at(0) & RADIOTAP_DB_ANTNOISE) // bit 13 { NS_ASSERT(false); // not yet implemented } @@ -442,7 +443,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // Properties of received frames. // Reference: https://www.radiotap.org/fields/RX%20flags.html // - if (m_present & RADIOTAP_RX_FLAGS) // bit 14 + if (m_present.at(0) & RADIOTAP_RX_FLAGS) // bit 14 { NS_ASSERT(false); // not yet implemented } @@ -451,7 +452,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // MCS field. // Reference: https://www.radiotap.org/fields/MCS.html // - if (m_present & RADIOTAP_MCS) // bit 19 + if (m_present.at(0) & RADIOTAP_MCS) // bit 19 { bytesRead += DeserializeMcs(start, bytesRead); } @@ -460,7 +461,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // A-MPDU Status, information about the received or transmitted A-MPDU. // Reference: https://www.radiotap.org/fields/A-MPDU%20status.html // - if (m_present & RADIOTAP_AMPDU_STATUS) + if (m_present.at(0) & RADIOTAP_AMPDU_STATUS) { bytesRead += DeserializeAmpduStatus(start, bytesRead); } @@ -469,7 +470,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // Information about the received or transmitted VHT frame. // Reference: https://www.radiotap.org/fields/VHT.html // - if (m_present & RADIOTAP_VHT) // bit 21 + if (m_present.at(0) & RADIOTAP_VHT) // bit 21 { bytesRead += DeserializeVht(start, bytesRead); } @@ -478,7 +479,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // HE field. // Reference: https://www.radiotap.org/fields/HE.html // - if (m_present & RADIOTAP_HE) // bit 23 + if (m_present.at(0) & RADIOTAP_HE) // bit 23 { bytesRead += DeserializeHe(start, bytesRead); } @@ -487,7 +488,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // HE MU field. // Reference: https://www.radiotap.org/fields/HE-MU.html // - if (m_present & RADIOTAP_HE_MU) // bit 24 + if (m_present.at(0) & RADIOTAP_HE_MU) // bit 24 { bytesRead += DeserializeHeMu(start, bytesRead); } @@ -496,7 +497,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // HE MU other user field. // Reference: https://www.radiotap.org/fields/HE-MU-other-user.html // - if (m_present & RADIOTAP_HE_MU_OTHER_USER) // bit 25 + if (m_present.at(0) & RADIOTAP_HE_MU_OTHER_USER) // bit 25 { bytesRead += DeserializeHeMuOtherUser(start, bytesRead); } @@ -505,7 +506,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // U-SIG field. // Reference: https://www.radiotap.org/fields/U-SIG.html // - if (m_presentExt && (*m_presentExt & RADIOTAP_USIG)) // bit 33 + if ((m_present.size() > 1) && m_present.at(1) & RADIOTAP_USIG) // bit 33 { bytesRead += DeserializeUsig(start, bytesRead); } @@ -514,7 +515,7 @@ RadiotapHeader::Deserialize(Buffer::Iterator start) // EHT field. // Reference: https://www.radiotap.org/fields/EHT.html // - if (m_presentExt && (*m_presentExt & RADIOTAP_EHT_SIG)) // bit 34 + if ((m_present.size() > 1) && m_present.at(1) & RADIOTAP_EHT_SIG) // bit 34 { bytesRead += DeserializeEht(start, bytesRead); } @@ -529,55 +530,58 @@ RadiotapHeader::Print(std::ostream& os) const { NS_LOG_FUNCTION(this << &os); os << " tsft=" << m_tsft << " flags=" << std::hex << m_flags << std::dec << " rate=" << +m_rate; - if (m_present & RADIOTAP_CHANNEL) + if (m_present.at(0) & RADIOTAP_CHANNEL) { PrintChannel(os); } os << std::dec << " signal=" << +m_antennaSignal << " noise=" << +m_antennaNoise; - if (m_present & RADIOTAP_MCS) + if (m_present.at(0) & RADIOTAP_MCS) { PrintMcs(os); } - if (m_present & RADIOTAP_AMPDU_STATUS) + if (m_present.at(0) & RADIOTAP_AMPDU_STATUS) { PrintAmpduStatus(os); } - if (m_present & RADIOTAP_VHT) + if (m_present.at(0) & RADIOTAP_VHT) { PrintVht(os); } - if (m_present & RADIOTAP_HE) + if (m_present.at(0) & RADIOTAP_HE) { PrintHe(os); } - if (m_present & RADIOTAP_HE_MU) + if (m_present.at(0) & RADIOTAP_HE_MU) { PrintHeMu(os); } - if (m_present & RADIOTAP_HE_MU_OTHER_USER) + if (m_present.at(0) & RADIOTAP_HE_MU_OTHER_USER) { PrintHeMuOtherUser(os); } - if (m_presentExt && (*m_presentExt & RADIOTAP_USIG)) + if ((m_present.size() > 1) && m_present.at(1) & RADIOTAP_USIG) { PrintUsig(os); } - if (m_presentExt && (*m_presentExt & RADIOTAP_EHT_SIG)) + if ((m_present.size() > 1) && m_present.at(1) & RADIOTAP_EHT_SIG) { PrintEht(os); } } void -RadiotapHeader::SetWifiHeader(bool extended) +RadiotapHeader::SetWifiHeader(std::size_t numPresentWords) { - NS_LOG_FUNCTION(this << extended); + NS_LOG_FUNCTION(this << numPresentWords); + NS_ASSERT_MSG(numPresentWords > 0, + "RadiotapHeader::SetWifiHeader() requires at least one it_present word"); NS_ASSERT_MSG(m_length == MIN_HEADER_SIZE, "RadiotapHeader::SetWifiHeader() should be called before any other Set* method"); - if (extended) + NS_ASSERT_MSG(m_present.size() == 1, "RadiotapHeader::SetWifiHeader() should be called once"); + for (std::size_t i = 0; i < (numPresentWords - 1); ++i) { - m_present |= RADIOTAP_EXT; - m_presentExt = 0; + m_present.at(i) |= RADIOTAP_EXT; + m_present.emplace_back(0); m_length += sizeof(RadiotapExtFlags); } } @@ -587,13 +591,13 @@ RadiotapHeader::SetTsft(uint64_t value) { NS_LOG_FUNCTION(this << value); - NS_ASSERT_MSG(!(m_present & RADIOTAP_TSFT), "TSFT radiotap field already present"); + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_TSFT), "TSFT radiotap field already present"); m_tsftPad = ((8 - m_length % 8) % 8); - m_present |= RADIOTAP_TSFT; + m_present.at(0) |= RADIOTAP_TSFT; m_length += 8 + m_tsftPad; m_tsft = value; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -618,12 +622,12 @@ RadiotapHeader::SetFrameFlags(uint8_t flags) { NS_LOG_FUNCTION(this << +flags); - NS_ASSERT_MSG(!(m_present & RADIOTAP_FLAGS), "Flags radiotap field already present"); - m_present |= RADIOTAP_FLAGS; + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_FLAGS), "Flags radiotap field already present"); + m_present.at(0) |= RADIOTAP_FLAGS; m_length += 1; m_flags = flags; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -632,12 +636,12 @@ RadiotapHeader::SetRate(uint8_t rate) { NS_LOG_FUNCTION(this << +rate); - NS_ASSERT_MSG(!(m_present & RADIOTAP_RATE), "Rate radiotap field already present"); - m_present |= RADIOTAP_RATE; + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_RATE), "Rate radiotap field already present"); + m_present.at(0) |= RADIOTAP_RATE; m_length += 1; m_rate = rate; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -646,13 +650,13 @@ RadiotapHeader::SetChannelFields(const ChannelFields& channelFields) { NS_LOG_FUNCTION(this << channelFields.frequency << channelFields.flags); - NS_ASSERT_MSG(!(m_present & RADIOTAP_CHANNEL), "Channel radiotap field already present"); + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_CHANNEL), "Channel radiotap field already present"); m_channelPad = ((2 - m_length % 2) % 2); - m_present |= RADIOTAP_CHANNEL; + m_present.at(0) |= RADIOTAP_CHANNEL; m_length += (sizeof(ChannelFields) + m_channelPad); m_channelFields = channelFields; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -686,9 +690,9 @@ RadiotapHeader::SetAntennaSignalPower(double signal) { NS_LOG_FUNCTION(this << signal); - NS_ASSERT_MSG(!(m_present & RADIOTAP_DBM_ANTSIGNAL), + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_DBM_ANTSIGNAL), "Antenna signal radiotap field already present"); - m_present |= RADIOTAP_DBM_ANTSIGNAL; + m_present.at(0) |= RADIOTAP_DBM_ANTSIGNAL; m_length += 1; if (signal > 127) @@ -704,7 +708,7 @@ RadiotapHeader::SetAntennaSignalPower(double signal) m_antennaSignal = static_cast(floor(signal + 0.5)); } - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -713,9 +717,9 @@ RadiotapHeader::SetAntennaNoisePower(double noise) { NS_LOG_FUNCTION(this << noise); - NS_ASSERT_MSG(!(m_present & RADIOTAP_DBM_ANTNOISE), + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_DBM_ANTNOISE), "Antenna noise radiotap field already present"); - m_present |= RADIOTAP_DBM_ANTNOISE; + m_present.at(0) |= RADIOTAP_DBM_ANTNOISE; m_length += 1; if (noise > 127.0) @@ -731,7 +735,7 @@ RadiotapHeader::SetAntennaNoisePower(double noise) m_antennaNoise = static_cast(floor(noise + 0.5)); } - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -740,12 +744,12 @@ RadiotapHeader::SetMcsFields(const McsFields& mcsFields) { NS_LOG_FUNCTION(this << +mcsFields.known << +mcsFields.flags << +mcsFields.mcs); - NS_ASSERT_MSG(!(m_present & RADIOTAP_MCS), "MCS radiotap field already present"); - m_present |= RADIOTAP_MCS; + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_MCS), "MCS radiotap field already present"); + m_present.at(0) |= RADIOTAP_MCS; m_length += sizeof(McsFields); m_mcsFields = mcsFields; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -778,14 +782,14 @@ RadiotapHeader::SetAmpduStatus(const AmpduStatusFields& ampduStatusFields) { NS_LOG_FUNCTION(this << ampduStatusFields.referenceNumber << ampduStatusFields.flags); - NS_ASSERT_MSG(!(m_present & RADIOTAP_AMPDU_STATUS), + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_AMPDU_STATUS), "A-MPDU status radiotap field already present"); m_ampduStatusPad = ((4 - m_length % 4) % 4); - m_present |= RADIOTAP_AMPDU_STATUS; + m_present.at(0) |= RADIOTAP_AMPDU_STATUS; m_length += (sizeof(ampduStatusFields) + m_ampduStatusPad); m_ampduStatusFields = ampduStatusFields; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -825,13 +829,13 @@ RadiotapHeader::SetVhtFields(const VhtFields& vhtFields) << +vhtFields.mcsNss.at(3) << +vhtFields.coding << +vhtFields.groupId << +vhtFields.partialAid); - NS_ASSERT_MSG(!(m_present & RADIOTAP_VHT), "VHT radiotap field already present"); + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_VHT), "VHT radiotap field already present"); m_vhtPad = ((2 - m_length % 2) % 2); - m_present |= RADIOTAP_VHT; + m_present.at(0) |= RADIOTAP_VHT; m_length += (sizeof(VhtFields) + m_vhtPad); m_vhtFields = vhtFields; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -887,13 +891,13 @@ RadiotapHeader::SetHeFields(const HeFields& heFields) NS_LOG_FUNCTION(this << heFields.data1 << heFields.data2 << heFields.data3 << heFields.data4 << heFields.data5 << heFields.data6); - NS_ASSERT_MSG(!(m_present & RADIOTAP_HE), "HE radiotap field already present"); + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_HE), "HE radiotap field already present"); m_hePad = ((2 - m_length % 2) % 2); - m_present |= RADIOTAP_HE; + m_present.at(0) |= RADIOTAP_HE; m_length += (sizeof(heFields) + m_hePad); m_heFields = heFields; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -937,13 +941,13 @@ RadiotapHeader::SetHeMuFields(const HeMuFields& heMuFields) { NS_LOG_FUNCTION(this << heMuFields.flags1 << heMuFields.flags2); - NS_ASSERT_MSG(!(m_present & RADIOTAP_HE_MU), "HE-MU radiotap field already present"); + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_HE_MU), "HE-MU radiotap field already present"); m_heMuPad = ((2 - m_length % 2) % 2); - m_present |= RADIOTAP_HE_MU; + m_present.at(0) |= RADIOTAP_HE_MU; m_length += (sizeof(heMuFields) + m_heMuPad); m_heMuFields = heMuFields; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -995,14 +999,14 @@ RadiotapHeader::SetHeMuOtherUserFields(const HeMuOtherUserFields& heMuOtherUserF << +heMuOtherUserFields.perUserPosition << +heMuOtherUserFields.perUserKnown); - NS_ASSERT_MSG(!(m_present & RADIOTAP_HE_MU_OTHER_USER), + NS_ASSERT_MSG(!(m_present.at(0) & RADIOTAP_HE_MU_OTHER_USER), "HE-MU-other-user radiotap field already present"); m_heMuOtherUserPad = ((2 - m_length % 2) % 2); - m_present |= RADIOTAP_HE_MU_OTHER_USER; + m_present.at(0) |= RADIOTAP_HE_MU_OTHER_USER; m_length += (sizeof(HeMuOtherUserFields) + m_heMuOtherUserPad); m_heMuOtherUserFields = heMuOtherUserFields; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present.at(0) << std::dec); } @@ -1042,11 +1046,12 @@ void RadiotapHeader::SetUsigFields(const UsigFields& usigFields) { NS_LOG_FUNCTION(this << usigFields.common << usigFields.mask << usigFields.value); - NS_ASSERT_MSG(m_presentExt, "Number of it_present words is incorrect"); - m_present |= RADIOTAP_TLV; + NS_ASSERT_MSG(m_present.size() >= 2, + "Number of it_present words (" << m_present.size() << ") is incorrect"); + m_present.at(0) |= RADIOTAP_TLV; - NS_ASSERT_MSG(!(*m_presentExt & RADIOTAP_USIG), "U-SIG radiotap field already present"); - *m_presentExt |= RADIOTAP_USIG; + NS_ASSERT_MSG(!(m_present.at(1) & RADIOTAP_USIG), "U-SIG radiotap field already present"); + m_present.at(1) |= RADIOTAP_USIG; m_usigTlvPad = ((8 - m_length % 8) % 8); m_usigTlv.type = 32 + std::countr_zero(RADIOTAP_USIG); @@ -1057,8 +1062,8 @@ RadiotapHeader::SetUsigFields(const UsigFields& usigFields) m_usigFields = usigFields; m_length += m_usigTlv.length + m_usigPad; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present - << " m_presentExt=0x" << *m_presentExt << std::dec); + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present[0]=0x" << std::hex + << m_present.at(0) << " m_present[1]=0x" << m_present.at(1) << std::dec); } void @@ -1104,11 +1109,12 @@ void RadiotapHeader::SetEhtFields(const EhtFields& ehtFields) { NS_LOG_FUNCTION(this << ehtFields.known); - NS_ASSERT_MSG(m_presentExt, "Number of it_present words is incorrect"); - m_present |= RADIOTAP_TLV; + NS_ASSERT_MSG(m_present.size() >= 2, + "Number of it_present words (" << m_present.size() << ") is incorrect"); + m_present.at(0) |= RADIOTAP_TLV; - NS_ASSERT_MSG(!(*m_presentExt & RADIOTAP_EHT_SIG), "EHT radiotap field already present"); - *m_presentExt |= RADIOTAP_EHT_SIG; + NS_ASSERT_MSG(!(m_present.at(1) & RADIOTAP_EHT_SIG), "EHT radiotap field already present"); + m_present.at(1) |= RADIOTAP_EHT_SIG; m_ehtTlvPad = ((8 - m_length % 8) % 8); m_ehtTlv.type = 32 + std::countr_zero(RADIOTAP_EHT_SIG); @@ -1119,8 +1125,8 @@ RadiotapHeader::SetEhtFields(const EhtFields& ehtFields) m_ehtFields = ehtFields; m_length += m_ehtTlv.length + m_ehtPad; - NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present=0x" << std::hex << m_present - << " m_presentExt=0x" << *m_presentExt << std::dec); + NS_LOG_LOGIC(this << " m_length=" << m_length << " m_present[0]=0x" << std::hex + << m_present.at(0) << " m_present[1]=0x" << m_present.at(1) << std::dec); } void diff --git a/src/network/utils/radiotap-header.h b/src/network/utils/radiotap-header.h index e8a36ea08..67a79e928 100644 --- a/src/network/utils/radiotap-header.h +++ b/src/network/utils/radiotap-header.h @@ -86,9 +86,9 @@ class RadiotapHeader : public Header * @brief Set the ieee80211_radiotap_header. This method must be called * before any other Set* method. * - * @param extended If true, one more it_present word follows the it_present bitmask. + * @param numPresentWords Number of it_present words in the radiotap header. */ - void SetWifiHeader(bool extended); + void SetWifiHeader(std::size_t numPresentWords); /** * @brief Set the Time Synchronization Function Timer (TSFT) value. Valid for @@ -1058,9 +1058,8 @@ class RadiotapHeader : public Header RADIOTAP_EHT_SIG = 0x00000004 }; - uint16_t m_length{MIN_HEADER_SIZE}; //!< entire length of radiotap data + header - uint32_t m_present{0}; //!< bits describing which fields follow header - std::optional m_presentExt{}; //!< optional extended present bitmask + uint16_t m_length{MIN_HEADER_SIZE}; //!< entire length of radiotap data + header + std::vector m_present{0}; //!< bits describing which fields follow header uint8_t m_tsftPad{0}; //!< TSFT padding. uint64_t m_tsft{0}; //!< Time Synchronization Function Timer (when the first bit of the MPDU diff --git a/src/wifi/helper/wifi-helper.cc b/src/wifi/helper/wifi-helper.cc index c5b6148d4..df1401ac5 100644 --- a/src/wifi/helper/wifi-helper.cc +++ b/src/wifi/helper/wifi-helper.cc @@ -275,14 +275,12 @@ WifiPhyHelper::PcapSniffTxEvent(const std::shared_ptr& info, } case PcapHelper::DLT_IEEE802_11_RADIO: { Ptr p = packet->Copy(); - RadiotapHeader header; - GetRadiotapHeader(header, - p, - channelFreqMhz, - info->device->GetPhy(phyId)->GetPrimary20Index(), - txVector, - aMpdu, - staId); + const auto header = GetRadiotapHeader(p, + channelFreqMhz, + info->device->GetPhy(phyId)->GetPrimary20Index(), + txVector, + aMpdu, + staId); p->AddHeader(header); file->Write(Simulator::Now(), p); return; @@ -318,15 +316,13 @@ WifiPhyHelper::PcapSniffRxEvent(const std::shared_ptr& info, } case PcapHelper::DLT_IEEE802_11_RADIO: { Ptr p = packet->Copy(); - RadiotapHeader header; - GetRadiotapHeader(header, - p, - channelFreqMhz, - info->device->GetPhy(phyId)->GetPrimary20Index(), - txVector, - aMpdu, - staId, - signalNoise); + const auto header = GetRadiotapHeader(p, + channelFreqMhz, + info->device->GetPhy(phyId)->GetPrimary20Index(), + txVector, + aMpdu, + staId, + signalNoise); p->AddHeader(header); file->Write(Simulator::Now(), p); return; @@ -336,36 +332,29 @@ WifiPhyHelper::PcapSniffRxEvent(const std::shared_ptr& info, } } -void -WifiPhyHelper::GetRadiotapHeader(RadiotapHeader& header, - Ptr packet, +RadiotapHeader +WifiPhyHelper::GetRadiotapHeader(Ptr packet, uint16_t channelFreqMhz, uint8_t p20Index, const WifiTxVector& txVector, MpduInfo aMpdu, uint16_t staId, - SignalNoiseDbm signalNoise) + std::optional signalNoise) { - GetRadiotapHeader(header, packet, channelFreqMhz, p20Index, txVector, aMpdu, staId); - header.SetAntennaSignalPower(signalNoise.signal); - header.SetAntennaNoisePower(signalNoise.noise); -} + RadiotapHeader header; -void -WifiPhyHelper::GetRadiotapHeader(RadiotapHeader& header, - Ptr packet, - uint16_t channelFreqMhz, - uint8_t p20Index, - const WifiTxVector& txVector, - MpduInfo aMpdu, - uint16_t staId) -{ const auto preamble = txVector.GetPreambleType(); const auto modClass = txVector.GetModulationClass(); const auto channelWidth = txVector.GetChannelWidth(); const auto gi = txVector.GetGuardInterval(); - header.SetWifiHeader(IsEht(preamble)); + header.SetWifiHeader(IsEht(preamble) ? 2 : 1); + + if (signalNoise) + { + header.SetAntennaSignalPower(signalNoise->signal); + header.SetAntennaNoisePower(signalNoise->noise); + } header.SetTsft(Simulator::Now().GetMicroSeconds()); @@ -817,6 +806,8 @@ WifiPhyHelper::GetRadiotapHeader(RadiotapHeader& header, ehtFields.userInfo.push_back(userInfo); header.SetEhtFields(ehtFields); } + + return header; } void diff --git a/src/wifi/helper/wifi-helper.h b/src/wifi/helper/wifi-helper.h index d8397ad3e..945a8a8c9 100644 --- a/src/wifi/helper/wifi-helper.h +++ b/src/wifi/helper/wifi-helper.h @@ -20,6 +20,7 @@ #include #include +#include #include namespace ns3 @@ -309,45 +310,26 @@ class WifiPhyHelper : public PcapHelperForDevice, public AsciiTraceHelperForDevi static Ptr GetOrCreatePcapFile(const std::shared_ptr& info, uint8_t phyId); - /** - * Get the Radiotap header for a transmitted packet. - * - * @param header the radiotap header to be filled in - * @param packet the packet - * @param channelFreqMhz the channel frequency - * @param p20Index the index of the primary20 channel - * @param txVector the TXVECTOR - * @param aMpdu the A-MPDU information - * @param staId the STA-ID - */ - static void GetRadiotapHeader(RadiotapHeader& header, - Ptr packet, - uint16_t channelFreqMhz, - uint8_t p20Index, - const WifiTxVector& txVector, - MpduInfo aMpdu, - uint16_t staId); - /** * Get the Radiotap header for a received packet. * - * @param header the radiotap header to be filled in * @param packet the packet * @param channelFreqMhz the channel frequency * @param p20Index the index of the primary20 channel * @param txVector the TXVECTOR * @param aMpdu the A-MPDU information * @param staId the STA-ID - * @param signalNoise the rx signal and noise information + * @param signalNoise the rx signal and noise information (for receiver only) + * @return the radiotap header */ - static void GetRadiotapHeader(RadiotapHeader& header, - Ptr packet, - uint16_t channelFreqMhz, - uint8_t p20Index, - const WifiTxVector& txVector, - MpduInfo aMpdu, - uint16_t staId, - SignalNoiseDbm signalNoise); + static RadiotapHeader GetRadiotapHeader( + Ptr packet, + uint16_t channelFreqMhz, + uint8_t p20Index, + const WifiTxVector& txVector, + MpduInfo aMpdu, + uint16_t staId, + std::optional signalNoise = std::nullopt); /** * @brief Enable pcap output the indicated net device.