wifi: Add new WifiMac::Enqueue methods to avoid code duplication
At this stage, these methods are not yet used.
This commit is contained in:
committed by
Stefano Avallone
parent
12d8a340bf
commit
35d4921402
@@ -222,6 +222,51 @@ MeshWifiInterfaceMac::SwitchFrequencyChannel(uint16_t new_id)
|
||||
//-----------------------------------------------------------------------------
|
||||
// Forward frame down
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
MeshWifiInterfaceMac::Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << *mpdu << to << from);
|
||||
|
||||
auto& hdr = mpdu->GetHeader();
|
||||
auto packet = mpdu->GetPacket()->Copy();
|
||||
|
||||
hdr.SetAddr2(GetAddress());
|
||||
hdr.SetAddr3(to);
|
||||
hdr.SetAddr4(from);
|
||||
hdr.SetDsFrom();
|
||||
hdr.SetDsTo();
|
||||
// Address 1 is unknown here. Routing plugin is responsible to correctly set it.
|
||||
hdr.SetAddr1(Mac48Address());
|
||||
// Filter packet through all installed plugins
|
||||
for (auto i = m_plugins.end() - 1; i != m_plugins.begin() - 1; i--)
|
||||
{
|
||||
bool drop = !((*i)->UpdateOutcomingFrame(packet, hdr, from, to));
|
||||
if (drop)
|
||||
{
|
||||
return; // plugin drops frame
|
||||
}
|
||||
}
|
||||
// Assert that address1 is set. Assert will fail e.g. if there is no installed routing plugin.
|
||||
NS_ASSERT(hdr.GetAddr1() != Mac48Address());
|
||||
// Queue frame
|
||||
if (GetWifiRemoteStationManager()->IsBrandNew(hdr.GetAddr1()))
|
||||
{
|
||||
// in adhoc mode, we assume that every destination
|
||||
// supports all the rates we support.
|
||||
for (const auto& mode : GetWifiPhy()->GetModeList())
|
||||
{
|
||||
GetWifiRemoteStationManager()->AddSupportedMode(hdr.GetAddr1(), mode);
|
||||
}
|
||||
GetWifiRemoteStationManager()->RecordDisassociated(hdr.GetAddr1());
|
||||
}
|
||||
|
||||
m_stats.sentFrames++;
|
||||
m_stats.sentBytes += packet->GetSize();
|
||||
auto tid = hdr.GetQosTid();
|
||||
NS_ASSERT(GetQosTxop(tid) != nullptr);
|
||||
GetQosTxop(tid)->Queue(Create<WifiMpdu>(packet, hdr));
|
||||
}
|
||||
|
||||
void
|
||||
MeshWifiInterfaceMac::ForwardDown(Ptr<Packet> packet, Mac48Address from, Mac48Address to)
|
||||
{
|
||||
|
||||
@@ -264,6 +264,7 @@ class MeshWifiInterfaceMac : public WifiMac
|
||||
typedef std::vector<Ptr<MeshWifiInterfaceMacPlugin>> PluginList; ///< PluginList typedef
|
||||
|
||||
void DoInitialize() override;
|
||||
void Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from) override;
|
||||
|
||||
/// \name Mesh timing intervals
|
||||
///@{
|
||||
|
||||
@@ -71,6 +71,62 @@ AdhocWifiMac::CanForwardPacketsTo(Mac48Address to) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AdhocWifiMac::Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << *mpdu << to << from);
|
||||
|
||||
if (GetWifiRemoteStationManager()->IsBrandNew(to))
|
||||
{
|
||||
// In ad hoc mode, we assume that every destination supports all the rates we support.
|
||||
if (GetHtSupported(SINGLE_LINK_OP_ID))
|
||||
{
|
||||
GetWifiRemoteStationManager()->AddAllSupportedMcs(to);
|
||||
GetWifiRemoteStationManager()->AddStationHtCapabilities(
|
||||
to,
|
||||
GetHtCapabilities(SINGLE_LINK_OP_ID));
|
||||
}
|
||||
if (GetVhtSupported(SINGLE_LINK_OP_ID))
|
||||
{
|
||||
GetWifiRemoteStationManager()->AddStationVhtCapabilities(
|
||||
to,
|
||||
GetVhtCapabilities(SINGLE_LINK_OP_ID));
|
||||
}
|
||||
if (GetHeSupported())
|
||||
{
|
||||
GetWifiRemoteStationManager()->AddStationHeCapabilities(
|
||||
to,
|
||||
GetHeCapabilities(SINGLE_LINK_OP_ID));
|
||||
if (Is6GhzBand(SINGLE_LINK_OP_ID))
|
||||
{
|
||||
GetWifiRemoteStationManager()->AddStationHe6GhzCapabilities(
|
||||
to,
|
||||
GetHe6GhzBandCapabilities(SINGLE_LINK_OP_ID));
|
||||
}
|
||||
}
|
||||
if (GetEhtSupported())
|
||||
{
|
||||
GetWifiRemoteStationManager()->AddStationEhtCapabilities(
|
||||
to,
|
||||
GetEhtCapabilities(SINGLE_LINK_OP_ID));
|
||||
}
|
||||
GetWifiRemoteStationManager()->AddAllSupportedModes(to);
|
||||
GetWifiRemoteStationManager()->RecordDisassociated(to);
|
||||
}
|
||||
|
||||
auto& hdr = mpdu->GetHeader();
|
||||
|
||||
hdr.SetAddr1(to);
|
||||
hdr.SetAddr2(GetAddress());
|
||||
hdr.SetAddr3(GetBssid(SINGLE_LINK_OP_ID));
|
||||
hdr.SetDsNotFrom();
|
||||
hdr.SetDsNotTo();
|
||||
|
||||
auto txop = hdr.IsQosData() ? StaticCast<Txop>(GetQosTxop(hdr.GetQosTid())) : GetTxop();
|
||||
NS_ASSERT(txop);
|
||||
txop->Queue(mpdu);
|
||||
}
|
||||
|
||||
void
|
||||
AdhocWifiMac::Enqueue(Ptr<Packet> packet, Mac48Address to)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,7 @@ class AdhocWifiMac : public WifiMac
|
||||
private:
|
||||
void Receive(Ptr<const WifiMpdu> mpdu, uint8_t linkId) override;
|
||||
void DoCompleteConfig() override;
|
||||
void Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from) override;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -525,6 +525,55 @@ ApWifiMac::Enqueue(Ptr<Packet> packet, Mac48Address to)
|
||||
Enqueue(packet, to, GetAddress());
|
||||
}
|
||||
|
||||
void
|
||||
ApWifiMac::Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << *mpdu << to << from);
|
||||
|
||||
std::list<Mac48Address> addr2Set;
|
||||
if (to.IsGroup())
|
||||
{
|
||||
// broadcast frames are transmitted on all the links
|
||||
for (uint8_t linkId = 0; linkId < GetNLinks(); linkId++)
|
||||
{
|
||||
addr2Set.push_back(GetFrameExchangeManager(linkId)->GetAddress());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the Transmitter Address (TA) is the MLD address only for non-broadcast data frames
|
||||
// exchanged between two MLDs
|
||||
addr2Set = {GetAddress()};
|
||||
auto linkId = IsAssociated(to);
|
||||
NS_ASSERT_MSG(linkId, "Station " << to << "is not associated, cannot send it a frame");
|
||||
if (GetNLinks() == 1 || !GetWifiRemoteStationManager(*linkId)->GetMldAddress(to))
|
||||
{
|
||||
addr2Set = {GetFrameExchangeManager(*linkId)->GetAddress()};
|
||||
}
|
||||
}
|
||||
|
||||
for (auto addr2 = addr2Set.cbegin(); addr2 != addr2Set.cend(); ++addr2)
|
||||
{
|
||||
auto& hdr = mpdu->GetHeader();
|
||||
|
||||
hdr.SetAddr1(to);
|
||||
hdr.SetAddr2(*addr2);
|
||||
hdr.SetAddr3(from);
|
||||
hdr.SetDsFrom();
|
||||
hdr.SetDsNotTo();
|
||||
|
||||
auto txop = hdr.IsQosData() ? StaticCast<Txop>(GetQosTxop(hdr.GetQosTid())) : GetTxop();
|
||||
NS_ASSERT(txop);
|
||||
txop->Queue(mpdu);
|
||||
|
||||
// create another MPDU if needed
|
||||
if (std::next(addr2) != addr2Set.cend())
|
||||
{
|
||||
mpdu = Create<WifiMpdu>(mpdu->GetPacket()->Copy(), hdr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ApWifiMac::SupportsSendFrom() const
|
||||
{
|
||||
|
||||
@@ -266,6 +266,7 @@ class ApWifiMac : public WifiMac
|
||||
Mac48Address DoGetLocalAddress(const Mac48Address& remoteAddr) const override;
|
||||
void Receive(Ptr<const WifiMpdu> mpdu, uint8_t linkId) override;
|
||||
void DoCompleteConfig() override;
|
||||
void Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from) override;
|
||||
|
||||
/**
|
||||
* Check whether the supported rate set included in the received (Re)Association
|
||||
|
||||
@@ -972,6 +972,38 @@ StaWifiMac::CanForwardPacketsTo(Mac48Address to) const
|
||||
return IsAssociated();
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::NotifyDropPacketToEnqueue(Ptr<Packet> packet, Mac48Address to)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << packet << to);
|
||||
TryToEnsureAssociated();
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << *mpdu << to << from);
|
||||
|
||||
auto& hdr = mpdu->GetHeader();
|
||||
|
||||
// the Receiver Address (RA) and the Transmitter Address (TA) are the MLD addresses only for
|
||||
// non-broadcast data frames exchanged between two MLDs
|
||||
auto linkIds = GetSetupLinkIds();
|
||||
NS_ASSERT(!linkIds.empty());
|
||||
uint8_t linkId = *linkIds.begin();
|
||||
const auto apMldAddr = GetWifiRemoteStationManager(linkId)->GetMldAddress(GetBssid(linkId));
|
||||
|
||||
hdr.SetAddr1(apMldAddr.value_or(GetBssid(linkId)));
|
||||
hdr.SetAddr2(apMldAddr ? GetAddress() : GetFrameExchangeManager(linkId)->GetAddress());
|
||||
hdr.SetAddr3(to);
|
||||
hdr.SetDsNotFrom();
|
||||
hdr.SetDsTo();
|
||||
|
||||
auto txop = hdr.IsQosData() ? StaticCast<Txop>(GetQosTxop(hdr.GetQosTid())) : GetTxop();
|
||||
NS_ASSERT(txop);
|
||||
txop->Queue(mpdu);
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::Enqueue(Ptr<Packet> packet, Mac48Address to)
|
||||
{
|
||||
|
||||
@@ -410,6 +410,8 @@ class StaWifiMac : public WifiMac
|
||||
void Receive(Ptr<const WifiMpdu> mpdu, uint8_t linkId) override;
|
||||
std::unique_ptr<LinkEntity> CreateLinkEntity() const override;
|
||||
Mac48Address DoGetLocalAddress(const Mac48Address& remoteAddr) const override;
|
||||
void Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from) override;
|
||||
void NotifyDropPacketToEnqueue(Ptr<Packet> packet, Mac48Address to) override;
|
||||
|
||||
/**
|
||||
* Process the Beacon frame received on the given link.
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/pointer.h"
|
||||
#include "ns3/shuffle.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "ns3/string.h"
|
||||
#include "ns3/vht-configuration.h"
|
||||
|
||||
@@ -1617,15 +1618,80 @@ WifiMac::UnblockUnicastTxOnLinks(WifiQueueBlockedReason reason,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::Enqueue(Ptr<Packet> packet, Mac48Address to)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << packet << to);
|
||||
// We're sending this packet with a from address that is our own. We
|
||||
// get that address from the lower MAC and make use of the
|
||||
// from-spoofing Enqueue() method to avoid duplicated code.
|
||||
Enqueue(packet, to, GetAddress());
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::Enqueue(Ptr<Packet> packet, Mac48Address to, Mac48Address from)
|
||||
{
|
||||
// We expect WifiMac subclasses which do support forwarding (e.g.,
|
||||
// AP) to override this method. Therefore, we throw a fatal error if
|
||||
// someone tries to invoke this method on a class which has not done
|
||||
// this.
|
||||
NS_FATAL_ERROR("This MAC entity (" << this << ", " << GetAddress()
|
||||
<< ") does not support Enqueue() with from address");
|
||||
NS_LOG_FUNCTION(this << packet << to << from);
|
||||
|
||||
// If we are not a QoS AP then we definitely want to use AC_BE to
|
||||
// transmit the packet. A TID of zero will map to AC_BE (through \c
|
||||
// QosUtilsMapTidToAc()), so we use that as our default here.
|
||||
uint8_t tid = 0;
|
||||
|
||||
SocketPriorityTag qos;
|
||||
if (packet->RemovePacketTag(qos) && qos.GetPriority() < 8)
|
||||
{
|
||||
tid = qos.GetPriority();
|
||||
}
|
||||
|
||||
Enqueue(packet, to, from, tid);
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::Enqueue(Ptr<Packet> packet, Mac48Address to, Mac48Address from, uint8_t tid)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << packet << to << from << tid);
|
||||
|
||||
NS_ABORT_MSG_IF(!SupportsSendFrom() && from != GetAddress(),
|
||||
"This Mac does not support forwarding frames");
|
||||
|
||||
if (!CanForwardPacketsTo(to))
|
||||
{
|
||||
NotifyTxDrop(packet);
|
||||
NotifyDropPacketToEnqueue(packet, to);
|
||||
return;
|
||||
}
|
||||
|
||||
WifiMacHeader hdr;
|
||||
|
||||
// For now, an AP that supports QoS does not support non-QoS
|
||||
// associations, and vice versa. In future the AP model should
|
||||
// support simultaneously associated QoS and non-QoS STAs, at which
|
||||
// point there will need to be per-association QoS state maintained
|
||||
// by the association state machine, and consulted here.
|
||||
if (GetQosSupported())
|
||||
{
|
||||
hdr.SetType(WIFI_MAC_QOSDATA);
|
||||
hdr.SetQosAckPolicy(WifiMacHeader::NORMAL_ACK);
|
||||
hdr.SetQosNoEosp();
|
||||
hdr.SetQosNoAmsdu();
|
||||
hdr.SetQosTid(tid);
|
||||
hdr.SetNoOrder(); // explicitly set to 0 for the time being since HT control field is not
|
||||
// yet implemented (set it to 1 when implemented)
|
||||
}
|
||||
else
|
||||
{
|
||||
hdr.SetType(WIFI_MAC_DATA);
|
||||
}
|
||||
|
||||
// create an MPDU and pass it to subclasses to finalize MAC header
|
||||
Enqueue(Create<WifiMpdu>(packet, hdr), to, from);
|
||||
}
|
||||
|
||||
void
|
||||
WifiMac::NotifyDropPacketToEnqueue(Ptr<Packet> packet, Mac48Address to)
|
||||
{
|
||||
NS_LOG_FUNCTION(this << packet << to);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -370,27 +370,43 @@ class WifiMac : public Object
|
||||
* \return whether packets can be forwarded to the given destination
|
||||
*/
|
||||
virtual bool CanForwardPacketsTo(Mac48Address to) const = 0;
|
||||
|
||||
/**
|
||||
* \param packet the packet to send.
|
||||
* \param to the address to which the packet should be sent.
|
||||
*
|
||||
* The packet should be enqueued in a TX queue, and should be
|
||||
* dequeued as soon as the DCF/EDCA function determines that
|
||||
* access is granted to this MAC.
|
||||
*/
|
||||
virtual void Enqueue(Ptr<Packet> packet, Mac48Address to);
|
||||
|
||||
/**
|
||||
* \param packet the packet to send.
|
||||
* \param to the address to which the packet should be sent.
|
||||
* \param from the address from which the packet should be sent.
|
||||
*
|
||||
* The packet should be enqueued in a TX queue, and should be
|
||||
* dequeued as soon as the DCF function determines that
|
||||
* access it granted to this MAC. The extra parameter "from" allows
|
||||
* dequeued as soon as the DCF/EDCA function determines that
|
||||
* access is granted to this MAC. The extra parameter "from" allows
|
||||
* this device to operate in a bridged mode, forwarding received
|
||||
* frames without altering the source address.
|
||||
*/
|
||||
virtual void Enqueue(Ptr<Packet> packet, Mac48Address to, Mac48Address from);
|
||||
|
||||
/**
|
||||
* \param packet the packet to send.
|
||||
* \param to the address to which the packet should be sent.
|
||||
* \param from the address from which the packet should be sent.
|
||||
* \param tid the TID to use to send this packet
|
||||
*
|
||||
* The packet should be enqueued in a TX queue, and should be
|
||||
* dequeued as soon as the DCF function determines that
|
||||
* access it granted to this MAC.
|
||||
* dequeued as soon as the DCF/EDCA function determines that
|
||||
* access is granted to this MAC. The extra parameter "tid" allows
|
||||
* to specify the TID to use in case QoS is supported.
|
||||
*/
|
||||
virtual void Enqueue(Ptr<Packet> packet, Mac48Address to) = 0;
|
||||
void Enqueue(Ptr<Packet> packet, Mac48Address to, Mac48Address from, uint8_t tid);
|
||||
|
||||
/**
|
||||
* \return if this MAC supports sending from arbitrary address.
|
||||
*
|
||||
@@ -1114,6 +1130,24 @@ class WifiMac : public Object
|
||||
*/
|
||||
void SetBkBlockAckInactivityTimeout(uint16_t timeout);
|
||||
|
||||
/**
|
||||
* \param mpdu the MPDU to send.
|
||||
* \param to the address to which the packet should be sent.
|
||||
* \param from the address from which the packet should be sent.
|
||||
*
|
||||
* Subclasses need to implement this method to finalize the MAC header of the MPDU
|
||||
* (MAC addresses and ToDS/FromDS flags) and enqueue the MPDU in a TX queue.
|
||||
*/
|
||||
virtual void Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from) = 0;
|
||||
|
||||
/**
|
||||
* Allow subclasses to take actions when a packet to enqueue has been dropped.
|
||||
*
|
||||
* \param packet the dropped packet
|
||||
* \param to the address to which the packet should have been sent
|
||||
*/
|
||||
virtual void NotifyDropPacketToEnqueue(Ptr<Packet> packet, Mac48Address to);
|
||||
|
||||
/**
|
||||
* This Boolean is set \c true iff this WifiMac is to model
|
||||
* 802.11e/WMM style Quality of Service. It is exposed through the
|
||||
|
||||
@@ -221,6 +221,10 @@ class MldSwapLinksTest : public TestCase
|
||||
void DoCompleteConfig() override
|
||||
{
|
||||
}
|
||||
|
||||
void Enqueue(Ptr<WifiMpdu> mpdu, Mac48Address to, Mac48Address from) override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user