wifi: Implement TID-to-Link Mapping IE
This commit is contained in:
committed by
Stefano Avallone
parent
66f838978b
commit
394548822e
@@ -29,6 +29,7 @@ set(source_files
|
||||
model/eht/eht-configuration.cc
|
||||
model/eht/eht-frame-exchange-manager.cc
|
||||
model/eht/eht-operation.cc
|
||||
model/eht/tid-to-link-mapping-element.cc
|
||||
model/eht/eht-phy.cc
|
||||
model/eht/eht-ppdu.cc
|
||||
model/eht/multi-link-element.cc
|
||||
@@ -177,6 +178,7 @@ set(header_files
|
||||
model/eht/eht-configuration.h
|
||||
model/eht/eht-frame-exchange-manager.h
|
||||
model/eht/eht-operation.h
|
||||
model/eht/tid-to-link-mapping-element.h
|
||||
model/eht/eht-phy.h
|
||||
model/eht/eht-ppdu.h
|
||||
model/eht/multi-link-element.h
|
||||
|
||||
189
src/wifi/model/eht/tid-to-link-mapping-element.cc
Normal file
189
src/wifi/model/eht/tid-to-link-mapping-element.cc
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 2022
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Sharan Naribole <sharan.naribole@gmail.com>
|
||||
*/
|
||||
|
||||
#include <ns3/assert.h>
|
||||
#include <ns3/tid-to-link-mapping-element.h>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
uint16_t
|
||||
TidToLinkMapping::Control::GetSubfieldSize() const
|
||||
{
|
||||
// IEEE 802.11be D2.0 Figure 9-1002an
|
||||
NS_ASSERT_MSG(defaultMapping != presenceBitmap.has_value(),
|
||||
"Presence bitmap not expected if default mapping is set");
|
||||
auto size = WIFI_TID_TO_LINK_MAPPING_CONTROL_BASIC_SIZE_B;
|
||||
if (defaultMapping)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
return size + WIFI_LINK_MAPPING_PRESENCE_IND_SIZE_B;
|
||||
}
|
||||
|
||||
void
|
||||
TidToLinkMapping::Control::Serialize(Buffer::Iterator& start) const
|
||||
{
|
||||
uint8_t val = static_cast<uint8_t>(direction);
|
||||
val |= ((defaultMapping ? 1 : 0) << 2);
|
||||
start.WriteU8(val);
|
||||
NS_ASSERT_MSG(defaultMapping != presenceBitmap.has_value(),
|
||||
"Presence bitmap not expected if default mapping is set");
|
||||
if (presenceBitmap.has_value())
|
||||
{
|
||||
start.WriteU8(presenceBitmap.value());
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t
|
||||
TidToLinkMapping::Control::Deserialize(Buffer::Iterator start)
|
||||
{
|
||||
auto i = start;
|
||||
uint8_t count = 0;
|
||||
auto val = i.ReadU8();
|
||||
count++;
|
||||
|
||||
direction = static_cast<TidLinkMapDir>(val & 0x03);
|
||||
defaultMapping = (((val >> 2) & 0x01) == 1);
|
||||
if (defaultMapping)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
presenceBitmap = i.ReadU8();
|
||||
return ++count;
|
||||
}
|
||||
|
||||
WifiInformationElementId
|
||||
TidToLinkMapping::ElementId() const
|
||||
{
|
||||
return IE_EXTENSION;
|
||||
}
|
||||
|
||||
WifiInformationElementId
|
||||
TidToLinkMapping::ElementIdExt() const
|
||||
{
|
||||
return IE_EXT_TID_TO_LINK_MAPPING_ELEMENT;
|
||||
}
|
||||
|
||||
void
|
||||
TidToLinkMapping::SetLinkMappingOfTid(uint8_t tid, std::list<uint8_t> linkIds)
|
||||
{
|
||||
NS_ABORT_MSG_IF(tid > 7, "Invalid tid: " << +tid);
|
||||
NS_ABORT_MSG_IF(m_control.defaultMapping,
|
||||
"Per-TID link mapping not expected if default mapping is set");
|
||||
|
||||
// derive link mapping for the given TID
|
||||
uint16_t linkMapping = 0;
|
||||
|
||||
for (const auto& linkId : linkIds)
|
||||
{
|
||||
linkMapping |= (1 << linkId);
|
||||
}
|
||||
|
||||
m_linkMapping[tid] = linkMapping;
|
||||
|
||||
if (!m_control.presenceBitmap.has_value())
|
||||
{
|
||||
m_control.presenceBitmap = 0;
|
||||
}
|
||||
*m_control.presenceBitmap |= (1 << tid);
|
||||
}
|
||||
|
||||
std::list<uint8_t>
|
||||
TidToLinkMapping::GetLinkMappingOfTid(uint8_t tid) const
|
||||
{
|
||||
auto it = m_linkMapping.find(tid);
|
||||
|
||||
if (it == m_linkMapping.end())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
std::list<uint8_t> linkIds;
|
||||
for (uint8_t linkId = 0; linkId < 15; linkId++)
|
||||
{
|
||||
if (((it->second >> linkId) & 0x0001) == 1)
|
||||
{
|
||||
linkIds.push_back(linkId);
|
||||
}
|
||||
}
|
||||
|
||||
return linkIds;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
TidToLinkMapping::GetInformationFieldSize() const
|
||||
{
|
||||
// IEEE 802.11be D2.0 9.4.2.314 TID-To-Link Mapping element
|
||||
uint16_t ret = WIFI_IE_ELEMENT_ID_EXT_SIZE; // Element ID Extension
|
||||
ret += m_control.GetSubfieldSize();
|
||||
NS_ASSERT_MSG(m_linkMapping.empty() == m_control.defaultMapping,
|
||||
"Per-TID link mapping not expected if default mapping is set");
|
||||
ret += WIFI_LINK_MAPPING_PER_TID_SIZE_B * (m_linkMapping.size());
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
TidToLinkMapping::SerializeInformationField(Buffer::Iterator start) const
|
||||
{
|
||||
// IEEE 802.11be D2.0 9.4.2.314 TID-To-Link Mapping element
|
||||
m_control.Serialize(start);
|
||||
NS_ASSERT_MSG(m_linkMapping.empty() == m_control.defaultMapping,
|
||||
"Per-TID link mapping not expected if default mapping is set");
|
||||
|
||||
for (const auto& [tid, linkMapping] : m_linkMapping)
|
||||
{
|
||||
start.WriteHtolsbU16(linkMapping);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t
|
||||
TidToLinkMapping::DeserializeInformationField(Buffer::Iterator start, uint16_t length)
|
||||
{
|
||||
auto i = start;
|
||||
uint16_t count = 0;
|
||||
auto nCtrlOctets = m_control.Deserialize(i);
|
||||
NS_ASSERT_MSG(nCtrlOctets <= length, "Tid-to-Link Mapping deserialize error");
|
||||
i.Next(nCtrlOctets);
|
||||
count += nCtrlOctets;
|
||||
m_linkMapping.clear();
|
||||
if (m_control.presenceBitmap.has_value())
|
||||
{
|
||||
NS_ABORT_MSG_IF(m_control.defaultMapping,
|
||||
"Default mapping should not be set when presence bitmap is present");
|
||||
const auto presenceBitmap = m_control.presenceBitmap.value();
|
||||
for (uint8_t tid = 0; tid < 8; tid++)
|
||||
{
|
||||
if (((presenceBitmap >> tid) & 0x01) == 1)
|
||||
{
|
||||
m_linkMapping[tid] = i.ReadLsbtohU16();
|
||||
count += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_ABORT_MSG_IF(count != length,
|
||||
"TID-to-Link Mapping Length (" << +length
|
||||
<< ") differs "
|
||||
"from actual number of bytes read ("
|
||||
<< +count << ")");
|
||||
return count;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
126
src/wifi/model/eht/tid-to-link-mapping-element.h
Normal file
126
src/wifi/model/eht/tid-to-link-mapping-element.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2022
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation;
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Sharan Naribole <sharan.naribole@gmail.com>
|
||||
*/
|
||||
|
||||
#ifndef TID_TO_LINK_MAPPING_H
|
||||
#define TID_TO_LINK_MAPPING_H
|
||||
|
||||
#include <ns3/wifi-information-element.h>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace ns3
|
||||
{
|
||||
|
||||
/**
|
||||
* TID-to-Link Mapping Control Direction
|
||||
* IEEE 802.11be D2.0 Figure 9-1002an
|
||||
*/
|
||||
enum class TidLinkMapDir : uint8_t
|
||||
{
|
||||
DOWNLINK = 0,
|
||||
UPLINK = 1,
|
||||
BOTH_DIRECTIONS = 2,
|
||||
};
|
||||
|
||||
/// whether to enforce the default link mapping
|
||||
constexpr auto DEFAULT_WIFI_TID_LINK_MAPPING{true};
|
||||
/// default value for the Direction subfield of the TID-To-Link Control field
|
||||
constexpr auto DEFAULT_WIFI_TID_LINK_MAP_DIR{TidLinkMapDir::BOTH_DIRECTIONS};
|
||||
/// size in bytes of the Link Mapping Of TID n field (IEEE 802.11be D2.0 9.4.2.314)
|
||||
constexpr uint16_t WIFI_LINK_MAPPING_PER_TID_SIZE_B = 2;
|
||||
/// size in bytes of the TID-To-Link Control field with default link mapping
|
||||
constexpr uint16_t WIFI_TID_TO_LINK_MAPPING_CONTROL_BASIC_SIZE_B =
|
||||
1; // IEEE 802.11be D2.0 9.4.2.314
|
||||
/// size in bytes of the Link Mapping Presence Indicator field (IEEE 802.11be D2.0 9.4.2.314)
|
||||
constexpr uint16_t WIFI_LINK_MAPPING_PRESENCE_IND_SIZE_B = 1;
|
||||
|
||||
/**
|
||||
* \brief TID-to-Link Mapping Information Element
|
||||
* \ingroup wifi
|
||||
*
|
||||
* This class serializes and deserializes
|
||||
* the TID-to-Link Mapping element
|
||||
* IEEE 802.11be D2.0 9.4.2.314
|
||||
*
|
||||
*/
|
||||
class TidToLinkMapping : public WifiInformationElement
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* TID-to-Link Mapping Control subfield
|
||||
* IEEE 802.11be D2.0 Figure 9-1002an
|
||||
*/
|
||||
struct Control
|
||||
{
|
||||
TidLinkMapDir direction{DEFAULT_WIFI_TID_LINK_MAP_DIR}; ///< Direction
|
||||
bool defaultMapping{DEFAULT_WIFI_TID_LINK_MAPPING}; ///< Default link mapping
|
||||
std::optional<uint8_t> presenceBitmap; ///< Link Mapping Presence Indicator
|
||||
|
||||
/// \return Serialized size of TID-to-Link Mapping Control in octets
|
||||
uint16_t GetSubfieldSize() const;
|
||||
|
||||
/**
|
||||
* Serialize the TID-to-Link Mapping Control subfield
|
||||
*
|
||||
* \param start iterator pointing to where the subfield should be written to
|
||||
*/
|
||||
void Serialize(Buffer::Iterator& start) const;
|
||||
/**
|
||||
* Deserialize the TID-to-Link Mapping Control subfield
|
||||
*
|
||||
* \param start iterator pointing to where the subfield should be read from
|
||||
* \return the number of octets read
|
||||
*/
|
||||
uint16_t Deserialize(Buffer::Iterator start);
|
||||
};
|
||||
|
||||
WifiInformationElementId ElementId() const override;
|
||||
WifiInformationElementId ElementIdExt() const override;
|
||||
|
||||
/**
|
||||
* Set the Link Mapping field of the given TID such that the given TID is mapped
|
||||
* to the links associated with the given link IDs.
|
||||
*
|
||||
* \param tid the given TID
|
||||
* \param linkIds the IDs of the links which the given TID is mapped to
|
||||
*/
|
||||
void SetLinkMappingOfTid(uint8_t tid, std::list<uint8_t> linkIds);
|
||||
/**
|
||||
* Get the Link Mapping field of the given TID.
|
||||
*
|
||||
* \param tid the given TID
|
||||
* \return the IDs of the links which the given TID is mapped to
|
||||
*/
|
||||
std::list<uint8_t> GetLinkMappingOfTid(uint8_t tid) const;
|
||||
|
||||
TidToLinkMapping::Control m_control; ///< TID-to-link Mapping Control
|
||||
std::map<uint8_t, uint16_t> m_linkMapping; ///< TID-indexed Link Mapping
|
||||
|
||||
private:
|
||||
uint16_t GetInformationFieldSize() const override;
|
||||
void SerializeInformationField(Buffer::Iterator start) const override;
|
||||
uint16_t DeserializeInformationField(Buffer::Iterator start, uint16_t length) override;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* TID_TO_LINK_MAPPING_H */
|
||||
@@ -236,6 +236,7 @@ typedef uint8_t WifiInformationElementId;
|
||||
#define IE_EXT_EHT_OPERATION ((WifiInformationElementId)106)
|
||||
#define IE_EXT_MULTI_LINK_ELEMENT ((WifiInformationElementId)107)
|
||||
#define IE_EXT_EHT_CAPABILITIES ((WifiInformationElementId)108)
|
||||
#define IE_EXT_TID_TO_LINK_MAPPING_ELEMENT ((WifiInformationElementId)109)
|
||||
|
||||
/**
|
||||
* \brief Information element, as defined in 802.11-2007 standard
|
||||
|
||||
Reference in New Issue
Block a user