wifi: (fixes #2831) trigger reassociation if PHY capabilities changed
This commit is contained in:
@@ -51,6 +51,7 @@ Bugs fixed
|
|||||||
- Bug 2824 - ICMP opcode fr fragment timeout drop is wrong
|
- Bug 2824 - ICMP opcode fr fragment timeout drop is wrong
|
||||||
- Bug 2828 - OLSR simple P2P example produces wrong results
|
- Bug 2828 - OLSR simple P2P example produces wrong results
|
||||||
- Bug 2827 - wifi: Active scanning not working with 802.11n/ac/ax
|
- Bug 2827 - wifi: Active scanning not working with 802.11n/ac/ax
|
||||||
|
- Bug 2831 - wifi: runtime channel width switch has no effect
|
||||||
- Bug 2836 - wifi: Missing VHT information in radiotap header when A-MPDU is used
|
- Bug 2836 - wifi: Missing VHT information in radiotap header when A-MPDU is used
|
||||||
- Bug 2838 - wifi: ht-wifi-network crashes with RTS/CTS enabled and frequency set to 2.4GHz
|
- Bug 2838 - wifi: ht-wifi-network crashes with RTS/CTS enabled and frequency set to 2.4GHz
|
||||||
- Bug 2843 - spectrum, wifi: Incorrect channel width and center frequency provided for non-HT PPDUs when building SpectralDensity
|
- Bug 2843 - spectrum, wifi: Incorrect channel width and center frequency provided for non-HT PPDUs when building SpectralDensity
|
||||||
|
|||||||
@@ -719,11 +719,11 @@ ApWifiMac::SendProbeResp (Mac48Address to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ApWifiMac::SendAssocResp (Mac48Address to, bool success)
|
ApWifiMac::SendAssocResp (Mac48Address to, bool success, bool isReassoc)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this << to << success);
|
NS_LOG_FUNCTION (this << to << success << isReassoc);
|
||||||
WifiMacHeader hdr;
|
WifiMacHeader hdr;
|
||||||
hdr.SetType (WIFI_MAC_MGT_ASSOCIATION_RESPONSE);
|
hdr.SetType (isReassoc ? WIFI_MAC_MGT_REASSOCIATION_RESPONSE : WIFI_MAC_MGT_ASSOCIATION_RESPONSE);
|
||||||
hdr.SetAddr1 (to);
|
hdr.SetAddr1 (to);
|
||||||
hdr.SetAddr2 (GetAddress ());
|
hdr.SetAddr2 (GetAddress ());
|
||||||
hdr.SetAddr3 (GetAddress ());
|
hdr.SetAddr3 (GetAddress ());
|
||||||
@@ -736,8 +736,25 @@ ApWifiMac::SendAssocResp (Mac48Address to, bool success)
|
|||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
code.SetSuccess ();
|
code.SetSuccess ();
|
||||||
uint16_t aid = GetNextAssociationId ();
|
uint16_t aid;
|
||||||
m_staList.insert (std::make_pair (aid, to));
|
bool found = false;
|
||||||
|
if (isReassoc)
|
||||||
|
{
|
||||||
|
for (std::map<uint16_t, Mac48Address>::const_iterator i = m_staList.begin (); i != m_staList.end (); ++i)
|
||||||
|
{
|
||||||
|
if (i->second == to)
|
||||||
|
{
|
||||||
|
aid = i->first;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
aid = GetNextAssociationId ();
|
||||||
|
m_staList.insert (std::make_pair (aid, to));
|
||||||
|
}
|
||||||
assoc.SetAssociationId (aid);
|
assoc.SetAssociationId (aid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -857,8 +874,7 @@ ApWifiMac::TxOk (const WifiMacHeader &hdr)
|
|||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this);
|
NS_LOG_FUNCTION (this);
|
||||||
RegularWifiMac::TxOk (hdr);
|
RegularWifiMac::TxOk (hdr);
|
||||||
|
if ((hdr.IsAssocResp () || hdr.IsReassocResp ())
|
||||||
if (hdr.IsAssocResp ()
|
|
||||||
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
|
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
|
||||||
{
|
{
|
||||||
NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ());
|
NS_LOG_DEBUG ("associated with sta=" << hdr.GetAddr1 ());
|
||||||
@@ -872,10 +888,10 @@ ApWifiMac::TxFailed (const WifiMacHeader &hdr)
|
|||||||
NS_LOG_FUNCTION (this);
|
NS_LOG_FUNCTION (this);
|
||||||
RegularWifiMac::TxFailed (hdr);
|
RegularWifiMac::TxFailed (hdr);
|
||||||
|
|
||||||
if (hdr.IsAssocResp ()
|
if ((hdr.IsAssocResp () || hdr.IsReassocResp ())
|
||||||
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
|
&& m_stationManager->IsWaitAssocTxOk (hdr.GetAddr1 ()))
|
||||||
{
|
{
|
||||||
NS_LOG_DEBUG ("assoc failed with sta=" << hdr.GetAddr1 ());
|
NS_LOG_DEBUG ("association failed with sta=" << hdr.GetAddr1 ());
|
||||||
m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
|
m_stationManager->RecordGotAssocTxFailed (hdr.GetAddr1 ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -884,9 +900,7 @@ void
|
|||||||
ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this << packet << hdr);
|
NS_LOG_FUNCTION (this << packet << hdr);
|
||||||
|
|
||||||
Mac48Address from = hdr->GetAddr2 ();
|
Mac48Address from = hdr->GetAddr2 ();
|
||||||
|
|
||||||
if (hdr->IsData ())
|
if (hdr->IsData ())
|
||||||
{
|
{
|
||||||
Mac48Address bssid = hdr->GetAddr1 ();
|
Mac48Address bssid = hdr->GetAddr1 ();
|
||||||
@@ -961,6 +975,7 @@ ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
if (hdr->IsProbeReq ())
|
if (hdr->IsProbeReq ())
|
||||||
{
|
{
|
||||||
NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
|
NS_ASSERT (hdr->GetAddr1 ().IsBroadcast ());
|
||||||
|
NS_LOG_DEBUG ("Probe request received from " << from << ": send probe response");
|
||||||
SendProbeResp (from);
|
SendProbeResp (from);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -968,6 +983,7 @@ ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
{
|
{
|
||||||
if (hdr->IsAssocReq ())
|
if (hdr->IsAssocReq ())
|
||||||
{
|
{
|
||||||
|
NS_LOG_DEBUG ("Association request received from " << from);
|
||||||
//first, verify that the the station's supported
|
//first, verify that the the station's supported
|
||||||
//rate set is compatible with our Basic Rate set
|
//rate set is compatible with our Basic Rate set
|
||||||
MgtAssocRequestHeader assocReq;
|
MgtAssocRequestHeader assocReq;
|
||||||
@@ -1074,14 +1090,12 @@ ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
}
|
}
|
||||||
if (problem)
|
if (problem)
|
||||||
{
|
{
|
||||||
//One of the Basic Rate set mode is not
|
NS_LOG_DEBUG ("One of the Basic Rate set mode is not supported by the station: send association response with an error status");
|
||||||
//supported by the station. So, we return an assoc
|
SendAssocResp (hdr->GetAddr2 (), false, false);
|
||||||
//response with an error status.
|
|
||||||
SendAssocResp (hdr->GetAddr2 (), false);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//station supports all rates in Basic Rate Set.
|
NS_LOG_DEBUG ("The Basic Rate set modes are supported by the station");
|
||||||
//record all its supported modes in its associated WifiRemoteStation
|
//record all its supported modes in its associated WifiRemoteStation
|
||||||
for (uint8_t j = 0; j < m_phy->GetNModes (); j++)
|
for (uint8_t j = 0; j < m_phy->GetNModes (); j++)
|
||||||
{
|
{
|
||||||
@@ -1136,18 +1150,202 @@ ApWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
if (!isHtStation)
|
if (!isHtStation)
|
||||||
{
|
{
|
||||||
m_nonHtStations.push_back (hdr->GetAddr2 ());
|
m_nonHtStations.push_back (hdr->GetAddr2 ());
|
||||||
|
m_nonHtStations.unique ();
|
||||||
}
|
}
|
||||||
if (!isErpStation && isDsssStation)
|
if (!isErpStation && isDsssStation)
|
||||||
{
|
{
|
||||||
m_nonErpStations.push_back (hdr->GetAddr2 ());
|
m_nonErpStations.push_back (hdr->GetAddr2 ());
|
||||||
|
m_nonErpStations.unique ();
|
||||||
}
|
}
|
||||||
// send assoc response with success status.
|
NS_LOG_DEBUG ("Send association response with success status");
|
||||||
SendAssocResp (hdr->GetAddr2 (), true);
|
SendAssocResp (hdr->GetAddr2 (), true, false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (hdr->IsReassocReq ())
|
||||||
|
{
|
||||||
|
NS_LOG_DEBUG ("Reassociation request received from " << from);
|
||||||
|
//first, verify that the the station's supported
|
||||||
|
//rate set is compatible with our Basic Rate set
|
||||||
|
MgtReassocRequestHeader reassocReq;
|
||||||
|
packet->RemoveHeader (reassocReq);
|
||||||
|
CapabilityInformation capabilities = reassocReq.GetCapabilities ();
|
||||||
|
m_stationManager->AddSupportedPlcpPreamble (from, capabilities.IsShortPreamble ());
|
||||||
|
SupportedRates rates = reassocReq.GetSupportedRates ();
|
||||||
|
bool problem = false;
|
||||||
|
bool isHtStation = false;
|
||||||
|
bool isOfdmStation = false;
|
||||||
|
bool isErpStation = false;
|
||||||
|
bool isDsssStation = false;
|
||||||
|
for (uint8_t i = 0; i < m_stationManager->GetNBasicModes (); i++)
|
||||||
|
{
|
||||||
|
WifiMode mode = m_stationManager->GetBasicMode (i);
|
||||||
|
if (!rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth ())))
|
||||||
|
{
|
||||||
|
if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS))
|
||||||
|
{
|
||||||
|
isDsssStation = false;
|
||||||
|
}
|
||||||
|
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
|
||||||
|
{
|
||||||
|
isErpStation = false;
|
||||||
|
}
|
||||||
|
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM)
|
||||||
|
{
|
||||||
|
isOfdmStation = false;
|
||||||
|
}
|
||||||
|
if (isDsssStation == false && isErpStation == false && isOfdmStation == false)
|
||||||
|
{
|
||||||
|
problem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((mode.GetModulationClass () == WIFI_MOD_CLASS_DSSS) || (mode.GetModulationClass () == WIFI_MOD_CLASS_HR_DSSS))
|
||||||
|
{
|
||||||
|
isDsssStation = true;
|
||||||
|
}
|
||||||
|
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_ERP_OFDM)
|
||||||
|
{
|
||||||
|
isErpStation = true;
|
||||||
|
}
|
||||||
|
else if (mode.GetModulationClass () == WIFI_MOD_CLASS_OFDM)
|
||||||
|
{
|
||||||
|
isOfdmStation = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_stationManager->AddSupportedErpSlotTime (from, capabilities.IsShortSlotTime () && isErpStation);
|
||||||
|
if (m_htSupported)
|
||||||
|
{
|
||||||
|
//check whether the HT STA supports all MCSs in Basic MCS Set
|
||||||
|
HtCapabilities htcapabilities = reassocReq.GetHtCapabilities ();
|
||||||
|
if (htcapabilities.IsSupportedMcs (0))
|
||||||
|
{
|
||||||
|
isHtStation = true;
|
||||||
|
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
|
||||||
|
{
|
||||||
|
WifiMode mcs = m_stationManager->GetBasicMcs (i);
|
||||||
|
if (!htcapabilities.IsSupportedMcs (mcs.GetMcsValue ()))
|
||||||
|
{
|
||||||
|
problem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_vhtSupported)
|
||||||
|
{
|
||||||
|
//check whether the VHT STA supports all MCSs in Basic MCS Set
|
||||||
|
VhtCapabilities vhtcapabilities = reassocReq.GetVhtCapabilities ();
|
||||||
|
if (vhtcapabilities.GetVhtCapabilitiesInfo () != 0)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
|
||||||
|
{
|
||||||
|
WifiMode mcs = m_stationManager->GetBasicMcs (i);
|
||||||
|
if (!vhtcapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
|
||||||
|
{
|
||||||
|
problem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_heSupported)
|
||||||
|
{
|
||||||
|
//check whether the HE STA supports all MCSs in Basic MCS Set
|
||||||
|
HeCapabilities hecapabilities = reassocReq.GetHeCapabilities ();
|
||||||
|
if (hecapabilities.GetSupportedMcsAndNss () != 0)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < m_stationManager->GetNBasicMcs (); i++)
|
||||||
|
{
|
||||||
|
WifiMode mcs = m_stationManager->GetBasicMcs (i);
|
||||||
|
if (!hecapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
|
||||||
|
{
|
||||||
|
problem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (problem)
|
||||||
|
{
|
||||||
|
NS_LOG_DEBUG ("One of the Basic Rate set mode is not supported by the station: send reassociation response with an error status");
|
||||||
|
SendAssocResp (hdr->GetAddr2 (), false, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NS_LOG_DEBUG ("The Basic Rate set modes are supported by the station");
|
||||||
|
//update all its supported modes in its associated WifiRemoteStation
|
||||||
|
for (uint8_t j = 0; j < m_phy->GetNModes (); j++)
|
||||||
|
{
|
||||||
|
WifiMode mode = m_phy->GetMode (j);
|
||||||
|
if (rates.IsSupportedRate (mode.GetDataRate (m_phy->GetChannelWidth ())))
|
||||||
|
{
|
||||||
|
m_stationManager->AddSupportedMode (from, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_htSupported)
|
||||||
|
{
|
||||||
|
HtCapabilities htCapabilities = reassocReq.GetHtCapabilities ();
|
||||||
|
if (htCapabilities.IsSupportedMcs (0))
|
||||||
|
{
|
||||||
|
m_stationManager->AddStationHtCapabilities (from, htCapabilities);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_vhtSupported)
|
||||||
|
{
|
||||||
|
VhtCapabilities vhtCapabilities = reassocReq.GetVhtCapabilities ();
|
||||||
|
//we will always fill in RxHighestSupportedLgiDataRate field at TX, so this can be used to check whether it supports VHT
|
||||||
|
if (vhtCapabilities.GetRxHighestSupportedLgiDataRate () > 0)
|
||||||
|
{
|
||||||
|
m_stationManager->AddStationVhtCapabilities (from, vhtCapabilities);
|
||||||
|
for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
|
||||||
|
{
|
||||||
|
WifiMode mcs = m_phy->GetMcs (i);
|
||||||
|
if (mcs.GetModulationClass () == WIFI_MOD_CLASS_VHT && vhtCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
|
||||||
|
{
|
||||||
|
m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs);
|
||||||
|
//here should add a control to add basic MCS when it is implemented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_heSupported)
|
||||||
|
{
|
||||||
|
HeCapabilities heCapabilities = reassocReq.GetHeCapabilities ();
|
||||||
|
//todo: once we support non constant rate managers, we should add checks here whether HE is supported by the peer
|
||||||
|
m_stationManager->AddStationHeCapabilities (from, heCapabilities);
|
||||||
|
for (uint8_t i = 0; i < m_phy->GetNMcs (); i++)
|
||||||
|
{
|
||||||
|
WifiMode mcs = m_phy->GetMcs (i);
|
||||||
|
if (mcs.GetModulationClass () == WIFI_MOD_CLASS_HE && heCapabilities.IsSupportedTxMcs (mcs.GetMcsValue ()))
|
||||||
|
{
|
||||||
|
m_stationManager->AddSupportedMcs (hdr->GetAddr2 (), mcs);
|
||||||
|
//here should add a control to add basic MCS when it is implemented
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_stationManager->RecordWaitAssocTxOk (from);
|
||||||
|
if (!isHtStation)
|
||||||
|
{
|
||||||
|
m_nonHtStations.push_back (hdr->GetAddr2 ());
|
||||||
|
m_nonHtStations.unique ();
|
||||||
|
}
|
||||||
|
if (!isErpStation && isDsssStation)
|
||||||
|
{
|
||||||
|
m_nonErpStations.push_back (hdr->GetAddr2 ());
|
||||||
|
m_nonErpStations.unique ();
|
||||||
|
}
|
||||||
|
NS_LOG_DEBUG ("Send reassociation response with success status");
|
||||||
|
SendAssocResp (hdr->GetAddr2 (), true, true);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (hdr->IsDisassociation ())
|
else if (hdr->IsDisassociation ())
|
||||||
{
|
{
|
||||||
|
NS_LOG_DEBUG ("Disassociation received from " << from);
|
||||||
m_stationManager->RecordDisassociated (from);
|
m_stationManager->RecordDisassociated (from);
|
||||||
for (std::map<uint16_t, Mac48Address>::const_iterator j = m_staList.begin (); j != m_staList.end (); j++)
|
for (std::map<uint16_t, Mac48Address>::const_iterator j = m_staList.begin (); j != m_staList.end (); j++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -199,13 +199,15 @@ private:
|
|||||||
*/
|
*/
|
||||||
void SendProbeResp (Mac48Address to);
|
void SendProbeResp (Mac48Address to);
|
||||||
/**
|
/**
|
||||||
* Forward an association response packet to the DCF. The standard is not clear on the correct
|
* Forward an association or a reassociation response packet to the DCF.
|
||||||
* queue for management frames if QoS is supported. We always use the DCF.
|
* The standard is not clear on the correct queue for management frames if QoS is supported.
|
||||||
|
* We always use the DCF.
|
||||||
*
|
*
|
||||||
* \param to the address of the STA we are sending an association response to
|
* \param to the address of the STA we are sending an association response to
|
||||||
* \param success indicates whether the association was successful or not
|
* \param success indicates whether the association was successful or not
|
||||||
|
* \param isReassoc indicates whether it is a reassociation response
|
||||||
*/
|
*/
|
||||||
void SendAssocResp (Mac48Address to, bool success);
|
void SendAssocResp (Mac48Address to, bool success, bool isReassoc);
|
||||||
/**
|
/**
|
||||||
* Forward a beacon packet to the beacon special DCF.
|
* Forward a beacon packet to the beacon special DCF.
|
||||||
*/
|
*/
|
||||||
@@ -300,7 +302,7 @@ private:
|
|||||||
EventId m_beaconEvent; //!< Event to generate one beacon
|
EventId m_beaconEvent; //!< Event to generate one beacon
|
||||||
Ptr<UniformRandomVariable> m_beaconJitter; //!< UniformRandomVariable used to randomize the time of the first beacon
|
Ptr<UniformRandomVariable> m_beaconJitter; //!< UniformRandomVariable used to randomize the time of the first beacon
|
||||||
bool m_enableBeaconJitter; //!< Flag whether the first beacon should be generated at random time
|
bool m_enableBeaconJitter; //!< Flag whether the first beacon should be generated at random time
|
||||||
std::map<uint16_t, Mac48Address> m_staList;//!< Map of all stations currently associated to the AP with their association ID
|
std::map<uint16_t, Mac48Address> m_staList; //!< Map of all stations currently associated to the AP with their association ID
|
||||||
std::list<Mac48Address> m_nonErpStations; //!< List of all non-ERP stations currently associated to the AP
|
std::list<Mac48Address> m_nonErpStations; //!< List of all non-ERP stations currently associated to the AP
|
||||||
std::list<Mac48Address> m_nonHtStations; //!< List of all non-HT stations currently associated to the AP
|
std::list<Mac48Address> m_nonHtStations; //!< List of all non-HT stations currently associated to the AP
|
||||||
bool m_enableNonErpProtection; //!< Flag whether protection mechanism is used or not when non-ERP STAs are present within the BSS
|
bool m_enableNonErpProtection; //!< Flag whether protection mechanism is used or not when non-ERP STAs are present within the BSS
|
||||||
|
|||||||
@@ -686,7 +686,203 @@ MgtAssocRequestHeader::Deserialize (Buffer::Iterator start)
|
|||||||
|
|
||||||
|
|
||||||
/***********************************************************
|
/***********************************************************
|
||||||
* Assoc Response
|
* Ressoc Request
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
NS_OBJECT_ENSURE_REGISTERED (MgtReassocRequestHeader);
|
||||||
|
|
||||||
|
MgtReassocRequestHeader::MgtReassocRequestHeader ()
|
||||||
|
: m_currentApAddr (Mac48Address ())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MgtReassocRequestHeader::~MgtReassocRequestHeader ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetSsid (Ssid ssid)
|
||||||
|
{
|
||||||
|
m_ssid = ssid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetSupportedRates (SupportedRates rates)
|
||||||
|
{
|
||||||
|
m_rates = rates;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetListenInterval (uint16_t interval)
|
||||||
|
{
|
||||||
|
m_listenInterval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetCapabilities (CapabilityInformation capabilities)
|
||||||
|
{
|
||||||
|
m_capability = capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
CapabilityInformation
|
||||||
|
MgtReassocRequestHeader::GetCapabilities (void) const
|
||||||
|
{
|
||||||
|
return m_capability;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetExtendedCapabilities (ExtendedCapabilities extendedcapabilities)
|
||||||
|
{
|
||||||
|
m_extendedCapability = extendedcapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExtendedCapabilities
|
||||||
|
MgtReassocRequestHeader::GetExtendedCapabilities (void) const
|
||||||
|
{
|
||||||
|
return m_extendedCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetHtCapabilities (HtCapabilities htcapabilities)
|
||||||
|
{
|
||||||
|
m_htCapability = htcapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
HtCapabilities
|
||||||
|
MgtReassocRequestHeader::GetHtCapabilities (void) const
|
||||||
|
{
|
||||||
|
return m_htCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetVhtCapabilities (VhtCapabilities vhtcapabilities)
|
||||||
|
{
|
||||||
|
m_vhtCapability = vhtcapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
VhtCapabilities
|
||||||
|
MgtReassocRequestHeader::GetVhtCapabilities (void) const
|
||||||
|
{
|
||||||
|
return m_vhtCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetHeCapabilities (HeCapabilities hecapabilities)
|
||||||
|
{
|
||||||
|
m_heCapability = hecapabilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeCapabilities
|
||||||
|
MgtReassocRequestHeader::GetHeCapabilities (void) const
|
||||||
|
{
|
||||||
|
return m_heCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ssid
|
||||||
|
MgtReassocRequestHeader::GetSsid (void) const
|
||||||
|
{
|
||||||
|
return m_ssid;
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportedRates
|
||||||
|
MgtReassocRequestHeader::GetSupportedRates (void) const
|
||||||
|
{
|
||||||
|
return m_rates;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t
|
||||||
|
MgtReassocRequestHeader::GetListenInterval (void) const
|
||||||
|
{
|
||||||
|
return m_listenInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::SetCurrentApAddress (Mac48Address currentApAddr)
|
||||||
|
{
|
||||||
|
m_currentApAddr = currentApAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeId
|
||||||
|
MgtReassocRequestHeader::GetTypeId (void)
|
||||||
|
{
|
||||||
|
static TypeId tid = TypeId ("ns3::MgtReassocRequestHeader")
|
||||||
|
.SetParent<Header> ()
|
||||||
|
.SetGroupName ("Wifi")
|
||||||
|
.AddConstructor<MgtReassocRequestHeader> ()
|
||||||
|
;
|
||||||
|
return tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeId
|
||||||
|
MgtReassocRequestHeader::GetInstanceTypeId (void) const
|
||||||
|
{
|
||||||
|
return GetTypeId ();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
MgtReassocRequestHeader::GetSerializedSize (void) const
|
||||||
|
{
|
||||||
|
uint32_t size = 0;
|
||||||
|
size += m_capability.GetSerializedSize ();
|
||||||
|
size += 2; //listen interval
|
||||||
|
size += 6; //current AP address
|
||||||
|
size += m_ssid.GetSerializedSize ();
|
||||||
|
size += m_rates.GetSerializedSize ();
|
||||||
|
size += m_rates.extended.GetSerializedSize ();
|
||||||
|
size += m_extendedCapability.GetSerializedSize ();
|
||||||
|
size += m_htCapability.GetSerializedSize ();
|
||||||
|
size += m_vhtCapability.GetSerializedSize ();
|
||||||
|
size += m_heCapability.GetSerializedSize ();
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::Print (std::ostream &os) const
|
||||||
|
{
|
||||||
|
os << "current AP address=" << m_currentApAddr << ", "
|
||||||
|
<< "ssid=" << m_ssid << ", "
|
||||||
|
<< "rates=" << m_rates << ", "
|
||||||
|
<< "HT Capabilities=" << m_htCapability << " , "
|
||||||
|
<< "VHT Capabilities=" << m_vhtCapability << " , "
|
||||||
|
<< "HE Capabilities=" << m_heCapability;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MgtReassocRequestHeader::Serialize (Buffer::Iterator start) const
|
||||||
|
{
|
||||||
|
Buffer::Iterator i = start;
|
||||||
|
i = m_capability.Serialize (i);
|
||||||
|
i.WriteHtolsbU16 (m_listenInterval);
|
||||||
|
WriteTo (i, m_currentApAddr);
|
||||||
|
i = m_ssid.Serialize (i);
|
||||||
|
i = m_rates.Serialize (i);
|
||||||
|
i = m_rates.extended.Serialize (i);
|
||||||
|
i = m_extendedCapability.Serialize (i);
|
||||||
|
i = m_htCapability.Serialize (i);
|
||||||
|
i = m_vhtCapability.Serialize (i);
|
||||||
|
i = m_heCapability.Serialize (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
MgtReassocRequestHeader::Deserialize (Buffer::Iterator start)
|
||||||
|
{
|
||||||
|
Buffer::Iterator i = start;
|
||||||
|
i = m_capability.Deserialize (i);
|
||||||
|
m_listenInterval = i.ReadLsbtohU16 ();
|
||||||
|
ReadFrom (i, m_currentApAddr);
|
||||||
|
i = m_ssid.Deserialize (i);
|
||||||
|
i = m_rates.Deserialize (i);
|
||||||
|
i = m_rates.extended.DeserializeIfPresent (i);
|
||||||
|
i = m_extendedCapability.DeserializeIfPresent (i);
|
||||||
|
i = m_htCapability.DeserializeIfPresent (i);
|
||||||
|
i = m_vhtCapability.DeserializeIfPresent (i);
|
||||||
|
i = m_heCapability.DeserializeIfPresent (i);
|
||||||
|
return i.GetDistanceFrom (start);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* Assoc/Reassoc Response
|
||||||
***********************************************************/
|
***********************************************************/
|
||||||
|
|
||||||
NS_OBJECT_ENSURE_REGISTERED (MgtAssocResponseHeader);
|
NS_OBJECT_ENSURE_REGISTERED (MgtAssocResponseHeader);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "edca-parameter-set.h"
|
#include "edca-parameter-set.h"
|
||||||
#include "he-capabilities.h"
|
#include "he-capabilities.h"
|
||||||
#include "he-operation.h"
|
#include "he-operation.h"
|
||||||
|
#include "ns3/address-utils.h"
|
||||||
|
|
||||||
namespace ns3 {
|
namespace ns3 {
|
||||||
|
|
||||||
@@ -173,7 +174,145 @@ private:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \ingroup wifi
|
* \ingroup wifi
|
||||||
* Implement the header for management frames of type association response.
|
* Implement the header for management frames of type reassociation request.
|
||||||
|
*/
|
||||||
|
class MgtReassocRequestHeader : public Header
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MgtReassocRequestHeader ();
|
||||||
|
~MgtReassocRequestHeader ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Service Set Identifier (SSID).
|
||||||
|
*
|
||||||
|
* \param ssid SSID
|
||||||
|
*/
|
||||||
|
void SetSsid (Ssid ssid);
|
||||||
|
/**
|
||||||
|
* Set the supported rates.
|
||||||
|
*
|
||||||
|
* \param rates the supported rates
|
||||||
|
*/
|
||||||
|
void SetSupportedRates (SupportedRates rates);
|
||||||
|
/**
|
||||||
|
* Set the listen interval.
|
||||||
|
*
|
||||||
|
* \param interval the listen interval
|
||||||
|
*/
|
||||||
|
void SetListenInterval (uint16_t interval);
|
||||||
|
/**
|
||||||
|
* Set the Capability information.
|
||||||
|
*
|
||||||
|
* \param capabilities Capability information
|
||||||
|
*/
|
||||||
|
void SetCapabilities (CapabilityInformation capabilities);
|
||||||
|
/**
|
||||||
|
* Set the Extended Capabilities.
|
||||||
|
*
|
||||||
|
* \param extendedcapabilities the Extended Capabilities
|
||||||
|
*/
|
||||||
|
void SetExtendedCapabilities (ExtendedCapabilities extendedcapabilities);
|
||||||
|
/**
|
||||||
|
* Set the HT capabilities.
|
||||||
|
*
|
||||||
|
* \param htcapabilities HT capabilities
|
||||||
|
*/
|
||||||
|
void SetHtCapabilities (HtCapabilities htcapabilities);
|
||||||
|
/**
|
||||||
|
* Set the VHT capabilities.
|
||||||
|
*
|
||||||
|
* \param vhtcapabilities VHT capabilities
|
||||||
|
*/
|
||||||
|
void SetVhtCapabilities (VhtCapabilities vhtcapabilities);
|
||||||
|
/**
|
||||||
|
* Set the HE capabilities.
|
||||||
|
*
|
||||||
|
* \param hecapabilities HE capabilities
|
||||||
|
*/
|
||||||
|
void SetHeCapabilities (HeCapabilities hecapabilities);
|
||||||
|
/**
|
||||||
|
* Return the Capability information.
|
||||||
|
*
|
||||||
|
* \return Capability information
|
||||||
|
*/
|
||||||
|
CapabilityInformation GetCapabilities (void) const;
|
||||||
|
/**
|
||||||
|
* Return the extended capabilities.
|
||||||
|
*
|
||||||
|
* \return the extended capabilities
|
||||||
|
*/
|
||||||
|
ExtendedCapabilities GetExtendedCapabilities (void) const;
|
||||||
|
/**
|
||||||
|
* Return the HT capabilities.
|
||||||
|
*
|
||||||
|
* \return HT capabilities
|
||||||
|
*/
|
||||||
|
HtCapabilities GetHtCapabilities (void) const;
|
||||||
|
/**
|
||||||
|
* Return the VHT capabilities.
|
||||||
|
*
|
||||||
|
* \return VHT capabilities
|
||||||
|
*/
|
||||||
|
VhtCapabilities GetVhtCapabilities (void) const;
|
||||||
|
/**
|
||||||
|
* Return the HE capabilities.
|
||||||
|
*
|
||||||
|
* \return HE capabilities
|
||||||
|
*/
|
||||||
|
HeCapabilities GetHeCapabilities (void) const;
|
||||||
|
/**
|
||||||
|
* Return the Service Set Identifier (SSID).
|
||||||
|
*
|
||||||
|
* \return SSID
|
||||||
|
*/
|
||||||
|
Ssid GetSsid (void) const;
|
||||||
|
/**
|
||||||
|
* Return the supported rates.
|
||||||
|
*
|
||||||
|
* \return the supported rates
|
||||||
|
*/
|
||||||
|
SupportedRates GetSupportedRates (void) const;
|
||||||
|
/**
|
||||||
|
* Return the listen interval.
|
||||||
|
*
|
||||||
|
* \return the listen interval
|
||||||
|
*/
|
||||||
|
uint16_t GetListenInterval (void) const;
|
||||||
|
/**
|
||||||
|
* Set the address of the current access point.
|
||||||
|
*
|
||||||
|
* \param currentApAddr address of the current access point
|
||||||
|
*/
|
||||||
|
void SetCurrentApAddress (Mac48Address currentApAddr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register this type.
|
||||||
|
* \return The TypeId.
|
||||||
|
*/
|
||||||
|
static TypeId GetTypeId (void);
|
||||||
|
TypeId GetInstanceTypeId (void) const;
|
||||||
|
void Print (std::ostream &os) const;
|
||||||
|
uint32_t GetSerializedSize (void) const;
|
||||||
|
void Serialize (Buffer::Iterator start) const;
|
||||||
|
uint32_t Deserialize (Buffer::Iterator start);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mac48Address m_currentApAddr; //!< Address of the current access point
|
||||||
|
Ssid m_ssid; //!< Service Set ID (SSID)
|
||||||
|
SupportedRates m_rates; //!< List of supported rates
|
||||||
|
CapabilityInformation m_capability; //!< Capability information
|
||||||
|
ExtendedCapabilities m_extendedCapability; //!< Extended capabilities
|
||||||
|
HtCapabilities m_htCapability; //!< HT capabilities
|
||||||
|
VhtCapabilities m_vhtCapability; //!< VHT capabilities
|
||||||
|
HeCapabilities m_heCapability; //!< HE capabilities
|
||||||
|
uint16_t m_listenInterval; //!< listen interval
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \ingroup wifi
|
||||||
|
* Implement the header for management frames of type association and reassociation response.
|
||||||
*/
|
*/
|
||||||
class MgtAssocResponseHeader : public Header
|
class MgtAssocResponseHeader : public Header
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1006,7 +1006,7 @@ RegularWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
void
|
void
|
||||||
RegularWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiMacHeader *hdr)
|
RegularWifiMac::DeaggregateAmsduAndForward (Ptr<Packet> aggregatedPacket, const WifiMacHeader *hdr)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION(this << aggregatedPacket << hdr);
|
NS_LOG_FUNCTION (this << aggregatedPacket << hdr);
|
||||||
MsduAggregator::DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
|
MsduAggregator::DeaggregatedMsdus packets = MsduAggregator::Deaggregate (aggregatedPacket);
|
||||||
for (MsduAggregator::DeaggregatedMsdusCI i = packets.begin ();
|
for (MsduAggregator::DeaggregatedMsdusCI i = packets.begin ();
|
||||||
i != packets.end (); ++i)
|
i != packets.end (); ++i)
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \param phy the physical layer attached to this MAC.
|
* \param phy the physical layer attached to this MAC.
|
||||||
*/
|
*/
|
||||||
void SetWifiPhy (const Ptr<WifiPhy> phy);
|
virtual void SetWifiPhy (const Ptr<WifiPhy> phy);
|
||||||
/**
|
/**
|
||||||
* \return the physical layer attached to this MAC.
|
* \return the physical layer attached to this MAC.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ StaWifiMac::GetTypeId (void)
|
|||||||
TimeValue (Seconds (0.05)),
|
TimeValue (Seconds (0.05)),
|
||||||
MakeTimeAccessor (&StaWifiMac::m_probeRequestTimeout),
|
MakeTimeAccessor (&StaWifiMac::m_probeRequestTimeout),
|
||||||
MakeTimeChecker ())
|
MakeTimeChecker ())
|
||||||
.AddAttribute ("AssocRequestTimeout", "The interval between two consecutive assoc request attempts.",
|
.AddAttribute ("AssocRequestTimeout", "The interval between two consecutive association request attempts.",
|
||||||
TimeValue (Seconds (0.5)),
|
TimeValue (Seconds (0.5)),
|
||||||
MakeTimeAccessor (&StaWifiMac::m_assocRequestTimeout),
|
MakeTimeAccessor (&StaWifiMac::m_assocRequestTimeout),
|
||||||
MakeTimeChecker ())
|
MakeTimeChecker ())
|
||||||
@@ -120,11 +120,20 @@ StaWifiMac::SetActiveProbing (bool enable)
|
|||||||
m_activeProbing = enable;
|
m_activeProbing = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StaWifiMac::GetActiveProbing (void) const
|
bool
|
||||||
|
StaWifiMac::GetActiveProbing (void) const
|
||||||
{
|
{
|
||||||
return m_activeProbing;
|
return m_activeProbing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StaWifiMac::SetWifiPhy (const Ptr<WifiPhy> phy)
|
||||||
|
{
|
||||||
|
NS_LOG_FUNCTION (this << phy);
|
||||||
|
RegularWifiMac::SetWifiPhy (phy);
|
||||||
|
m_phy->SetCapabilitiesChangedCallback (MakeCallback (&StaWifiMac::PhyCapabilitiesChanged, this));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StaWifiMac::SendProbeRequest (void)
|
StaWifiMac::SendProbeRequest (void)
|
||||||
{
|
{
|
||||||
@@ -171,11 +180,11 @@ StaWifiMac::SendProbeRequest (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StaWifiMac::SendAssociationRequest (void)
|
StaWifiMac::SendAssociationRequest (bool isReassoc)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this << GetBssid ());
|
NS_LOG_FUNCTION (this << GetBssid () << isReassoc);
|
||||||
WifiMacHeader hdr;
|
WifiMacHeader hdr;
|
||||||
hdr.SetType (WIFI_MAC_MGT_ASSOCIATION_REQUEST);
|
hdr.SetType (isReassoc ? WIFI_MAC_MGT_REASSOCIATION_REQUEST : WIFI_MAC_MGT_ASSOCIATION_REQUEST);
|
||||||
hdr.SetAddr1 (GetBssid ());
|
hdr.SetAddr1 (GetBssid ());
|
||||||
hdr.SetAddr2 (GetAddress ());
|
hdr.SetAddr2 (GetAddress ());
|
||||||
hdr.SetAddr3 (GetBssid ());
|
hdr.SetAddr3 (GetBssid ());
|
||||||
@@ -183,24 +192,49 @@ StaWifiMac::SendAssociationRequest (void)
|
|||||||
hdr.SetDsNotTo ();
|
hdr.SetDsNotTo ();
|
||||||
hdr.SetNoOrder ();
|
hdr.SetNoOrder ();
|
||||||
Ptr<Packet> packet = Create<Packet> ();
|
Ptr<Packet> packet = Create<Packet> ();
|
||||||
MgtAssocRequestHeader assoc;
|
if (!isReassoc)
|
||||||
assoc.SetSsid (GetSsid ());
|
|
||||||
assoc.SetSupportedRates (GetSupportedRates ());
|
|
||||||
assoc.SetCapabilities (GetCapabilities ());
|
|
||||||
if (m_htSupported || m_vhtSupported || m_heSupported)
|
|
||||||
{
|
{
|
||||||
assoc.SetExtendedCapabilities (GetExtendedCapabilities ());
|
MgtAssocRequestHeader assoc;
|
||||||
assoc.SetHtCapabilities (GetHtCapabilities ());
|
assoc.SetSsid (GetSsid ());
|
||||||
|
assoc.SetSupportedRates (GetSupportedRates ());
|
||||||
|
assoc.SetCapabilities (GetCapabilities ());
|
||||||
|
if (m_htSupported || m_vhtSupported || m_heSupported)
|
||||||
|
{
|
||||||
|
assoc.SetExtendedCapabilities (GetExtendedCapabilities ());
|
||||||
|
assoc.SetHtCapabilities (GetHtCapabilities ());
|
||||||
|
}
|
||||||
|
if (m_vhtSupported || m_heSupported)
|
||||||
|
{
|
||||||
|
assoc.SetVhtCapabilities (GetVhtCapabilities ());
|
||||||
|
}
|
||||||
|
if (m_heSupported)
|
||||||
|
{
|
||||||
|
assoc.SetHeCapabilities (GetHeCapabilities ());
|
||||||
|
}
|
||||||
|
packet->AddHeader (assoc);
|
||||||
}
|
}
|
||||||
if (m_vhtSupported || m_heSupported)
|
else
|
||||||
{
|
{
|
||||||
assoc.SetVhtCapabilities (GetVhtCapabilities ());
|
MgtReassocRequestHeader reassoc;
|
||||||
|
reassoc.SetCurrentApAddress (GetBssid ());
|
||||||
|
reassoc.SetSsid (GetSsid ());
|
||||||
|
reassoc.SetSupportedRates (GetSupportedRates ());
|
||||||
|
reassoc.SetCapabilities (GetCapabilities ());
|
||||||
|
if (m_htSupported || m_vhtSupported || m_heSupported)
|
||||||
|
{
|
||||||
|
reassoc.SetExtendedCapabilities (GetExtendedCapabilities ());
|
||||||
|
reassoc.SetHtCapabilities (GetHtCapabilities ());
|
||||||
|
}
|
||||||
|
if (m_vhtSupported || m_heSupported)
|
||||||
|
{
|
||||||
|
reassoc.SetVhtCapabilities (GetVhtCapabilities ());
|
||||||
|
}
|
||||||
|
if (m_heSupported)
|
||||||
|
{
|
||||||
|
reassoc.SetHeCapabilities (GetHeCapabilities ());
|
||||||
|
}
|
||||||
|
packet->AddHeader (reassoc);
|
||||||
}
|
}
|
||||||
if (m_heSupported)
|
|
||||||
{
|
|
||||||
assoc.SetHeCapabilities (GetHeCapabilities ());
|
|
||||||
}
|
|
||||||
packet->AddHeader (assoc);
|
|
||||||
|
|
||||||
//The standard is not clear on the correct queue for management
|
//The standard is not clear on the correct queue for management
|
||||||
//frames if we are a QoS AP. The approach taken here is to always
|
//frames if we are a QoS AP. The approach taken here is to always
|
||||||
@@ -245,15 +279,15 @@ StaWifiMac::TryToEnsureAssociated (void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT_ASSOC_RESP:
|
case WAIT_ASSOC_RESP:
|
||||||
/* we have sent an assoc request so we do not need to
|
/* we have sent an association request so we do not need to
|
||||||
re-send an assoc request right now. We just need to
|
re-send an association request right now. We just need to
|
||||||
wait until either assoc-request-timeout or until
|
wait until either assoc-request-timeout or until
|
||||||
we get an assoc response.
|
we get an association response.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
case REFUSED:
|
case REFUSED:
|
||||||
/* we have sent an assoc request and received a negative
|
/* we have sent an association request and received a negative
|
||||||
assoc resp. We wait until someone restarts an
|
association response. We wait until someone restarts an
|
||||||
association with a given ssid.
|
association with a given ssid.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
@@ -265,7 +299,7 @@ StaWifiMac::AssocRequestTimeout (void)
|
|||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this);
|
NS_LOG_FUNCTION (this);
|
||||||
SetState (WAIT_ASSOC_RESP);
|
SetState (WAIT_ASSOC_RESP);
|
||||||
SendAssociationRequest ();
|
SendAssociationRequest (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -447,7 +481,8 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (hdr->IsProbeReq ()
|
else if (hdr->IsProbeReq ()
|
||||||
|| hdr->IsAssocReq ())
|
|| hdr->IsAssocReq ()
|
||||||
|
|| hdr->IsReassocReq ())
|
||||||
{
|
{
|
||||||
//This is a frame aimed at an AP, so we can safely ignore it.
|
//This is a frame aimed at an AP, so we can safely ignore it.
|
||||||
NotifyRxDrop (packet);
|
NotifyRxDrop (packet);
|
||||||
@@ -455,6 +490,7 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
}
|
}
|
||||||
else if (hdr->IsBeacon ())
|
else if (hdr->IsBeacon ())
|
||||||
{
|
{
|
||||||
|
NS_LOG_DEBUG ("Beacon received");
|
||||||
MgtBeaconHeader beacon;
|
MgtBeaconHeader beacon;
|
||||||
packet->RemoveHeader (beacon);
|
packet->RemoveHeader (beacon);
|
||||||
CapabilityInformation capabilities = beacon.GetCapabilities ();
|
CapabilityInformation capabilities = beacon.GetCapabilities ();
|
||||||
@@ -608,7 +644,8 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
if (goodBeacon && m_state == BEACON_MISSED)
|
if (goodBeacon && m_state == BEACON_MISSED)
|
||||||
{
|
{
|
||||||
SetState (WAIT_ASSOC_RESP);
|
SetState (WAIT_ASSOC_RESP);
|
||||||
SendAssociationRequest ();
|
NS_LOG_DEBUG ("Good beacon received: send association request");
|
||||||
|
SendAssociationRequest (false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -616,12 +653,13 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
{
|
{
|
||||||
if (m_state == WAIT_PROBE_RESP)
|
if (m_state == WAIT_PROBE_RESP)
|
||||||
{
|
{
|
||||||
|
NS_LOG_DEBUG ("Probe response received");
|
||||||
MgtProbeResponseHeader probeResp;
|
MgtProbeResponseHeader probeResp;
|
||||||
packet->RemoveHeader (probeResp);
|
packet->RemoveHeader (probeResp);
|
||||||
CapabilityInformation capabilities = probeResp.GetCapabilities ();
|
CapabilityInformation capabilities = probeResp.GetCapabilities ();
|
||||||
if (!probeResp.GetSsid ().IsEqual (GetSsid ()))
|
if (!probeResp.GetSsid ().IsEqual (GetSsid ()))
|
||||||
{
|
{
|
||||||
//not a probe resp for our ssid.
|
NS_LOG_DEBUG ("Probe response is not for our SSID");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SupportedRates rates = probeResp.GetSupportedRates ();
|
SupportedRates rates = probeResp.GetSupportedRates ();
|
||||||
@@ -630,6 +668,7 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
uint8_t selector = m_phy->GetBssMembershipSelector (i);
|
uint8_t selector = m_phy->GetBssMembershipSelector (i);
|
||||||
if (!rates.IsBssMembershipSelectorRate (selector))
|
if (!rates.IsBssMembershipSelectorRate (selector))
|
||||||
{
|
{
|
||||||
|
NS_LOG_DEBUG ("Supported rates do not fit with the BSS membership selector");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -692,11 +731,11 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
m_probeRequestEvent.Cancel ();
|
m_probeRequestEvent.Cancel ();
|
||||||
}
|
}
|
||||||
SetState (WAIT_ASSOC_RESP);
|
SetState (WAIT_ASSOC_RESP);
|
||||||
SendAssociationRequest ();
|
SendAssociationRequest (false);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (hdr->IsAssocResp ())
|
else if (hdr->IsAssocResp () || hdr->IsReassocResp ())
|
||||||
{
|
{
|
||||||
if (m_state == WAIT_ASSOC_RESP)
|
if (m_state == WAIT_ASSOC_RESP)
|
||||||
{
|
{
|
||||||
@@ -709,7 +748,14 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
if (assocResp.GetStatusCode ().IsSuccess ())
|
if (assocResp.GetStatusCode ().IsSuccess ())
|
||||||
{
|
{
|
||||||
SetState (ASSOCIATED);
|
SetState (ASSOCIATED);
|
||||||
NS_LOG_DEBUG ("assoc completed");
|
if (hdr->IsReassocResp ())
|
||||||
|
{
|
||||||
|
NS_LOG_DEBUG ("reassociation done");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NS_LOG_DEBUG ("association completed");
|
||||||
|
}
|
||||||
CapabilityInformation capabilities = assocResp.GetCapabilities ();
|
CapabilityInformation capabilities = assocResp.GetCapabilities ();
|
||||||
SupportedRates rates = assocResp.GetSupportedRates ();
|
SupportedRates rates = assocResp.GetSupportedRates ();
|
||||||
bool isShortPreambleEnabled = capabilities.IsShortPreamble ();
|
bool isShortPreambleEnabled = capabilities.IsShortPreamble ();
|
||||||
@@ -869,7 +915,7 @@ StaWifiMac::Receive (Ptr<Packet> packet, const WifiMacHeader *hdr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NS_LOG_DEBUG ("assoc refused");
|
NS_LOG_DEBUG ("association refused");
|
||||||
SetState (REFUSED);
|
SetState (REFUSED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -938,4 +984,16 @@ StaWifiMac::SetEdcaParameters (AcIndex ac, uint32_t cwMin, uint32_t cwMax, uint8
|
|||||||
edca->SetTxopLimit (txopLimit);
|
edca->SetTxopLimit (txopLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
StaWifiMac::PhyCapabilitiesChanged (void)
|
||||||
|
{
|
||||||
|
NS_LOG_FUNCTION (this);
|
||||||
|
if (IsAssociated ())
|
||||||
|
{
|
||||||
|
NS_LOG_DEBUG ("PHY capabilities changed: send reassociation request");
|
||||||
|
SetState (WAIT_ASSOC_RESP);
|
||||||
|
SendAssociationRequest (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace ns3
|
} //namespace ns3
|
||||||
|
|||||||
@@ -58,6 +58,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void Enqueue (Ptr<const Packet> packet, Mac48Address to);
|
void Enqueue (Ptr<const Packet> packet, Mac48Address to);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param phy the physical layer attached to this MAC.
|
||||||
|
*/
|
||||||
|
void SetWifiPhy (const Ptr<WifiPhy> phy);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@@ -93,10 +98,14 @@ private:
|
|||||||
*/
|
*/
|
||||||
void SendProbeRequest (void);
|
void SendProbeRequest (void);
|
||||||
/**
|
/**
|
||||||
* Forward an association request packet to the DCF. The standard is not clear on the correct
|
* Forward an association or reassociation request packet to the DCF.
|
||||||
* queue for management frames if QoS is supported. We always use the DCF.
|
* The standard is not clear on the correct queue for management frames if QoS is supported.
|
||||||
|
* We always use the DCF.
|
||||||
|
*
|
||||||
|
* \param isReassoc flag whether it is a reassociation request
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
void SendAssociationRequest (void);
|
void SendAssociationRequest (bool isReassoc);
|
||||||
/**
|
/**
|
||||||
* Try to ensure that we are associated with an AP by taking an appropriate action
|
* Try to ensure that we are associated with an AP by taking an appropriate action
|
||||||
* depending on the current association status.
|
* depending on the current association status.
|
||||||
@@ -164,6 +173,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
CapabilityInformation GetCapabilities (void) const;
|
CapabilityInformation GetCapabilities (void) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate that PHY capabilities have changed.
|
||||||
|
*/
|
||||||
|
void PhyCapabilitiesChanged (void);
|
||||||
|
|
||||||
MacState m_state; ///< MAC state
|
MacState m_state; ///< MAC state
|
||||||
Time m_probeRequestTimeout; ///< probe request timeout
|
Time m_probeRequestTimeout; ///< probe request timeout
|
||||||
Time m_assocRequestTimeout; ///< assoc request timeout
|
Time m_assocRequestTimeout; ///< assoc request timeout
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ WifiNetDevice::DoDispose (void)
|
|||||||
void
|
void
|
||||||
WifiNetDevice::DoInitialize (void)
|
WifiNetDevice::DoInitialize (void)
|
||||||
{
|
{
|
||||||
|
NS_LOG_FUNCTION_NOARGS ();
|
||||||
m_phy->Initialize ();
|
m_phy->Initialize ();
|
||||||
m_mac->Initialize ();
|
m_mac->Initialize ();
|
||||||
m_stationManager->Initialize ();
|
m_stationManager->Initialize ();
|
||||||
@@ -140,7 +141,7 @@ WifiNetDevice::NotifyNewAggregate (void)
|
|||||||
// register the select queue callback
|
// register the select queue callback
|
||||||
m_queueInterface->SetSelectQueueCallback (MakeCallback (&WifiNetDevice::SelectQueue, this));
|
m_queueInterface->SetSelectQueueCallback (MakeCallback (&WifiNetDevice::SelectQueue, this));
|
||||||
m_queueInterface->SetLateTxQueuesCreation (true);
|
m_queueInterface->SetLateTxQueuesCreation (true);
|
||||||
FlowControlConfig ();
|
FlowControlConfig ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NetDevice::NotifyNewAggregate ();
|
NetDevice::NotifyNewAggregate ();
|
||||||
|
|||||||
@@ -434,6 +434,12 @@ WifiPhy::UnregisterListener (WifiPhyListener *listener)
|
|||||||
m_state->UnregisterListener (listener);
|
m_state->UnregisterListener (listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
WifiPhy::SetCapabilitiesChangedCallback (Callback<void> callback)
|
||||||
|
{
|
||||||
|
m_capabilitiesChangedCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WifiPhy::InitializeFrequencyChannelNumber (void)
|
WifiPhy::InitializeFrequencyChannelNumber (void)
|
||||||
{
|
{
|
||||||
@@ -537,7 +543,7 @@ WifiPhy::GetTxPowerEnd (void) const
|
|||||||
void
|
void
|
||||||
WifiPhy::SetNTxPower (uint8_t n)
|
WifiPhy::SetNTxPower (uint8_t n)
|
||||||
{
|
{
|
||||||
NS_LOG_FUNCTION (this << static_cast<uint16_t>(n));
|
NS_LOG_FUNCTION (this << static_cast<uint16_t> (n));
|
||||||
m_nTxPower = n;
|
m_nTxPower = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,7 +713,7 @@ WifiPhy::GetFrameCaptureModel (void) const
|
|||||||
{
|
{
|
||||||
return m_frameCaptureModel;
|
return m_frameCaptureModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WifiPhy::SetWifiRadioEnergyModel (const Ptr<WifiRadioEnergyModel> wifiRadioEnergyModel)
|
WifiPhy::SetWifiRadioEnergyModel (const Ptr<WifiRadioEnergyModel> wifiRadioEnergyModel)
|
||||||
{
|
{
|
||||||
@@ -1267,9 +1273,15 @@ WifiPhy::GetFrequency (void) const
|
|||||||
void
|
void
|
||||||
WifiPhy::SetChannelWidth (uint8_t channelwidth)
|
WifiPhy::SetChannelWidth (uint8_t channelwidth)
|
||||||
{
|
{
|
||||||
|
NS_LOG_FUNCTION (this << static_cast<uint16_t> (channelwidth));
|
||||||
NS_ASSERT_MSG (channelwidth == 5 || channelwidth == 10 || channelwidth == 20 || channelwidth == 22 || channelwidth == 40 || channelwidth == 80 || channelwidth == 160, "wrong channel width value");
|
NS_ASSERT_MSG (channelwidth == 5 || channelwidth == 10 || channelwidth == 20 || channelwidth == 22 || channelwidth == 40 || channelwidth == 80 || channelwidth == 160, "wrong channel width value");
|
||||||
|
bool changed = (m_channelWidth == channelwidth);
|
||||||
m_channelWidth = channelwidth;
|
m_channelWidth = channelwidth;
|
||||||
AddSupportedChannelWidth (channelwidth);
|
AddSupportedChannelWidth (channelwidth);
|
||||||
|
if (changed && !m_capabilitiesChangedCallback.IsNull ())
|
||||||
|
{
|
||||||
|
m_capabilitiesChangedCallback ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
@@ -1296,8 +1308,13 @@ void
|
|||||||
WifiPhy::SetMaxSupportedTxSpatialStreams (uint8_t streams)
|
WifiPhy::SetMaxSupportedTxSpatialStreams (uint8_t streams)
|
||||||
{
|
{
|
||||||
NS_ASSERT (streams <= GetNumberOfAntennas ());
|
NS_ASSERT (streams <= GetNumberOfAntennas ());
|
||||||
|
bool changed = (m_txSpatialStreams == streams);
|
||||||
m_txSpatialStreams = streams;
|
m_txSpatialStreams = streams;
|
||||||
ConfigureHtDeviceMcsSet ();
|
ConfigureHtDeviceMcsSet ();
|
||||||
|
if (changed && !m_capabilitiesChangedCallback.IsNull ())
|
||||||
|
{
|
||||||
|
m_capabilitiesChangedCallback ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
@@ -1310,7 +1327,12 @@ void
|
|||||||
WifiPhy::SetMaxSupportedRxSpatialStreams (uint8_t streams)
|
WifiPhy::SetMaxSupportedRxSpatialStreams (uint8_t streams)
|
||||||
{
|
{
|
||||||
NS_ASSERT (streams <= GetNumberOfAntennas ());
|
NS_ASSERT (streams <= GetNumberOfAntennas ());
|
||||||
|
bool changed = (m_rxSpatialStreams == streams);
|
||||||
m_rxSpatialStreams = streams;
|
m_rxSpatialStreams = streams;
|
||||||
|
if (changed && !m_capabilitiesChangedCallback.IsNull ())
|
||||||
|
{
|
||||||
|
m_capabilitiesChangedCallback ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t
|
uint8_t
|
||||||
@@ -2398,10 +2420,10 @@ WifiPhy::StartReceivePreambleAndHeader (Ptr<Packet> packet, double rxPowerW, Tim
|
|||||||
|
|
||||||
if (tag.GetFrameComplete () == 0)
|
if (tag.GetFrameComplete () == 0)
|
||||||
{
|
{
|
||||||
NS_LOG_DEBUG ("drop packet because of incomplete frame");
|
NS_LOG_DEBUG ("drop packet because of incomplete frame");
|
||||||
NotifyRxDrop (packet);
|
NotifyRxDrop (packet);
|
||||||
m_plcpSuccess = false;
|
m_plcpSuccess = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiTxVector txVector = tag.GetWifiTxVector ();
|
WifiTxVector txVector = tag.GetWifiTxVector ();
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class FrameCaptureModel;
|
|||||||
* WifiRadioEnergyModel class
|
* WifiRadioEnergyModel class
|
||||||
*/
|
*/
|
||||||
class WifiRadioEnergyModel;
|
class WifiRadioEnergyModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This enumeration defines the type of an MPDU.
|
* This enumeration defines the type of an MPDU.
|
||||||
*/
|
*/
|
||||||
@@ -257,6 +257,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
void UnregisterListener (WifiPhyListener *listener);
|
void UnregisterListener (WifiPhyListener *listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \param callback the callback to invoke when PHY capabilities have changed.
|
||||||
|
*/
|
||||||
|
void SetCapabilitiesChangedCallback (Callback<void> callback);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived).
|
* Starting receiving the plcp of a packet (i.e. the first bit of the preamble has arrived).
|
||||||
*
|
*
|
||||||
@@ -353,7 +358,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* \return true if the current state of the PHY layer is WifiPhy::OFF, false otherwise.
|
* \return true if the current state of the PHY layer is WifiPhy::OFF, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool IsStateOff (void) const ;
|
bool IsStateOff (void) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \return the amount of time since the current state has started.
|
* \return the amount of time since the current state has started.
|
||||||
@@ -1798,7 +1803,7 @@ private:
|
|||||||
* \return the FrequencyWidthPair found
|
* \return the FrequencyWidthPair found
|
||||||
*/
|
*/
|
||||||
FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard (uint8_t channelNumber, WifiPhyStandard standard) const;
|
FrequencyWidthPair GetFrequencyWidthForChannelNumberStandard (uint8_t channelNumber, WifiPhyStandard standard) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Due to newly arrived signal, the current reception cannot be continued and has to be aborted
|
* Due to newly arrived signal, the current reception cannot be continued and has to be aborted
|
||||||
*
|
*
|
||||||
@@ -1809,7 +1814,7 @@ private:
|
|||||||
* Eventually switch to CCA busy
|
* Eventually switch to CCA busy
|
||||||
*/
|
*/
|
||||||
void MaybeCcaBusyDuration (void);
|
void MaybeCcaBusyDuration (void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starting receiving the packet after having detected the medium is idle or after a reception switch.
|
* Starting receiving the packet after having detected the medium is idle or after a reception switch.
|
||||||
*
|
*
|
||||||
@@ -1987,6 +1992,8 @@ private:
|
|||||||
Ptr<InterferenceHelper::Event> m_currentEvent; //!< Hold the current event
|
Ptr<InterferenceHelper::Event> m_currentEvent; //!< Hold the current event
|
||||||
Ptr<FrameCaptureModel> m_frameCaptureModel; //!< Frame capture model
|
Ptr<FrameCaptureModel> m_frameCaptureModel; //!< Frame capture model
|
||||||
Ptr<WifiRadioEnergyModel> m_wifiRadioEnergyModel; //!< Wifi radio energy model
|
Ptr<WifiRadioEnergyModel> m_wifiRadioEnergyModel; //!< Wifi radio energy model
|
||||||
|
|
||||||
|
Callback<void> m_capabilitiesChangedCallback; //!< Callback when PHY capabilities changed
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1283,7 +1283,7 @@ Bug2483TestCase::DoRun (void)
|
|||||||
spectrumChannel->AddPropagationLossModel (lossModel);
|
spectrumChannel->AddPropagationLossModel (lossModel);
|
||||||
|
|
||||||
Ptr<ConstantSpeedPropagationDelayModel> delayModel
|
Ptr<ConstantSpeedPropagationDelayModel> delayModel
|
||||||
= CreateObject<ConstantSpeedPropagationDelayModel> ();
|
= CreateObject<ConstantSpeedPropagationDelayModel> ();
|
||||||
spectrumChannel->SetPropagationDelayModel (delayModel);
|
spectrumChannel->SetPropagationDelayModel (delayModel);
|
||||||
|
|
||||||
spectrumPhy.SetChannel (spectrumChannel);
|
spectrumPhy.SetChannel (spectrumChannel);
|
||||||
@@ -1343,6 +1343,177 @@ Bug2483TestCase::DoRun (void)
|
|||||||
NS_TEST_ASSERT_MSG_EQ (std::get<3> (m_distinctTuples[1]), WifiModulationClass::WIFI_MOD_CLASS_VHT, "Second tuple should be VHT_OFDM");
|
NS_TEST_ASSERT_MSG_EQ (std::get<3> (m_distinctTuples[1]), WifiModulationClass::WIFI_MOD_CLASS_VHT, "Second tuple should be VHT_OFDM");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* Make sure that the channel width and the channel number can be changed at runtime.
|
||||||
|
*
|
||||||
|
* The scenario considers an access point and a station using a 20 MHz channel width.
|
||||||
|
* After 1s, we change the channel width and the channel number to use a 40 MHz channel.
|
||||||
|
* The tests checks the operational channel width sent in Beacon frames
|
||||||
|
* and verify that a reassociation procedure is executed.
|
||||||
|
*
|
||||||
|
* See \bugid{2831}
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Bug2831TestCase : public TestCase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Bug2831TestCase ();
|
||||||
|
virtual ~Bug2831TestCase ();
|
||||||
|
virtual void DoRun (void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Function called to change the supported channel width at runtime
|
||||||
|
*/
|
||||||
|
void ChangeSupportedChannelWidth (void);
|
||||||
|
/**
|
||||||
|
* Callback triggered when a packet is received by the PHYs
|
||||||
|
* \param context the context
|
||||||
|
* \param p the received packet
|
||||||
|
*/
|
||||||
|
void RxCallback (std::string context, Ptr<const Packet> p);
|
||||||
|
|
||||||
|
Ptr<YansWifiPhy> m_apPhy; ///< AP PHY
|
||||||
|
Ptr<YansWifiPhy> m_staPhy; ///< STA PHY
|
||||||
|
|
||||||
|
uint8_t m_reassocReqCount; ///< count number of reassociation requests
|
||||||
|
uint8_t m_reassocRespCount; ///< count number of reassociation responses
|
||||||
|
uint8_t m_countOperationalChannelWidth20; ///< count number of beacon frames announcing a 20 MHz operating channel width
|
||||||
|
uint8_t m_countOperationalChannelWidth40; ///< count number of beacon frames announcing a 40 MHz operating channel width
|
||||||
|
};
|
||||||
|
|
||||||
|
Bug2831TestCase::Bug2831TestCase ()
|
||||||
|
: TestCase ("Test case for Bug 2831"),
|
||||||
|
m_reassocReqCount (0),
|
||||||
|
m_reassocRespCount (0),
|
||||||
|
m_countOperationalChannelWidth20 (0),
|
||||||
|
m_countOperationalChannelWidth40 (0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Bug2831TestCase::~Bug2831TestCase ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Bug2831TestCase::ChangeSupportedChannelWidth ()
|
||||||
|
{
|
||||||
|
m_apPhy->SetChannelNumber (38);
|
||||||
|
m_apPhy->SetChannelWidth (40);
|
||||||
|
m_staPhy->SetChannelNumber (38);
|
||||||
|
m_staPhy->SetChannelWidth (40);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Bug2831TestCase::RxCallback (std::string context, Ptr<const Packet> p)
|
||||||
|
{
|
||||||
|
Ptr<Packet> packet = p->Copy ();
|
||||||
|
WifiMacHeader hdr;
|
||||||
|
packet->RemoveHeader (hdr);
|
||||||
|
if (hdr.IsReassocReq ())
|
||||||
|
{
|
||||||
|
m_reassocReqCount++;
|
||||||
|
}
|
||||||
|
else if (hdr.IsReassocResp ())
|
||||||
|
{
|
||||||
|
m_reassocRespCount++;
|
||||||
|
}
|
||||||
|
else if (hdr.IsBeacon ())
|
||||||
|
{
|
||||||
|
MgtBeaconHeader beacon;
|
||||||
|
packet->RemoveHeader (beacon);
|
||||||
|
HtOperation htOperation = beacon.GetHtOperation ();
|
||||||
|
if (htOperation.GetStaChannelWidth () > 0)
|
||||||
|
{
|
||||||
|
m_countOperationalChannelWidth40++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_countOperationalChannelWidth20++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Bug2831TestCase::DoRun (void)
|
||||||
|
{
|
||||||
|
Ptr<YansWifiChannel> channel = CreateObject<YansWifiChannel> ();
|
||||||
|
ObjectFactory propDelay;
|
||||||
|
propDelay.SetTypeId ("ns3::ConstantSpeedPropagationDelayModel");
|
||||||
|
Ptr<PropagationDelayModel> propagationDelay = propDelay.Create<PropagationDelayModel> ();
|
||||||
|
Ptr<PropagationLossModel> propagationLoss = CreateObject<RandomPropagationLossModel> ();
|
||||||
|
channel->SetPropagationDelayModel (propagationDelay);
|
||||||
|
channel->SetPropagationLossModel (propagationLoss);
|
||||||
|
|
||||||
|
Ptr<Node> apNode = CreateObject<Node> ();
|
||||||
|
Ptr<WifiNetDevice> apDev = CreateObject<WifiNetDevice> ();
|
||||||
|
ObjectFactory mac;
|
||||||
|
mac.SetTypeId ("ns3::ApWifiMac");
|
||||||
|
Ptr<WifiMac> apMac = mac.Create<WifiMac> ();
|
||||||
|
apMac->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
|
||||||
|
|
||||||
|
Ptr<Node> staNode = CreateObject<Node> ();
|
||||||
|
Ptr<WifiNetDevice> staDev = CreateObject<WifiNetDevice> ();
|
||||||
|
mac.SetTypeId ("ns3::StaWifiMac");
|
||||||
|
Ptr<WifiMac> staMac = mac.Create<WifiMac> ();
|
||||||
|
staMac->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
|
||||||
|
|
||||||
|
Ptr<ConstantPositionMobilityModel> apMobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||||
|
apMobility->SetPosition (Vector (0.0, 0.0, 0.0));
|
||||||
|
apNode->AggregateObject (apMobility);
|
||||||
|
|
||||||
|
Ptr<ErrorRateModel> error = CreateObject<YansErrorRateModel> ();
|
||||||
|
m_apPhy = CreateObject<YansWifiPhy> ();
|
||||||
|
m_apPhy->SetErrorRateModel (error);
|
||||||
|
m_apPhy->SetChannel (channel);
|
||||||
|
m_apPhy->SetMobility (apMobility);
|
||||||
|
m_apPhy->SetDevice (apDev);
|
||||||
|
m_apPhy->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
|
||||||
|
m_apPhy->SetChannelNumber (36);
|
||||||
|
m_apPhy->SetChannelWidth (20);
|
||||||
|
|
||||||
|
Ptr<ConstantPositionMobilityModel> staMobility = CreateObject<ConstantPositionMobilityModel> ();
|
||||||
|
staMobility->SetPosition (Vector (1.0, 0.0, 0.0));
|
||||||
|
staNode->AggregateObject (staMobility);
|
||||||
|
|
||||||
|
m_staPhy = CreateObject<YansWifiPhy> ();
|
||||||
|
m_staPhy->SetErrorRateModel (error);
|
||||||
|
m_staPhy->SetChannel (channel);
|
||||||
|
m_staPhy->SetMobility (staMobility);
|
||||||
|
m_staPhy->SetDevice (apDev);
|
||||||
|
m_staPhy->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
|
||||||
|
m_staPhy->SetChannelNumber (36);
|
||||||
|
m_staPhy->SetChannelWidth (20);
|
||||||
|
|
||||||
|
apMac->SetAddress (Mac48Address::Allocate ());
|
||||||
|
apDev->SetMac (apMac);
|
||||||
|
apDev->SetPhy (m_apPhy);
|
||||||
|
ObjectFactory manager;
|
||||||
|
manager.SetTypeId ("ns3::ConstantRateWifiManager");
|
||||||
|
apDev->SetRemoteStationManager (manager.Create<WifiRemoteStationManager> ());
|
||||||
|
apNode->AddDevice (apDev);
|
||||||
|
|
||||||
|
staMac->SetAddress (Mac48Address::Allocate ());
|
||||||
|
staDev->SetMac (staMac);
|
||||||
|
staDev->SetPhy (m_staPhy);
|
||||||
|
staDev->SetRemoteStationManager (manager.Create<WifiRemoteStationManager> ());
|
||||||
|
staNode->AddDevice (staDev);
|
||||||
|
|
||||||
|
Config::Connect ("/NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::WifiPhy/PhyRxBegin", MakeCallback (&Bug2831TestCase::RxCallback, this));
|
||||||
|
|
||||||
|
Simulator::Schedule (Seconds (1.0), &Bug2831TestCase::ChangeSupportedChannelWidth, this);
|
||||||
|
|
||||||
|
Simulator::Stop (Seconds (3.0));
|
||||||
|
Simulator::Run ();
|
||||||
|
Simulator::Destroy ();
|
||||||
|
|
||||||
|
NS_TEST_ASSERT_MSG_EQ (m_reassocReqCount, 1, "Reassociation request not received");
|
||||||
|
NS_TEST_ASSERT_MSG_EQ (m_reassocRespCount, 1, "Reassociation response not received");
|
||||||
|
NS_TEST_ASSERT_MSG_EQ (m_countOperationalChannelWidth20, 10, "Incorrect operational channel width before channel change");
|
||||||
|
NS_TEST_ASSERT_MSG_EQ (m_countOperationalChannelWidth40, 20, "Incorrect operational channel width after channel change");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \ingroup wifi-test
|
* \ingroup wifi-test
|
||||||
* \ingroup tests
|
* \ingroup tests
|
||||||
@@ -1366,6 +1537,7 @@ WifiTestSuite::WifiTestSuite ()
|
|||||||
AddTestCase (new SetChannelFrequencyTest, TestCase::QUICK);
|
AddTestCase (new SetChannelFrequencyTest, TestCase::QUICK);
|
||||||
AddTestCase (new Bug2222TestCase, TestCase::QUICK); //Bug 2222
|
AddTestCase (new Bug2222TestCase, TestCase::QUICK); //Bug 2222
|
||||||
AddTestCase (new Bug2483TestCase, TestCase::QUICK); //Bug 2483
|
AddTestCase (new Bug2483TestCase, TestCase::QUICK); //Bug 2483
|
||||||
|
AddTestCase (new Bug2831TestCase, TestCase::QUICK); //Bug 2831
|
||||||
}
|
}
|
||||||
|
|
||||||
static WifiTestSuite g_wifiTestSuite; ///< the test suite
|
static WifiTestSuite g_wifiTestSuite; ///< the test suite
|
||||||
|
|||||||
Reference in New Issue
Block a user