wifi: StaWifiMac makes use of the Association Manager
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "ns3/frame-exchange-manager.h"
|
||||
#include "ns3/wifi-protection-manager.h"
|
||||
#include "ns3/wifi-ack-manager.h"
|
||||
#include "ns3/wifi-assoc-manager.h"
|
||||
#include "ns3/multi-user-scheduler.h"
|
||||
#include "ns3/boolean.h"
|
||||
|
||||
@@ -33,6 +34,7 @@ WifiMacHelper::WifiMacHelper ()
|
||||
//By default, we create an AdHoc MAC layer (without QoS).
|
||||
SetType ("ns3::AdhocWifiMac");
|
||||
|
||||
m_assocManager.SetTypeId ("ns3::WifiDefaultAssocManager");
|
||||
m_protectionManager.SetTypeId ("ns3::WifiDefaultProtectionManager");
|
||||
m_ackManager.SetTypeId ("ns3::WifiDefaultAckManager");
|
||||
}
|
||||
@@ -98,6 +100,13 @@ WifiMacHelper::Create (Ptr<WifiNetDevice> device, WifiStandard standard) const
|
||||
apMac->AggregateObject (muScheduler);
|
||||
}
|
||||
|
||||
// create and install the Association Manager if this is a STA
|
||||
if (auto staMac = DynamicCast<StaWifiMac> (mac); staMac != nullptr)
|
||||
{
|
||||
Ptr<WifiAssocManager> assocManager = m_assocManager.Create<WifiAssocManager> ();
|
||||
staMac->SetAssocManager (assocManager);
|
||||
}
|
||||
|
||||
return mac;
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,16 @@ public:
|
||||
template <typename... Args>
|
||||
void SetType (std::string type, Args&&... args);
|
||||
|
||||
/**
|
||||
* Helper function used to set the Association Manager.
|
||||
*
|
||||
* \tparam Args \deduced Template type parameter pack for the sequence of name-value pairs.
|
||||
* \param type the type of Association Manager
|
||||
* \param args A sequence of name-value pairs of the attributes to set.
|
||||
*/
|
||||
template <typename... Args>
|
||||
void SetAssocManager (std::string type, Args&&... args);
|
||||
|
||||
/**
|
||||
* Helper function used to set the Protection Manager.
|
||||
*
|
||||
@@ -111,6 +121,7 @@ public:
|
||||
|
||||
protected:
|
||||
ObjectFactory m_mac; ///< MAC object factory
|
||||
ObjectFactory m_assocManager; ///< Association Manager
|
||||
ObjectFactory m_protectionManager; ///< Factory to create a protection manager
|
||||
ObjectFactory m_ackManager; ///< Factory to create an acknowledgment manager
|
||||
ObjectFactory m_muScheduler; ///< Multi-user Scheduler object factory
|
||||
@@ -133,6 +144,14 @@ WifiMacHelper::SetType (std::string type, Args&&... args)
|
||||
m_mac.Set (args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void
|
||||
WifiMacHelper::SetAssocManager (std::string type, Args&&... args)
|
||||
{
|
||||
m_assocManager.SetTypeId (type);
|
||||
m_assocManager.Set (args...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void
|
||||
WifiMacHelper::SetProtectionManager (std::string type, Args&&... args)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "wifi-phy.h"
|
||||
#include "mgt-headers.h"
|
||||
#include "snr-tag.h"
|
||||
#include "wifi-assoc-manager.h"
|
||||
#include "wifi-net-device.h"
|
||||
#include "ns3/ht-configuration.h"
|
||||
#include "ns3/he-configuration.h"
|
||||
@@ -99,8 +100,6 @@ StaWifiMac::GetTypeId (void)
|
||||
StaWifiMac::StaWifiMac ()
|
||||
: m_state (UNASSOCIATED),
|
||||
m_aid (0),
|
||||
m_waitBeaconEvent (),
|
||||
m_probeRequestEvent (),
|
||||
m_assocRequestEvent (),
|
||||
m_beaconWatchdogEnd (Seconds (0))
|
||||
{
|
||||
@@ -118,6 +117,18 @@ StaWifiMac::DoInitialize (void)
|
||||
StartScanning ();
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::DoDispose (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (m_assocManager)
|
||||
{
|
||||
m_assocManager->Dispose ();
|
||||
}
|
||||
m_assocManager = nullptr;
|
||||
WifiMac::DoDispose ();
|
||||
}
|
||||
|
||||
StaWifiMac::~StaWifiMac ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
@@ -131,6 +142,14 @@ StaWifiMac::AssignStreams (int64_t stream)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::SetAssocManager (Ptr<WifiAssocManager> assocManager)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << assocManager);
|
||||
m_assocManager = assocManager;
|
||||
m_assocManager->SetStaWifiMac (this);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
StaWifiMac::GetAssociationId (void) const
|
||||
{
|
||||
@@ -167,6 +186,15 @@ StaWifiMac::SetWifiPhys (const std::vector<Ptr<WifiPhy>>& phys)
|
||||
}
|
||||
}
|
||||
|
||||
WifiScanParams::Channel
|
||||
StaWifiMac::GetCurrentChannel (uint8_t linkId) const
|
||||
{
|
||||
auto phy = GetWifiPhy (linkId);
|
||||
uint16_t width = phy->GetOperatingChannel ().IsOfdm () ? 20 : phy->GetChannelWidth ();
|
||||
uint8_t ch = phy->GetOperatingChannel ().GetPrimaryChannelNumber (width, phy->GetStandard ());
|
||||
return {ch, phy->GetPhyBand ()};
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::SendProbeRequest (void)
|
||||
{
|
||||
@@ -354,68 +382,68 @@ void
|
||||
StaWifiMac::StartScanning (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_candidateAps.clear ();
|
||||
if (m_probeRequestEvent.IsRunning ())
|
||||
SetState (SCANNING);
|
||||
NS_ASSERT (m_assocManager);
|
||||
|
||||
WifiScanParams scanParams;
|
||||
scanParams.ssid = GetSsid ();
|
||||
for (uint8_t linkId = 0; linkId < GetNLinks (); linkId++)
|
||||
{
|
||||
m_probeRequestEvent.Cancel ();
|
||||
WifiScanParams::ChannelList channel {(GetWifiPhy (linkId)->HasFixedPhyBand ())
|
||||
? WifiScanParams::Channel {0, GetWifiPhy (linkId)->GetPhyBand ()}
|
||||
: WifiScanParams::Channel {0, WIFI_PHY_BAND_UNSPECIFIED}};
|
||||
|
||||
scanParams.channelList.push_back (channel);
|
||||
}
|
||||
if (m_waitBeaconEvent.IsRunning ())
|
||||
if (m_activeProbing)
|
||||
{
|
||||
m_waitBeaconEvent.Cancel ();
|
||||
}
|
||||
if (GetActiveProbing ())
|
||||
{
|
||||
SendProbeRequest ();
|
||||
m_probeRequestEvent = Simulator::Schedule (m_probeRequestTimeout,
|
||||
&StaWifiMac::ScanningTimeout,
|
||||
this);
|
||||
scanParams.type = WifiScanParams::ACTIVE;
|
||||
scanParams.probeDelay = MicroSeconds (m_probeDelay->GetValue ());
|
||||
scanParams.minChannelTime = scanParams.maxChannelTime = m_probeRequestTimeout;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_waitBeaconEvent = Simulator::Schedule (m_waitBeaconTimeout,
|
||||
&StaWifiMac::ScanningTimeout,
|
||||
this);
|
||||
scanParams.type = WifiScanParams::PASSIVE;
|
||||
scanParams.maxChannelTime = m_waitBeaconTimeout;
|
||||
}
|
||||
SetState (SCANNING);
|
||||
|
||||
m_assocManager->StartScanning (std::move (scanParams));
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::ScanningTimeout (void)
|
||||
StaWifiMac::ScanningTimeout (const std::optional<ApInfo>& bestAp)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (!m_candidateAps.empty ())
|
||||
{
|
||||
ApInfo bestAp = m_candidateAps.front();
|
||||
m_candidateAps.erase(m_candidateAps.begin ());
|
||||
NS_LOG_DEBUG ("Attempting to associate with BSSID " << bestAp.m_bssid);
|
||||
UpdateApInfo (bestAp.m_frame, bestAp.m_apAddr, bestAp.m_bssid, bestAp.m_linkId);
|
||||
// lambda to get beacon interval from Beacon or Probe Response
|
||||
auto getBeaconInterval =
|
||||
[](auto&& frame)
|
||||
{
|
||||
using T = std::decay_t<decltype (frame)>;
|
||||
if constexpr (std::is_same_v<T, MgtBeaconHeader>
|
||||
|| std::is_same_v<T, MgtProbeResponseHeader>)
|
||||
{
|
||||
return MicroSeconds (frame.GetBeaconIntervalUs ());
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG ("Unexpected frame type");
|
||||
return Seconds (0);
|
||||
}
|
||||
};
|
||||
Time beaconInterval = std::visit (getBeaconInterval, bestAp.m_frame);
|
||||
Time delay = beaconInterval * m_maxMissedBeacons;
|
||||
RestartBeaconWatchdog (delay);
|
||||
SetState (WAIT_ASSOC_RESP);
|
||||
SendAssociationRequest (false);
|
||||
}
|
||||
else
|
||||
|
||||
if (!bestAp.has_value ())
|
||||
{
|
||||
NS_LOG_DEBUG ("Exhausted list of candidate AP; restart scanning");
|
||||
StartScanning ();
|
||||
return;
|
||||
}
|
||||
|
||||
NS_LOG_DEBUG ("Attempting to associate with BSSID " << bestAp->m_bssid);
|
||||
UpdateApInfo (bestAp->m_frame, bestAp->m_apAddr, bestAp->m_bssid, bestAp->m_linkId);
|
||||
// lambda to get beacon interval from Beacon or Probe Response
|
||||
auto getBeaconInterval =
|
||||
[](auto&& frame)
|
||||
{
|
||||
using T = std::decay_t<decltype (frame)>;
|
||||
if constexpr (std::is_same_v<T, MgtBeaconHeader> || std::is_same_v<T, MgtProbeResponseHeader>)
|
||||
{
|
||||
return MicroSeconds (frame.GetBeaconIntervalUs ());
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ABORT_MSG ("Unexpected frame type");
|
||||
return Seconds (0);
|
||||
}
|
||||
};
|
||||
Time beaconInterval = std::visit (getBeaconInterval, bestAp->m_frame);
|
||||
Time delay = beaconInterval * m_maxMissedBeacons;
|
||||
RestartBeaconWatchdog (delay);
|
||||
SetState (WAIT_ASSOC_RESP);
|
||||
SendAssociationRequest (false);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -645,10 +673,9 @@ StaWifiMac::Receive (Ptr<WifiMacQueueItem> mpdu, uint8_t linkId)
|
||||
}
|
||||
else
|
||||
{
|
||||
// we retain this Beacon as candidate AP if the SSID matches ours and the
|
||||
// supported rates fit the configured BSS membership selector
|
||||
goodBeacon = ((GetSsid ().IsBroadcast () || beacon.GetSsid ().IsEqual (GetSsid ()))
|
||||
&& CheckSupportedRates (beacon, linkId));
|
||||
// we retain this Beacon as candidate AP if the supported rates fit the
|
||||
// configured BSS membership selector
|
||||
goodBeacon = CheckSupportedRates (beacon, linkId);
|
||||
}
|
||||
|
||||
if (!goodBeacon)
|
||||
@@ -663,9 +690,9 @@ StaWifiMac::Receive (Ptr<WifiMacQueueItem> mpdu, uint8_t linkId)
|
||||
RestartBeaconWatchdog (delay);
|
||||
UpdateApInfo (beacon, hdr->GetAddr2 (), hdr->GetAddr3 (), linkId);
|
||||
}
|
||||
else if (m_state == SCANNING)
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("Beacon received while scanning from " << hdr->GetAddr2 ());
|
||||
NS_LOG_DEBUG ("Beacon received from " << hdr->GetAddr2 ());
|
||||
SnrTag snrTag;
|
||||
bool removed = copy->RemovePacketTag (snrTag);
|
||||
NS_ASSERT (removed);
|
||||
@@ -673,36 +700,34 @@ StaWifiMac::Receive (Ptr<WifiMacQueueItem> mpdu, uint8_t linkId)
|
||||
apInfo.m_apAddr = hdr->GetAddr2 ();
|
||||
apInfo.m_bssid = hdr->GetAddr3 ();
|
||||
apInfo.m_snr = snrTag.Get ();
|
||||
apInfo.m_frame = beacon;
|
||||
apInfo.m_frame = std::move (beacon);
|
||||
apInfo.m_linkId = linkId;
|
||||
UpdateCandidateApList (apInfo);
|
||||
apInfo.m_channel = {GetCurrentChannel (linkId)};
|
||||
m_assocManager->NotifyApInfo (std::move (apInfo));
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (hdr->IsProbeResp ())
|
||||
{
|
||||
if (m_state == SCANNING)
|
||||
NS_LOG_DEBUG ("Probe response received from " << hdr->GetAddr2 ());
|
||||
MgtProbeResponseHeader probeResp;
|
||||
Ptr<Packet> copy = packet->Copy ();
|
||||
copy->RemoveHeader (probeResp);
|
||||
if (!CheckSupportedRates (probeResp, linkId))
|
||||
{
|
||||
NS_LOG_DEBUG ("Probe response received while scanning from " << hdr->GetAddr2 ());
|
||||
MgtProbeResponseHeader probeResp;
|
||||
Ptr<Packet> copy = packet->Copy ();
|
||||
copy->RemoveHeader (probeResp);
|
||||
if ((!GetSsid ().IsBroadcast () && !probeResp.GetSsid ().IsEqual (GetSsid ()))
|
||||
|| !CheckSupportedRates (probeResp, linkId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
SnrTag snrTag;
|
||||
bool removed = copy->RemovePacketTag (snrTag);
|
||||
NS_ASSERT (removed);
|
||||
ApInfo apInfo;
|
||||
apInfo.m_apAddr = hdr->GetAddr2 ();
|
||||
apInfo.m_bssid = hdr->GetAddr3 ();
|
||||
apInfo.m_snr = snrTag.Get ();
|
||||
apInfo.m_frame = probeResp;
|
||||
apInfo.m_linkId = linkId;
|
||||
UpdateCandidateApList (apInfo);
|
||||
return;
|
||||
}
|
||||
SnrTag snrTag;
|
||||
bool removed = copy->RemovePacketTag (snrTag);
|
||||
NS_ASSERT (removed);
|
||||
ApInfo apInfo;
|
||||
apInfo.m_apAddr = hdr->GetAddr2 ();
|
||||
apInfo.m_bssid = hdr->GetAddr3 ();
|
||||
apInfo.m_snr = snrTag.Get ();
|
||||
apInfo.m_frame = std::move (probeResp);
|
||||
apInfo.m_linkId = linkId;
|
||||
apInfo.m_channel = {GetCurrentChannel (linkId)};
|
||||
m_assocManager->NotifyApInfo (std::move (apInfo));
|
||||
return;
|
||||
}
|
||||
else if (hdr->IsAssocResp () || hdr->IsReassocResp ())
|
||||
@@ -736,14 +761,8 @@ StaWifiMac::Receive (Ptr<WifiMacQueueItem> mpdu, uint8_t linkId)
|
||||
else
|
||||
{
|
||||
NS_LOG_DEBUG ("association refused");
|
||||
if (m_candidateAps.empty ())
|
||||
{
|
||||
SetState (REFUSED);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScanningTimeout ();
|
||||
}
|
||||
SetState (REFUSED);
|
||||
StartScanning ();
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -782,32 +801,6 @@ StaWifiMac::CheckSupportedRates (std::variant<MgtBeaconHeader, MgtProbeResponseH
|
||||
return std::visit (check, frame);
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::UpdateCandidateApList (ApInfo newApInfo)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << newApInfo.m_bssid << newApInfo.m_apAddr << newApInfo.m_snr << newApInfo.m_frame.index () +newApInfo.m_linkId);
|
||||
// Remove duplicate ApInfo entry
|
||||
for (std::vector<ApInfo>::iterator i = m_candidateAps.begin(); i != m_candidateAps.end(); ++i)
|
||||
{
|
||||
if (newApInfo.m_bssid == (*i).m_bssid)
|
||||
{
|
||||
m_candidateAps.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Insert before the entry with lower SNR
|
||||
for (std::vector<ApInfo>::iterator i = m_candidateAps.begin(); i != m_candidateAps.end(); ++i)
|
||||
{
|
||||
if (newApInfo.m_snr > (*i).m_snr)
|
||||
{
|
||||
m_candidateAps.insert (i, newApInfo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If new ApInfo is the lowest, insert at back
|
||||
m_candidateAps.push_back(newApInfo);
|
||||
}
|
||||
|
||||
void
|
||||
StaWifiMac::UpdateApInfo (const MgtFrameType& frame, const Mac48Address& apAddr,
|
||||
const Mac48Address& bssid, uint8_t linkId)
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace ns3 {
|
||||
class SupportedRates;
|
||||
class CapabilityInformation;
|
||||
class RandomVariableStream;
|
||||
class WifiAssocManager;
|
||||
|
||||
|
||||
/**
|
||||
@@ -168,6 +169,13 @@ public:
|
||||
*/
|
||||
void SetWifiPhys (const std::vector<Ptr<WifiPhy>>& phys) override;
|
||||
|
||||
/**
|
||||
* Set the Association Manager.
|
||||
*
|
||||
* \param assocManager the Association Manager
|
||||
*/
|
||||
void SetAssocManager (Ptr<WifiAssocManager> assocManager);
|
||||
|
||||
/**
|
||||
* Forward a probe request packet to the DCF. The standard is not clear on the correct
|
||||
* queue for management frames if QoS is supported. We always use the DCF.
|
||||
@@ -178,8 +186,10 @@ public:
|
||||
* This method is called after wait beacon timeout or wait probe request timeout has
|
||||
* occurred. This will trigger association process from beacons or probe responses
|
||||
* gathered while scanning.
|
||||
*
|
||||
* \param bestAp the info about the best AP to associate with, if one was found
|
||||
*/
|
||||
void ScanningTimeout (void);
|
||||
void ScanningTimeout (const std::optional<ApInfo>& bestAp);
|
||||
|
||||
/**
|
||||
* Return whether we are associated with an AP.
|
||||
@@ -260,14 +270,6 @@ private:
|
||||
void UpdateApInfo (const MgtFrameType& frame, const Mac48Address& apAddr,
|
||||
const Mac48Address& bssid, uint8_t linkId);
|
||||
|
||||
/**
|
||||
* Update list of candidate AP to associate. The list should contain ApInfo sorted from
|
||||
* best to worst SNR, with no duplicate.
|
||||
*
|
||||
* \param newApInfo the new ApInfo to be inserted
|
||||
*/
|
||||
void UpdateCandidateApList (ApInfo newApInfo);
|
||||
|
||||
/**
|
||||
* Forward an association or reassociation request packet to the DCF.
|
||||
* The standard is not clear on the correct queue for management frames if QoS is supported.
|
||||
@@ -357,15 +359,24 @@ private:
|
||||
*/
|
||||
void PhyCapabilitiesChanged (void);
|
||||
|
||||
/**
|
||||
* Get the current primary20 channel used on the given link as a
|
||||
* (channel number, PHY band) pair.
|
||||
*
|
||||
* \param linkId the ID of the given link
|
||||
* \return a (channel number, PHY band) pair
|
||||
*/
|
||||
WifiScanParams::Channel GetCurrentChannel (uint8_t linkId) const;
|
||||
|
||||
void DoInitialize (void) override;
|
||||
void DoDispose (void) override;
|
||||
|
||||
MacState m_state; ///< MAC state
|
||||
uint16_t m_aid; ///< Association AID
|
||||
Ptr<WifiAssocManager> m_assocManager; ///< Association Manager
|
||||
Time m_waitBeaconTimeout; ///< wait beacon timeout
|
||||
Time m_probeRequestTimeout; ///< probe request timeout
|
||||
Time m_assocRequestTimeout; ///< association request timeout
|
||||
EventId m_waitBeaconEvent; ///< wait beacon event
|
||||
EventId m_probeRequestEvent; ///< probe request event
|
||||
EventId m_assocRequestEvent; ///< association request event
|
||||
EventId m_beaconWatchdog; ///< beacon watchdog
|
||||
Time m_beaconWatchdogEnd; ///< beacon watchdog end
|
||||
@@ -373,11 +384,6 @@ private:
|
||||
bool m_activeProbing; ///< active probing
|
||||
Ptr<RandomVariableStream> m_probeDelay; ///< RandomVariable used to randomize the time
|
||||
///< of the first Probe Response on each channel
|
||||
std::vector<ApInfo> m_candidateAps; ///< list of candidate APs to associate to
|
||||
// Note: std::multiset<ApInfo> might be a candidate container to implement
|
||||
// this sorted list, but we are using a std::vector because we want to sort
|
||||
// based on SNR but find duplicates based on BSSID, and in practice this
|
||||
// candidate vector should not be too large.
|
||||
|
||||
TracedCallback<Mac48Address> m_assocLogger; ///< association logger
|
||||
TracedCallback<Mac48Address> m_deAssocLogger; ///< disassociation logger
|
||||
|
||||
@@ -226,7 +226,7 @@ WifiAssocManager::ScanningTimeout (void)
|
||||
{
|
||||
if (m_apList.empty ())
|
||||
{
|
||||
m_mac->ScanningTimeout (/*std::nullopt*/);
|
||||
m_mac->ScanningTimeout (std::nullopt);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ WifiAssocManager::ScanningTimeout (void)
|
||||
m_apListIt.erase (bestAp.m_bssid);
|
||||
} while (!CanBeReturned (bestAp));
|
||||
|
||||
m_mac->ScanningTimeout (/*std::move (bestAp)*/);
|
||||
m_mac->ScanningTimeout (std::move (bestAp));
|
||||
}
|
||||
|
||||
} //namespace ns3
|
||||
|
||||
@@ -436,13 +436,18 @@ WifiPrimaryChannelsTest::DoSetup (void)
|
||||
void
|
||||
WifiPrimaryChannelsTest::DoRun (void)
|
||||
{
|
||||
// schedule association requests at different times
|
||||
// schedule association requests at different times. One station's SSID is
|
||||
// set to the correct value before initialization, so that such a station
|
||||
// starts the scanning procedure by looking for the correct SSID
|
||||
Ptr<WifiNetDevice> dev;
|
||||
|
||||
for (uint16_t i = 0; i < m_nStationsPerBss; i++)
|
||||
// association can be done in parallel over the multiple BSSes
|
||||
for (uint8_t bss = 0; bss < m_nBss; bss++)
|
||||
{
|
||||
// association can be done in parallel over the multiple BSSes
|
||||
for (uint8_t bss = 0; bss < m_nBss; bss++)
|
||||
dev = DynamicCast<WifiNetDevice> (m_staDevices[bss].Get (0));
|
||||
dev->GetMac ()->SetSsid (Ssid ("wifi-ssid-" + std::to_string (bss)));
|
||||
|
||||
for (uint16_t i = 1; i < m_nStationsPerBss; i++)
|
||||
{
|
||||
dev = DynamicCast<WifiNetDevice> (m_staDevices[bss].Get (i));
|
||||
Simulator::Schedule (i * MicroSeconds (102400), &WifiMac::SetSsid,
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#include "ns3/frame-exchange-manager.h"
|
||||
#include "ns3/wifi-default-protection-manager.h"
|
||||
#include "ns3/wifi-default-ack-manager.h"
|
||||
#include "ns3/wifi-default-assoc-manager.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
@@ -160,6 +161,10 @@ WifiTest::CreateOne (Vector pos, Ptr<YansWifiChannel> channel)
|
||||
mac->SetAddress (Mac48Address::Allocate ());
|
||||
dev->SetMac (mac);
|
||||
mac->ConfigureStandard (WIFI_STANDARD_80211a);
|
||||
if (mac->GetTypeOfStation () == STA)
|
||||
{
|
||||
StaticCast<StaWifiMac> (mac)->SetAssocManager (CreateObject<WifiDefaultAssocManager> ());
|
||||
}
|
||||
Ptr<FrameExchangeManager> fem = mac->GetFrameExchangeManager ();
|
||||
Ptr<WifiProtectionManager> protectionManager = CreateObject<WifiDefaultProtectionManager> ();
|
||||
protectionManager->SetWifiMac (mac);
|
||||
@@ -1801,6 +1806,7 @@ Bug2831TestCase::DoRun (void)
|
||||
staMac->SetDevice (staDev);
|
||||
staMac->SetAddress (Mac48Address::Allocate ());
|
||||
staMac->ConfigureStandard (WIFI_STANDARD_80211ax);
|
||||
StaticCast<StaWifiMac> (staMac)->SetAssocManager (CreateObject<WifiDefaultAssocManager> ());
|
||||
fem = staMac->GetFrameExchangeManager ();
|
||||
protectionManager = CreateObject<WifiDefaultProtectionManager> ();
|
||||
protectionManager->SetWifiMac (staMac);
|
||||
|
||||
@@ -192,14 +192,16 @@ WifiTxopTest::DoRun (void)
|
||||
|
||||
m_apDevices = wifi.Install (phy, mac, wifiApNode);
|
||||
|
||||
// schedule association requests at different times
|
||||
Time init = MilliSeconds (100);
|
||||
Ptr<WifiNetDevice> dev;
|
||||
// schedule association requests at different times. One station's SSID is
|
||||
// set to the correct value before initialization, so that such a station
|
||||
// starts the scanning procedure by looking for the correct SSID
|
||||
Ptr<WifiNetDevice> dev = DynamicCast<WifiNetDevice> (m_staDevices.Get (0));
|
||||
dev->GetMac ()->SetSsid (Ssid ("wifi-txop-ssid"));
|
||||
|
||||
for (uint16_t i = 0; i < m_nStations; i++)
|
||||
for (uint16_t i = 1; i < m_nStations; i++)
|
||||
{
|
||||
dev = DynamicCast<WifiNetDevice> (m_staDevices.Get (i));
|
||||
Simulator::Schedule (init + i * MicroSeconds (102400), &WifiMac::SetSsid,
|
||||
Simulator::Schedule (i * MicroSeconds (102400), &WifiMac::SetSsid,
|
||||
dev->GetMac (), Ssid ("wifi-txop-ssid"));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user