wifi: Queue scheduler allows (un)blocking links for specific container queues
This commit is contained in:
@@ -74,6 +74,26 @@ class WifiMacQueueSchedulerImpl : public WifiMacQueueScheduler
|
||||
const WifiContainerQueueId& prevQueueId) final;
|
||||
/** \copydoc ns3::WifiMacQueueScheduler::GetLinkIds */
|
||||
std::list<uint8_t> GetLinkIds(AcIndex ac, Ptr<const WifiMpdu> mpdu) final;
|
||||
/** \copydoc ns3::WifiMacQueueScheduler::BlockQueues */
|
||||
void BlockQueues(WifiQueueBlockedReason reason,
|
||||
AcIndex ac,
|
||||
const std::list<WifiContainerQueueType>& types,
|
||||
const Mac48Address& rxAddress,
|
||||
const Mac48Address& txAddress,
|
||||
const std::set<uint8_t>& tids,
|
||||
const std::set<uint8_t>& linkIds) final;
|
||||
/** \copydoc ns3::WifiMacQueueScheduler::UnblockQueues */
|
||||
void UnblockQueues(WifiQueueBlockedReason reason,
|
||||
AcIndex ac,
|
||||
const std::list<WifiContainerQueueType>& types,
|
||||
const Mac48Address& rxAddress,
|
||||
const Mac48Address& txAddress,
|
||||
const std::set<uint8_t>& tids,
|
||||
const std::set<uint8_t>& linkIds) final;
|
||||
/** \copydoc ns3::WifiMacQueueScheduler::GetQueueLinkMask */
|
||||
std::optional<Mask> GetQueueLinkMask(AcIndex ac,
|
||||
const WifiContainerQueueId& queueId,
|
||||
uint8_t linkId) final;
|
||||
/** \copydoc ns3::WifiMacQueueScheduler::HasToDropBeforeEnqueue */
|
||||
Ptr<WifiMpdu> HasToDropBeforeEnqueue(AcIndex ac, Ptr<WifiMpdu> mpdu) final;
|
||||
/** \copydoc ns3::WifiMacQueueScheduler::NotifyEnqueue */
|
||||
@@ -226,6 +246,29 @@ class WifiMacQueueSchedulerImpl : public WifiMacQueueScheduler
|
||||
*/
|
||||
virtual void DoNotifyRemove(AcIndex ac, const std::list<Ptr<WifiMpdu>>& mpdus) = 0;
|
||||
|
||||
/**
|
||||
* Block or unblock the given set of links for the container queues of the given types and
|
||||
* Access Category that hold frames having the given Receiver Address (RA),
|
||||
* Transmitter Address (TA) and TID (if needed) for the given reason.
|
||||
*
|
||||
* \param block true to block the queues, false to unblock
|
||||
* \param reason the reason for blocking the queues
|
||||
* \param ac the given Access Category
|
||||
* \param types the types of the queues to block
|
||||
* \param rxAddress the Receiver Address (RA) of the frames
|
||||
* \param txAddress the Transmitter Address (TA) of the frames
|
||||
* \param tids the TIDs optionally identifying the queues to block
|
||||
* \param linkIds set of links to block (empty to block all setup links)
|
||||
*/
|
||||
void DoBlockQueues(bool block,
|
||||
WifiQueueBlockedReason reason,
|
||||
AcIndex ac,
|
||||
const std::list<WifiContainerQueueType>& types,
|
||||
const Mac48Address& rxAddress,
|
||||
const Mac48Address& txAddress,
|
||||
const std::set<uint8_t>& tids,
|
||||
const std::set<uint8_t>& linkIds);
|
||||
|
||||
std::vector<PerAcInfo> m_perAcInfo{AC_UNDEF}; //!< vector of per-AC information
|
||||
NS_LOG_TEMPLATE_DECLARE; //!< the log component
|
||||
};
|
||||
@@ -399,6 +442,114 @@ WifiMacQueueSchedulerImpl<Priority, Compare>::GetLinkIds(AcIndex ac, Ptr<const W
|
||||
return linkIds;
|
||||
}
|
||||
|
||||
template <class Priority, class Compare>
|
||||
void
|
||||
WifiMacQueueSchedulerImpl<Priority, Compare>::DoBlockQueues(
|
||||
bool block,
|
||||
WifiQueueBlockedReason reason,
|
||||
AcIndex ac,
|
||||
const std::list<WifiContainerQueueType>& types,
|
||||
const Mac48Address& rxAddress,
|
||||
const Mac48Address& txAddress,
|
||||
const std::set<uint8_t>& tids,
|
||||
const std::set<uint8_t>& linkIds)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << block << reason << ac << rxAddress << txAddress);
|
||||
std::list<WifiMacHeader> headers;
|
||||
|
||||
for (const auto queueType : types)
|
||||
{
|
||||
switch (queueType)
|
||||
{
|
||||
case WIFI_CTL_QUEUE:
|
||||
headers.emplace_back(WIFI_MAC_CTL_BACKREQ);
|
||||
break;
|
||||
case WIFI_MGT_QUEUE:
|
||||
headers.emplace_back(WIFI_MAC_MGT_ACTION);
|
||||
break;
|
||||
case WIFI_QOSDATA_QUEUE:
|
||||
NS_ASSERT_MSG(!tids.empty(),
|
||||
"TID must be specified for queues containing QoS data frames");
|
||||
for (const auto tid : tids)
|
||||
{
|
||||
headers.emplace_back(WIFI_MAC_QOSDATA);
|
||||
headers.back().SetQosTid(tid);
|
||||
}
|
||||
break;
|
||||
case WIFI_DATA_QUEUE:
|
||||
headers.emplace_back(WIFI_MAC_DATA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (auto& hdr : headers)
|
||||
{
|
||||
hdr.SetAddr1(rxAddress);
|
||||
hdr.SetAddr2(txAddress);
|
||||
|
||||
auto queueInfoIt = InitQueueInfo(ac, Create<WifiMpdu>(Create<Packet>(), hdr));
|
||||
for (auto& [linkId, mask] : queueInfoIt->second.linkIds)
|
||||
{
|
||||
if (linkIds.empty() || linkIds.count(linkId) > 0)
|
||||
{
|
||||
mask.set(static_cast<std::size_t>(reason), block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class Priority, class Compare>
|
||||
void
|
||||
WifiMacQueueSchedulerImpl<Priority, Compare>::BlockQueues(
|
||||
WifiQueueBlockedReason reason,
|
||||
AcIndex ac,
|
||||
const std::list<WifiContainerQueueType>& types,
|
||||
const Mac48Address& rxAddress,
|
||||
const Mac48Address& txAddress,
|
||||
const std::set<uint8_t>& tids,
|
||||
const std::set<uint8_t>& linkIds)
|
||||
{
|
||||
DoBlockQueues(true, reason, ac, types, rxAddress, txAddress, tids, linkIds);
|
||||
}
|
||||
|
||||
template <class Priority, class Compare>
|
||||
void
|
||||
WifiMacQueueSchedulerImpl<Priority, Compare>::UnblockQueues(
|
||||
WifiQueueBlockedReason reason,
|
||||
AcIndex ac,
|
||||
const std::list<WifiContainerQueueType>& types,
|
||||
const Mac48Address& rxAddress,
|
||||
const Mac48Address& txAddress,
|
||||
const std::set<uint8_t>& tids,
|
||||
const std::set<uint8_t>& linkIds)
|
||||
{
|
||||
DoBlockQueues(false, reason, ac, types, rxAddress, txAddress, tids, linkIds);
|
||||
}
|
||||
|
||||
template <class Priority, class Compare>
|
||||
std::optional<WifiMacQueueScheduler::Mask>
|
||||
WifiMacQueueSchedulerImpl<Priority, Compare>::GetQueueLinkMask(AcIndex ac,
|
||||
const WifiContainerQueueId& queueId,
|
||||
uint8_t linkId)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << +ac << +linkId);
|
||||
|
||||
const auto queueInfoIt = m_perAcInfo[ac].queueInfoMap.find(queueId);
|
||||
|
||||
if (queueInfoIt == m_perAcInfo[ac].queueInfoMap.cend())
|
||||
{
|
||||
// the given container queue does not exist
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const auto& linkIds = queueInfoIt->second.linkIds;
|
||||
if (const auto linkIt = linkIds.find(linkId); linkIt != linkIds.cend())
|
||||
{
|
||||
return linkIt->second;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <class Priority, class Compare>
|
||||
std::optional<WifiContainerQueueId>
|
||||
WifiMacQueueSchedulerImpl<Priority, Compare>::GetNext(AcIndex ac, uint8_t linkId)
|
||||
|
||||
@@ -44,6 +44,26 @@ enum class WifiQueueBlockedReason : uint8_t
|
||||
REASONS_COUNT = 0
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Stream insertion operator.
|
||||
*
|
||||
* \param os the stream
|
||||
* \param reason the reason to block container queues
|
||||
* \returns a reference to the stream
|
||||
*/
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, WifiQueueBlockedReason reason)
|
||||
{
|
||||
switch (reason)
|
||||
{
|
||||
case WifiQueueBlockedReason::REASONS_COUNT:
|
||||
return (os << "REASONS_COUNT");
|
||||
default:
|
||||
NS_ABORT_MSG("Unknown queue blocked reason");
|
||||
return (os << "unknown");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \ingroup wifi
|
||||
*
|
||||
@@ -101,9 +121,66 @@ class WifiMacQueueScheduler : public Object
|
||||
*/
|
||||
virtual std::list<uint8_t> GetLinkIds(AcIndex ac, Ptr<const WifiMpdu> mpdu) = 0;
|
||||
|
||||
/**
|
||||
* Block the given set of links for the container queues of the given types and
|
||||
* Access Category that hold frames having the given Receiver Address (RA),
|
||||
* Transmitter Address (TA) and TID (if needed) for the given reason, such that
|
||||
* frames in these queues are not transmitted on the given set of links.
|
||||
*
|
||||
* \param reason the reason for blocking the queues
|
||||
* \param ac the given Access Category
|
||||
* \param types the types of the queues to block
|
||||
* \param rxAddress the Receiver Address (RA) of the frames
|
||||
* \param txAddress the Transmitter Address (TA) of the frames
|
||||
* \param tids the TIDs optionally identifying the queues to block
|
||||
* \param linkIds set of links to block (empty to block all setup links)
|
||||
*/
|
||||
virtual void BlockQueues(WifiQueueBlockedReason reason,
|
||||
AcIndex ac,
|
||||
const std::list<WifiContainerQueueType>& types,
|
||||
const Mac48Address& rxAddress,
|
||||
const Mac48Address& txAddress,
|
||||
const std::set<uint8_t>& tids = {},
|
||||
const std::set<uint8_t>& linkIds = {}) = 0;
|
||||
/**
|
||||
* Unblock the given set of links for the container queues of the given types and
|
||||
* Access Category that hold frames having the given Receiver Address (RA),
|
||||
* Transmitter Address (TA) and TID (if needed) for the given reason, such that
|
||||
* frames in these queues can be transmitted on the given set of links.
|
||||
*
|
||||
* \param reason the reason for unblocking the queues
|
||||
* \param ac the given Access Category
|
||||
* \param types the types of the queues to unblock
|
||||
* \param rxAddress the Receiver Address (RA) of the frames
|
||||
* \param txAddress the Transmitter Address (TA) of the frames
|
||||
* \param tids the TIDs optionally identifying the queues to unblock
|
||||
* \param linkIds set of links to unblock (empty to unblock all setup links)
|
||||
*/
|
||||
virtual void UnblockQueues(WifiQueueBlockedReason reason,
|
||||
AcIndex ac,
|
||||
const std::list<WifiContainerQueueType>& types,
|
||||
const Mac48Address& rxAddress,
|
||||
const Mac48Address& txAddress,
|
||||
const std::set<uint8_t>& tids = {},
|
||||
const std::set<uint8_t>& linkIds = {}) = 0;
|
||||
|
||||
/// Bitset identifying the reasons to block individual links for a container queue
|
||||
using Mask = std::bitset<static_cast<std::size_t>(WifiQueueBlockedReason::REASONS_COUNT)>;
|
||||
|
||||
/**
|
||||
* Get the mask associated with the given container queue indicating whether the given link
|
||||
* is blocked and for which reason, provided that the given container queue exists and has
|
||||
* a mask for the given link.
|
||||
*
|
||||
* \param ac the given Access Category
|
||||
* \param queueId the ID of the given container queue
|
||||
* \param linkId the ID of the given link
|
||||
* \return the mask associated with the given container queue for the given link
|
||||
*/
|
||||
virtual std::optional<Mask> GetQueueLinkMask(AcIndex ac,
|
||||
const WifiContainerQueueId& queueId,
|
||||
uint8_t linkId) = 0;
|
||||
|
||||
/**
|
||||
* Check whether an MPDU has to be dropped before enqueuing the given MPDU.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user