diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 12fe6d521..8744c02a0 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -37,6 +37,10 @@ Bugs fixed - Bug 2893 - lte: GetPgw in helper should be const - Bug 3027 - lte: S1 signalling is done before RRC connection establishment is finished - #11 - mobility: Rectangle::GetClosestSide returns the correct side also for positions outside the rectangle +- #27 - wifi: Re-compute the A-MPDU after an RTS/CTS exchange fails +- #33 - wifi: Issues with QosTxop::StartNextPacket +- #35 - Unexpected EDCA performance under virtual collisions for 802.11n +- #45 - Wi-Fi transmits frames outside BlockAck window - #53 - Token Bank Fair Queue Scheduler is creating a transmit opportunity of 0 bytes - #54 - RadioBearerStats are not correctly connected diff --git a/examples/wireless/80211e-txop.cc b/examples/wireless/80211e-txop.cc index 92fa534a7..f85539ada 100644 --- a/examples/wireless/80211e-txop.cc +++ b/examples/wireless/80211e-txop.cc @@ -65,6 +65,24 @@ using namespace ns3; NS_LOG_COMPONENT_DEFINE ("80211eTxop"); +/** + * Keeps the maximum duration among all TXOPs + */ +struct TxopDurationTracer +{ + void Trace (Time startTime, Time duration); + Time m_max {Seconds (0)}; +}; + +void +TxopDurationTracer::Trace (Time startTime, Time duration) +{ + if (duration > m_max) + { + m_max = duration; + } +} + int main (int argc, char *argv[]) { uint32_t payloadSize = 1472; //bytes @@ -137,6 +155,15 @@ int main (int argc, char *argv[]) edca = ptr.Get (); edca->SetTxopLimit (MicroSeconds (3008)); + // Trace TXOP duration for BE on STA1 + dev = wifiStaNodes.Get (1)->GetDevice (0); + wifi_dev = DynamicCast (dev); + wifi_mac = wifi_dev->GetMac (); + wifi_mac->GetAttribute ("BE_Txop", ptr); + edca = ptr.Get (); + TxopDurationTracer beTxopTracer; + edca->TraceConnectWithoutContext ("TxopTrace", MakeCallback (&TxopDurationTracer::Trace, &beTxopTracer)); + //Network C ssid = Ssid ("network-C"); phy.Set ("ChannelNumber", UintegerValue (44)); @@ -152,6 +179,15 @@ int main (int argc, char *argv[]) "EnableBeaconJitter", BooleanValue (false)); apDeviceC = wifi.Install (phy, mac, wifiApNodes.Get (2)); + // Trace TXOP duration for VI on STA2 + dev = wifiStaNodes.Get (2)->GetDevice (0); + wifi_dev = DynamicCast (dev); + wifi_mac = wifi_dev->GetMac (); + wifi_mac->GetAttribute ("VI_Txop", ptr); + edca = ptr.Get (); + TxopDurationTracer viTxopTracer; + edca->TraceConnectWithoutContext ("TxopTrace", MakeCallback (&TxopDurationTracer::Trace, &viTxopTracer)); + //Network D ssid = Ssid ("network-D"); phy.Set ("ChannelNumber", UintegerValue (48)); @@ -325,7 +361,8 @@ int main (int argc, char *argv[]) Simulator::Destroy (); double throughput = totalPacketsThroughA * payloadSize * 8 / (simulationTime * 1000000.0); - std::cout << "Throughput for AC_BE with default TXOP limit (0ms): " << throughput << " Mbit/s" << '\n'; + std::cout << "AC_BE with default TXOP limit (0ms): " << '\n' + << " Throughput = " << throughput << " Mbit/s" << '\n'; if (verifyResults && (throughput < 28 || throughput > 29)) { NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!"); @@ -333,23 +370,38 @@ int main (int argc, char *argv[]) } throughput = totalPacketsThroughB * payloadSize * 8 / (simulationTime * 1000000.0); - std::cout << "Throughput for AC_BE with non-default TXOP limit (3.008ms): " << throughput << " Mbit/s" << '\n'; + std::cout << "AC_BE with non-default TXOP limit (3.008ms): " << '\n' + << " Throughput = " << throughput << " Mbit/s" << '\n'; if (verifyResults && (throughput < 35.5 || throughput > 36.5)) { NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!"); exit (1); } + std::cout << " Maximum TXOP duration = " << beTxopTracer.m_max.GetMicroSeconds () << " us" << '\n'; + if (verifyResults && (beTxopTracer.m_max < MicroSeconds (2700) || beTxopTracer.m_max > MicroSeconds (3008))) + { + NS_LOG_ERROR ("Maximum TXOP duration " << beTxopTracer.m_max << " is not in the expected boundaries!"); + exit (1); + } throughput = totalPacketsThroughC * payloadSize * 8 / (simulationTime * 1000000.0); - std::cout << "Throughput for AC_VI with default TXOP limit (3.008ms): " << throughput << " Mbit/s" << '\n'; + std::cout << "AC_VI with default TXOP limit (3.008ms): " << '\n' + << " Throughput = " << throughput << " Mbit/s" << '\n'; if (verifyResults && (throughput < 36 || throughput > 37)) { NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!"); exit (1); } + std::cout << " Maximum TXOP duration = " << viTxopTracer.m_max.GetMicroSeconds () << " us" << '\n'; + if (verifyResults && (viTxopTracer.m_max < MicroSeconds (2700) || viTxopTracer.m_max > MicroSeconds (3008))) + { + NS_LOG_ERROR ("Maximum TXOP duration " << viTxopTracer.m_max << " is not in the expected boundaries!"); + exit (1); + } throughput = totalPacketsThroughD * payloadSize * 8 / (simulationTime * 1000000.0); - std::cout << "Throughput for AC_VI with non-default TXOP limit (0ms): " << throughput << " Mbit/s" << '\n'; + std::cout << "AC_VI with non-default TXOP limit (0ms): " << '\n' + << " Throughput = " << throughput << " Mbit/s" << '\n'; if (verifyResults && (throughput < 31.5 || throughput > 32.5)) { NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!"); diff --git a/examples/wireless/examples-to-run.py b/examples/wireless/examples-to-run.py index 41f72ef0d..ab124ffc5 100755 --- a/examples/wireless/examples-to-run.py +++ b/examples/wireless/examples-to-run.py @@ -52,6 +52,7 @@ cpp_examples = [ ("simple-ht-hidden-stations --simulationTime=1 --enableRts=1 --nMpdus=32 --minExpectedThroughput=57 --maxExpectedThroughput=58", "True", "True"), ("mixed-network --simulationTime=1", "True", "True"), ("wifi-aggregation --simulationTime=1 --verifyResults=1", "True", "True"), + ("wifi-txop-aggregation --simulationTime=1 --verifyResults=1", "True", "True"), ("80211e-txop --simulationTime=1 --verifyResults=1", "True", "True"), ("wifi-multi-tos --simulationTime=1 --nWifi=16 --useRts=1 --useShortGuardInterval=1", "True", "True"), ("wifi-tcp", "True", "True"), diff --git a/examples/wireless/wifi-txop-aggregation.cc b/examples/wireless/wifi-txop-aggregation.cc new file mode 100644 index 000000000..22e08f592 --- /dev/null +++ b/examples/wireless/wifi-txop-aggregation.cc @@ -0,0 +1,470 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2016 Sébastien Deronne + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Sébastien Deronne + */ + +#include "ns3/command-line.h" +#include "ns3/config.h" +#include "ns3/uinteger.h" +#include "ns3/boolean.h" +#include "ns3/string.h" +#include "ns3/pointer.h" +#include "ns3/log.h" +#include "ns3/yans-wifi-helper.h" +#include "ns3/ssid.h" +#include "ns3/mobility-helper.h" +#include "ns3/internet-stack-helper.h" +#include "ns3/ipv4-address-helper.h" +#include "ns3/udp-client-server-helper.h" +#include "ns3/packet-sink-helper.h" +#include "ns3/yans-wifi-channel.h" +#include "ns3/wifi-net-device.h" +#include "ns3/wifi-mac.h" +#include "ns3/qos-txop.h" + +// This is an example that illustrates how 802.11n aggregation is configured. +// It defines 4 independent Wi-Fi networks (working on different channels). +// Each network contains one access point and one station. Each station +// continuously transmits data packets to its respective AP. +// +// Network topology (numbers in parentheses are channel numbers): +// +// Network A (36) Network B (40) Network C (44) Network D (48) +// * * * * * * * * +// | | | | | | | | +// AP A STA A AP B STA B AP C STA C AP D STA D +// +// The aggregation parameters are configured differently on the 4 stations: +// - station A uses default aggregation parameter values (A-MSDU disabled, A-MPDU enabled with maximum size of 65 kB); +// - station B doesn't use aggregation (both A-MPDU and A-MSDU are disabled); +// - station C enables A-MSDU (with maximum size of 8 kB) but disables A-MPDU; +// - station D uses two-level aggregation (A-MPDU with maximum size of 32 kB and A-MSDU with maximum size of 4 kB). +// +// The user can select the distance between the stations and the APs, can enable/disable the RTS/CTS mechanism +// and can modify the duration of a TXOP. +// Example: ./waf --run "wifi-aggregation --distance=10 --enableRts=0 --simulationTime=20" +// +// The output prints the throughput and the maximum TXOP duration measured for the 4 cases/networks +// described above. When default aggregation parameters are enabled, the +// maximum A-MPDU size is 65 kB and the throughput is maximal. When aggregation is disabled, the throughput is about the half of the +// physical bitrate as in legacy wifi networks. When only A-MSDU is enabled, the throughput is increased but is not maximal, since the maximum +// A-MSDU size is limited to 7935 bytes (whereas the maximum A-MPDU size is limited to 65535 bytes). When A-MSDU and A-MPDU are both enabled +// (= two-level aggregation), the throughput is slightly smaller than the first scenario since we set a smaller maximum A-MPDU size. +// +// When the distance is increased, the frame error rate gets higher, and the output shows how it affects the throughput for the 4 networks. +// Even through A-MSDU has less overheads than A-MPDU, A-MSDU is less robust against transmission errors than A-MPDU. When the distance is +// augmented, the throughput for the third scenario is more affected than the throughput obtained in other networks. + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("TxopMpduAggregation"); + +/** + * Keeps the maximum duration among all TXOPs + */ +struct TxopDurationTracer +{ + void Trace (Time startTime, Time duration); + Time m_max {Seconds (0)}; +}; + +void +TxopDurationTracer::Trace (Time startTime, Time duration) +{ + if (duration > m_max) + { + m_max = duration; + } +} + +int main (int argc, char *argv[]) +{ + uint32_t payloadSize = 1472; //bytes + double simulationTime = 10; //seconds + double txopLimit = 3520; //microseconds + double distance = 5; //meters + bool enableRts = 0; + bool enablePcap = 0; + bool verifyResults = 0; //used for regression + + CommandLine cmd; + cmd.AddValue ("payloadSize", "Payload size in bytes", payloadSize); + cmd.AddValue ("enableRts", "Enable or disable RTS/CTS", enableRts); + cmd.AddValue ("txopLimit", "TXOP duration in microseconds", txopLimit); + cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime); + cmd.AddValue ("distance", "Distance in meters between the station and the access point", distance); + cmd.AddValue ("enablePcap", "Enable/disable pcap file generation", enablePcap); + cmd.AddValue ("verifyResults", "Enable/disable results verification at the end of the simulation", verifyResults); + cmd.Parse (argc, argv); + + Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", enableRts ? StringValue ("0") : StringValue ("999999")); + + NodeContainer wifiStaNodes; + wifiStaNodes.Create (4); + NodeContainer wifiApNodes; + wifiApNodes.Create (4); + + YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); + YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); + phy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO); + phy.SetChannel (channel.Create ()); + + WifiHelper wifi; + wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ); + wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue ("HtMcs7"), "ControlMode", StringValue ("HtMcs0")); + WifiMacHelper mac; + + NetDeviceContainer staDeviceA, staDeviceB, staDeviceC, staDeviceD, apDeviceA, apDeviceB, apDeviceC, apDeviceD; + Ssid ssid; + + // Network A + ssid = Ssid ("network-A"); + phy.Set ("ChannelNumber", UintegerValue (36)); + mac.SetType ("ns3::StaWifiMac", + "Ssid", SsidValue (ssid)); + staDeviceA = wifi.Install (phy, mac, wifiStaNodes.Get (0)); + + mac.SetType ("ns3::ApWifiMac", + "Ssid", SsidValue (ssid), + "EnableBeaconJitter", BooleanValue (false)); + apDeviceA = wifi.Install (phy, mac, wifiApNodes.Get (0)); + + // Modify EDCA configuration (TXOP limit) for AC_BE + Ptr dev = wifiApNodes.Get (0)->GetDevice (0); + Ptr wifi_dev = DynamicCast (dev); + PointerValue ptr; + Ptr edca; + wifi_dev->GetMac ()->GetAttribute ("BE_Txop", ptr); + edca = ptr.Get (); + edca->SetTxopLimit (MicroSeconds (txopLimit)); + + // Trace TXOP duration for BE on AP A + TxopDurationTracer netA; + edca->TraceConnectWithoutContext ("TxopTrace", MakeCallback (&TxopDurationTracer::Trace, &netA)); + + // Network B + ssid = Ssid ("network-B"); + phy.Set ("ChannelNumber", UintegerValue (40)); + mac.SetType ("ns3::StaWifiMac", + "Ssid", SsidValue (ssid)); + + staDeviceB = wifi.Install (phy, mac, wifiStaNodes.Get (1)); + + // Disable A-MPDU + dev = wifiStaNodes.Get (1)->GetDevice (0); + wifi_dev = DynamicCast (dev); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (0)); + + mac.SetType ("ns3::ApWifiMac", + "Ssid", SsidValue (ssid), + "EnableBeaconJitter", BooleanValue (false)); + apDeviceB = wifi.Install (phy, mac, wifiApNodes.Get (1)); + + // Disable A-MPDU + dev = wifiApNodes.Get (1)->GetDevice (0); + wifi_dev = DynamicCast (dev); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (0)); + + // Modify EDCA configuration (TXOP limit) for AC_BE + wifi_dev->GetMac ()->GetAttribute ("BE_Txop", ptr); + edca = ptr.Get (); + edca->SetTxopLimit (MicroSeconds (txopLimit)); + + // Trace TXOP duration for BE on AP B + TxopDurationTracer netB; + edca->TraceConnectWithoutContext ("TxopTrace", MakeCallback (&TxopDurationTracer::Trace, &netB)); + + // Network C + ssid = Ssid ("network-C"); + phy.Set ("ChannelNumber", UintegerValue (44)); + mac.SetType ("ns3::StaWifiMac", + "Ssid", SsidValue (ssid)); + + staDeviceC = wifi.Install (phy, mac, wifiStaNodes.Get (2)); + + // Disable A-MPDU and enable A-MSDU with the highest maximum size allowed by the standard (7935 bytes) + dev = wifiStaNodes.Get (2)->GetDevice (0); + wifi_dev = DynamicCast (dev); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (0)); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmsduSize", UintegerValue (7935)); + + mac.SetType ("ns3::ApWifiMac", + "Ssid", SsidValue (ssid), + "EnableBeaconJitter", BooleanValue (false)); + apDeviceC = wifi.Install (phy, mac, wifiApNodes.Get (2)); + + // Disable A-MPDU and enable A-MSDU with the highest maximum size allowed by the standard (7935 bytes) + dev = wifiApNodes.Get (2)->GetDevice (0); + wifi_dev = DynamicCast (dev); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (0)); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmsduSize", UintegerValue (7935)); + + // Modify EDCA configuration (TXOP limit) for AC_BE + wifi_dev->GetMac ()->GetAttribute ("BE_Txop", ptr); + edca = ptr.Get (); + edca->SetTxopLimit (MicroSeconds (txopLimit)); + + // Trace TXOP duration for BE on AP C + TxopDurationTracer netC; + edca->TraceConnectWithoutContext ("TxopTrace", MakeCallback (&TxopDurationTracer::Trace, &netC)); + + // Network D + ssid = Ssid ("network-D"); + phy.Set ("ChannelNumber", UintegerValue (48)); + mac.SetType ("ns3::StaWifiMac", + "Ssid", SsidValue (ssid)); + + staDeviceD = wifi.Install (phy, mac, wifiStaNodes.Get (3)); + + // Enable A-MPDU with a smaller size than the default one and + // enable A-MSDU with the smallest maximum size allowed by the standard (3839 bytes) + dev = wifiStaNodes.Get (3)->GetDevice (0); + wifi_dev = DynamicCast (dev); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (32768)); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmsduSize", UintegerValue (3839)); + + mac.SetType ("ns3::ApWifiMac", + "Ssid", SsidValue (ssid), + "EnableBeaconJitter", BooleanValue (false)); + apDeviceD = wifi.Install (phy, mac, wifiApNodes.Get (3)); + + // Enable A-MPDU with a smaller size than the default one and + // enable A-MSDU with the smallest maximum size allowed by the standard (3839 bytes) + dev = wifiApNodes.Get (3)->GetDevice (0); + wifi_dev = DynamicCast (dev); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (32768)); + wifi_dev->GetMac ()->SetAttribute ("BE_MaxAmsduSize", UintegerValue (3839)); + + // Modify EDCA configuration (TXOP limit) for AC_BE + wifi_dev->GetMac ()->GetAttribute ("BE_Txop", ptr); + edca = ptr.Get (); + edca->SetTxopLimit (MicroSeconds (txopLimit)); + + // Trace TXOP duration for BE on AP D + TxopDurationTracer netD; + edca->TraceConnectWithoutContext ("TxopTrace", MakeCallback (&TxopDurationTracer::Trace, &netD)); + + // Setting mobility model + MobilityHelper mobility; + Ptr positionAlloc = CreateObject (); + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + + // Set position for APs + positionAlloc->Add (Vector (0.0, 0.0, 0.0)); + positionAlloc->Add (Vector (10.0, 0.0, 0.0)); + positionAlloc->Add (Vector (20.0, 0.0, 0.0)); + positionAlloc->Add (Vector (30.0, 0.0, 0.0)); + // Set position for STAs + positionAlloc->Add (Vector (distance, 0.0, 0.0)); + positionAlloc->Add (Vector (10 + distance, 0.0, 0.0)); + positionAlloc->Add (Vector (20 + distance, 0.0, 0.0)); + positionAlloc->Add (Vector (30 + distance, 0.0, 0.0)); + + mobility.SetPositionAllocator (positionAlloc); + mobility.Install (wifiApNodes); + mobility.Install (wifiStaNodes); + + // Internet stack + InternetStackHelper stack; + stack.Install (wifiApNodes); + stack.Install (wifiStaNodes); + + Ipv4AddressHelper address; + address.SetBase ("192.168.1.0", "255.255.255.0"); + Ipv4InterfaceContainer StaInterfaceA; + StaInterfaceA = address.Assign (staDeviceA); + Ipv4InterfaceContainer ApInterfaceA; + ApInterfaceA = address.Assign (apDeviceA); + + address.SetBase ("192.168.2.0", "255.255.255.0"); + Ipv4InterfaceContainer StaInterfaceB; + StaInterfaceB = address.Assign (staDeviceB); + Ipv4InterfaceContainer ApInterfaceB; + ApInterfaceB = address.Assign (apDeviceB); + + address.SetBase ("192.168.3.0", "255.255.255.0"); + Ipv4InterfaceContainer StaInterfaceC; + StaInterfaceC = address.Assign (staDeviceC); + Ipv4InterfaceContainer ApInterfaceC; + ApInterfaceC = address.Assign (apDeviceC); + + address.SetBase ("192.168.4.0", "255.255.255.0"); + Ipv4InterfaceContainer StaInterfaceD; + StaInterfaceD = address.Assign (staDeviceD); + Ipv4InterfaceContainer ApInterfaceD; + ApInterfaceD = address.Assign (apDeviceD); + + // Setting applications + uint16_t port = 9; + UdpServerHelper serverA (port); + ApplicationContainer serverAppA = serverA.Install (wifiStaNodes.Get (0)); + serverAppA.Start (Seconds (0.0)); + serverAppA.Stop (Seconds (simulationTime + 1)); + + UdpClientHelper clientA (StaInterfaceA.GetAddress (0), port); + clientA.SetAttribute ("MaxPackets", UintegerValue (4294967295u)); + clientA.SetAttribute ("Interval", TimeValue (Time ("0.00002"))); //packets/s + clientA.SetAttribute ("PacketSize", UintegerValue (payloadSize)); + + ApplicationContainer clientAppA = clientA.Install (wifiApNodes.Get (0)); + clientAppA.Start (Seconds (1.0)); + clientAppA.Stop (Seconds (simulationTime + 1)); + + UdpServerHelper serverB (port); + ApplicationContainer serverAppB = serverB.Install (wifiStaNodes.Get (1)); + serverAppB.Start (Seconds (0.0)); + serverAppB.Stop (Seconds (simulationTime + 1)); + + UdpClientHelper clientB (StaInterfaceB.GetAddress (0), port); + clientB.SetAttribute ("MaxPackets", UintegerValue (4294967295u)); + clientB.SetAttribute ("Interval", TimeValue (Time ("0.00002"))); //packets/s + clientB.SetAttribute ("PacketSize", UintegerValue (payloadSize)); + + ApplicationContainer clientAppB = clientB.Install (wifiApNodes.Get (1)); + clientAppB.Start (Seconds (1.0)); + clientAppB.Stop (Seconds (simulationTime + 1)); + + UdpServerHelper serverC (port); + ApplicationContainer serverAppC = serverC.Install (wifiStaNodes.Get (2)); + serverAppC.Start (Seconds (0.0)); + serverAppC.Stop (Seconds (simulationTime + 1)); + + UdpClientHelper clientC (StaInterfaceC.GetAddress (0), port); + clientC.SetAttribute ("MaxPackets", UintegerValue (4294967295u)); + clientC.SetAttribute ("Interval", TimeValue (Time ("0.00002"))); //packets/s + clientC.SetAttribute ("PacketSize", UintegerValue (payloadSize)); + + ApplicationContainer clientAppC = clientC.Install (wifiApNodes.Get (2)); + clientAppC.Start (Seconds (1.0)); + clientAppC.Stop (Seconds (simulationTime + 1)); + + UdpServerHelper serverD (port); + ApplicationContainer serverAppD = serverD.Install (wifiStaNodes.Get (3)); + serverAppD.Start (Seconds (0.0)); + serverAppD.Stop (Seconds (simulationTime + 1)); + + UdpClientHelper clientD (StaInterfaceD.GetAddress (0), port); + clientD.SetAttribute ("MaxPackets", UintegerValue (4294967295u)); + clientD.SetAttribute ("Interval", TimeValue (Time ("0.00002"))); //packets/s + clientD.SetAttribute ("PacketSize", UintegerValue (payloadSize)); + + ApplicationContainer clientAppD = clientD.Install (wifiApNodes.Get (3)); + clientAppD.Start (Seconds (1.0)); + clientAppD.Stop (Seconds (simulationTime + 1)); + + if (enablePcap) + { + phy.EnablePcap ("AP_A", apDeviceA.Get (0)); + phy.EnablePcap ("STA_A", staDeviceA.Get (0)); + phy.EnablePcap ("AP_B", apDeviceB.Get (0)); + phy.EnablePcap ("STA_B", staDeviceB.Get (0)); + phy.EnablePcap ("AP_C", apDeviceC.Get (0)); + phy.EnablePcap ("STA_C", staDeviceC.Get (0)); + phy.EnablePcap ("AP_D", apDeviceD.Get (0)); + phy.EnablePcap ("STA_D", staDeviceD.Get (0)); + } + + Simulator::Stop (Seconds (simulationTime + 1)); + Simulator::Run (); + + // Show results + uint64_t totalPacketsThroughA = DynamicCast (serverAppA.Get (0))->GetReceived (); + uint64_t totalPacketsThroughB = DynamicCast (serverAppB.Get (0))->GetReceived (); + uint64_t totalPacketsThroughC = DynamicCast (serverAppC.Get (0))->GetReceived (); + uint64_t totalPacketsThroughD = DynamicCast (serverAppD.Get (0))->GetReceived (); + + Simulator::Destroy (); + + double throughput = totalPacketsThroughA * payloadSize * 8 / (simulationTime * 1000000.0); + std::cout << "Default configuration (A-MPDU aggregation enabled, 65kB): " << '\n' + << " Throughput = " << throughput << " Mbit/s" << '\n'; + if (verifyResults && (throughput < 57 || throughput > 58)) + { + NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!"); + exit (1); + } + if (txopLimit) + { + std::cout << " Maximum TXOP duration (TXOP limit = " << txopLimit << "us): " + << netA.m_max.GetMicroSeconds () << " us" << '\n'; + if (verifyResults && txopLimit && (netA.m_max < MicroSeconds (3350) || netA.m_max > MicroSeconds (3520))) + { + NS_LOG_ERROR ("Maximum TXOP duration " << netA.m_max << " is not in the expected boundaries!"); + exit (1); + } + } + + throughput = totalPacketsThroughB * payloadSize * 8 / (simulationTime * 1000000.0); + std::cout << "Aggregation disabled: " << '\n' + << " Throughput = " << throughput << " Mbit/s" << '\n'; + if (verifyResults && (throughput < 39 || throughput > 40)) + { + NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!"); + exit (1); + } + if (txopLimit) + { + std::cout << " Maximum TXOP duration (TXOP limit = " << txopLimit << "us): " + << netB.m_max.GetMicroSeconds () << " us" << '\n'; + if (verifyResults && (netB.m_max < MicroSeconds (3350) || netB.m_max > MicroSeconds (3520))) + { + NS_LOG_ERROR ("Maximum TXOP duration " << netB.m_max << " is not in the expected boundaries!"); + exit (1); + } + } + + throughput = totalPacketsThroughC * payloadSize * 8 / (simulationTime * 1000000.0); + std::cout << "A-MPDU disabled and A-MSDU enabled (8kB): " << '\n' + << " Throughput = " << throughput << " Mbit/s" << '\n'; + if (verifyResults && (throughput < 53 || throughput > 53.5)) + { + NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!"); + exit (1); + } + if (txopLimit) + { + std::cout << " Maximum TXOP duration (TXOP limit = " << txopLimit << "us): " + << netC.m_max.GetMicroSeconds () << " us" << '\n'; + if (verifyResults && (netC.m_max < MicroSeconds (3350) || netC.m_max > MicroSeconds (3520))) + { + NS_LOG_ERROR ("Maximum TXOP duration " << netC.m_max << " is not in the expected boundaries!"); + exit (1); + } + } + + throughput = totalPacketsThroughD * payloadSize * 8 / (simulationTime * 1000000.0); + std::cout << "A-MPDU enabled (32kB) and A-MSDU enabled (4kB): " << '\n' + << " Throughput = " << throughput << " Mbit/s" << '\n'; + if (verifyResults && (throughput < 58 || throughput > 59)) + { + NS_LOG_ERROR ("Obtained throughput " << throughput << " is not in the expected boundaries!"); + exit (1); + } + if (txopLimit) + { + std::cout << " Maximum TXOP duration (TXOP limit = " << txopLimit << "us): " + << netD.m_max.GetMicroSeconds () << " us" << '\n'; + if (verifyResults && txopLimit && (netD.m_max < MicroSeconds (3350) || netD.m_max > MicroSeconds (3520))) + { + NS_LOG_ERROR ("Maximum TXOP duration " << netD.m_max << " is not in the expected boundaries!"); + exit (1); + } + } + + return 0; +} diff --git a/examples/wireless/wscript b/examples/wireless/wscript index 3396e9fb3..b8798f7f1 100644 --- a/examples/wireless/wscript +++ b/examples/wireless/wscript @@ -77,6 +77,9 @@ def build(bld): obj = bld.create_ns3_program('wifi-aggregation', ['wifi', 'applications']) obj.source = 'wifi-aggregation.cc' + obj = bld.create_ns3_program('wifi-txop-aggregation', ['wifi', 'applications']) + obj.source = 'wifi-txop-aggregation.cc' + obj = bld.create_ns3_program('simple-ht-hidden-stations', ['wifi', 'applications']) obj.source = 'simple-ht-hidden-stations.cc' diff --git a/src/network/utils/drop-tail-queue.h b/src/network/utils/drop-tail-queue.h index adb9c411d..981cd23b8 100644 --- a/src/network/utils/drop-tail-queue.h +++ b/src/network/utils/drop-tail-queue.h @@ -52,8 +52,8 @@ public: virtual Ptr Peek (void) const; private: - using Queue::Head; - using Queue::Tail; + using Queue::begin; + using Queue::end; using Queue::DoEnqueue; using Queue::DoDequeue; using Queue::DoRemove; @@ -99,7 +99,7 @@ DropTailQueue::Enqueue (Ptr item) { NS_LOG_FUNCTION (this << item); - return DoEnqueue (Tail (), item); + return DoEnqueue (end (), item); } template @@ -108,7 +108,7 @@ DropTailQueue::Dequeue (void) { NS_LOG_FUNCTION (this); - Ptr item = DoDequeue (Head ()); + Ptr item = DoDequeue (begin ()); NS_LOG_LOGIC ("Popped " << item); @@ -121,7 +121,7 @@ DropTailQueue::Remove (void) { NS_LOG_FUNCTION (this); - Ptr item = DoRemove (Head ()); + Ptr item = DoRemove (begin ()); NS_LOG_LOGIC ("Removed " << item); @@ -134,7 +134,7 @@ DropTailQueue::Peek (void) const { NS_LOG_FUNCTION (this); - return DoPeek (Head ()); + return DoPeek (begin ()); } // The following explicit template instantiation declarations prevent all the diff --git a/src/network/utils/queue.h b/src/network/utils/queue.h index e8e168ef9..7c0316f34 100644 --- a/src/network/utils/queue.h +++ b/src/network/utils/queue.h @@ -302,38 +302,72 @@ protected: /// Const iterator. typedef typename std::list >::const_iterator ConstIterator; + /// Iterator. + typedef typename std::list >::iterator Iterator; /** * \brief Get a const iterator which refers to the first item in the queue. * - * Subclasses can browse the items in the queue by using an iterator + * Subclasses can browse the items in the queue by using a const iterator * * \code - * for (auto i = Head (); i != Tail (); ++i) + * for (auto i = begin (); i != end (); ++i) * { - * (*i)->method (); // some method of the Item class + * (*i)->method (); // some const method of the Item class * } * \endcode * * \returns a const iterator which refers to the first item in the queue. */ - ConstIterator Head (void) const; + ConstIterator begin (void) const; /** - * \brief Get a const iterator which indicates past-the-last item in the queue. + * \brief Get an iterator which refers to the first item in the queue. * * Subclasses can browse the items in the queue by using an iterator * * \code - * for (auto i = Head (); i != Tail (); ++i) + * for (auto i = begin (); i != end (); ++i) * { * (*i)->method (); // some method of the Item class * } * \endcode * + * \returns an iterator which refers to the first item in the queue. + */ + Iterator begin (void); + + /** + * \brief Get a const iterator which indicates past-the-last item in the queue. + * + * Subclasses can browse the items in the queue by using a const iterator + * + * \code + * for (auto i = begin (); i != end (); ++i) + * { + * (*i)->method (); // some const method of the Item class + * } + * \endcode + * * \returns a const iterator which indicates past-the-last item in the queue. */ - ConstIterator Tail (void) const; + ConstIterator end (void) const; + + /** + * \brief Get an iterator which indicates past-the-last item in the queue. + * + * Subclasses can browse the items in the queue by using an iterator + * + * \code + * for (auto i = begin (); i != end (); ++i) + * { + * (*i)->method (); // some method of the Item class + * } + * \endcode + * + * \returns an iterator which indicates past-the-last item in the queue. + */ + Iterator end (void); /** * Push an item in the queue @@ -559,17 +593,29 @@ Queue::DoPeek (ConstIterator pos) const } template -typename Queue::ConstIterator Queue::Head (void) const +typename Queue::ConstIterator Queue::begin (void) const { return m_packets.cbegin (); } template -typename Queue::ConstIterator Queue::Tail (void) const +typename Queue::Iterator Queue::begin (void) +{ + return m_packets.begin (); +} + +template +typename Queue::ConstIterator Queue::end (void) const { return m_packets.cend (); } +template +typename Queue::Iterator Queue::end (void) +{ + return m_packets.end (); +} + template void Queue::DropBeforeEnqueue (Ptr item) diff --git a/src/wave/bindings/modulegen__gcc_ILP32.py b/src/wave/bindings/modulegen__gcc_ILP32.py index bf7782eaf..3589c183a 100644 --- a/src/wave/bindings/modulegen__gcc_ILP32.py +++ b/src/wave/bindings/modulegen__gcc_ILP32.py @@ -124,6 +124,8 @@ def register_types(module): module.add_class('DefaultDeleter', import_from_module='ns.core', template_parameters=['ns3::WifiInformationElement']) ## default-deleter.h (module 'core'): ns3::DefaultDeleter [struct] module.add_class('DefaultDeleter', import_from_module='ns.core', template_parameters=['ns3::WifiMacQueueItem']) + ## default-deleter.h (module 'core'): ns3::DefaultDeleter [struct] + module.add_class('DefaultDeleter', import_from_module='ns.core', template_parameters=['ns3::WifiPsdu']) ## channel-scheduler.h (module 'wave'): ns3::EdcaParameter [struct] module.add_class('EdcaParameter') ## event-id.h (module 'core'): ns3::EventId [class] @@ -219,7 +221,7 @@ def register_types(module): ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement [class] module.add_class('OriginatorBlockAckAgreement', import_from_module='ns.wifi', parent=root_module['ns3::BlockAckAgreement']) ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement::State [enumeration] - module.add_enum('State', ['PENDING', 'ESTABLISHED', 'INACTIVE', 'NO_REPLY', 'RESET', 'REJECTED'], outer_class=root_module['ns3::OriginatorBlockAckAgreement'], import_from_module='ns.wifi') + module.add_enum('State', ['PENDING', 'ESTABLISHED', 'NO_REPLY', 'RESET', 'REJECTED'], outer_class=root_module['ns3::OriginatorBlockAckAgreement'], import_from_module='ns.wifi') ## packet-metadata.h (module 'network'): ns3::PacketMetadata [class] module.add_class('PacketMetadata', import_from_module='ns.network') ## packet-metadata.h (module 'network'): ns3::PacketMetadata::Item [struct] @@ -406,6 +408,8 @@ def register_types(module): module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::WifiInformationElement', 'ns3::empty', 'ns3::DefaultDeleter'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount > [class] module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::WifiMacQueueItem', 'ns3::empty', 'ns3::DefaultDeleter'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) + ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount > [class] + module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::WifiPsdu', 'ns3::empty', 'ns3::DefaultDeleter'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## socket.h (module 'network'): ns3::Socket [class] module.add_class('Socket', import_from_module='ns.network', parent=root_module['ns3::Object']) ## socket.h (module 'network'): ns3::Socket::SocketErrno [enumeration] @@ -512,6 +516,8 @@ def register_types(module): typehandlers.add_type_alias(u'void ( * ) ( ns3::Ptr< ns3::Packet const >, ns3::WifiMode, ns3::WifiPreamble, uint8_t )', u'ns3::WifiPhyStateHelper::TxTracedCallback') typehandlers.add_type_alias(u'void ( * ) ( ns3::Ptr< ns3::Packet const >, ns3::WifiMode, ns3::WifiPreamble, uint8_t )*', u'ns3::WifiPhyStateHelper::TxTracedCallback*') typehandlers.add_type_alias(u'void ( * ) ( ns3::Ptr< ns3::Packet const >, ns3::WifiMode, ns3::WifiPreamble, uint8_t )&', u'ns3::WifiPhyStateHelper::TxTracedCallback&') + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu [class] + module.add_class('WifiPsdu', import_from_module='ns.wifi', parent=root_module['ns3::SimpleRefCount< ns3::WifiPsdu, ns3::empty, ns3::DefaultDeleter >']) ## wifi-remote-station-manager.h (module 'wifi'): ns3::WifiRemoteStationManager [class] module.add_class('WifiRemoteStationManager', import_from_module='ns.wifi', parent=root_module['ns3::Object']) ## wifi-remote-station-manager.h (module 'wifi'): ns3::WifiRemoteStationManager::ProtectionMode [enumeration] @@ -973,13 +979,14 @@ def register_types(module): module.add_container('std::vector< ns3::Ipv6Address >', 'ns3::Ipv6Address', container_type=u'vector') module.add_container('std::vector< bool >', 'bool', container_type=u'vector') module.add_container('std::vector< unsigned short >', 'short unsigned int', container_type=u'vector') + module.add_container('std::vector< ns3::Ptr< ns3::WifiMacQueueItem > >', 'ns3::Ptr< ns3::WifiMacQueueItem >', container_type=u'vector') + module.add_container('std::set< unsigned char >', 'unsigned char', container_type=u'set') module.add_container('std::vector< ns3::WifiRemoteStation * >', 'ns3::WifiRemoteStation *', container_type=u'vector') module.add_container('std::vector< ns3::WifiRemoteStationState * >', 'ns3::WifiRemoteStationState *', container_type=u'vector') module.add_container('std::map< unsigned int, unsigned int >', ('unsigned int', 'unsigned int'), container_type=u'map') module.add_container('std::list< unsigned int >', 'unsigned int', container_type=u'list') module.add_container('std::list< std::pair< ns3::Ptr< ns3::Packet >, ns3::AmpduSubframeHeader > >', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmpduSubframeHeader >', container_type=u'list') module.add_container('std::map< ns3::AcIndex, ns3::Ptr< ns3::QosTxop > >', ('ns3::AcIndex', 'ns3::Ptr< ns3::QosTxop >'), container_type=u'map') - module.add_container('std::vector< ns3::Ptr< ns3::WifiMacQueueItem > >', 'ns3::Ptr< ns3::WifiMacQueueItem >', container_type=u'vector') module.add_container('ns3::MpduAggregator::DeaggregatedMpdus', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmpduSubframeHeader >', container_type=u'list') module.add_container('std::list< ns3::Ptr< ns3::Packet const > >', 'ns3::Ptr< ns3::Packet const >', container_type=u'list') module.add_container('ns3::MpduAggregator::EdcaQueues', ('ns3::AcIndex', 'ns3::Ptr< ns3::QosTxop >'), container_type=u'map') @@ -987,6 +994,7 @@ def register_types(module): module.add_container('ns3::MsduAggregator::DeaggregatedMsdus', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmsduSubframeHeader >', container_type=u'list') module.add_container('ns3::MsduAggregator::EdcaQueues', ('ns3::AcIndex', 'ns3::Ptr< ns3::QosTxop >'), container_type=u'map') module.add_container('std::map< ns3::Mac48Address, bool >', ('ns3::Mac48Address', 'bool'), container_type=u'map') + module.add_container('std::list< ns3::Ptr< ns3::WifiMacQueueItem > >', 'ns3::Ptr< ns3::WifiMacQueueItem >', container_type=u'list') module.add_container('std::map< unsigned int, ns3::Ptr< ns3::OcbWifiMac > >', ('unsigned int', 'ns3::Ptr< ns3::OcbWifiMac >'), container_type=u'map') module.add_container('std::vector< ns3::Ptr< ns3::WifiPhy > >', 'ns3::Ptr< ns3::WifiPhy >', container_type=u'vector') typehandlers.add_type_alias(u'ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::WifiTxVector, std::vector< bool >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', u'ns3::RxOkCallback') @@ -1164,6 +1172,7 @@ def register_methods(root_module): register_Ns3DefaultDeleter__Ns3TraceSourceAccessor_methods(root_module, root_module['ns3::DefaultDeleter< ns3::TraceSourceAccessor >']) register_Ns3DefaultDeleter__Ns3WifiInformationElement_methods(root_module, root_module['ns3::DefaultDeleter< ns3::WifiInformationElement >']) register_Ns3DefaultDeleter__Ns3WifiMacQueueItem_methods(root_module, root_module['ns3::DefaultDeleter< ns3::WifiMacQueueItem >']) + register_Ns3DefaultDeleter__Ns3WifiPsdu_methods(root_module, root_module['ns3::DefaultDeleter< ns3::WifiPsdu >']) register_Ns3EdcaParameter_methods(root_module, root_module['ns3::EdcaParameter']) register_Ns3EventId_methods(root_module, root_module['ns3::EventId']) register_Ns3Hasher_methods(root_module, root_module['ns3::Hasher']) @@ -1269,6 +1278,7 @@ def register_methods(root_module): register_Ns3SimpleRefCount__Ns3TraceSourceAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3TraceSourceAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::TraceSourceAccessor, ns3::empty, ns3::DefaultDeleter >']) register_Ns3SimpleRefCount__Ns3WifiInformationElement_Ns3Empty_Ns3DefaultDeleter__lt__ns3WifiInformationElement__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::WifiInformationElement, ns3::empty, ns3::DefaultDeleter >']) register_Ns3SimpleRefCount__Ns3WifiMacQueueItem_Ns3Empty_Ns3DefaultDeleter__lt__ns3WifiMacQueueItem__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::WifiMacQueueItem, ns3::empty, ns3::DefaultDeleter >']) + register_Ns3SimpleRefCount__Ns3WifiPsdu_Ns3Empty_Ns3DefaultDeleter__lt__ns3WifiPsdu__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::WifiPsdu, ns3::empty, ns3::DefaultDeleter >']) register_Ns3Socket_methods(root_module, root_module['ns3::Socket']) register_Ns3SocketIpTosTag_methods(root_module, root_module['ns3::SocketIpTosTag']) register_Ns3SocketIpTtlTag_methods(root_module, root_module['ns3::SocketIpTtlTag']) @@ -1293,6 +1303,7 @@ def register_methods(root_module): register_Ns3WifiMacQueueItem_methods(root_module, root_module['ns3::WifiMacQueueItem']) register_Ns3WifiPhy_methods(root_module, root_module['ns3::WifiPhy']) register_Ns3WifiPhyStateHelper_methods(root_module, root_module['ns3::WifiPhyStateHelper']) + register_Ns3WifiPsdu_methods(root_module, root_module['ns3::WifiPsdu']) register_Ns3WifiRemoteStationManager_methods(root_module, root_module['ns3::WifiRemoteStationManager']) register_Ns3YansWavePhyHelper_methods(root_module, root_module['ns3::YansWavePhyHelper']) register_Ns3ZetaRandomVariable_methods(root_module, root_module['ns3::ZetaRandomVariable']) @@ -2577,6 +2588,18 @@ def register_Ns3DefaultDeleter__Ns3WifiMacQueueItem_methods(root_module, cls): is_static=True) return +def register_Ns3DefaultDeleter__Ns3WifiPsdu_methods(root_module, cls): + ## default-deleter.h (module 'core'): ns3::DefaultDeleter::DefaultDeleter() [constructor] + cls.add_constructor([]) + ## default-deleter.h (module 'core'): ns3::DefaultDeleter::DefaultDeleter(ns3::DefaultDeleter const & arg0) [constructor] + cls.add_constructor([param('ns3::DefaultDeleter< ns3::WifiPsdu > const &', 'arg0')]) + ## default-deleter.h (module 'core'): static void ns3::DefaultDeleter::Delete(ns3::WifiPsdu * object) [member function] + cls.add_method('Delete', + 'void', + [param('ns3::WifiPsdu *', 'object')], + is_static=True) + return + def register_Ns3EdcaParameter_methods(root_module, cls): ## channel-scheduler.h (module 'wave'): ns3::EdcaParameter::EdcaParameter() [constructor] cls.add_constructor([]) @@ -3753,6 +3776,11 @@ def register_Ns3MacLowTransmissionParameters_methods(root_module, cls): cls.add_method('EnableRts', 'void', []) + ## mac-low-transmission-parameters.h (module 'wifi'): ns3::BlockAckType ns3::MacLowTransmissionParameters::GetBlockAckType() const [member function] + cls.add_method('GetBlockAckType', + 'ns3::BlockAckType', + [], + is_const=True) ## mac-low-transmission-parameters.h (module 'wifi'): uint32_t ns3::MacLowTransmissionParameters::GetNextPacketSize() const [member function] cls.add_method('GetNextPacketSize', 'uint32_t', @@ -3768,23 +3796,8 @@ def register_Ns3MacLowTransmissionParameters_methods(root_module, cls): 'bool', [], is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitBasicBlockAck() const [member function] - cls.add_method('MustWaitBasicBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitCompressedBlockAck() const [member function] - cls.add_method('MustWaitCompressedBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitExtendedCompressedBlockAck() const [member function] - cls.add_method('MustWaitExtendedCompressedBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitMultiTidBlockAck() const [member function] - cls.add_method('MustWaitMultiTidBlockAck', + ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitBlockAck() const [member function] + cls.add_method('MustWaitBlockAck', 'bool', [], is_const=True) @@ -4085,25 +4098,11 @@ def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls): cls.add_constructor([param('ns3::OriginatorBlockAckAgreement const &', 'arg0')]) ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement(ns3::Mac48Address recipient, uint8_t tid) [constructor] cls.add_constructor([param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) - ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::CompleteExchange() [member function] - cls.add_method('CompleteExchange', - 'void', - []) - ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsBlockAckRequestNeeded() const [member function] - cls.add_method('IsBlockAckRequestNeeded', - 'bool', - [], - is_const=True) ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsEstablished() const [member function] cls.add_method('IsEstablished', 'bool', [], is_const=True) - ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsInactive() const [member function] - cls.add_method('IsInactive', - 'bool', - [], - is_const=True) ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsNoReply() const [member function] cls.add_method('IsNoReply', 'bool', @@ -4124,10 +4123,6 @@ def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls): 'bool', [], is_const=True) - ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::NotifyMpduTransmission(uint16_t nextSeqNumber) [member function] - cls.add_method('NotifyMpduTransmission', - 'void', - [param('uint16_t', 'nextSeqNumber')]) ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::SetState(ns3::OriginatorBlockAckAgreement::State state) [member function] cls.add_method('SetState', 'void', @@ -5320,6 +5315,10 @@ def register_Ns3WifiHelper_methods(root_module, cls): 'ns3::NetDeviceContainer', [param('ns3::WifiPhyHelper const &', 'phy'), param('ns3::WifiMacHelper const &', 'mac'), param('std::string', 'nodeName')], is_const=True, is_virtual=True) + ## wifi-helper.h (module 'wifi'): void ns3::WifiHelper::SetObssPdAlgorithm(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetObssPdAlgorithm', + 'void', + [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')]) ## wifi-helper.h (module 'wifi'): void ns3::WifiHelper::SetRemoteStationManager(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] cls.add_method('SetRemoteStationManager', 'void', @@ -6802,6 +6801,13 @@ def register_Ns3SimpleRefCount__Ns3WifiMacQueueItem_Ns3Empty_Ns3DefaultDeleter__ cls.add_constructor([param('ns3::SimpleRefCount< ns3::WifiMacQueueItem, ns3::empty, ns3::DefaultDeleter< ns3::WifiMacQueueItem > > const &', 'o')]) return +def register_Ns3SimpleRefCount__Ns3WifiPsdu_Ns3Empty_Ns3DefaultDeleter__lt__ns3WifiPsdu__gt___methods(root_module, cls): + ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount >::SimpleRefCount() [constructor] + cls.add_constructor([]) + ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount >::SimpleRefCount(ns3::SimpleRefCount > const & o) [constructor] + cls.add_constructor([param('ns3::SimpleRefCount< ns3::WifiPsdu, ns3::empty, ns3::DefaultDeleter< ns3::WifiPsdu > > const &', 'o')]) + return + def register_Ns3Socket_methods(root_module, cls): ## socket.h (module 'network'): ns3::Socket::Socket(ns3::Socket const & arg0) [constructor] cls.add_constructor([param('ns3::Socket const &', 'arg0')]) @@ -7926,11 +7932,16 @@ def register_Ns3Txop_methods(root_module, cls): 'void', [], is_virtual=True) - ## txop.h (module 'wifi'): bool ns3::Txop::HasTxop() const [member function] - cls.add_method('HasTxop', - 'bool', + ## txop.h (module 'wifi'): ns3::Time ns3::Txop::GetTxopRemaining() const [member function] + cls.add_method('GetTxopRemaining', + 'ns3::Time', [], is_const=True, is_virtual=True) + ## txop.h (module 'wifi'): void ns3::Txop::TerminateTxop() [member function] + cls.add_method('TerminateTxop', + 'void', + [], + is_virtual=True) ## txop.h (module 'wifi'): bool ns3::Txop::CanStartNextPolling() const [member function] cls.add_method('CanStartNextPolling', 'bool', @@ -9176,6 +9187,10 @@ def register_Ns3WifiPhy_methods(root_module, cls): cls.add_method('EndReceive', 'void', [param('ns3::Ptr< ns3::Event >', 'event'), param('ns3::Time', 'psduDuration')]) + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::EndReceiveInterBss() [member function] + cls.add_method('EndReceiveInterBss', + 'void', + []) ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::SendPacket(ns3::Ptr packet, ns3::WifiTxVector txVector) [member function] cls.add_method('SendPacket', 'void', @@ -9854,10 +9869,10 @@ def register_Ns3WifiPhy_methods(root_module, cls): 'ns3::WifiMode', [], is_static=True) - ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr packet) [member function] + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr packet, double txPowerW) [member function] cls.add_method('NotifyTxBegin', 'void', - [param('ns3::Ptr< ns3::Packet const >', 'packet')]) + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('double', 'txPowerW')]) ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyTxEnd(ns3::Ptr packet) [member function] cls.add_method('NotifyTxEnd', 'void', @@ -10101,6 +10116,19 @@ def register_Ns3WifiPhy_methods(root_module, cls): 'double', [param('uint8_t', 'power')], is_const=True) + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::ResetCca(bool powerRestricted, double txPowerMaxSiso=0, double txPowerMaxMimo=0) [member function] + cls.add_method('ResetCca', + 'void', + [param('bool', 'powerRestricted'), param('double', 'txPowerMaxSiso', default_value='0'), param('double', 'txPowerMaxMimo', default_value='0')]) + ## wifi-phy.h (module 'wifi'): double ns3::WifiPhy::GetTxPowerForTransmission(ns3::WifiTxVector txVector) const [member function] + cls.add_method('GetTxPowerForTransmission', + 'double', + [param('ns3::WifiTxVector', 'txVector')], + is_const=True) + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyChannelAccessRequested() [member function] + cls.add_method('NotifyChannelAccessRequested', + 'void', + []) ## wifi-phy.h (module 'wifi'): ns3::WifiPhy::WifiPhy(ns3::WifiPhy const & arg0) [constructor] cls.add_constructor([param('ns3::WifiPhy const &', 'arg0')]) ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::DoInitialize() [member function] @@ -10252,6 +10280,114 @@ def register_Ns3WifiPhyStateHelper_methods(root_module, cls): [param('ns3::WifiPhyListener *', 'listener')]) return +def register_Ns3WifiPsdu_methods(root_module, cls): + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(ns3::WifiPsdu const & arg0) [constructor] + cls.add_constructor([param('ns3::WifiPsdu const &', 'arg0')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(ns3::Ptr p, ns3::WifiMacHeader const & header) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::Packet const >', 'p'), param('ns3::WifiMacHeader const &', 'header')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(ns3::Ptr mpdu, bool isSingle) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu'), param('bool', 'isSingle')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(ns3::Ptr mpdu, bool isSingle) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu'), param('bool', 'isSingle')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(std::vector, std::allocator > > mpduList) [constructor] + cls.add_constructor([param('std::vector< ns3::Ptr< ns3::WifiMacQueueItem > >', 'mpduList')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiMacHeader::QosAckPolicy ns3::WifiPsdu::GetAckPolicyForTid(uint8_t tid) const [member function] + cls.add_method('GetAckPolicyForTid', + 'ns3::WifiMacHeader::QosAckPolicy', + [param('uint8_t', 'tid')], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Mac48Address ns3::WifiPsdu::GetAddr1() const [member function] + cls.add_method('GetAddr1', + 'ns3::Mac48Address', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Mac48Address ns3::WifiPsdu::GetAddr2() const [member function] + cls.add_method('GetAddr2', + 'ns3::Mac48Address', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Time ns3::WifiPsdu::GetDuration() const [member function] + cls.add_method('GetDuration', + 'ns3::Time', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::WifiMacHeader const & ns3::WifiPsdu::GetHeader(std::size_t i) const [member function] + cls.add_method('GetHeader', + 'ns3::WifiMacHeader const &', + [param('std::size_t', 'i')], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::WifiMacHeader & ns3::WifiPsdu::GetHeader(std::size_t i) [member function] + cls.add_method('GetHeader', + 'ns3::WifiMacHeader &', + [param('std::size_t', 'i')]) + ## wifi-psdu.h (module 'wifi'): std::size_t ns3::WifiPsdu::GetNMpdus() const [member function] + cls.add_method('GetNMpdus', + 'std::size_t', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Ptr ns3::WifiPsdu::GetPacket() const [member function] + cls.add_method('GetPacket', + 'ns3::Ptr< ns3::Packet const >', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Ptr ns3::WifiPsdu::GetPayload(std::size_t i) const [member function] + cls.add_method('GetPayload', + 'ns3::Ptr< ns3::Packet const >', + [param('std::size_t', 'i')], + is_const=True) + ## wifi-psdu.h (module 'wifi'): uint32_t ns3::WifiPsdu::GetSize() const [member function] + cls.add_method('GetSize', + 'uint32_t', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): std::set, std::allocator > ns3::WifiPsdu::GetTids() const [member function] + cls.add_method('GetTids', + 'std::set< unsigned char >', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Time ns3::WifiPsdu::GetTimeStamp(std::size_t i) const [member function] + cls.add_method('GetTimeStamp', + 'ns3::Time', + [param('std::size_t', 'i')], + is_const=True) + ## wifi-psdu.h (module 'wifi'): bool ns3::WifiPsdu::IsAggregate() const [member function] + cls.add_method('IsAggregate', + 'bool', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): bool ns3::WifiPsdu::IsSingle() const [member function] + cls.add_method('IsSingle', + 'bool', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): void ns3::WifiPsdu::SetAckPolicyForTid(uint8_t tid, ns3::WifiMacHeader::QosAckPolicy policy) [member function] + cls.add_method('SetAckPolicyForTid', + 'void', + [param('uint8_t', 'tid'), param('ns3::WifiMacHeader::QosAckPolicy', 'policy')]) + ## wifi-psdu.h (module 'wifi'): void ns3::WifiPsdu::SetDuration(ns3::Time duration) [member function] + cls.add_method('SetDuration', + 'void', + [param('ns3::Time', 'duration')]) + ## wifi-psdu.h (module 'wifi'): std::vector, std::allocator > >::const_iterator ns3::WifiPsdu::begin() const [member function] + cls.add_method('begin', + 'std::vector< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): std::vector, std::allocator > >::iterator ns3::WifiPsdu::begin() [member function] + cls.add_method('begin', + 'std::vector< ns3::Ptr< ns3::WifiMacQueueItem > > iterator', + []) + ## wifi-psdu.h (module 'wifi'): std::vector, std::allocator > >::const_iterator ns3::WifiPsdu::end() const [member function] + cls.add_method('end', + 'std::vector< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): std::vector, std::allocator > >::iterator ns3::WifiPsdu::end() [member function] + cls.add_method('end', + 'std::vector< ns3::Ptr< ns3::WifiMacQueueItem > > iterator', + []) + return + def register_Ns3WifiRemoteStationManager_methods(root_module, cls): ## wifi-remote-station-manager.h (module 'wifi'): ns3::WifiRemoteStationManager::WifiRemoteStationManager(ns3::WifiRemoteStationManager const & arg0) [constructor] cls.add_constructor([param('ns3::WifiRemoteStationManager const &', 'arg0')]) @@ -11146,23 +11282,27 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('UpdateAgreement', 'void', [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'recipient')]) - ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::StorePacket(ns3::Ptr mpdu) [member function] + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::StorePacket(ns3::Ptr mpdu) [member function] cls.add_method('StorePacket', 'void', - [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) - ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::GetNextPacket(bool removePacket) [member function] - cls.add_method('GetNextPacket', - 'ns3::Ptr< ns3::WifiMacQueueItem >', - [param('bool', 'removePacket')]) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasBar(ns3::Bar & bar) [member function] + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasBar(ns3::Bar & bar, bool remove=true) [member function] cls.add_method('HasBar', 'bool', - [param('ns3::Bar &', 'bar')]) + [param('ns3::Bar &', 'bar'), param('bool', 'remove', default_value='true')]) ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasPackets() const [member function] cls.add_method('HasPackets', 'bool', [], is_const=True) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyGotAck(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyGotAck', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyMissedAck(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyMissedAck', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyGotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address recipient, double rxSnr, ns3::WifiMode txMode, double dataSnr) [member function] cls.add_method('NotifyGotBlockAck', 'void', @@ -11171,16 +11311,15 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('NotifyMissedBlockAck', 'void', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::DiscardOutstandingMpdus(ns3::Mac48Address recipient, uint8_t tid) [member function] + cls.add_method('DiscardOutstandingMpdus', + 'void', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## block-ack-manager.h (module 'wifi'): uint32_t ns3::BlockAckManager::GetNBufferedPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function] cls.add_method('GetNBufferedPackets', 'uint32_t', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], is_const=True) - ## block-ack-manager.h (module 'wifi'): uint32_t ns3::BlockAckManager::GetNRetryNeededPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('GetNRetryNeededPackets', - 'uint32_t', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyAgreementEstablished(ns3::Mac48Address recipient, uint8_t tid, uint16_t startingSeq) [member function] cls.add_method('NotifyAgreementEstablished', 'void', @@ -11201,14 +11340,14 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('NotifyMpduTransmission', 'void', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'nextSeqNumber'), param('ns3::WifiMacHeader::QosAckPolicy', 'policy')]) - ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::CompleteAmpduExchange(ns3::Mac48Address recipient, uint8_t tid) [member function] - cls.add_method('CompleteAmpduExchange', - 'void', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetBlockAckThreshold(uint8_t nPackets) [member function] cls.add_method('SetBlockAckThreshold', 'void', [param('uint8_t', 'nPackets')]) + ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::GetRetransmitQueue() [member function] + cls.add_method('GetRetransmitQueue', + 'ns3::Ptr< ns3::WifiMacQueue >', + []) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetQueue(ns3::Ptr const queue) [member function] cls.add_method('SetQueue', 'void', @@ -11241,24 +11380,6 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('SwitchToBlockAckIfNeeded', 'bool', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'startingSeq')]) - ## block-ack-manager.h (module 'wifi'): uint16_t ns3::BlockAckManager::GetSeqNumOfNextRetryPacket(ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('GetSeqNumOfNextRetryPacket', - 'uint16_t', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::AlreadyExists(uint16_t currentSeq, ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('AlreadyExists', - 'bool', - [param('uint16_t', 'currentSeq'), param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::RemovePacket(uint8_t tid, ns3::Mac48Address recipient, uint16_t seqnumber) [member function] - cls.add_method('RemovePacket', - 'bool', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient'), param('uint16_t', 'seqnumber')]) - ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::PeekNextPacketByTidAndAddress(uint8_t tid, ns3::Mac48Address recipient) [member function] - cls.add_method('PeekNextPacketByTidAndAddress', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient')]) ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::NeedBarRetransmission(uint8_t tid, uint16_t seqNumber, ns3::Mac48Address recipient) [member function] cls.add_method('NeedBarRetransmission', 'bool', @@ -11268,6 +11389,11 @@ def register_Ns3BlockAckManager_methods(root_module, cls): 'uint16_t', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], is_const=True) + ## block-ack-manager.h (module 'wifi'): uint16_t ns3::BlockAckManager::GetOriginatorStartingSequence(ns3::Mac48Address recipient, uint8_t tid) const [member function] + cls.add_method('GetOriginatorStartingSequence', + 'uint16_t', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], + is_const=True) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetTxOkCallback(ns3::BlockAckManager::TxOk callback) [member function] cls.add_method('SetTxOkCallback', 'void', @@ -11276,6 +11402,14 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('SetTxFailedCallback', 'void', [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyDiscardedMpdu(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyDiscardedMpdu', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::ScheduleBlockAckReq(ns3::Mac48Address recipient, uint8_t tid) [member function] + cls.add_method('ScheduleBlockAckReq', + 'void', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) return def register_Ns3BooleanChecker_methods(root_module, cls): @@ -14420,6 +14554,11 @@ def register_Ns3MacLow_methods(root_module, cls): 'ns3::Time', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters const &', 'params'), param('uint32_t', 'fragmentSize', default_value='0')], is_const=True) + ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::CalculateOverheadTxTime(ns3::Ptr item, ns3::MacLowTransmissionParameters const & params) const [member function] + cls.add_method('CalculateOverheadTxTime', + 'ns3::Time', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item'), param('ns3::MacLowTransmissionParameters const &', 'params')], + is_const=True) ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::CalculateTransmissionTime(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters const & parameters) const [member function] cls.add_method('CalculateTransmissionTime', 'ns3::Time', @@ -14446,10 +14585,6 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('DoNavStartNow', 'bool', [param('ns3::Time', 'duration')]) - ## mac-low.h (module 'wifi'): void ns3::MacLow::FlushAggregateQueue(uint8_t tid) [member function] - cls.add_method('FlushAggregateQueue', - 'void', - [param('uint8_t', 'tid')]) ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::GetAckTimeout() const [member function] cls.add_method('GetAckTimeout', 'ns3::Time', @@ -14495,10 +14630,10 @@ def register_Ns3MacLow_methods(root_module, cls): 'bool', [], is_const=True) - ## mac-low.h (module 'wifi'): ns3::WifiTxVector ns3::MacLow::GetDataTxVector(ns3::Ptr packet, ns3::WifiMacHeader const * hdr) const [member function] + ## mac-low.h (module 'wifi'): ns3::WifiTxVector ns3::MacLow::GetDataTxVector(ns3::Ptr item) const [member function] cls.add_method('GetDataTxVector', 'ns3::WifiTxVector', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr')], + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item')], is_const=True, is_virtual=True) ## mac-low.h (module 'wifi'): ns3::Ptr ns3::MacLow::GetMpduAggregator() const [member function] cls.add_method('GetMpduAggregator', @@ -14667,10 +14802,10 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager > const', 'manager')]) - ## mac-low.h (module 'wifi'): void ns3::MacLow::StartTransmission(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] + ## mac-low.h (module 'wifi'): void ns3::MacLow::StartTransmission(ns3::Ptr mpdu, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] cls.add_method('StartTransmission', 'void', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], is_virtual=True) ## mac-low.h (module 'wifi'): void ns3::MacLow::DoDispose() [member function] cls.add_method('DoDispose', @@ -15269,6 +15404,11 @@ def register_Ns3Packet_methods(root_module, cls): 'void', [param('ns3::Tag const &', 'tag')], is_const=True) + ## packet.h (module 'network'): void ns3::Packet::AddByteTag(ns3::Tag const & tag, uint32_t start, uint32_t end) const [member function] + cls.add_method('AddByteTag', + 'void', + [param('ns3::Tag const &', 'tag'), param('uint32_t', 'start'), param('uint32_t', 'end')], + is_const=True) ## packet.h (module 'network'): void ns3::Packet::AddHeader(ns3::Header const & header) [member function] cls.add_method('AddHeader', 'void', @@ -15569,15 +15709,16 @@ def register_Ns3QosTxop_methods(root_module, cls): 'bool', [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], is_const=True) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteAmpduTransfer(ns3::Mac48Address recipient, uint8_t tid) [member function] - cls.add_method('CompleteAmpduTransfer', - 'void', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## qos-txop.h (module 'wifi'): uint16_t ns3::QosTxop::GetBaBufferSize(ns3::Mac48Address address, uint8_t tid) const [member function] cls.add_method('GetBaBufferSize', 'uint16_t', [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], is_const=True) + ## qos-txop.h (module 'wifi'): uint16_t ns3::QosTxop::GetBaStartingSequence(ns3::Mac48Address address, uint8_t tid) const [member function] + cls.add_method('GetBaStartingSequence', + 'uint16_t', + [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], + is_const=True) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::NotifyAccessGranted() [member function] cls.add_method('NotifyAccessGranted', 'void', @@ -15593,11 +15734,10 @@ def register_Ns3QosTxop_methods(root_module, cls): 'void', [], is_virtual=True) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::MissedCts() [member function] - cls.add_method('MissedCts', + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::NotifyMissedCts(std::list, std::allocator > > mpduList) [member function] + cls.add_method('NotifyMissedCts', 'void', - [], - is_virtual=True) + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > >', 'mpduList')]) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::GotAck() [member function] cls.add_method('GotAck', 'void', @@ -15689,10 +15829,10 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('SendDelbaFrame', 'void', [param('ns3::Mac48Address', 'addr'), param('uint8_t', 'tid'), param('bool', 'byOriginator')]) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteMpduTx(ns3::Ptr mpdu) [member function] + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteMpduTx(ns3::Ptr mpdu) [member function] cls.add_method('CompleteMpduTx', 'void', - [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::GetAmpduExist(ns3::Mac48Address dest) const [member function] cls.add_method('GetAmpduExist', 'bool', @@ -15728,14 +15868,27 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('PeekNextSequenceNumberFor', 'uint16_t', [param('ns3::WifiMacHeader const *', 'hdr')]) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::RemoveRetransmitPacket(uint8_t tid, ns3::Mac48Address recipient, uint16_t seqnumber) [member function] - cls.add_method('RemoveRetransmitPacket', - 'void', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient'), param('uint16_t', 'seqnumber')]) - ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::PeekNextRetransmitPacket(uint8_t tid, ns3::Mac48Address recipient) [member function] - cls.add_method('PeekNextRetransmitPacket', + ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::PeekNextFrame(uint8_t tid=8, ns3::Mac48Address recipient=ns3::Mac48Address::GetBroadcast()) [member function] + cls.add_method('PeekNextFrame', 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient')]) + [param('uint8_t', 'tid', default_value='8'), param('ns3::Mac48Address', 'recipient', default_value='ns3::Mac48Address::GetBroadcast()')]) + ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::DequeuePeekedFrame(ns3::Ptr peekedItem, ns3::WifiTxVector txVector, bool aggregate=true, uint32_t ampduSize=0, ns3::Time ppduDurationLimit=ns3::Seconds(0)) [member function] + cls.add_method('DequeuePeekedFrame', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'peekedItem'), param('ns3::WifiTxVector', 'txVector'), param('bool', 'aggregate', default_value='true'), param('uint32_t', 'ampduSize', default_value='0'), param('ns3::Time', 'ppduDurationLimit', default_value='ns3::Seconds(0)')]) + ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsWithinSizeAndTimeLimits(ns3::Ptr mpdu, ns3::WifiTxVector txVector, uint32_t ampduSize, ns3::Time ppduDurationLimit) [member function] + cls.add_method('IsWithinSizeAndTimeLimits', + 'bool', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu'), param('ns3::WifiTxVector', 'txVector'), param('uint32_t', 'ampduSize'), param('ns3::Time', 'ppduDurationLimit')]) + ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsWithinSizeAndTimeLimits(uint32_t mpduSize, ns3::Mac48Address receiver, uint8_t tid, ns3::WifiTxVector txVector, uint32_t ampduSize, ns3::Time ppduDurationLimit) [member function] + cls.add_method('IsWithinSizeAndTimeLimits', + 'bool', + [param('uint32_t', 'mpduSize'), param('ns3::Mac48Address', 'receiver'), param('uint8_t', 'tid'), param('ns3::WifiTxVector', 'txVector'), param('uint32_t', 'ampduSize'), param('ns3::Time', 'ppduDurationLimit')]) + ## qos-txop.h (module 'wifi'): ns3::MacLowTransmissionParameters ns3::QosTxop::GetTransmissionParameters(ns3::Ptr frame) const [member function] + cls.add_method('GetTransmissionParameters', + 'ns3::MacLowTransmissionParameters', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'frame')], + is_const=True) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::BaTxOk(ns3::WifiMacHeader const & hdr) [member function] cls.add_method('BaTxOk', 'void', @@ -15754,11 +15907,16 @@ def register_Ns3QosTxop_methods(root_module, cls): [param('ns3::WifiMacHeader const &', 'hdr')]) ## qos-txop.h (module 'wifi'): ns3::QosTxop::QosTxop(ns3::QosTxop const & arg0) [constructor] cls.add_constructor([param('ns3::QosTxop const &', 'arg0')]) - ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::HasTxop() const [member function] - cls.add_method('HasTxop', - 'bool', + ## qos-txop.h (module 'wifi'): ns3::Time ns3::QosTxop::GetTxopRemaining() const [member function] + cls.add_method('GetTxopRemaining', + 'ns3::Time', [], is_const=True, visibility='private', is_virtual=True) + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::TerminateTxop() [member function] + cls.add_method('TerminateTxop', + 'void', + [], + visibility='private', is_virtual=True) ## qos-txop.h (module 'wifi'): uint32_t ns3::QosTxop::GetNextFragmentSize() const [member function] cls.add_method('GetNextFragmentSize', 'uint32_t', @@ -15825,16 +15983,26 @@ def register_Ns3Queue__Ns3Packet_methods(root_module, cls): []) ## queue.h (module 'network'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::Packet > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::Packet > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::Packet > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::Packet > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::Packet > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -15901,16 +16069,26 @@ def register_Ns3Queue__Ns3QueueDiscItem_methods(root_module, cls): []) ## queue.h (module 'network'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::QueueDiscItem > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::QueueDiscItem > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::QueueDiscItem > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::QueueDiscItem > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::QueueDiscItem > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -15977,16 +16155,26 @@ def register_Ns3Queue__Ns3WifiMacQueueItem_methods(root_module, cls): []) ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::WifiMacQueueItem > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::WifiMacQueueItem > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::WifiMacQueueItem > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -16981,28 +17169,28 @@ def register_Ns3VhtCapabilities_methods(root_module, cls): return def register_Ns3WaveMacLow_methods(root_module, cls): + ## wave-mac-low.h (module 'wave'): ns3::WaveMacLow::WaveMacLow(ns3::WaveMacLow const & arg0) [constructor] + cls.add_constructor([param('ns3::WaveMacLow const &', 'arg0')]) + ## wave-mac-low.h (module 'wave'): ns3::WaveMacLow::WaveMacLow() [constructor] + cls.add_constructor([]) ## wave-mac-low.h (module 'wave'): static ns3::TypeId ns3::WaveMacLow::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) - ## wave-mac-low.h (module 'wave'): ns3::WaveMacLow::WaveMacLow() [constructor] - cls.add_constructor([]) ## wave-mac-low.h (module 'wave'): void ns3::WaveMacLow::SetWaveNetDevice(ns3::Ptr device) [member function] cls.add_method('SetWaveNetDevice', 'void', [param('ns3::Ptr< ns3::WaveNetDevice >', 'device')]) - ## wave-mac-low.h (module 'wave'): void ns3::WaveMacLow::StartTransmission(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] + ## wave-mac-low.h (module 'wave'): void ns3::WaveMacLow::StartTransmission(ns3::Ptr mpdu, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] cls.add_method('StartTransmission', 'void', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], is_virtual=True) - ## wave-mac-low.h (module 'wave'): ns3::WaveMacLow::WaveMacLow(ns3::WaveMacLow const & arg0) [constructor] - cls.add_constructor([param('ns3::WaveMacLow const &', 'arg0')]) - ## wave-mac-low.h (module 'wave'): ns3::WifiTxVector ns3::WaveMacLow::GetDataTxVector(ns3::Ptr packet, ns3::WifiMacHeader const * hdr) const [member function] + ## wave-mac-low.h (module 'wave'): ns3::WifiTxVector ns3::WaveMacLow::GetDataTxVector(ns3::Ptr item) const [member function] cls.add_method('GetDataTxVector', 'ns3::WifiTxVector', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr')], + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item')], is_const=True, visibility='private', is_virtual=True) return @@ -17041,6 +17229,10 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('PushFront', 'bool', [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'item')]) + ## wifi-mac-queue.h (module 'wifi'): bool ns3::WifiMacQueue::Insert(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] + cls.add_method('Insert', + 'bool', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos'), param('ns3::Ptr< ns3::WifiMacQueueItem >', 'item')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue() [member function] cls.add_method('Dequeue', 'ns3::Ptr< ns3::WifiMacQueueItem >', @@ -17050,27 +17242,47 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('DequeueByAddress', 'ns3::Ptr< ns3::WifiMacQueueItem >', [param('ns3::Mac48Address', 'dest')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTid(uint8_t tid) [member function] + cls.add_method('DequeueByTid', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('uint8_t', 'tid')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTidAndAddress(uint8_t tid, ns3::Mac48Address dest) [member function] cls.add_method('DequeueByTidAndAddress', 'ns3::Ptr< ns3::WifiMacQueueItem >', [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest')]) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::Ptr const blockedPackets) [member function] + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::Ptr const blockedPackets=nullptr) [member function] cls.add_method('DequeueFirstAvailable', 'ns3::Ptr< ns3::WifiMacQueueItem >', - [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets')]) + [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets', default_value='nullptr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue(ns3::Queue::ConstIterator pos) [member function] + cls.add_method('Dequeue', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Peek() const [member function] cls.add_method('Peek', 'ns3::Ptr< ns3::WifiMacQueueItem const >', [], is_const=True, is_virtual=True) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekByTidAndAddress(uint8_t tid, ns3::Mac48Address dest) [member function] + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByAddress(ns3::Mac48Address dest, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] + cls.add_method('PeekByAddress', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('ns3::Mac48Address', 'dest'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByTid(uint8_t tid, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] + cls.add_method('PeekByTid', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('uint8_t', 'tid'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByTidAndAddress(uint8_t tid, ns3::Mac48Address dest, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] cls.add_method('PeekByTidAndAddress', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest')]) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekFirstAvailable(ns3::Ptr const blockedPackets) [member function] + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekFirstAvailable(ns3::Ptr const blockedPackets=nullptr, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] cls.add_method('PeekFirstAvailable', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets')]) + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets', default_value='nullptr'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Remove() [member function] cls.add_method('Remove', 'ns3::Ptr< ns3::WifiMacQueueItem >', @@ -17080,6 +17292,10 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('Remove', 'bool', [param('ns3::Ptr< ns3::Packet const >', 'packet')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::Remove(ns3::Queue::ConstIterator pos, bool removeExpired=false) [member function] + cls.add_method('Remove', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos'), param('bool', 'removeExpired', default_value='false')]) ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetNPacketsByAddress(ns3::Mac48Address dest) [member function] cls.add_method('GetNPacketsByAddress', 'uint32_t', @@ -17100,6 +17316,8 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('GetNBytes', 'uint32_t', []) + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::EMPTY [variable] + cls.add_static_attribute('EMPTY', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator const', is_const=True) ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::WifiMacQueue(ns3::WifiMacQueue const & arg0) [constructor] cls.add_constructor([param('ns3::WifiMacQueue const &', 'arg0')]) return diff --git a/src/wave/bindings/modulegen__gcc_LP64.py b/src/wave/bindings/modulegen__gcc_LP64.py index 72c35bd8b..237162c3f 100644 --- a/src/wave/bindings/modulegen__gcc_LP64.py +++ b/src/wave/bindings/modulegen__gcc_LP64.py @@ -124,6 +124,8 @@ def register_types(module): module.add_class('DefaultDeleter', import_from_module='ns.core', template_parameters=['ns3::WifiInformationElement']) ## default-deleter.h (module 'core'): ns3::DefaultDeleter [struct] module.add_class('DefaultDeleter', import_from_module='ns.core', template_parameters=['ns3::WifiMacQueueItem']) + ## default-deleter.h (module 'core'): ns3::DefaultDeleter [struct] + module.add_class('DefaultDeleter', import_from_module='ns.core', template_parameters=['ns3::WifiPsdu']) ## channel-scheduler.h (module 'wave'): ns3::EdcaParameter [struct] module.add_class('EdcaParameter') ## event-id.h (module 'core'): ns3::EventId [class] @@ -219,7 +221,7 @@ def register_types(module): ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement [class] module.add_class('OriginatorBlockAckAgreement', import_from_module='ns.wifi', parent=root_module['ns3::BlockAckAgreement']) ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement::State [enumeration] - module.add_enum('State', ['PENDING', 'ESTABLISHED', 'INACTIVE', 'NO_REPLY', 'RESET', 'REJECTED'], outer_class=root_module['ns3::OriginatorBlockAckAgreement'], import_from_module='ns.wifi') + module.add_enum('State', ['PENDING', 'ESTABLISHED', 'NO_REPLY', 'RESET', 'REJECTED'], outer_class=root_module['ns3::OriginatorBlockAckAgreement'], import_from_module='ns.wifi') ## packet-metadata.h (module 'network'): ns3::PacketMetadata [class] module.add_class('PacketMetadata', import_from_module='ns.network') ## packet-metadata.h (module 'network'): ns3::PacketMetadata::Item [struct] @@ -406,6 +408,8 @@ def register_types(module): module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::WifiInformationElement', 'ns3::empty', 'ns3::DefaultDeleter'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount > [class] module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::WifiMacQueueItem', 'ns3::empty', 'ns3::DefaultDeleter'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) + ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount > [class] + module.add_class('SimpleRefCount', automatic_type_narrowing=True, import_from_module='ns.core', template_parameters=['ns3::WifiPsdu', 'ns3::empty', 'ns3::DefaultDeleter'], parent=root_module['ns3::empty'], memory_policy=cppclass.ReferenceCountingMethodsPolicy(incref_method='Ref', decref_method='Unref', peekref_method='GetReferenceCount')) ## socket.h (module 'network'): ns3::Socket [class] module.add_class('Socket', import_from_module='ns.network', parent=root_module['ns3::Object']) ## socket.h (module 'network'): ns3::Socket::SocketErrno [enumeration] @@ -512,6 +516,8 @@ def register_types(module): typehandlers.add_type_alias(u'void ( * ) ( ns3::Ptr< ns3::Packet const >, ns3::WifiMode, ns3::WifiPreamble, uint8_t )', u'ns3::WifiPhyStateHelper::TxTracedCallback') typehandlers.add_type_alias(u'void ( * ) ( ns3::Ptr< ns3::Packet const >, ns3::WifiMode, ns3::WifiPreamble, uint8_t )*', u'ns3::WifiPhyStateHelper::TxTracedCallback*') typehandlers.add_type_alias(u'void ( * ) ( ns3::Ptr< ns3::Packet const >, ns3::WifiMode, ns3::WifiPreamble, uint8_t )&', u'ns3::WifiPhyStateHelper::TxTracedCallback&') + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu [class] + module.add_class('WifiPsdu', import_from_module='ns.wifi', parent=root_module['ns3::SimpleRefCount< ns3::WifiPsdu, ns3::empty, ns3::DefaultDeleter >']) ## wifi-remote-station-manager.h (module 'wifi'): ns3::WifiRemoteStationManager [class] module.add_class('WifiRemoteStationManager', import_from_module='ns.wifi', parent=root_module['ns3::Object']) ## wifi-remote-station-manager.h (module 'wifi'): ns3::WifiRemoteStationManager::ProtectionMode [enumeration] @@ -973,13 +979,14 @@ def register_types(module): module.add_container('std::vector< ns3::Ipv6Address >', 'ns3::Ipv6Address', container_type=u'vector') module.add_container('std::vector< bool >', 'bool', container_type=u'vector') module.add_container('std::vector< unsigned short >', 'short unsigned int', container_type=u'vector') + module.add_container('std::vector< ns3::Ptr< ns3::WifiMacQueueItem > >', 'ns3::Ptr< ns3::WifiMacQueueItem >', container_type=u'vector') + module.add_container('std::set< unsigned char >', 'unsigned char', container_type=u'set') module.add_container('std::vector< ns3::WifiRemoteStation * >', 'ns3::WifiRemoteStation *', container_type=u'vector') module.add_container('std::vector< ns3::WifiRemoteStationState * >', 'ns3::WifiRemoteStationState *', container_type=u'vector') module.add_container('std::map< unsigned int, unsigned int >', ('unsigned int', 'unsigned int'), container_type=u'map') module.add_container('std::list< unsigned int >', 'unsigned int', container_type=u'list') module.add_container('std::list< std::pair< ns3::Ptr< ns3::Packet >, ns3::AmpduSubframeHeader > >', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmpduSubframeHeader >', container_type=u'list') module.add_container('std::map< ns3::AcIndex, ns3::Ptr< ns3::QosTxop > >', ('ns3::AcIndex', 'ns3::Ptr< ns3::QosTxop >'), container_type=u'map') - module.add_container('std::vector< ns3::Ptr< ns3::WifiMacQueueItem > >', 'ns3::Ptr< ns3::WifiMacQueueItem >', container_type=u'vector') module.add_container('ns3::MpduAggregator::DeaggregatedMpdus', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmpduSubframeHeader >', container_type=u'list') module.add_container('std::list< ns3::Ptr< ns3::Packet const > >', 'ns3::Ptr< ns3::Packet const >', container_type=u'list') module.add_container('ns3::MpduAggregator::EdcaQueues', ('ns3::AcIndex', 'ns3::Ptr< ns3::QosTxop >'), container_type=u'map') @@ -987,6 +994,7 @@ def register_types(module): module.add_container('ns3::MsduAggregator::DeaggregatedMsdus', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmsduSubframeHeader >', container_type=u'list') module.add_container('ns3::MsduAggregator::EdcaQueues', ('ns3::AcIndex', 'ns3::Ptr< ns3::QosTxop >'), container_type=u'map') module.add_container('std::map< ns3::Mac48Address, bool >', ('ns3::Mac48Address', 'bool'), container_type=u'map') + module.add_container('std::list< ns3::Ptr< ns3::WifiMacQueueItem > >', 'ns3::Ptr< ns3::WifiMacQueueItem >', container_type=u'list') module.add_container('std::map< unsigned int, ns3::Ptr< ns3::OcbWifiMac > >', ('unsigned int', 'ns3::Ptr< ns3::OcbWifiMac >'), container_type=u'map') module.add_container('std::vector< ns3::Ptr< ns3::WifiPhy > >', 'ns3::Ptr< ns3::WifiPhy >', container_type=u'vector') typehandlers.add_type_alias(u'ns3::Callback< void, ns3::Ptr< ns3::Packet >, double, ns3::WifiTxVector, std::vector< bool >, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', u'ns3::RxOkCallback') @@ -1164,6 +1172,7 @@ def register_methods(root_module): register_Ns3DefaultDeleter__Ns3TraceSourceAccessor_methods(root_module, root_module['ns3::DefaultDeleter< ns3::TraceSourceAccessor >']) register_Ns3DefaultDeleter__Ns3WifiInformationElement_methods(root_module, root_module['ns3::DefaultDeleter< ns3::WifiInformationElement >']) register_Ns3DefaultDeleter__Ns3WifiMacQueueItem_methods(root_module, root_module['ns3::DefaultDeleter< ns3::WifiMacQueueItem >']) + register_Ns3DefaultDeleter__Ns3WifiPsdu_methods(root_module, root_module['ns3::DefaultDeleter< ns3::WifiPsdu >']) register_Ns3EdcaParameter_methods(root_module, root_module['ns3::EdcaParameter']) register_Ns3EventId_methods(root_module, root_module['ns3::EventId']) register_Ns3Hasher_methods(root_module, root_module['ns3::Hasher']) @@ -1269,6 +1278,7 @@ def register_methods(root_module): register_Ns3SimpleRefCount__Ns3TraceSourceAccessor_Ns3Empty_Ns3DefaultDeleter__lt__ns3TraceSourceAccessor__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::TraceSourceAccessor, ns3::empty, ns3::DefaultDeleter >']) register_Ns3SimpleRefCount__Ns3WifiInformationElement_Ns3Empty_Ns3DefaultDeleter__lt__ns3WifiInformationElement__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::WifiInformationElement, ns3::empty, ns3::DefaultDeleter >']) register_Ns3SimpleRefCount__Ns3WifiMacQueueItem_Ns3Empty_Ns3DefaultDeleter__lt__ns3WifiMacQueueItem__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::WifiMacQueueItem, ns3::empty, ns3::DefaultDeleter >']) + register_Ns3SimpleRefCount__Ns3WifiPsdu_Ns3Empty_Ns3DefaultDeleter__lt__ns3WifiPsdu__gt___methods(root_module, root_module['ns3::SimpleRefCount< ns3::WifiPsdu, ns3::empty, ns3::DefaultDeleter >']) register_Ns3Socket_methods(root_module, root_module['ns3::Socket']) register_Ns3SocketIpTosTag_methods(root_module, root_module['ns3::SocketIpTosTag']) register_Ns3SocketIpTtlTag_methods(root_module, root_module['ns3::SocketIpTtlTag']) @@ -1293,6 +1303,7 @@ def register_methods(root_module): register_Ns3WifiMacQueueItem_methods(root_module, root_module['ns3::WifiMacQueueItem']) register_Ns3WifiPhy_methods(root_module, root_module['ns3::WifiPhy']) register_Ns3WifiPhyStateHelper_methods(root_module, root_module['ns3::WifiPhyStateHelper']) + register_Ns3WifiPsdu_methods(root_module, root_module['ns3::WifiPsdu']) register_Ns3WifiRemoteStationManager_methods(root_module, root_module['ns3::WifiRemoteStationManager']) register_Ns3YansWavePhyHelper_methods(root_module, root_module['ns3::YansWavePhyHelper']) register_Ns3ZetaRandomVariable_methods(root_module, root_module['ns3::ZetaRandomVariable']) @@ -2577,6 +2588,18 @@ def register_Ns3DefaultDeleter__Ns3WifiMacQueueItem_methods(root_module, cls): is_static=True) return +def register_Ns3DefaultDeleter__Ns3WifiPsdu_methods(root_module, cls): + ## default-deleter.h (module 'core'): ns3::DefaultDeleter::DefaultDeleter() [constructor] + cls.add_constructor([]) + ## default-deleter.h (module 'core'): ns3::DefaultDeleter::DefaultDeleter(ns3::DefaultDeleter const & arg0) [constructor] + cls.add_constructor([param('ns3::DefaultDeleter< ns3::WifiPsdu > const &', 'arg0')]) + ## default-deleter.h (module 'core'): static void ns3::DefaultDeleter::Delete(ns3::WifiPsdu * object) [member function] + cls.add_method('Delete', + 'void', + [param('ns3::WifiPsdu *', 'object')], + is_static=True) + return + def register_Ns3EdcaParameter_methods(root_module, cls): ## channel-scheduler.h (module 'wave'): ns3::EdcaParameter::EdcaParameter() [constructor] cls.add_constructor([]) @@ -3753,6 +3776,11 @@ def register_Ns3MacLowTransmissionParameters_methods(root_module, cls): cls.add_method('EnableRts', 'void', []) + ## mac-low-transmission-parameters.h (module 'wifi'): ns3::BlockAckType ns3::MacLowTransmissionParameters::GetBlockAckType() const [member function] + cls.add_method('GetBlockAckType', + 'ns3::BlockAckType', + [], + is_const=True) ## mac-low-transmission-parameters.h (module 'wifi'): uint32_t ns3::MacLowTransmissionParameters::GetNextPacketSize() const [member function] cls.add_method('GetNextPacketSize', 'uint32_t', @@ -3768,23 +3796,8 @@ def register_Ns3MacLowTransmissionParameters_methods(root_module, cls): 'bool', [], is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitBasicBlockAck() const [member function] - cls.add_method('MustWaitBasicBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitCompressedBlockAck() const [member function] - cls.add_method('MustWaitCompressedBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitExtendedCompressedBlockAck() const [member function] - cls.add_method('MustWaitExtendedCompressedBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitMultiTidBlockAck() const [member function] - cls.add_method('MustWaitMultiTidBlockAck', + ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitBlockAck() const [member function] + cls.add_method('MustWaitBlockAck', 'bool', [], is_const=True) @@ -4085,25 +4098,11 @@ def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls): cls.add_constructor([param('ns3::OriginatorBlockAckAgreement const &', 'arg0')]) ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement(ns3::Mac48Address recipient, uint8_t tid) [constructor] cls.add_constructor([param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) - ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::CompleteExchange() [member function] - cls.add_method('CompleteExchange', - 'void', - []) - ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsBlockAckRequestNeeded() const [member function] - cls.add_method('IsBlockAckRequestNeeded', - 'bool', - [], - is_const=True) ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsEstablished() const [member function] cls.add_method('IsEstablished', 'bool', [], is_const=True) - ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsInactive() const [member function] - cls.add_method('IsInactive', - 'bool', - [], - is_const=True) ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsNoReply() const [member function] cls.add_method('IsNoReply', 'bool', @@ -4124,10 +4123,6 @@ def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls): 'bool', [], is_const=True) - ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::NotifyMpduTransmission(uint16_t nextSeqNumber) [member function] - cls.add_method('NotifyMpduTransmission', - 'void', - [param('uint16_t', 'nextSeqNumber')]) ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::SetState(ns3::OriginatorBlockAckAgreement::State state) [member function] cls.add_method('SetState', 'void', @@ -5320,6 +5315,10 @@ def register_Ns3WifiHelper_methods(root_module, cls): 'ns3::NetDeviceContainer', [param('ns3::WifiPhyHelper const &', 'phy'), param('ns3::WifiMacHelper const &', 'mac'), param('std::string', 'nodeName')], is_const=True, is_virtual=True) + ## wifi-helper.h (module 'wifi'): void ns3::WifiHelper::SetObssPdAlgorithm(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] + cls.add_method('SetObssPdAlgorithm', + 'void', + [param('std::string', 'type'), param('std::string', 'n0', default_value='""'), param('ns3::AttributeValue const &', 'v0', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n1', default_value='""'), param('ns3::AttributeValue const &', 'v1', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n2', default_value='""'), param('ns3::AttributeValue const &', 'v2', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n3', default_value='""'), param('ns3::AttributeValue const &', 'v3', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n4', default_value='""'), param('ns3::AttributeValue const &', 'v4', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n5', default_value='""'), param('ns3::AttributeValue const &', 'v5', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n6', default_value='""'), param('ns3::AttributeValue const &', 'v6', default_value='ns3::EmptyAttributeValue()'), param('std::string', 'n7', default_value='""'), param('ns3::AttributeValue const &', 'v7', default_value='ns3::EmptyAttributeValue()')]) ## wifi-helper.h (module 'wifi'): void ns3::WifiHelper::SetRemoteStationManager(std::string type, std::string n0="", ns3::AttributeValue const & v0=ns3::EmptyAttributeValue(), std::string n1="", ns3::AttributeValue const & v1=ns3::EmptyAttributeValue(), std::string n2="", ns3::AttributeValue const & v2=ns3::EmptyAttributeValue(), std::string n3="", ns3::AttributeValue const & v3=ns3::EmptyAttributeValue(), std::string n4="", ns3::AttributeValue const & v4=ns3::EmptyAttributeValue(), std::string n5="", ns3::AttributeValue const & v5=ns3::EmptyAttributeValue(), std::string n6="", ns3::AttributeValue const & v6=ns3::EmptyAttributeValue(), std::string n7="", ns3::AttributeValue const & v7=ns3::EmptyAttributeValue()) [member function] cls.add_method('SetRemoteStationManager', 'void', @@ -6802,6 +6801,13 @@ def register_Ns3SimpleRefCount__Ns3WifiMacQueueItem_Ns3Empty_Ns3DefaultDeleter__ cls.add_constructor([param('ns3::SimpleRefCount< ns3::WifiMacQueueItem, ns3::empty, ns3::DefaultDeleter< ns3::WifiMacQueueItem > > const &', 'o')]) return +def register_Ns3SimpleRefCount__Ns3WifiPsdu_Ns3Empty_Ns3DefaultDeleter__lt__ns3WifiPsdu__gt___methods(root_module, cls): + ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount >::SimpleRefCount() [constructor] + cls.add_constructor([]) + ## simple-ref-count.h (module 'core'): ns3::SimpleRefCount >::SimpleRefCount(ns3::SimpleRefCount > const & o) [constructor] + cls.add_constructor([param('ns3::SimpleRefCount< ns3::WifiPsdu, ns3::empty, ns3::DefaultDeleter< ns3::WifiPsdu > > const &', 'o')]) + return + def register_Ns3Socket_methods(root_module, cls): ## socket.h (module 'network'): ns3::Socket::Socket(ns3::Socket const & arg0) [constructor] cls.add_constructor([param('ns3::Socket const &', 'arg0')]) @@ -7926,11 +7932,16 @@ def register_Ns3Txop_methods(root_module, cls): 'void', [], is_virtual=True) - ## txop.h (module 'wifi'): bool ns3::Txop::HasTxop() const [member function] - cls.add_method('HasTxop', - 'bool', + ## txop.h (module 'wifi'): ns3::Time ns3::Txop::GetTxopRemaining() const [member function] + cls.add_method('GetTxopRemaining', + 'ns3::Time', [], is_const=True, is_virtual=True) + ## txop.h (module 'wifi'): void ns3::Txop::TerminateTxop() [member function] + cls.add_method('TerminateTxop', + 'void', + [], + is_virtual=True) ## txop.h (module 'wifi'): bool ns3::Txop::CanStartNextPolling() const [member function] cls.add_method('CanStartNextPolling', 'bool', @@ -9176,6 +9187,10 @@ def register_Ns3WifiPhy_methods(root_module, cls): cls.add_method('EndReceive', 'void', [param('ns3::Ptr< ns3::Event >', 'event'), param('ns3::Time', 'psduDuration')]) + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::EndReceiveInterBss() [member function] + cls.add_method('EndReceiveInterBss', + 'void', + []) ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::SendPacket(ns3::Ptr packet, ns3::WifiTxVector txVector) [member function] cls.add_method('SendPacket', 'void', @@ -9854,10 +9869,10 @@ def register_Ns3WifiPhy_methods(root_module, cls): 'ns3::WifiMode', [], is_static=True) - ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr packet) [member function] + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyTxBegin(ns3::Ptr packet, double txPowerW) [member function] cls.add_method('NotifyTxBegin', 'void', - [param('ns3::Ptr< ns3::Packet const >', 'packet')]) + [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('double', 'txPowerW')]) ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyTxEnd(ns3::Ptr packet) [member function] cls.add_method('NotifyTxEnd', 'void', @@ -10101,6 +10116,19 @@ def register_Ns3WifiPhy_methods(root_module, cls): 'double', [param('uint8_t', 'power')], is_const=True) + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::ResetCca(bool powerRestricted, double txPowerMaxSiso=0, double txPowerMaxMimo=0) [member function] + cls.add_method('ResetCca', + 'void', + [param('bool', 'powerRestricted'), param('double', 'txPowerMaxSiso', default_value='0'), param('double', 'txPowerMaxMimo', default_value='0')]) + ## wifi-phy.h (module 'wifi'): double ns3::WifiPhy::GetTxPowerForTransmission(ns3::WifiTxVector txVector) const [member function] + cls.add_method('GetTxPowerForTransmission', + 'double', + [param('ns3::WifiTxVector', 'txVector')], + is_const=True) + ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::NotifyChannelAccessRequested() [member function] + cls.add_method('NotifyChannelAccessRequested', + 'void', + []) ## wifi-phy.h (module 'wifi'): ns3::WifiPhy::WifiPhy(ns3::WifiPhy const & arg0) [constructor] cls.add_constructor([param('ns3::WifiPhy const &', 'arg0')]) ## wifi-phy.h (module 'wifi'): void ns3::WifiPhy::DoInitialize() [member function] @@ -10252,6 +10280,114 @@ def register_Ns3WifiPhyStateHelper_methods(root_module, cls): [param('ns3::WifiPhyListener *', 'listener')]) return +def register_Ns3WifiPsdu_methods(root_module, cls): + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(ns3::WifiPsdu const & arg0) [constructor] + cls.add_constructor([param('ns3::WifiPsdu const &', 'arg0')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(ns3::Ptr p, ns3::WifiMacHeader const & header) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::Packet const >', 'p'), param('ns3::WifiMacHeader const &', 'header')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(ns3::Ptr mpdu, bool isSingle) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu'), param('bool', 'isSingle')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(ns3::Ptr mpdu, bool isSingle) [constructor] + cls.add_constructor([param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu'), param('bool', 'isSingle')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiPsdu::WifiPsdu(std::vector, std::allocator > > mpduList) [constructor] + cls.add_constructor([param('std::vector< ns3::Ptr< ns3::WifiMacQueueItem > >', 'mpduList')]) + ## wifi-psdu.h (module 'wifi'): ns3::WifiMacHeader::QosAckPolicy ns3::WifiPsdu::GetAckPolicyForTid(uint8_t tid) const [member function] + cls.add_method('GetAckPolicyForTid', + 'ns3::WifiMacHeader::QosAckPolicy', + [param('uint8_t', 'tid')], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Mac48Address ns3::WifiPsdu::GetAddr1() const [member function] + cls.add_method('GetAddr1', + 'ns3::Mac48Address', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Mac48Address ns3::WifiPsdu::GetAddr2() const [member function] + cls.add_method('GetAddr2', + 'ns3::Mac48Address', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Time ns3::WifiPsdu::GetDuration() const [member function] + cls.add_method('GetDuration', + 'ns3::Time', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::WifiMacHeader const & ns3::WifiPsdu::GetHeader(std::size_t i) const [member function] + cls.add_method('GetHeader', + 'ns3::WifiMacHeader const &', + [param('std::size_t', 'i')], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::WifiMacHeader & ns3::WifiPsdu::GetHeader(std::size_t i) [member function] + cls.add_method('GetHeader', + 'ns3::WifiMacHeader &', + [param('std::size_t', 'i')]) + ## wifi-psdu.h (module 'wifi'): std::size_t ns3::WifiPsdu::GetNMpdus() const [member function] + cls.add_method('GetNMpdus', + 'std::size_t', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Ptr ns3::WifiPsdu::GetPacket() const [member function] + cls.add_method('GetPacket', + 'ns3::Ptr< ns3::Packet const >', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Ptr ns3::WifiPsdu::GetPayload(std::size_t i) const [member function] + cls.add_method('GetPayload', + 'ns3::Ptr< ns3::Packet const >', + [param('std::size_t', 'i')], + is_const=True) + ## wifi-psdu.h (module 'wifi'): uint32_t ns3::WifiPsdu::GetSize() const [member function] + cls.add_method('GetSize', + 'uint32_t', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): std::set, std::allocator > ns3::WifiPsdu::GetTids() const [member function] + cls.add_method('GetTids', + 'std::set< unsigned char >', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): ns3::Time ns3::WifiPsdu::GetTimeStamp(std::size_t i) const [member function] + cls.add_method('GetTimeStamp', + 'ns3::Time', + [param('std::size_t', 'i')], + is_const=True) + ## wifi-psdu.h (module 'wifi'): bool ns3::WifiPsdu::IsAggregate() const [member function] + cls.add_method('IsAggregate', + 'bool', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): bool ns3::WifiPsdu::IsSingle() const [member function] + cls.add_method('IsSingle', + 'bool', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): void ns3::WifiPsdu::SetAckPolicyForTid(uint8_t tid, ns3::WifiMacHeader::QosAckPolicy policy) [member function] + cls.add_method('SetAckPolicyForTid', + 'void', + [param('uint8_t', 'tid'), param('ns3::WifiMacHeader::QosAckPolicy', 'policy')]) + ## wifi-psdu.h (module 'wifi'): void ns3::WifiPsdu::SetDuration(ns3::Time duration) [member function] + cls.add_method('SetDuration', + 'void', + [param('ns3::Time', 'duration')]) + ## wifi-psdu.h (module 'wifi'): std::vector, std::allocator > >::const_iterator ns3::WifiPsdu::begin() const [member function] + cls.add_method('begin', + 'std::vector< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): std::vector, std::allocator > >::iterator ns3::WifiPsdu::begin() [member function] + cls.add_method('begin', + 'std::vector< ns3::Ptr< ns3::WifiMacQueueItem > > iterator', + []) + ## wifi-psdu.h (module 'wifi'): std::vector, std::allocator > >::const_iterator ns3::WifiPsdu::end() const [member function] + cls.add_method('end', + 'std::vector< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', + [], + is_const=True) + ## wifi-psdu.h (module 'wifi'): std::vector, std::allocator > >::iterator ns3::WifiPsdu::end() [member function] + cls.add_method('end', + 'std::vector< ns3::Ptr< ns3::WifiMacQueueItem > > iterator', + []) + return + def register_Ns3WifiRemoteStationManager_methods(root_module, cls): ## wifi-remote-station-manager.h (module 'wifi'): ns3::WifiRemoteStationManager::WifiRemoteStationManager(ns3::WifiRemoteStationManager const & arg0) [constructor] cls.add_constructor([param('ns3::WifiRemoteStationManager const &', 'arg0')]) @@ -11146,23 +11282,27 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('UpdateAgreement', 'void', [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'recipient')]) - ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::StorePacket(ns3::Ptr mpdu) [member function] + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::StorePacket(ns3::Ptr mpdu) [member function] cls.add_method('StorePacket', 'void', - [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) - ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::GetNextPacket(bool removePacket) [member function] - cls.add_method('GetNextPacket', - 'ns3::Ptr< ns3::WifiMacQueueItem >', - [param('bool', 'removePacket')]) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasBar(ns3::Bar & bar) [member function] + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasBar(ns3::Bar & bar, bool remove=true) [member function] cls.add_method('HasBar', 'bool', - [param('ns3::Bar &', 'bar')]) + [param('ns3::Bar &', 'bar'), param('bool', 'remove', default_value='true')]) ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasPackets() const [member function] cls.add_method('HasPackets', 'bool', [], is_const=True) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyGotAck(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyGotAck', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyMissedAck(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyMissedAck', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyGotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address recipient, double rxSnr, ns3::WifiMode txMode, double dataSnr) [member function] cls.add_method('NotifyGotBlockAck', 'void', @@ -11171,16 +11311,15 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('NotifyMissedBlockAck', 'void', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::DiscardOutstandingMpdus(ns3::Mac48Address recipient, uint8_t tid) [member function] + cls.add_method('DiscardOutstandingMpdus', + 'void', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## block-ack-manager.h (module 'wifi'): uint32_t ns3::BlockAckManager::GetNBufferedPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function] cls.add_method('GetNBufferedPackets', 'uint32_t', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], is_const=True) - ## block-ack-manager.h (module 'wifi'): uint32_t ns3::BlockAckManager::GetNRetryNeededPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('GetNRetryNeededPackets', - 'uint32_t', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyAgreementEstablished(ns3::Mac48Address recipient, uint8_t tid, uint16_t startingSeq) [member function] cls.add_method('NotifyAgreementEstablished', 'void', @@ -11201,14 +11340,14 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('NotifyMpduTransmission', 'void', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'nextSeqNumber'), param('ns3::WifiMacHeader::QosAckPolicy', 'policy')]) - ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::CompleteAmpduExchange(ns3::Mac48Address recipient, uint8_t tid) [member function] - cls.add_method('CompleteAmpduExchange', - 'void', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetBlockAckThreshold(uint8_t nPackets) [member function] cls.add_method('SetBlockAckThreshold', 'void', [param('uint8_t', 'nPackets')]) + ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::GetRetransmitQueue() [member function] + cls.add_method('GetRetransmitQueue', + 'ns3::Ptr< ns3::WifiMacQueue >', + []) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetQueue(ns3::Ptr const queue) [member function] cls.add_method('SetQueue', 'void', @@ -11241,24 +11380,6 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('SwitchToBlockAckIfNeeded', 'bool', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'startingSeq')]) - ## block-ack-manager.h (module 'wifi'): uint16_t ns3::BlockAckManager::GetSeqNumOfNextRetryPacket(ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('GetSeqNumOfNextRetryPacket', - 'uint16_t', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::AlreadyExists(uint16_t currentSeq, ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('AlreadyExists', - 'bool', - [param('uint16_t', 'currentSeq'), param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::RemovePacket(uint8_t tid, ns3::Mac48Address recipient, uint16_t seqnumber) [member function] - cls.add_method('RemovePacket', - 'bool', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient'), param('uint16_t', 'seqnumber')]) - ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::PeekNextPacketByTidAndAddress(uint8_t tid, ns3::Mac48Address recipient) [member function] - cls.add_method('PeekNextPacketByTidAndAddress', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient')]) ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::NeedBarRetransmission(uint8_t tid, uint16_t seqNumber, ns3::Mac48Address recipient) [member function] cls.add_method('NeedBarRetransmission', 'bool', @@ -11268,6 +11389,11 @@ def register_Ns3BlockAckManager_methods(root_module, cls): 'uint16_t', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], is_const=True) + ## block-ack-manager.h (module 'wifi'): uint16_t ns3::BlockAckManager::GetOriginatorStartingSequence(ns3::Mac48Address recipient, uint8_t tid) const [member function] + cls.add_method('GetOriginatorStartingSequence', + 'uint16_t', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], + is_const=True) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetTxOkCallback(ns3::BlockAckManager::TxOk callback) [member function] cls.add_method('SetTxOkCallback', 'void', @@ -11276,6 +11402,14 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('SetTxFailedCallback', 'void', [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyDiscardedMpdu(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyDiscardedMpdu', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::ScheduleBlockAckReq(ns3::Mac48Address recipient, uint8_t tid) [member function] + cls.add_method('ScheduleBlockAckReq', + 'void', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) return def register_Ns3BooleanChecker_methods(root_module, cls): @@ -14420,6 +14554,11 @@ def register_Ns3MacLow_methods(root_module, cls): 'ns3::Time', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters const &', 'params'), param('uint32_t', 'fragmentSize', default_value='0')], is_const=True) + ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::CalculateOverheadTxTime(ns3::Ptr item, ns3::MacLowTransmissionParameters const & params) const [member function] + cls.add_method('CalculateOverheadTxTime', + 'ns3::Time', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item'), param('ns3::MacLowTransmissionParameters const &', 'params')], + is_const=True) ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::CalculateTransmissionTime(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters const & parameters) const [member function] cls.add_method('CalculateTransmissionTime', 'ns3::Time', @@ -14446,10 +14585,6 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('DoNavStartNow', 'bool', [param('ns3::Time', 'duration')]) - ## mac-low.h (module 'wifi'): void ns3::MacLow::FlushAggregateQueue(uint8_t tid) [member function] - cls.add_method('FlushAggregateQueue', - 'void', - [param('uint8_t', 'tid')]) ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::GetAckTimeout() const [member function] cls.add_method('GetAckTimeout', 'ns3::Time', @@ -14495,10 +14630,10 @@ def register_Ns3MacLow_methods(root_module, cls): 'bool', [], is_const=True) - ## mac-low.h (module 'wifi'): ns3::WifiTxVector ns3::MacLow::GetDataTxVector(ns3::Ptr packet, ns3::WifiMacHeader const * hdr) const [member function] + ## mac-low.h (module 'wifi'): ns3::WifiTxVector ns3::MacLow::GetDataTxVector(ns3::Ptr item) const [member function] cls.add_method('GetDataTxVector', 'ns3::WifiTxVector', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr')], + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item')], is_const=True, is_virtual=True) ## mac-low.h (module 'wifi'): ns3::Ptr ns3::MacLow::GetMpduAggregator() const [member function] cls.add_method('GetMpduAggregator', @@ -14667,10 +14802,10 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager > const', 'manager')]) - ## mac-low.h (module 'wifi'): void ns3::MacLow::StartTransmission(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] + ## mac-low.h (module 'wifi'): void ns3::MacLow::StartTransmission(ns3::Ptr mpdu, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] cls.add_method('StartTransmission', 'void', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], is_virtual=True) ## mac-low.h (module 'wifi'): void ns3::MacLow::DoDispose() [member function] cls.add_method('DoDispose', @@ -15269,6 +15404,11 @@ def register_Ns3Packet_methods(root_module, cls): 'void', [param('ns3::Tag const &', 'tag')], is_const=True) + ## packet.h (module 'network'): void ns3::Packet::AddByteTag(ns3::Tag const & tag, uint32_t start, uint32_t end) const [member function] + cls.add_method('AddByteTag', + 'void', + [param('ns3::Tag const &', 'tag'), param('uint32_t', 'start'), param('uint32_t', 'end')], + is_const=True) ## packet.h (module 'network'): void ns3::Packet::AddHeader(ns3::Header const & header) [member function] cls.add_method('AddHeader', 'void', @@ -15569,15 +15709,16 @@ def register_Ns3QosTxop_methods(root_module, cls): 'bool', [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], is_const=True) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteAmpduTransfer(ns3::Mac48Address recipient, uint8_t tid) [member function] - cls.add_method('CompleteAmpduTransfer', - 'void', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## qos-txop.h (module 'wifi'): uint16_t ns3::QosTxop::GetBaBufferSize(ns3::Mac48Address address, uint8_t tid) const [member function] cls.add_method('GetBaBufferSize', 'uint16_t', [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], is_const=True) + ## qos-txop.h (module 'wifi'): uint16_t ns3::QosTxop::GetBaStartingSequence(ns3::Mac48Address address, uint8_t tid) const [member function] + cls.add_method('GetBaStartingSequence', + 'uint16_t', + [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], + is_const=True) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::NotifyAccessGranted() [member function] cls.add_method('NotifyAccessGranted', 'void', @@ -15593,11 +15734,10 @@ def register_Ns3QosTxop_methods(root_module, cls): 'void', [], is_virtual=True) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::MissedCts() [member function] - cls.add_method('MissedCts', + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::NotifyMissedCts(std::list, std::allocator > > mpduList) [member function] + cls.add_method('NotifyMissedCts', 'void', - [], - is_virtual=True) + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > >', 'mpduList')]) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::GotAck() [member function] cls.add_method('GotAck', 'void', @@ -15689,10 +15829,10 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('SendDelbaFrame', 'void', [param('ns3::Mac48Address', 'addr'), param('uint8_t', 'tid'), param('bool', 'byOriginator')]) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteMpduTx(ns3::Ptr mpdu) [member function] + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteMpduTx(ns3::Ptr mpdu) [member function] cls.add_method('CompleteMpduTx', 'void', - [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::GetAmpduExist(ns3::Mac48Address dest) const [member function] cls.add_method('GetAmpduExist', 'bool', @@ -15728,14 +15868,27 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('PeekNextSequenceNumberFor', 'uint16_t', [param('ns3::WifiMacHeader const *', 'hdr')]) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::RemoveRetransmitPacket(uint8_t tid, ns3::Mac48Address recipient, uint16_t seqnumber) [member function] - cls.add_method('RemoveRetransmitPacket', - 'void', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient'), param('uint16_t', 'seqnumber')]) - ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::PeekNextRetransmitPacket(uint8_t tid, ns3::Mac48Address recipient) [member function] - cls.add_method('PeekNextRetransmitPacket', + ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::PeekNextFrame(uint8_t tid=8, ns3::Mac48Address recipient=ns3::Mac48Address::GetBroadcast()) [member function] + cls.add_method('PeekNextFrame', 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient')]) + [param('uint8_t', 'tid', default_value='8'), param('ns3::Mac48Address', 'recipient', default_value='ns3::Mac48Address::GetBroadcast()')]) + ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::DequeuePeekedFrame(ns3::Ptr peekedItem, ns3::WifiTxVector txVector, bool aggregate=true, uint32_t ampduSize=0, ns3::Time ppduDurationLimit=ns3::Seconds(0)) [member function] + cls.add_method('DequeuePeekedFrame', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'peekedItem'), param('ns3::WifiTxVector', 'txVector'), param('bool', 'aggregate', default_value='true'), param('uint32_t', 'ampduSize', default_value='0'), param('ns3::Time', 'ppduDurationLimit', default_value='ns3::Seconds(0)')]) + ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsWithinSizeAndTimeLimits(ns3::Ptr mpdu, ns3::WifiTxVector txVector, uint32_t ampduSize, ns3::Time ppduDurationLimit) [member function] + cls.add_method('IsWithinSizeAndTimeLimits', + 'bool', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu'), param('ns3::WifiTxVector', 'txVector'), param('uint32_t', 'ampduSize'), param('ns3::Time', 'ppduDurationLimit')]) + ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsWithinSizeAndTimeLimits(uint32_t mpduSize, ns3::Mac48Address receiver, uint8_t tid, ns3::WifiTxVector txVector, uint32_t ampduSize, ns3::Time ppduDurationLimit) [member function] + cls.add_method('IsWithinSizeAndTimeLimits', + 'bool', + [param('uint32_t', 'mpduSize'), param('ns3::Mac48Address', 'receiver'), param('uint8_t', 'tid'), param('ns3::WifiTxVector', 'txVector'), param('uint32_t', 'ampduSize'), param('ns3::Time', 'ppduDurationLimit')]) + ## qos-txop.h (module 'wifi'): ns3::MacLowTransmissionParameters ns3::QosTxop::GetTransmissionParameters(ns3::Ptr frame) const [member function] + cls.add_method('GetTransmissionParameters', + 'ns3::MacLowTransmissionParameters', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'frame')], + is_const=True) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::BaTxOk(ns3::WifiMacHeader const & hdr) [member function] cls.add_method('BaTxOk', 'void', @@ -15754,11 +15907,16 @@ def register_Ns3QosTxop_methods(root_module, cls): [param('ns3::WifiMacHeader const &', 'hdr')]) ## qos-txop.h (module 'wifi'): ns3::QosTxop::QosTxop(ns3::QosTxop const & arg0) [constructor] cls.add_constructor([param('ns3::QosTxop const &', 'arg0')]) - ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::HasTxop() const [member function] - cls.add_method('HasTxop', - 'bool', + ## qos-txop.h (module 'wifi'): ns3::Time ns3::QosTxop::GetTxopRemaining() const [member function] + cls.add_method('GetTxopRemaining', + 'ns3::Time', [], is_const=True, visibility='private', is_virtual=True) + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::TerminateTxop() [member function] + cls.add_method('TerminateTxop', + 'void', + [], + visibility='private', is_virtual=True) ## qos-txop.h (module 'wifi'): uint32_t ns3::QosTxop::GetNextFragmentSize() const [member function] cls.add_method('GetNextFragmentSize', 'uint32_t', @@ -15825,16 +15983,26 @@ def register_Ns3Queue__Ns3Packet_methods(root_module, cls): []) ## queue.h (module 'network'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::Packet > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::Packet > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::Packet > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::Packet > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::Packet > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -15901,16 +16069,26 @@ def register_Ns3Queue__Ns3QueueDiscItem_methods(root_module, cls): []) ## queue.h (module 'network'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::QueueDiscItem > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::QueueDiscItem > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::QueueDiscItem > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::QueueDiscItem > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::QueueDiscItem > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -15977,16 +16155,26 @@ def register_Ns3Queue__Ns3WifiMacQueueItem_methods(root_module, cls): []) ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::WifiMacQueueItem > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::WifiMacQueueItem > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::WifiMacQueueItem > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -16981,28 +17169,28 @@ def register_Ns3VhtCapabilities_methods(root_module, cls): return def register_Ns3WaveMacLow_methods(root_module, cls): + ## wave-mac-low.h (module 'wave'): ns3::WaveMacLow::WaveMacLow(ns3::WaveMacLow const & arg0) [constructor] + cls.add_constructor([param('ns3::WaveMacLow const &', 'arg0')]) + ## wave-mac-low.h (module 'wave'): ns3::WaveMacLow::WaveMacLow() [constructor] + cls.add_constructor([]) ## wave-mac-low.h (module 'wave'): static ns3::TypeId ns3::WaveMacLow::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', [], is_static=True) - ## wave-mac-low.h (module 'wave'): ns3::WaveMacLow::WaveMacLow() [constructor] - cls.add_constructor([]) ## wave-mac-low.h (module 'wave'): void ns3::WaveMacLow::SetWaveNetDevice(ns3::Ptr device) [member function] cls.add_method('SetWaveNetDevice', 'void', [param('ns3::Ptr< ns3::WaveNetDevice >', 'device')]) - ## wave-mac-low.h (module 'wave'): void ns3::WaveMacLow::StartTransmission(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] + ## wave-mac-low.h (module 'wave'): void ns3::WaveMacLow::StartTransmission(ns3::Ptr mpdu, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] cls.add_method('StartTransmission', 'void', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], is_virtual=True) - ## wave-mac-low.h (module 'wave'): ns3::WaveMacLow::WaveMacLow(ns3::WaveMacLow const & arg0) [constructor] - cls.add_constructor([param('ns3::WaveMacLow const &', 'arg0')]) - ## wave-mac-low.h (module 'wave'): ns3::WifiTxVector ns3::WaveMacLow::GetDataTxVector(ns3::Ptr packet, ns3::WifiMacHeader const * hdr) const [member function] + ## wave-mac-low.h (module 'wave'): ns3::WifiTxVector ns3::WaveMacLow::GetDataTxVector(ns3::Ptr item) const [member function] cls.add_method('GetDataTxVector', 'ns3::WifiTxVector', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr')], + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item')], is_const=True, visibility='private', is_virtual=True) return @@ -17041,6 +17229,10 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('PushFront', 'bool', [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'item')]) + ## wifi-mac-queue.h (module 'wifi'): bool ns3::WifiMacQueue::Insert(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] + cls.add_method('Insert', + 'bool', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos'), param('ns3::Ptr< ns3::WifiMacQueueItem >', 'item')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue() [member function] cls.add_method('Dequeue', 'ns3::Ptr< ns3::WifiMacQueueItem >', @@ -17050,27 +17242,47 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('DequeueByAddress', 'ns3::Ptr< ns3::WifiMacQueueItem >', [param('ns3::Mac48Address', 'dest')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTid(uint8_t tid) [member function] + cls.add_method('DequeueByTid', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('uint8_t', 'tid')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTidAndAddress(uint8_t tid, ns3::Mac48Address dest) [member function] cls.add_method('DequeueByTidAndAddress', 'ns3::Ptr< ns3::WifiMacQueueItem >', [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest')]) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::Ptr const blockedPackets) [member function] + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::Ptr const blockedPackets=nullptr) [member function] cls.add_method('DequeueFirstAvailable', 'ns3::Ptr< ns3::WifiMacQueueItem >', - [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets')]) + [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets', default_value='nullptr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue(ns3::Queue::ConstIterator pos) [member function] + cls.add_method('Dequeue', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Peek() const [member function] cls.add_method('Peek', 'ns3::Ptr< ns3::WifiMacQueueItem const >', [], is_const=True, is_virtual=True) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekByTidAndAddress(uint8_t tid, ns3::Mac48Address dest) [member function] + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByAddress(ns3::Mac48Address dest, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] + cls.add_method('PeekByAddress', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('ns3::Mac48Address', 'dest'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByTid(uint8_t tid, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] + cls.add_method('PeekByTid', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('uint8_t', 'tid'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByTidAndAddress(uint8_t tid, ns3::Mac48Address dest, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] cls.add_method('PeekByTidAndAddress', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest')]) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekFirstAvailable(ns3::Ptr const blockedPackets) [member function] + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekFirstAvailable(ns3::Ptr const blockedPackets=nullptr, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] cls.add_method('PeekFirstAvailable', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets')]) + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets', default_value='nullptr'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Remove() [member function] cls.add_method('Remove', 'ns3::Ptr< ns3::WifiMacQueueItem >', @@ -17080,6 +17292,10 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('Remove', 'bool', [param('ns3::Ptr< ns3::Packet const >', 'packet')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::Remove(ns3::Queue::ConstIterator pos, bool removeExpired=false) [member function] + cls.add_method('Remove', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos'), param('bool', 'removeExpired', default_value='false')]) ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetNPacketsByAddress(ns3::Mac48Address dest) [member function] cls.add_method('GetNPacketsByAddress', 'uint32_t', @@ -17100,6 +17316,8 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('GetNBytes', 'uint32_t', []) + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::EMPTY [variable] + cls.add_static_attribute('EMPTY', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator const', is_const=True) ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::WifiMacQueue(ns3::WifiMacQueue const & arg0) [constructor] cls.add_constructor([param('ns3::WifiMacQueue const &', 'arg0')]) return diff --git a/src/wave/model/wave-mac-low.cc b/src/wave/model/wave-mac-low.cc index 0dcde912d..132c204b2 100644 --- a/src/wave/model/wave-mac-low.cc +++ b/src/wave/model/wave-mac-low.cc @@ -60,17 +60,17 @@ WaveMacLow::SetWaveNetDevice (Ptr device) } WifiTxVector -WaveMacLow::GetDataTxVector (Ptr packet, const WifiMacHeader *hdr) const +WaveMacLow::GetDataTxVector (Ptr item) const { - NS_LOG_FUNCTION (this << packet << hdr); + NS_LOG_FUNCTION (this << *item); HigherLayerTxVectorTag datatag; bool found; - found = ConstCast (packet)->PeekPacketTag (datatag); + found = ConstCast (item->GetPacket ())->PeekPacketTag (datatag); // if high layer has not controlled transmit parameters, the real transmit parameters // will be determined by MAC layer itself. if (!found) { - return MacLow::GetDataTxVector (packet, hdr); + return MacLow::GetDataTxVector (item); } // if high layer has set the transmit parameters with non-adaption mode, @@ -83,7 +83,7 @@ WaveMacLow::GetDataTxVector (Ptr packet, const WifiMacHeader *hdr) // if high layer has set the transmit parameters with non-adaption mode, // the real transmit parameters are determined by both high layer and MAC layer. WifiTxVector txHigher = datatag.GetTxVector (); - WifiTxVector txMac = MacLow::GetDataTxVector (packet, hdr); + WifiTxVector txMac = MacLow::GetDataTxVector (item); WifiTxVector txAdapter; txAdapter.SetChannelWidth (10); // the DataRate set by higher layer is the minimum data rate @@ -106,22 +106,21 @@ WaveMacLow::GetDataTxVector (Ptr packet, const WifiMacHeader *hdr) } void -WaveMacLow::StartTransmission (Ptr packet, - const WifiMacHeader* hdr, +WaveMacLow::StartTransmission (Ptr mpdu, MacLowTransmissionParameters params, Ptr dca) { - NS_LOG_FUNCTION (this << packet << hdr << params << dca); + NS_LOG_FUNCTION (this << *mpdu << params << dca); Ptr phy = MacLow::GetPhy (); uint32_t curChannel = phy->GetChannelNumber (); // if current channel access is not AlternatingAccess, just do as MacLow. if (!m_scheduler->IsAlternatingAccessAssigned (curChannel)) { - MacLow::StartTransmission (packet, hdr, params, dca); + MacLow::StartTransmission (mpdu, params, dca); return; } - Time transmissionTime = MacLow::CalculateTransmissionTime (packet, hdr, params); + Time transmissionTime = MacLow::CalculateTransmissionTime (mpdu->GetPacket (), &mpdu->GetHeader (), params); Time remainingTime = m_coordinator->NeedTimeToGuardInterval (); if (transmissionTime > remainingTime) @@ -134,7 +133,7 @@ WaveMacLow::StartTransmission (Ptr packet, } else { - MacLow::StartTransmission (packet, hdr, params, dca); + MacLow::StartTransmission (mpdu, params, dca); } } diff --git a/src/wave/model/wave-mac-low.h b/src/wave/model/wave-mac-low.h index fb5663818..5e896a3eb 100644 --- a/src/wave/model/wave-mac-low.h +++ b/src/wave/model/wave-mac-low.h @@ -29,6 +29,7 @@ namespace ns3 { class WaveNetDevice; +class WifiMacQueueItem; /** * \ingroup wave @@ -62,16 +63,14 @@ public: void SetWaveNetDevice (Ptr device); /** - * \param packet packet to send - * \param hdr 802.11 header for packet to send + * \param mpdu packet to send * \param parameters the transmission parameters to use for this packet. * \param txop pointer to the calling Txop. * * Start the transmission of the input packet and notify the listener * of transmission events. */ - virtual void StartTransmission (Ptr packet, - const WifiMacHeader* hdr, + virtual void StartTransmission (Ptr mpdu, MacLowTransmissionParameters parameters, Ptr txop); private: @@ -80,11 +79,10 @@ private: * The function consults WifiRemoteStationManager, which controls the rate * to different destinations. * - * \param packet the packet being asked for TXVECTOR - * \param hdr the WifiMacHeader - * \return TXVECTOR for the given packet + * \param item the item being asked for TXVECTOR + * \return TXVECTOR for the given item */ - virtual WifiTxVector GetDataTxVector (Ptr packet, const WifiMacHeader *hdr) const; + virtual WifiTxVector GetDataTxVector (Ptr item) const; Ptr m_scheduler; ///< the channel scheduler Ptr m_coordinator; ///< the channel coordinator diff --git a/src/wifi/bindings/modulegen__gcc_ILP32.py b/src/wifi/bindings/modulegen__gcc_ILP32.py index 508857f34..e877e43ef 100644 --- a/src/wifi/bindings/modulegen__gcc_ILP32.py +++ b/src/wifi/bindings/modulegen__gcc_ILP32.py @@ -217,7 +217,7 @@ def register_types(module): ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement [class] module.add_class('OriginatorBlockAckAgreement', parent=root_module['ns3::BlockAckAgreement']) ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement::State [enumeration] - module.add_enum('State', ['PENDING', 'ESTABLISHED', 'INACTIVE', 'NO_REPLY', 'RESET', 'REJECTED'], outer_class=root_module['ns3::OriginatorBlockAckAgreement']) + module.add_enum('State', ['PENDING', 'ESTABLISHED', 'NO_REPLY', 'RESET', 'REJECTED'], outer_class=root_module['ns3::OriginatorBlockAckAgreement']) ## packet-metadata.h (module 'network'): ns3::PacketMetadata [class] module.add_class('PacketMetadata', import_from_module='ns.network') ## packet-metadata.h (module 'network'): ns3::PacketMetadata::Item [struct] @@ -1127,6 +1127,7 @@ def register_types(module): module.add_container('ns3::MsduAggregator::DeaggregatedMsdus', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmsduSubframeHeader >', container_type=u'list') module.add_container('ns3::MsduAggregator::EdcaQueues', ('ns3::AcIndex', 'ns3::Ptr< ns3::QosTxop >'), container_type=u'map') module.add_container('std::map< ns3::Mac48Address, bool >', ('ns3::Mac48Address', 'bool'), container_type=u'map') + module.add_container('std::list< ns3::Ptr< ns3::WifiMacQueueItem > >', 'ns3::Ptr< ns3::WifiMacQueueItem >', container_type=u'list') typehandlers.add_type_alias(u'void ( * ) ( std::ostream & )', u'ns3::TimePrinter') typehandlers.add_type_alias(u'void ( * ) ( std::ostream & )*', u'ns3::TimePrinter*') typehandlers.add_type_alias(u'void ( * ) ( std::ostream & )&', u'ns3::TimePrinter&') @@ -2597,7 +2598,7 @@ def register_Ns3DataRate_methods(root_module, cls): cls.add_method('CalculateTxTime', 'double', [param('uint32_t', 'bytes')], - is_const=True) + deprecated=True, is_const=True) ## data-rate.h (module 'network'): uint64_t ns3::DataRate::GetBitRate() const [member function] cls.add_method('GetBitRate', 'uint64_t', @@ -3489,7 +3490,7 @@ def register_Ns3Ipv6Address_methods(root_module, cls): cls.add_method('IsAllHostsMulticast', 'bool', [], - is_const=True) + deprecated=True, is_const=True) ## ipv6-address.h (module 'network'): bool ns3::Ipv6Address::IsAllNodesMulticast() const [member function] cls.add_method('IsAllNodesMulticast', 'bool', @@ -3887,6 +3888,11 @@ def register_Ns3MacLowTransmissionParameters_methods(root_module, cls): cls.add_method('EnableRts', 'void', []) + ## mac-low-transmission-parameters.h (module 'wifi'): ns3::BlockAckType ns3::MacLowTransmissionParameters::GetBlockAckType() const [member function] + cls.add_method('GetBlockAckType', + 'ns3::BlockAckType', + [], + is_const=True) ## mac-low-transmission-parameters.h (module 'wifi'): uint32_t ns3::MacLowTransmissionParameters::GetNextPacketSize() const [member function] cls.add_method('GetNextPacketSize', 'uint32_t', @@ -3902,23 +3908,8 @@ def register_Ns3MacLowTransmissionParameters_methods(root_module, cls): 'bool', [], is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitBasicBlockAck() const [member function] - cls.add_method('MustWaitBasicBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitCompressedBlockAck() const [member function] - cls.add_method('MustWaitCompressedBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitExtendedCompressedBlockAck() const [member function] - cls.add_method('MustWaitExtendedCompressedBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitMultiTidBlockAck() const [member function] - cls.add_method('MustWaitMultiTidBlockAck', + ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitBlockAck() const [member function] + cls.add_method('MustWaitBlockAck', 'bool', [], is_const=True) @@ -4194,25 +4185,11 @@ def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls): cls.add_constructor([param('ns3::OriginatorBlockAckAgreement const &', 'arg0')]) ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement(ns3::Mac48Address recipient, uint8_t tid) [constructor] cls.add_constructor([param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) - ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::CompleteExchange() [member function] - cls.add_method('CompleteExchange', - 'void', - []) - ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsBlockAckRequestNeeded() const [member function] - cls.add_method('IsBlockAckRequestNeeded', - 'bool', - [], - is_const=True) ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsEstablished() const [member function] cls.add_method('IsEstablished', 'bool', [], is_const=True) - ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsInactive() const [member function] - cls.add_method('IsInactive', - 'bool', - [], - is_const=True) ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsNoReply() const [member function] cls.add_method('IsNoReply', 'bool', @@ -4233,10 +4210,6 @@ def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls): 'bool', [], is_const=True) - ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::NotifyMpduTransmission(uint16_t nextSeqNumber) [member function] - cls.add_method('NotifyMpduTransmission', - 'void', - [param('uint16_t', 'nextSeqNumber')]) ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::SetState(ns3::OriginatorBlockAckAgreement::State state) [member function] cls.add_method('SetState', 'void', @@ -5047,7 +5020,8 @@ def register_Ns3TypeId_methods(root_module, cls): ## type-id.h (module 'core'): ns3::TypeId ns3::TypeId::AddTraceSource(std::string name, std::string help, ns3::Ptr accessor) [member function] cls.add_method('AddTraceSource', 'ns3::TypeId', - [param('std::string', 'name'), param('std::string', 'help'), param('ns3::Ptr< ns3::TraceSourceAccessor const >', 'accessor')]) + [param('std::string', 'name'), param('std::string', 'help'), param('ns3::Ptr< ns3::TraceSourceAccessor const >', 'accessor')], + deprecated=True) ## type-id.h (module 'core'): ns3::TypeId ns3::TypeId::AddTraceSource(std::string name, std::string help, ns3::Ptr accessor, std::string callback, ns3::TypeId::SupportLevel supportLevel=::ns3::TypeId::SupportLevel::SUPPORTED, std::string const & supportMsg="") [member function] cls.add_method('AddTraceSource', 'ns3::TypeId', @@ -8621,6 +8595,11 @@ def register_Ns3Txop_methods(root_module, cls): 'ns3::Time', [], is_const=True) + ## txop.h (module 'wifi'): ns3::Time ns3::Txop::GetTxopRemaining() const [member function] + cls.add_method('GetTxopRemaining', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## txop.h (module 'wifi'): static ns3::TypeId ns3::Txop::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', @@ -8645,11 +8624,6 @@ def register_Ns3Txop_methods(root_module, cls): cls.add_method('GotCfEnd', 'void', []) - ## txop.h (module 'wifi'): bool ns3::Txop::HasTxop() const [member function] - cls.add_method('HasTxop', - 'bool', - [], - is_const=True, is_virtual=True) ## txop.h (module 'wifi'): bool ns3::Txop::IsAccessRequested() const [member function] cls.add_method('IsAccessRequested', 'bool', @@ -8772,6 +8746,11 @@ def register_Ns3Txop_methods(root_module, cls): 'void', [], is_virtual=True) + ## txop.h (module 'wifi'): void ns3::Txop::TerminateTxop() [member function] + cls.add_method('TerminateTxop', + 'void', + [], + is_virtual=True) ## txop.h (module 'wifi'): void ns3::Txop::DoDispose() [member function] cls.add_method('DoDispose', 'void', @@ -12680,23 +12659,27 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('UpdateAgreement', 'void', [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'recipient')]) - ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::StorePacket(ns3::Ptr mpdu) [member function] + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::StorePacket(ns3::Ptr mpdu) [member function] cls.add_method('StorePacket', 'void', - [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) - ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::GetNextPacket(bool removePacket) [member function] - cls.add_method('GetNextPacket', - 'ns3::Ptr< ns3::WifiMacQueueItem >', - [param('bool', 'removePacket')]) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasBar(ns3::Bar & bar) [member function] + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasBar(ns3::Bar & bar, bool remove=true) [member function] cls.add_method('HasBar', 'bool', - [param('ns3::Bar &', 'bar')]) + [param('ns3::Bar &', 'bar'), param('bool', 'remove', default_value='true')]) ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasPackets() const [member function] cls.add_method('HasPackets', 'bool', [], is_const=True) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyGotAck(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyGotAck', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyMissedAck(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyMissedAck', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyGotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address recipient, double rxSnr, ns3::WifiMode txMode, double dataSnr) [member function] cls.add_method('NotifyGotBlockAck', 'void', @@ -12705,16 +12688,15 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('NotifyMissedBlockAck', 'void', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::DiscardOutstandingMpdus(ns3::Mac48Address recipient, uint8_t tid) [member function] + cls.add_method('DiscardOutstandingMpdus', + 'void', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## block-ack-manager.h (module 'wifi'): uint32_t ns3::BlockAckManager::GetNBufferedPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function] cls.add_method('GetNBufferedPackets', 'uint32_t', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], is_const=True) - ## block-ack-manager.h (module 'wifi'): uint32_t ns3::BlockAckManager::GetNRetryNeededPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('GetNRetryNeededPackets', - 'uint32_t', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyAgreementEstablished(ns3::Mac48Address recipient, uint8_t tid, uint16_t startingSeq) [member function] cls.add_method('NotifyAgreementEstablished', 'void', @@ -12735,14 +12717,14 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('NotifyMpduTransmission', 'void', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'nextSeqNumber'), param('ns3::WifiMacHeader::QosAckPolicy', 'policy')]) - ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::CompleteAmpduExchange(ns3::Mac48Address recipient, uint8_t tid) [member function] - cls.add_method('CompleteAmpduExchange', - 'void', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetBlockAckThreshold(uint8_t nPackets) [member function] cls.add_method('SetBlockAckThreshold', 'void', [param('uint8_t', 'nPackets')]) + ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::GetRetransmitQueue() [member function] + cls.add_method('GetRetransmitQueue', + 'ns3::Ptr< ns3::WifiMacQueue >', + []) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetQueue(ns3::Ptr const queue) [member function] cls.add_method('SetQueue', 'void', @@ -12775,24 +12757,6 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('SwitchToBlockAckIfNeeded', 'bool', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'startingSeq')]) - ## block-ack-manager.h (module 'wifi'): uint16_t ns3::BlockAckManager::GetSeqNumOfNextRetryPacket(ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('GetSeqNumOfNextRetryPacket', - 'uint16_t', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::AlreadyExists(uint16_t currentSeq, ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('AlreadyExists', - 'bool', - [param('uint16_t', 'currentSeq'), param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::RemovePacket(uint8_t tid, ns3::Mac48Address recipient, uint16_t seqnumber) [member function] - cls.add_method('RemovePacket', - 'bool', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient'), param('uint16_t', 'seqnumber')]) - ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::PeekNextPacketByTidAndAddress(uint8_t tid, ns3::Mac48Address recipient) [member function] - cls.add_method('PeekNextPacketByTidAndAddress', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient')]) ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::NeedBarRetransmission(uint8_t tid, uint16_t seqNumber, ns3::Mac48Address recipient) [member function] cls.add_method('NeedBarRetransmission', 'bool', @@ -12802,6 +12766,11 @@ def register_Ns3BlockAckManager_methods(root_module, cls): 'uint16_t', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], is_const=True) + ## block-ack-manager.h (module 'wifi'): uint16_t ns3::BlockAckManager::GetOriginatorStartingSequence(ns3::Mac48Address recipient, uint8_t tid) const [member function] + cls.add_method('GetOriginatorStartingSequence', + 'uint16_t', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], + is_const=True) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetTxOkCallback(ns3::BlockAckManager::TxOk callback) [member function] cls.add_method('SetTxOkCallback', 'void', @@ -12810,6 +12779,14 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('SetTxFailedCallback', 'void', [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyDiscardedMpdu(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyDiscardedMpdu', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::ScheduleBlockAckReq(ns3::Mac48Address recipient, uint8_t tid) [member function] + cls.add_method('ScheduleBlockAckReq', + 'void', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) return def register_Ns3BooleanChecker_methods(root_module, cls): @@ -16524,6 +16501,11 @@ def register_Ns3MacLow_methods(root_module, cls): 'ns3::Time', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters const &', 'params'), param('uint32_t', 'fragmentSize', default_value='0')], is_const=True) + ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::CalculateOverheadTxTime(ns3::Ptr item, ns3::MacLowTransmissionParameters const & params) const [member function] + cls.add_method('CalculateOverheadTxTime', + 'ns3::Time', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item'), param('ns3::MacLowTransmissionParameters const &', 'params')], + is_const=True) ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::CalculateTransmissionTime(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters const & parameters) const [member function] cls.add_method('CalculateTransmissionTime', 'ns3::Time', @@ -16550,10 +16532,6 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('DoNavStartNow', 'bool', [param('ns3::Time', 'duration')]) - ## mac-low.h (module 'wifi'): void ns3::MacLow::FlushAggregateQueue(uint8_t tid) [member function] - cls.add_method('FlushAggregateQueue', - 'void', - [param('uint8_t', 'tid')]) ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::GetAckTimeout() const [member function] cls.add_method('GetAckTimeout', 'ns3::Time', @@ -16599,10 +16577,10 @@ def register_Ns3MacLow_methods(root_module, cls): 'bool', [], is_const=True) - ## mac-low.h (module 'wifi'): ns3::WifiTxVector ns3::MacLow::GetDataTxVector(ns3::Ptr packet, ns3::WifiMacHeader const * hdr) const [member function] + ## mac-low.h (module 'wifi'): ns3::WifiTxVector ns3::MacLow::GetDataTxVector(ns3::Ptr item) const [member function] cls.add_method('GetDataTxVector', 'ns3::WifiTxVector', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr')], + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item')], is_const=True, is_virtual=True) ## mac-low.h (module 'wifi'): ns3::Ptr ns3::MacLow::GetMpduAggregator() const [member function] cls.add_method('GetMpduAggregator', @@ -16771,10 +16749,10 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager > const', 'manager')]) - ## mac-low.h (module 'wifi'): void ns3::MacLow::StartTransmission(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] + ## mac-low.h (module 'wifi'): void ns3::MacLow::StartTransmission(ns3::Ptr mpdu, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] cls.add_method('StartTransmission', 'void', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], is_virtual=True) ## mac-low.h (module 'wifi'): void ns3::MacLow::DoDispose() [member function] cls.add_method('DoDispose', @@ -17963,7 +17941,7 @@ def register_Ns3ParetoRandomVariable_methods(root_module, cls): cls.add_method('GetMean', 'double', [], - is_const=True) + deprecated=True, is_const=True) ## random-variable-stream.h (module 'core'): double ns3::ParetoRandomVariable::GetScale() const [member function] cls.add_method('GetScale', 'double', @@ -18109,18 +18087,18 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('BaTxOk', 'void', [param('ns3::WifiMacHeader const &', 'hdr')]) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteAmpduTransfer(ns3::Mac48Address recipient, uint8_t tid) [member function] - cls.add_method('CompleteAmpduTransfer', - 'void', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteConfig() [member function] cls.add_method('CompleteConfig', 'void', []) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteMpduTx(ns3::Ptr mpdu) [member function] + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteMpduTx(ns3::Ptr mpdu) [member function] cls.add_method('CompleteMpduTx', 'void', - [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) + ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::DequeuePeekedFrame(ns3::Ptr peekedItem, ns3::WifiTxVector txVector, bool aggregate=true, uint32_t ampduSize=0, ns3::Time ppduDurationLimit=ns3::Seconds(0)) [member function] + cls.add_method('DequeuePeekedFrame', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'peekedItem'), param('ns3::WifiTxVector', 'txVector'), param('bool', 'aggregate', default_value='true'), param('uint32_t', 'ampduSize', default_value='0'), param('ns3::Time', 'ppduDurationLimit', default_value='ns3::Seconds(0)')]) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::EndTxNoAck() [member function] cls.add_method('EndTxNoAck', 'void', @@ -18146,6 +18124,11 @@ def register_Ns3QosTxop_methods(root_module, cls): 'uint16_t', [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], is_const=True) + ## qos-txop.h (module 'wifi'): uint16_t ns3::QosTxop::GetBaStartingSequence(ns3::Mac48Address address, uint8_t tid) const [member function] + cls.add_method('GetBaStartingSequence', + 'uint16_t', + [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], + is_const=True) ## qos-txop.h (module 'wifi'): uint8_t ns3::QosTxop::GetBlockAckThreshold() const [member function] cls.add_method('GetBlockAckThreshold', 'uint8_t', @@ -18165,6 +18148,11 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('GetNextSequenceNumberFor', 'uint16_t', [param('ns3::WifiMacHeader const *', 'hdr')]) + ## qos-txop.h (module 'wifi'): ns3::MacLowTransmissionParameters ns3::QosTxop::GetTransmissionParameters(ns3::Ptr frame) const [member function] + cls.add_method('GetTransmissionParameters', + 'ns3::MacLowTransmissionParameters', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'frame')], + is_const=True) ## qos-txop.h (module 'wifi'): static ns3::TypeId ns3::QosTxop::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', @@ -18198,6 +18186,14 @@ def register_Ns3QosTxop_methods(root_module, cls): 'bool', [], is_const=True, is_virtual=True) + ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsWithinSizeAndTimeLimits(ns3::Ptr mpdu, ns3::WifiTxVector txVector, uint32_t ampduSize, ns3::Time ppduDurationLimit) [member function] + cls.add_method('IsWithinSizeAndTimeLimits', + 'bool', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu'), param('ns3::WifiTxVector', 'txVector'), param('uint32_t', 'ampduSize'), param('ns3::Time', 'ppduDurationLimit')]) + ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsWithinSizeAndTimeLimits(uint32_t mpduSize, ns3::Mac48Address receiver, uint8_t tid, ns3::WifiTxVector txVector, uint32_t ampduSize, ns3::Time ppduDurationLimit) [member function] + cls.add_method('IsWithinSizeAndTimeLimits', + 'bool', + [param('uint32_t', 'mpduSize'), param('ns3::Mac48Address', 'receiver'), param('uint8_t', 'tid'), param('ns3::WifiTxVector', 'txVector'), param('uint32_t', 'ampduSize'), param('ns3::Time', 'ppduDurationLimit')]) ## qos-txop.h (module 'wifi'): ns3::Mac48Address ns3::QosTxop::MapDestAddressForAggregation(ns3::WifiMacHeader const & hdr) [member function] cls.add_method('MapDestAddressForAggregation', 'ns3::Mac48Address', @@ -18216,11 +18212,6 @@ def register_Ns3QosTxop_methods(root_module, cls): 'void', [param('uint8_t', 'nMpdus')], is_virtual=True) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::MissedCts() [member function] - cls.add_method('MissedCts', - 'void', - [], - is_virtual=True) ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::NeedBarRetransmission() [member function] cls.add_method('NeedBarRetransmission', 'bool', @@ -18245,10 +18236,14 @@ def register_Ns3QosTxop_methods(root_module, cls): 'void', [], is_virtual=True) - ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::PeekNextRetransmitPacket(uint8_t tid, ns3::Mac48Address recipient) [member function] - cls.add_method('PeekNextRetransmitPacket', + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::NotifyMissedCts(std::list, std::allocator > > mpduList) [member function] + cls.add_method('NotifyMissedCts', + 'void', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > >', 'mpduList')]) + ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::PeekNextFrame(uint8_t tid=8, ns3::Mac48Address recipient=ns3::Mac48Address::GetBroadcast()) [member function] + cls.add_method('PeekNextFrame', 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient')]) + [param('uint8_t', 'tid', default_value='8'), param('ns3::Mac48Address', 'recipient', default_value='ns3::Mac48Address::GetBroadcast()')]) ## qos-txop.h (module 'wifi'): uint16_t ns3::QosTxop::PeekNextSequenceNumberFor(ns3::WifiMacHeader const * hdr) [member function] cls.add_method('PeekNextSequenceNumberFor', 'uint16_t', @@ -18257,10 +18252,6 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('PushFront', 'void', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')]) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::RemoveRetransmitPacket(uint8_t tid, ns3::Mac48Address recipient, uint16_t seqnumber) [member function] - cls.add_method('RemoveRetransmitPacket', - 'void', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient'), param('uint16_t', 'seqnumber')]) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::RestartAccessIfNeeded() [member function] cls.add_method('RestartAccessIfNeeded', 'void', @@ -18340,9 +18331,9 @@ def register_Ns3QosTxop_methods(root_module, cls): 'uint32_t', [], is_const=True, visibility='private', is_virtual=True) - ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::HasTxop() const [member function] - cls.add_method('HasTxop', - 'bool', + ## qos-txop.h (module 'wifi'): ns3::Time ns3::QosTxop::GetTxopRemaining() const [member function] + cls.add_method('GetTxopRemaining', + 'ns3::Time', [], is_const=True, visibility='private', is_virtual=True) ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsLastFragment() const [member function] @@ -18350,6 +18341,11 @@ def register_Ns3QosTxop_methods(root_module, cls): 'bool', [], is_const=True, visibility='private', is_virtual=True) + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::TerminateTxop() [member function] + cls.add_method('TerminateTxop', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3Queue__Ns3Packet_methods(root_module, cls): @@ -18386,16 +18382,26 @@ def register_Ns3Queue__Ns3Packet_methods(root_module, cls): []) ## queue.h (module 'network'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::Packet > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::Packet > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::Packet > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::Packet > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::Packet > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -18462,16 +18468,26 @@ def register_Ns3Queue__Ns3QueueDiscItem_methods(root_module, cls): []) ## queue.h (module 'network'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::QueueDiscItem > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::QueueDiscItem > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::QueueDiscItem > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::QueueDiscItem > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::QueueDiscItem > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -18538,16 +18554,26 @@ def register_Ns3Queue__Ns3WifiMacQueueItem_methods(root_module, cls): []) ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::WifiMacQueueItem > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::WifiMacQueueItem > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::WifiMacQueueItem > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -20067,6 +20093,10 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('PushFront', 'bool', [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'item')]) + ## wifi-mac-queue.h (module 'wifi'): bool ns3::WifiMacQueue::Insert(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] + cls.add_method('Insert', + 'bool', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos'), param('ns3::Ptr< ns3::WifiMacQueueItem >', 'item')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue() [member function] cls.add_method('Dequeue', 'ns3::Ptr< ns3::WifiMacQueueItem >', @@ -20076,27 +20106,47 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('DequeueByAddress', 'ns3::Ptr< ns3::WifiMacQueueItem >', [param('ns3::Mac48Address', 'dest')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTid(uint8_t tid) [member function] + cls.add_method('DequeueByTid', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('uint8_t', 'tid')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTidAndAddress(uint8_t tid, ns3::Mac48Address dest) [member function] cls.add_method('DequeueByTidAndAddress', 'ns3::Ptr< ns3::WifiMacQueueItem >', [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest')]) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::Ptr const blockedPackets) [member function] + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::Ptr const blockedPackets=nullptr) [member function] cls.add_method('DequeueFirstAvailable', 'ns3::Ptr< ns3::WifiMacQueueItem >', - [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets')]) + [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets', default_value='nullptr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue(ns3::Queue::ConstIterator pos) [member function] + cls.add_method('Dequeue', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Peek() const [member function] cls.add_method('Peek', 'ns3::Ptr< ns3::WifiMacQueueItem const >', [], is_const=True, is_virtual=True) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekByTidAndAddress(uint8_t tid, ns3::Mac48Address dest) [member function] + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByAddress(ns3::Mac48Address dest, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] + cls.add_method('PeekByAddress', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('ns3::Mac48Address', 'dest'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByTid(uint8_t tid, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] + cls.add_method('PeekByTid', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('uint8_t', 'tid'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByTidAndAddress(uint8_t tid, ns3::Mac48Address dest, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] cls.add_method('PeekByTidAndAddress', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest')]) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekFirstAvailable(ns3::Ptr const blockedPackets) [member function] + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekFirstAvailable(ns3::Ptr const blockedPackets=nullptr, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] cls.add_method('PeekFirstAvailable', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets')]) + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets', default_value='nullptr'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Remove() [member function] cls.add_method('Remove', 'ns3::Ptr< ns3::WifiMacQueueItem >', @@ -20106,6 +20156,10 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('Remove', 'bool', [param('ns3::Ptr< ns3::Packet const >', 'packet')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::Remove(ns3::Queue::ConstIterator pos, bool removeExpired=false) [member function] + cls.add_method('Remove', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos'), param('bool', 'removeExpired', default_value='false')]) ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetNPacketsByAddress(ns3::Mac48Address dest) [member function] cls.add_method('GetNPacketsByAddress', 'uint32_t', @@ -20126,6 +20180,8 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('GetNBytes', 'uint32_t', []) + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::EMPTY [variable] + cls.add_static_attribute('EMPTY', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator const', is_const=True) ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::WifiMacQueue(ns3::WifiMacQueue const & arg0) [constructor] cls.add_constructor([param('ns3::WifiMacQueue const &', 'arg0')]) return diff --git a/src/wifi/bindings/modulegen__gcc_LP64.py b/src/wifi/bindings/modulegen__gcc_LP64.py index 594ba4001..961fb4cd1 100644 --- a/src/wifi/bindings/modulegen__gcc_LP64.py +++ b/src/wifi/bindings/modulegen__gcc_LP64.py @@ -217,7 +217,7 @@ def register_types(module): ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement [class] module.add_class('OriginatorBlockAckAgreement', parent=root_module['ns3::BlockAckAgreement']) ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement::State [enumeration] - module.add_enum('State', ['PENDING', 'ESTABLISHED', 'INACTIVE', 'NO_REPLY', 'RESET', 'REJECTED'], outer_class=root_module['ns3::OriginatorBlockAckAgreement']) + module.add_enum('State', ['PENDING', 'ESTABLISHED', 'NO_REPLY', 'RESET', 'REJECTED'], outer_class=root_module['ns3::OriginatorBlockAckAgreement']) ## packet-metadata.h (module 'network'): ns3::PacketMetadata [class] module.add_class('PacketMetadata', import_from_module='ns.network') ## packet-metadata.h (module 'network'): ns3::PacketMetadata::Item [struct] @@ -1127,6 +1127,7 @@ def register_types(module): module.add_container('ns3::MsduAggregator::DeaggregatedMsdus', 'std::pair< ns3::Ptr< ns3::Packet >, ns3::AmsduSubframeHeader >', container_type=u'list') module.add_container('ns3::MsduAggregator::EdcaQueues', ('ns3::AcIndex', 'ns3::Ptr< ns3::QosTxop >'), container_type=u'map') module.add_container('std::map< ns3::Mac48Address, bool >', ('ns3::Mac48Address', 'bool'), container_type=u'map') + module.add_container('std::list< ns3::Ptr< ns3::WifiMacQueueItem > >', 'ns3::Ptr< ns3::WifiMacQueueItem >', container_type=u'list') typehandlers.add_type_alias(u'void ( * ) ( std::ostream & )', u'ns3::TimePrinter') typehandlers.add_type_alias(u'void ( * ) ( std::ostream & )*', u'ns3::TimePrinter*') typehandlers.add_type_alias(u'void ( * ) ( std::ostream & )&', u'ns3::TimePrinter&') @@ -2597,7 +2598,7 @@ def register_Ns3DataRate_methods(root_module, cls): cls.add_method('CalculateTxTime', 'double', [param('uint32_t', 'bytes')], - is_const=True) + deprecated=True, is_const=True) ## data-rate.h (module 'network'): uint64_t ns3::DataRate::GetBitRate() const [member function] cls.add_method('GetBitRate', 'uint64_t', @@ -3489,7 +3490,7 @@ def register_Ns3Ipv6Address_methods(root_module, cls): cls.add_method('IsAllHostsMulticast', 'bool', [], - is_const=True) + deprecated=True, is_const=True) ## ipv6-address.h (module 'network'): bool ns3::Ipv6Address::IsAllNodesMulticast() const [member function] cls.add_method('IsAllNodesMulticast', 'bool', @@ -3887,6 +3888,11 @@ def register_Ns3MacLowTransmissionParameters_methods(root_module, cls): cls.add_method('EnableRts', 'void', []) + ## mac-low-transmission-parameters.h (module 'wifi'): ns3::BlockAckType ns3::MacLowTransmissionParameters::GetBlockAckType() const [member function] + cls.add_method('GetBlockAckType', + 'ns3::BlockAckType', + [], + is_const=True) ## mac-low-transmission-parameters.h (module 'wifi'): uint32_t ns3::MacLowTransmissionParameters::GetNextPacketSize() const [member function] cls.add_method('GetNextPacketSize', 'uint32_t', @@ -3902,23 +3908,8 @@ def register_Ns3MacLowTransmissionParameters_methods(root_module, cls): 'bool', [], is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitBasicBlockAck() const [member function] - cls.add_method('MustWaitBasicBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitCompressedBlockAck() const [member function] - cls.add_method('MustWaitCompressedBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitExtendedCompressedBlockAck() const [member function] - cls.add_method('MustWaitExtendedCompressedBlockAck', - 'bool', - [], - is_const=True) - ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitMultiTidBlockAck() const [member function] - cls.add_method('MustWaitMultiTidBlockAck', + ## mac-low-transmission-parameters.h (module 'wifi'): bool ns3::MacLowTransmissionParameters::MustWaitBlockAck() const [member function] + cls.add_method('MustWaitBlockAck', 'bool', [], is_const=True) @@ -4194,25 +4185,11 @@ def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls): cls.add_constructor([param('ns3::OriginatorBlockAckAgreement const &', 'arg0')]) ## originator-block-ack-agreement.h (module 'wifi'): ns3::OriginatorBlockAckAgreement::OriginatorBlockAckAgreement(ns3::Mac48Address recipient, uint8_t tid) [constructor] cls.add_constructor([param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) - ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::CompleteExchange() [member function] - cls.add_method('CompleteExchange', - 'void', - []) - ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsBlockAckRequestNeeded() const [member function] - cls.add_method('IsBlockAckRequestNeeded', - 'bool', - [], - is_const=True) ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsEstablished() const [member function] cls.add_method('IsEstablished', 'bool', [], is_const=True) - ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsInactive() const [member function] - cls.add_method('IsInactive', - 'bool', - [], - is_const=True) ## originator-block-ack-agreement.h (module 'wifi'): bool ns3::OriginatorBlockAckAgreement::IsNoReply() const [member function] cls.add_method('IsNoReply', 'bool', @@ -4233,10 +4210,6 @@ def register_Ns3OriginatorBlockAckAgreement_methods(root_module, cls): 'bool', [], is_const=True) - ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::NotifyMpduTransmission(uint16_t nextSeqNumber) [member function] - cls.add_method('NotifyMpduTransmission', - 'void', - [param('uint16_t', 'nextSeqNumber')]) ## originator-block-ack-agreement.h (module 'wifi'): void ns3::OriginatorBlockAckAgreement::SetState(ns3::OriginatorBlockAckAgreement::State state) [member function] cls.add_method('SetState', 'void', @@ -5047,7 +5020,8 @@ def register_Ns3TypeId_methods(root_module, cls): ## type-id.h (module 'core'): ns3::TypeId ns3::TypeId::AddTraceSource(std::string name, std::string help, ns3::Ptr accessor) [member function] cls.add_method('AddTraceSource', 'ns3::TypeId', - [param('std::string', 'name'), param('std::string', 'help'), param('ns3::Ptr< ns3::TraceSourceAccessor const >', 'accessor')]) + [param('std::string', 'name'), param('std::string', 'help'), param('ns3::Ptr< ns3::TraceSourceAccessor const >', 'accessor')], + deprecated=True) ## type-id.h (module 'core'): ns3::TypeId ns3::TypeId::AddTraceSource(std::string name, std::string help, ns3::Ptr accessor, std::string callback, ns3::TypeId::SupportLevel supportLevel=::ns3::TypeId::SupportLevel::SUPPORTED, std::string const & supportMsg="") [member function] cls.add_method('AddTraceSource', 'ns3::TypeId', @@ -8621,6 +8595,11 @@ def register_Ns3Txop_methods(root_module, cls): 'ns3::Time', [], is_const=True) + ## txop.h (module 'wifi'): ns3::Time ns3::Txop::GetTxopRemaining() const [member function] + cls.add_method('GetTxopRemaining', + 'ns3::Time', + [], + is_const=True, is_virtual=True) ## txop.h (module 'wifi'): static ns3::TypeId ns3::Txop::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', @@ -8645,11 +8624,6 @@ def register_Ns3Txop_methods(root_module, cls): cls.add_method('GotCfEnd', 'void', []) - ## txop.h (module 'wifi'): bool ns3::Txop::HasTxop() const [member function] - cls.add_method('HasTxop', - 'bool', - [], - is_const=True, is_virtual=True) ## txop.h (module 'wifi'): bool ns3::Txop::IsAccessRequested() const [member function] cls.add_method('IsAccessRequested', 'bool', @@ -8772,6 +8746,11 @@ def register_Ns3Txop_methods(root_module, cls): 'void', [], is_virtual=True) + ## txop.h (module 'wifi'): void ns3::Txop::TerminateTxop() [member function] + cls.add_method('TerminateTxop', + 'void', + [], + is_virtual=True) ## txop.h (module 'wifi'): void ns3::Txop::DoDispose() [member function] cls.add_method('DoDispose', 'void', @@ -12680,23 +12659,27 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('UpdateAgreement', 'void', [param('ns3::MgtAddBaResponseHeader const *', 'respHdr'), param('ns3::Mac48Address', 'recipient')]) - ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::StorePacket(ns3::Ptr mpdu) [member function] + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::StorePacket(ns3::Ptr mpdu) [member function] cls.add_method('StorePacket', 'void', - [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) - ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::GetNextPacket(bool removePacket) [member function] - cls.add_method('GetNextPacket', - 'ns3::Ptr< ns3::WifiMacQueueItem >', - [param('bool', 'removePacket')]) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasBar(ns3::Bar & bar) [member function] + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasBar(ns3::Bar & bar, bool remove=true) [member function] cls.add_method('HasBar', 'bool', - [param('ns3::Bar &', 'bar')]) + [param('ns3::Bar &', 'bar'), param('bool', 'remove', default_value='true')]) ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::HasPackets() const [member function] cls.add_method('HasPackets', 'bool', [], is_const=True) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyGotAck(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyGotAck', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyMissedAck(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyMissedAck', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyGotBlockAck(ns3::CtrlBAckResponseHeader const * blockAck, ns3::Mac48Address recipient, double rxSnr, ns3::WifiMode txMode, double dataSnr) [member function] cls.add_method('NotifyGotBlockAck', 'void', @@ -12705,16 +12688,15 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('NotifyMissedBlockAck', 'void', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::DiscardOutstandingMpdus(ns3::Mac48Address recipient, uint8_t tid) [member function] + cls.add_method('DiscardOutstandingMpdus', + 'void', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## block-ack-manager.h (module 'wifi'): uint32_t ns3::BlockAckManager::GetNBufferedPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function] cls.add_method('GetNBufferedPackets', 'uint32_t', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], is_const=True) - ## block-ack-manager.h (module 'wifi'): uint32_t ns3::BlockAckManager::GetNRetryNeededPackets(ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('GetNRetryNeededPackets', - 'uint32_t', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyAgreementEstablished(ns3::Mac48Address recipient, uint8_t tid, uint16_t startingSeq) [member function] cls.add_method('NotifyAgreementEstablished', 'void', @@ -12735,14 +12717,14 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('NotifyMpduTransmission', 'void', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'nextSeqNumber'), param('ns3::WifiMacHeader::QosAckPolicy', 'policy')]) - ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::CompleteAmpduExchange(ns3::Mac48Address recipient, uint8_t tid) [member function] - cls.add_method('CompleteAmpduExchange', - 'void', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetBlockAckThreshold(uint8_t nPackets) [member function] cls.add_method('SetBlockAckThreshold', 'void', [param('uint8_t', 'nPackets')]) + ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::GetRetransmitQueue() [member function] + cls.add_method('GetRetransmitQueue', + 'ns3::Ptr< ns3::WifiMacQueue >', + []) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetQueue(ns3::Ptr const queue) [member function] cls.add_method('SetQueue', 'void', @@ -12775,24 +12757,6 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('SwitchToBlockAckIfNeeded', 'bool', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid'), param('uint16_t', 'startingSeq')]) - ## block-ack-manager.h (module 'wifi'): uint16_t ns3::BlockAckManager::GetSeqNumOfNextRetryPacket(ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('GetSeqNumOfNextRetryPacket', - 'uint16_t', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::AlreadyExists(uint16_t currentSeq, ns3::Mac48Address recipient, uint8_t tid) const [member function] - cls.add_method('AlreadyExists', - 'bool', - [param('uint16_t', 'currentSeq'), param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], - is_const=True) - ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::RemovePacket(uint8_t tid, ns3::Mac48Address recipient, uint16_t seqnumber) [member function] - cls.add_method('RemovePacket', - 'bool', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient'), param('uint16_t', 'seqnumber')]) - ## block-ack-manager.h (module 'wifi'): ns3::Ptr ns3::BlockAckManager::PeekNextPacketByTidAndAddress(uint8_t tid, ns3::Mac48Address recipient) [member function] - cls.add_method('PeekNextPacketByTidAndAddress', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient')]) ## block-ack-manager.h (module 'wifi'): bool ns3::BlockAckManager::NeedBarRetransmission(uint8_t tid, uint16_t seqNumber, ns3::Mac48Address recipient) [member function] cls.add_method('NeedBarRetransmission', 'bool', @@ -12802,6 +12766,11 @@ def register_Ns3BlockAckManager_methods(root_module, cls): 'uint16_t', [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], is_const=True) + ## block-ack-manager.h (module 'wifi'): uint16_t ns3::BlockAckManager::GetOriginatorStartingSequence(ns3::Mac48Address recipient, uint8_t tid) const [member function] + cls.add_method('GetOriginatorStartingSequence', + 'uint16_t', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')], + is_const=True) ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::SetTxOkCallback(ns3::BlockAckManager::TxOk callback) [member function] cls.add_method('SetTxOkCallback', 'void', @@ -12810,6 +12779,14 @@ def register_Ns3BlockAckManager_methods(root_module, cls): cls.add_method('SetTxFailedCallback', 'void', [param('ns3::Callback< void, ns3::WifiMacHeader const &, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'callback')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::NotifyDiscardedMpdu(ns3::Ptr mpdu) [member function] + cls.add_method('NotifyDiscardedMpdu', + 'void', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + ## block-ack-manager.h (module 'wifi'): void ns3::BlockAckManager::ScheduleBlockAckReq(ns3::Mac48Address recipient, uint8_t tid) [member function] + cls.add_method('ScheduleBlockAckReq', + 'void', + [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) return def register_Ns3BooleanChecker_methods(root_module, cls): @@ -16524,6 +16501,11 @@ def register_Ns3MacLow_methods(root_module, cls): 'ns3::Time', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters const &', 'params'), param('uint32_t', 'fragmentSize', default_value='0')], is_const=True) + ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::CalculateOverheadTxTime(ns3::Ptr item, ns3::MacLowTransmissionParameters const & params) const [member function] + cls.add_method('CalculateOverheadTxTime', + 'ns3::Time', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item'), param('ns3::MacLowTransmissionParameters const &', 'params')], + is_const=True) ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::CalculateTransmissionTime(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters const & parameters) const [member function] cls.add_method('CalculateTransmissionTime', 'ns3::Time', @@ -16550,10 +16532,6 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('DoNavStartNow', 'bool', [param('ns3::Time', 'duration')]) - ## mac-low.h (module 'wifi'): void ns3::MacLow::FlushAggregateQueue(uint8_t tid) [member function] - cls.add_method('FlushAggregateQueue', - 'void', - [param('uint8_t', 'tid')]) ## mac-low.h (module 'wifi'): ns3::Time ns3::MacLow::GetAckTimeout() const [member function] cls.add_method('GetAckTimeout', 'ns3::Time', @@ -16599,10 +16577,10 @@ def register_Ns3MacLow_methods(root_module, cls): 'bool', [], is_const=True) - ## mac-low.h (module 'wifi'): ns3::WifiTxVector ns3::MacLow::GetDataTxVector(ns3::Ptr packet, ns3::WifiMacHeader const * hdr) const [member function] + ## mac-low.h (module 'wifi'): ns3::WifiTxVector ns3::MacLow::GetDataTxVector(ns3::Ptr item) const [member function] cls.add_method('GetDataTxVector', 'ns3::WifiTxVector', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr')], + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'item')], is_const=True, is_virtual=True) ## mac-low.h (module 'wifi'): ns3::Ptr ns3::MacLow::GetMpduAggregator() const [member function] cls.add_method('GetMpduAggregator', @@ -16771,10 +16749,10 @@ def register_Ns3MacLow_methods(root_module, cls): cls.add_method('SetWifiRemoteStationManager', 'void', [param('ns3::Ptr< ns3::WifiRemoteStationManager > const', 'manager')]) - ## mac-low.h (module 'wifi'): void ns3::MacLow::StartTransmission(ns3::Ptr packet, ns3::WifiMacHeader const * hdr, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] + ## mac-low.h (module 'wifi'): void ns3::MacLow::StartTransmission(ns3::Ptr mpdu, ns3::MacLowTransmissionParameters parameters, ns3::Ptr txop) [member function] cls.add_method('StartTransmission', 'void', - [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const *', 'hdr'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu'), param('ns3::MacLowTransmissionParameters', 'parameters'), param('ns3::Ptr< ns3::Txop >', 'txop')], is_virtual=True) ## mac-low.h (module 'wifi'): void ns3::MacLow::DoDispose() [member function] cls.add_method('DoDispose', @@ -17963,7 +17941,7 @@ def register_Ns3ParetoRandomVariable_methods(root_module, cls): cls.add_method('GetMean', 'double', [], - is_const=True) + deprecated=True, is_const=True) ## random-variable-stream.h (module 'core'): double ns3::ParetoRandomVariable::GetScale() const [member function] cls.add_method('GetScale', 'double', @@ -18109,18 +18087,18 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('BaTxOk', 'void', [param('ns3::WifiMacHeader const &', 'hdr')]) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteAmpduTransfer(ns3::Mac48Address recipient, uint8_t tid) [member function] - cls.add_method('CompleteAmpduTransfer', - 'void', - [param('ns3::Mac48Address', 'recipient'), param('uint8_t', 'tid')]) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteConfig() [member function] cls.add_method('CompleteConfig', 'void', []) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteMpduTx(ns3::Ptr mpdu) [member function] + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::CompleteMpduTx(ns3::Ptr mpdu) [member function] cls.add_method('CompleteMpduTx', 'void', - [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu')]) + [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'mpdu')]) + ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::DequeuePeekedFrame(ns3::Ptr peekedItem, ns3::WifiTxVector txVector, bool aggregate=true, uint32_t ampduSize=0, ns3::Time ppduDurationLimit=ns3::Seconds(0)) [member function] + cls.add_method('DequeuePeekedFrame', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'peekedItem'), param('ns3::WifiTxVector', 'txVector'), param('bool', 'aggregate', default_value='true'), param('uint32_t', 'ampduSize', default_value='0'), param('ns3::Time', 'ppduDurationLimit', default_value='ns3::Seconds(0)')]) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::EndTxNoAck() [member function] cls.add_method('EndTxNoAck', 'void', @@ -18146,6 +18124,11 @@ def register_Ns3QosTxop_methods(root_module, cls): 'uint16_t', [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], is_const=True) + ## qos-txop.h (module 'wifi'): uint16_t ns3::QosTxop::GetBaStartingSequence(ns3::Mac48Address address, uint8_t tid) const [member function] + cls.add_method('GetBaStartingSequence', + 'uint16_t', + [param('ns3::Mac48Address', 'address'), param('uint8_t', 'tid')], + is_const=True) ## qos-txop.h (module 'wifi'): uint8_t ns3::QosTxop::GetBlockAckThreshold() const [member function] cls.add_method('GetBlockAckThreshold', 'uint8_t', @@ -18165,6 +18148,11 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('GetNextSequenceNumberFor', 'uint16_t', [param('ns3::WifiMacHeader const *', 'hdr')]) + ## qos-txop.h (module 'wifi'): ns3::MacLowTransmissionParameters ns3::QosTxop::GetTransmissionParameters(ns3::Ptr frame) const [member function] + cls.add_method('GetTransmissionParameters', + 'ns3::MacLowTransmissionParameters', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'frame')], + is_const=True) ## qos-txop.h (module 'wifi'): static ns3::TypeId ns3::QosTxop::GetTypeId() [member function] cls.add_method('GetTypeId', 'ns3::TypeId', @@ -18198,6 +18186,14 @@ def register_Ns3QosTxop_methods(root_module, cls): 'bool', [], is_const=True, is_virtual=True) + ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsWithinSizeAndTimeLimits(ns3::Ptr mpdu, ns3::WifiTxVector txVector, uint32_t ampduSize, ns3::Time ppduDurationLimit) [member function] + cls.add_method('IsWithinSizeAndTimeLimits', + 'bool', + [param('ns3::Ptr< ns3::WifiMacQueueItem const >', 'mpdu'), param('ns3::WifiTxVector', 'txVector'), param('uint32_t', 'ampduSize'), param('ns3::Time', 'ppduDurationLimit')]) + ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsWithinSizeAndTimeLimits(uint32_t mpduSize, ns3::Mac48Address receiver, uint8_t tid, ns3::WifiTxVector txVector, uint32_t ampduSize, ns3::Time ppduDurationLimit) [member function] + cls.add_method('IsWithinSizeAndTimeLimits', + 'bool', + [param('uint32_t', 'mpduSize'), param('ns3::Mac48Address', 'receiver'), param('uint8_t', 'tid'), param('ns3::WifiTxVector', 'txVector'), param('uint32_t', 'ampduSize'), param('ns3::Time', 'ppduDurationLimit')]) ## qos-txop.h (module 'wifi'): ns3::Mac48Address ns3::QosTxop::MapDestAddressForAggregation(ns3::WifiMacHeader const & hdr) [member function] cls.add_method('MapDestAddressForAggregation', 'ns3::Mac48Address', @@ -18216,11 +18212,6 @@ def register_Ns3QosTxop_methods(root_module, cls): 'void', [param('uint8_t', 'nMpdus')], is_virtual=True) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::MissedCts() [member function] - cls.add_method('MissedCts', - 'void', - [], - is_virtual=True) ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::NeedBarRetransmission() [member function] cls.add_method('NeedBarRetransmission', 'bool', @@ -18245,10 +18236,14 @@ def register_Ns3QosTxop_methods(root_module, cls): 'void', [], is_virtual=True) - ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::PeekNextRetransmitPacket(uint8_t tid, ns3::Mac48Address recipient) [member function] - cls.add_method('PeekNextRetransmitPacket', + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::NotifyMissedCts(std::list, std::allocator > > mpduList) [member function] + cls.add_method('NotifyMissedCts', + 'void', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > >', 'mpduList')]) + ## qos-txop.h (module 'wifi'): ns3::Ptr ns3::QosTxop::PeekNextFrame(uint8_t tid=8, ns3::Mac48Address recipient=ns3::Mac48Address::GetBroadcast()) [member function] + cls.add_method('PeekNextFrame', 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient')]) + [param('uint8_t', 'tid', default_value='8'), param('ns3::Mac48Address', 'recipient', default_value='ns3::Mac48Address::GetBroadcast()')]) ## qos-txop.h (module 'wifi'): uint16_t ns3::QosTxop::PeekNextSequenceNumberFor(ns3::WifiMacHeader const * hdr) [member function] cls.add_method('PeekNextSequenceNumberFor', 'uint16_t', @@ -18257,10 +18252,6 @@ def register_Ns3QosTxop_methods(root_module, cls): cls.add_method('PushFront', 'void', [param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::WifiMacHeader const &', 'hdr')]) - ## qos-txop.h (module 'wifi'): void ns3::QosTxop::RemoveRetransmitPacket(uint8_t tid, ns3::Mac48Address recipient, uint16_t seqnumber) [member function] - cls.add_method('RemoveRetransmitPacket', - 'void', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'recipient'), param('uint16_t', 'seqnumber')]) ## qos-txop.h (module 'wifi'): void ns3::QosTxop::RestartAccessIfNeeded() [member function] cls.add_method('RestartAccessIfNeeded', 'void', @@ -18340,9 +18331,9 @@ def register_Ns3QosTxop_methods(root_module, cls): 'uint32_t', [], is_const=True, visibility='private', is_virtual=True) - ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::HasTxop() const [member function] - cls.add_method('HasTxop', - 'bool', + ## qos-txop.h (module 'wifi'): ns3::Time ns3::QosTxop::GetTxopRemaining() const [member function] + cls.add_method('GetTxopRemaining', + 'ns3::Time', [], is_const=True, visibility='private', is_virtual=True) ## qos-txop.h (module 'wifi'): bool ns3::QosTxop::IsLastFragment() const [member function] @@ -18350,6 +18341,11 @@ def register_Ns3QosTxop_methods(root_module, cls): 'bool', [], is_const=True, visibility='private', is_virtual=True) + ## qos-txop.h (module 'wifi'): void ns3::QosTxop::TerminateTxop() [member function] + cls.add_method('TerminateTxop', + 'void', + [], + visibility='private', is_virtual=True) return def register_Ns3Queue__Ns3Packet_methods(root_module, cls): @@ -18386,16 +18382,26 @@ def register_Ns3Queue__Ns3Packet_methods(root_module, cls): []) ## queue.h (module 'network'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::Packet > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::Packet > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::Packet > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::Packet > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::Packet > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -18462,16 +18468,26 @@ def register_Ns3Queue__Ns3QueueDiscItem_methods(root_module, cls): []) ## queue.h (module 'network'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::QueueDiscItem > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::QueueDiscItem > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::QueueDiscItem > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::QueueDiscItem > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::QueueDiscItem > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -18538,16 +18554,26 @@ def register_Ns3Queue__Ns3WifiMacQueueItem_methods(root_module, cls): []) ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::Queue(ns3::Queue const & arg0) [constructor] cls.add_constructor([param('ns3::Queue< ns3::WifiMacQueueItem > const &', 'arg0')]) - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Head() const [member function] - cls.add_method('Head', + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::begin() const [member function] + cls.add_method('begin', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', [], is_const=True, visibility='protected') - ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::Tail() const [member function] - cls.add_method('Tail', + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::begin() [member function] + cls.add_method('begin', + 'ns3::Queue< ns3::WifiMacQueueItem > Iterator', + [], + visibility='protected') + ## queue.h (module 'network'): ns3::Queue::ConstIterator ns3::Queue::end() const [member function] + cls.add_method('end', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', [], is_const=True, visibility='protected') + ## queue.h (module 'network'): ns3::Queue::Iterator ns3::Queue::end() [member function] + cls.add_method('end', + 'ns3::Queue< ns3::WifiMacQueueItem > Iterator', + [], + visibility='protected') ## queue.h (module 'network'): bool ns3::Queue::DoEnqueue(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] cls.add_method('DoEnqueue', 'bool', @@ -20067,6 +20093,10 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('PushFront', 'bool', [param('ns3::Ptr< ns3::WifiMacQueueItem >', 'item')]) + ## wifi-mac-queue.h (module 'wifi'): bool ns3::WifiMacQueue::Insert(ns3::Queue::ConstIterator pos, ns3::Ptr item) [member function] + cls.add_method('Insert', + 'bool', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos'), param('ns3::Ptr< ns3::WifiMacQueueItem >', 'item')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue() [member function] cls.add_method('Dequeue', 'ns3::Ptr< ns3::WifiMacQueueItem >', @@ -20076,27 +20106,47 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('DequeueByAddress', 'ns3::Ptr< ns3::WifiMacQueueItem >', [param('ns3::Mac48Address', 'dest')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTid(uint8_t tid) [member function] + cls.add_method('DequeueByTid', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('uint8_t', 'tid')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueByTidAndAddress(uint8_t tid, ns3::Mac48Address dest) [member function] cls.add_method('DequeueByTidAndAddress', 'ns3::Ptr< ns3::WifiMacQueueItem >', [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest')]) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::Ptr const blockedPackets) [member function] + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::DequeueFirstAvailable(ns3::Ptr const blockedPackets=nullptr) [member function] cls.add_method('DequeueFirstAvailable', 'ns3::Ptr< ns3::WifiMacQueueItem >', - [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets')]) + [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets', default_value='nullptr')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Dequeue(ns3::Queue::ConstIterator pos) [member function] + cls.add_method('Dequeue', + 'ns3::Ptr< ns3::WifiMacQueueItem >', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos')]) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Peek() const [member function] cls.add_method('Peek', 'ns3::Ptr< ns3::WifiMacQueueItem const >', [], is_const=True, is_virtual=True) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekByTidAndAddress(uint8_t tid, ns3::Mac48Address dest) [member function] + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByAddress(ns3::Mac48Address dest, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] + cls.add_method('PeekByAddress', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('ns3::Mac48Address', 'dest'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByTid(uint8_t tid, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] + cls.add_method('PeekByTid', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('uint8_t', 'tid'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekByTidAndAddress(uint8_t tid, ns3::Mac48Address dest, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] cls.add_method('PeekByTidAndAddress', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest')]) - ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::PeekFirstAvailable(ns3::Ptr const blockedPackets) [member function] + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('uint8_t', 'tid'), param('ns3::Mac48Address', 'dest'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::PeekFirstAvailable(ns3::Ptr const blockedPackets=nullptr, ns3::Queue::ConstIterator pos=ns3::WifiMacQueue::EMPTY) const [member function] cls.add_method('PeekFirstAvailable', - 'ns3::Ptr< ns3::WifiMacQueueItem const >', - [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets')]) + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('ns3::Ptr< ns3::QosBlockedDestinations > const', 'blockedPackets', default_value='nullptr'), param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos', default_value='ns3::WifiMacQueue::EMPTY')], + is_const=True) ## wifi-mac-queue.h (module 'wifi'): ns3::Ptr ns3::WifiMacQueue::Remove() [member function] cls.add_method('Remove', 'ns3::Ptr< ns3::WifiMacQueueItem >', @@ -20106,6 +20156,10 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('Remove', 'bool', [param('ns3::Ptr< ns3::Packet const >', 'packet')]) + ## wifi-mac-queue.h (module 'wifi'): ns3::Queue::ConstIterator ns3::WifiMacQueue::Remove(ns3::Queue::ConstIterator pos, bool removeExpired=false) [member function] + cls.add_method('Remove', + 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator', + [param('std::list< ns3::Ptr< ns3::WifiMacQueueItem > > const_iterator', 'pos'), param('bool', 'removeExpired', default_value='false')]) ## wifi-mac-queue.h (module 'wifi'): uint32_t ns3::WifiMacQueue::GetNPacketsByAddress(ns3::Mac48Address dest) [member function] cls.add_method('GetNPacketsByAddress', 'uint32_t', @@ -20126,6 +20180,8 @@ def register_Ns3WifiMacQueue_methods(root_module, cls): cls.add_method('GetNBytes', 'uint32_t', []) + ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::EMPTY [variable] + cls.add_static_attribute('EMPTY', 'ns3::Queue< ns3::WifiMacQueueItem > ConstIterator const', is_const=True) ## wifi-mac-queue.h (module 'wifi'): ns3::WifiMacQueue::WifiMacQueue(ns3::WifiMacQueue const & arg0) [constructor] cls.add_constructor([param('ns3::WifiMacQueue const &', 'arg0')]) return diff --git a/src/wifi/model/block-ack-manager.cc b/src/wifi/model/block-ack-manager.cc index f6319558c..4f578f99e 100644 --- a/src/wifi/model/block-ack-manager.cc +++ b/src/wifi/model/block-ack-manager.cc @@ -66,6 +66,8 @@ BlockAckManager::GetTypeId (void) BlockAckManager::BlockAckManager () { NS_LOG_FUNCTION (this); + m_retryPackets = CreateObject (); + m_retryPackets->TraceConnectWithoutContext ("Expired", MakeCallback (&BlockAckManager::NotifyDiscardedMpdu, this)); } BlockAckManager::~BlockAckManager () @@ -73,7 +75,7 @@ BlockAckManager::~BlockAckManager () NS_LOG_FUNCTION (this); m_queue = 0; m_agreements.clear (); - m_retryPackets.clear (); + m_retryPackets = 0; } bool @@ -93,8 +95,6 @@ BlockAckManager::ExistsAgreementInState (Mac48Address recipient, uint8_t tid, { switch (state) { - case OriginatorBlockAckAgreement::INACTIVE: - return it->second.first.IsInactive (); case OriginatorBlockAckAgreement::ESTABLISHED: return it->second.first.IsEstablished (); case OriginatorBlockAckAgreement::PENDING: @@ -122,7 +122,7 @@ BlockAckManager::CreateAgreement (const MgtAddBaRequestHeader *reqHdr, Mac48Addr /* For now we assume that originator doesn't use this field. Use of this field is mandatory only for recipient */ agreement.SetBufferSize (reqHdr->GetBufferSize()); - agreement.SetWinEnd ((agreement.GetStartingSequence () + agreement.GetBufferSize () - 1) % 4096); + agreement.SetWinEnd ((agreement.GetStartingSequence () + agreement.GetBufferSize () - 1) % SEQNO_SPACE_SIZE); agreement.SetTimeout (reqHdr->GetTimeout ()); agreement.SetAmsduSupport (reqHdr->IsAmsduSupported ()); agreement.SetHtSupported (m_stationManager->GetHtSupported ()); @@ -156,11 +156,11 @@ BlockAckManager::DestroyAgreement (Mac48Address recipient, uint8_t tid) AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); if (it != m_agreements.end ()) { - for (std::list::const_iterator i = m_retryPackets.begin (); i != m_retryPackets.end (); ) + for (WifiMacQueue::ConstIterator i = m_retryPackets->begin (); i != m_retryPackets->end (); ) { if ((*i)->GetHeader ().GetAddr1 () == recipient && (*i)->GetHeader ().GetQosTid () == tid) { - i = m_retryPackets.erase (i); + i = m_retryPackets->Remove (i); } else { @@ -195,6 +195,9 @@ BlockAckManager::UpdateAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Ad agreement.SetBufferSize (respHdr->GetBufferSize () + 1); agreement.SetTimeout (respHdr->GetTimeout ()); agreement.SetAmsduSupport (respHdr->IsAmsduSupported ()); + // update the starting sequence number because some frames may have been sent + // under Normal Ack policy after the transmission of the ADDBA Request frame + agreement.SetStartingSequence (m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient)); if (respHdr->IsImmediateBlockAck ()) { agreement.SetImmediateBlockAck (); @@ -220,225 +223,67 @@ BlockAckManager::UpdateAgreement (const MgtAddBaResponseHeader *respHdr, Mac48Ad m_unblockPackets (recipient, tid); } -void -BlockAckManager::StorePacket (Ptr mpdu) +Ptr +BlockAckManager::GetRetransmitQueue (void) { - NS_LOG_FUNCTION (this << mpdu); + return m_retryPackets; +} + +void +BlockAckManager::StorePacket (Ptr mpdu) +{ + NS_LOG_FUNCTION (this << *mpdu); NS_ASSERT (mpdu->GetHeader ().IsQosData ()); uint8_t tid = mpdu->GetHeader ().GetQosTid (); Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); - AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); - NS_ASSERT (it != m_agreements.end ()); - PacketQueueI queueIt = it->second.second.begin (); - for (; queueIt != it->second.second.end (); ) + AgreementsI agreementIt = m_agreements.find (std::make_pair (recipient, tid)); + NS_ASSERT (agreementIt != m_agreements.end ()); + + uint16_t startingSeq = agreementIt->second.first.GetStartingSequence (); + uint16_t mpduDist = (mpdu->GetHeader ().GetSequenceNumber () - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE; + + if (mpduDist >= SEQNO_SPACE_HALF_SIZE) { - if (((mpdu->GetHeader ().GetSequenceNumber () - queueIt->GetHeader ().GetSequenceNumber () + 4096) % 4096) > 2047) + NS_LOG_DEBUG ("Got an old packet. Do nothing"); + return; + } + + // store the packet and keep the list sorted in increasing order of sequence number + // with respect to the starting sequence number + PacketQueueI it = agreementIt->second.second.begin (); + while (it != agreementIt->second.second.end ()) + { + if (mpdu->GetHeader ().GetSequenceControl () == (*it)->GetHeader ().GetSequenceControl ()) + { + NS_LOG_DEBUG ("Packet already in the queue of the BA agreement"); + return; + } + + uint16_t dist = ((*it)->GetHeader ().GetSequenceNumber () - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE; + + if (mpduDist < dist || + (mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () < (*it)->GetHeader ().GetFragmentNumber ())) { - queueIt = it->second.second.insert (queueIt, *mpdu); break; } - else - { - queueIt++; - } - } - if (queueIt == it->second.second.end ()) - { - it->second.second.push_back (*mpdu); - } -} -void -BlockAckManager::CompleteAmpduExchange (Mac48Address recipient, uint8_t tid) -{ - AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); - NS_ASSERT (it != m_agreements.end ()); - OriginatorBlockAckAgreement &agreement = (*it).second.first; - agreement.CompleteExchange (); -} - -Ptr -BlockAckManager::GetNextPacket (bool removePacket) -{ - NS_LOG_FUNCTION (this << removePacket); - Ptr item; - uint8_t tid; - Mac48Address recipient; - CleanupBuffers (); - if (!m_retryPackets.empty ()) - { - NS_LOG_DEBUG ("Retry buffer size is " << m_retryPackets.size ()); - std::list::const_iterator it = m_retryPackets.begin (); - while (it != m_retryPackets.end ()) - { - if ((*it)->GetHeader ().IsQosData ()) - { - tid = (*it)->GetHeader ().GetQosTid (); - } - else - { - NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data"); - } - recipient = (*it)->GetHeader ().GetAddr1 (); - AgreementsI agreement = m_agreements.find (std::make_pair (recipient, tid)); - NS_ASSERT (agreement != m_agreements.end ()); - if (removePacket) - { - if (QosUtilsIsOldPacket (agreement->second.first.GetStartingSequence (), (*it)->GetHeader ().GetSequenceNumber ())) - { - //Standard says the originator should not send a packet with seqnum < winstart - NS_LOG_DEBUG ("The Retry packet have sequence number < WinStartO --> Discard " - << (*it)->GetHeader ().GetSequenceNumber () << " " - << agreement->second.first.GetStartingSequence ()); - agreement->second.second.erase ((*it)); - it = m_retryPackets.erase (it); - continue; - } - else if (((((*it)->GetHeader ().GetSequenceNumber () - agreement->second.first.GetStartingSequence ()) + 4096) % 4096) > (agreement->second.first.GetBufferSize () - 1)) - { - agreement->second.first.SetStartingSequence ((*it)->GetHeader ().GetSequenceNumber ()); - } - } - item = Create (**it); - item->GetHeader ().SetRetry (); - if (item->GetHeader ().IsQosData ()) - { - tid = item->GetHeader ().GetQosTid (); - } - else - { - NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data"); - } - recipient = item->GetHeader ().GetAddr1 (); - if (!agreement->second.first.IsHtSupported () - && (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED) - || SwitchToBlockAckIfNeeded (recipient, tid, item->GetHeader ().GetSequenceNumber ()))) - { - item->GetHeader ().SetQosAckPolicy (WifiMacHeader::BLOCK_ACK); - } - else - { - /* From section 9.10.3 in IEEE802.11e standard: - * In order to improve efficiency, originators using the Block Ack facility - * may send MPDU frames with the Ack Policy subfield in QoS control frames - * set to Normal Ack if only a few MPDUs are available for transmission.[...] - * When there are sufficient number of MPDUs, the originator may switch back to - * the use of Block Ack. - */ - item->GetHeader ().SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); - if (removePacket) - { - AgreementsI i = m_agreements.find (std::make_pair (recipient, tid)); - i->second.second.erase (*it); - } - } - if (removePacket) - { - NS_LOG_INFO ("Retry packet seq = " << item->GetHeader ().GetSequenceNumber ()); - it = m_retryPackets.erase (it); - NS_LOG_DEBUG ("Removed one packet, retry buffer size = " << m_retryPackets.size ()); - } - break; - } + it++; } - return item; -} - -Ptr -BlockAckManager::PeekNextPacketByTidAndAddress (uint8_t tid, Mac48Address recipient) -{ - NS_LOG_FUNCTION (this); - Ptr item = 0; - CleanupBuffers (); - AgreementsI agreement = m_agreements.find (std::make_pair (recipient, tid)); - NS_ASSERT (agreement != m_agreements.end ()); - std::list::const_iterator it = m_retryPackets.begin (); - for (; it != m_retryPackets.end (); it++) - { - if (!(*it)->GetHeader ().IsQosData ()) - { - NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data"); - } - if ((*it)->GetHeader ().GetAddr1 () == recipient && (*it)->GetHeader ().GetQosTid () == tid) - { - if (QosUtilsIsOldPacket (agreement->second.first.GetStartingSequence (), (*it)->GetHeader ().GetSequenceNumber ())) - { - //standard says the originator should not send a packet with seqnum < winstart - NS_LOG_DEBUG ("The Retry packet have sequence number < WinStartO --> Discard " - << (*it)->GetHeader ().GetSequenceNumber () << " " - << agreement->second.first.GetStartingSequence ()); - agreement->second.second.erase ((*it)); - it = m_retryPackets.erase (it); - it--; - continue; - } - else if (((((*it)->GetHeader ().GetSequenceNumber () - agreement->second.first.GetStartingSequence ()) + 4096) % 4096) > (agreement->second.first.GetBufferSize () - 1)) - { - agreement->second.first.SetStartingSequence ((*it)->GetHeader ().GetSequenceNumber ()); - } - WifiMacHeader hdr = (*it)->GetHeader (); - hdr.SetRetry (); - item = Create ((*it)->GetPacket (), hdr, (*it)->GetTimeStamp ()); - NS_LOG_INFO ("Retry packet seq = " << hdr.GetSequenceNumber ()); - if (!agreement->second.first.IsHtSupported () - && (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED) - || SwitchToBlockAckIfNeeded (recipient, tid, hdr.GetSequenceNumber ()))) - { - hdr.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK); - } - else - { - /* From section 9.10.3 in IEEE802.11e standard: - * In order to improve efficiency, originators using the Block Ack facility - * may send MPDU frames with the Ack Policy subfield in QoS control frames - * set to Normal Ack if only a few MPDUs are available for transmission.[...] - * When there are sufficient number of MPDUs, the originator may switch back to - * the use of Block Ack. - */ - hdr.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); - } - NS_LOG_DEBUG ("Peeked one packet from retry buffer size = " << m_retryPackets.size () ); - return item; - } - } - return item; + agreementIt->second.second.insert (it, mpdu); } bool -BlockAckManager::RemovePacket (uint8_t tid, Mac48Address recipient, uint16_t seqnumber) +BlockAckManager::HasBar (Bar &bar, bool remove) { - NS_LOG_FUNCTION (this << seqnumber); - std::list::const_iterator it = m_retryPackets.begin (); - for (; it != m_retryPackets.end (); it++) - { - if (!(*it)->GetHeader ().IsQosData ()) - { - NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data"); - } - if ((*it)->GetHeader ().GetAddr1 () == recipient && (*it)->GetHeader ().GetQosTid () == tid - && (*it)->GetHeader ().GetSequenceNumber () == seqnumber) - { - WifiMacHeader hdr = (*it)->GetHeader (); - AgreementsI i = m_agreements.find (std::make_pair (recipient, tid)); - i->second.second.erase ((*it)); - m_retryPackets.erase (it); - NS_LOG_DEBUG ("Removed Packet from retry queue = " << hdr.GetSequenceNumber () << " " << +tid << " " << recipient << " Buffer Size = " << m_retryPackets.size ()); - return true; - } - } - return false; -} - -bool -BlockAckManager::HasBar (Bar &bar) -{ - CleanupBuffers (); if (m_bars.size () > 0) { bar = m_bars.front (); - m_bars.pop_front (); + if (remove) + { + m_bars.pop_front (); + } return true; } return false; @@ -448,7 +293,7 @@ bool BlockAckManager::HasPackets (void) const { NS_LOG_FUNCTION (this); - return (m_retryPackets.size () > 0 || m_bars.size () > 0); + return (!m_retryPackets->IsEmpty () || m_bars.size () > 0); } uint32_t @@ -464,10 +309,10 @@ BlockAckManager::GetNBufferedPackets (Mac48Address recipient, uint8_t tid) const PacketQueueCI queueIt = (*it).second.second.begin (); while (queueIt != (*it).second.second.end ()) { - uint16_t currentSeq = (*queueIt).GetHeader ().GetSequenceNumber (); + uint16_t currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber (); nPackets++; /* a fragmented packet must be counted as one packet */ - while (queueIt != (*it).second.second.end () && (*queueIt).GetHeader ().GetSequenceNumber () == currentSeq) + while (queueIt != (*it).second.second.end () && (*queueIt)->GetHeader ().GetSequenceNumber () == currentSeq) { queueIt++; } @@ -475,41 +320,6 @@ BlockAckManager::GetNBufferedPackets (Mac48Address recipient, uint8_t tid) const return nPackets; } -uint32_t -BlockAckManager::GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const -{ - NS_LOG_FUNCTION (this << recipient << +tid); - uint32_t nPackets = 0; - uint16_t currentSeq = 0; - if (ExistsAgreement (recipient, tid)) - { - std::list::const_iterator it = m_retryPackets.begin (); - while (it != m_retryPackets.end ()) - { - if (!(*it)->GetHeader ().IsQosData ()) - { - NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data"); - } - if ((*it)->GetHeader ().GetAddr1 () == recipient && (*it)->GetHeader ().GetQosTid () == tid) - { - currentSeq = (*it)->GetHeader ().GetSequenceNumber (); - nPackets++; - /* a fragmented packet must be counted as one packet */ - while (it != m_retryPackets.end () && (*it)->GetHeader ().GetSequenceNumber () == currentSeq) - { - it++; - } - } - //go to next packet - else - { - it++; - } - } - } - return nPackets; -} - void BlockAckManager::SetBlockAckThreshold (uint8_t nPackets) { @@ -524,31 +334,77 @@ BlockAckManager::SetWifiRemoteStationManager (const Ptr mpdu) { - std::list::const_iterator it = m_retryPackets.begin (); - while (it != m_retryPackets.end ()) + NS_LOG_FUNCTION (this << *mpdu); + NS_ASSERT (mpdu->GetHeader ().IsQosData ()); + + Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); + uint8_t tid = mpdu->GetHeader ().GetQosTid (); + NS_ASSERT (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)); + + AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); + NS_ASSERT (it != m_agreements.end ()); + + // remove the acknowledged frame from the queue of outstanding packets + PacketQueueI queueIt = it->second.second.begin (); + while (queueIt != it->second.second.end ()) { - if (!(*it)->GetHeader ().IsQosData ()) + if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ()) { - NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data"); + queueIt = it->second.second.erase (queueIt); } - if ((*it)->GetHeader ().GetAddr1 () == recipient && (*it)->GetHeader ().GetQosTid () == tid - && currentSeq == (*it)->GetHeader ().GetSequenceNumber ()) - { - return true; - } - it++; + else + { + queueIt++; + } } - return false; + + uint16_t startingSeq = it->second.first.GetStartingSequence (); + if (mpdu->GetHeader ().GetSequenceNumber () == startingSeq) + { + // make the transmit window advance + it->second.first.SetStartingSequence ((startingSeq + 1) % SEQNO_SPACE_SIZE); + } +} + +void +BlockAckManager::NotifyMissedAck (Ptr mpdu) +{ + NS_LOG_FUNCTION (this << *mpdu); + NS_ASSERT (mpdu->GetHeader ().IsQosData ()); + + Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); + uint8_t tid = mpdu->GetHeader ().GetQosTid (); + NS_ASSERT (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)); + + AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); + NS_ASSERT (it != m_agreements.end ()); + + // remove the frame from the queue of outstanding packets (it will be re-inserted + // if retransmitted) + PacketQueueI queueIt = it->second.second.begin (); + while (queueIt != it->second.second.end ()) + { + if ((*queueIt)->GetHeader ().GetSequenceNumber () == mpdu->GetHeader ().GetSequenceNumber ()) + { + queueIt = it->second.second.erase (queueIt); + } + else + { + queueIt++; + } + } + + // insert in the retransmission queue + InsertInRetryQueue (mpdu); } void BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recipient, double rxSnr, WifiMode txMode, double dataSnr) { NS_LOG_FUNCTION (this << blockAck << recipient << rxSnr << txMode.GetUniqueName () << dataSnr); - uint16_t sequenceFirstLost = 0; if (!blockAck->IsMultiTid ()) { uint8_t tid = blockAck->GetTidInfo (); @@ -572,81 +428,76 @@ BlockAckManager::NotifyGotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac4 this, recipient, tid); } + + uint16_t currentStartingSeq = it->second.first.GetStartingSequence (); + uint16_t currentSeq = SEQNO_SPACE_SIZE; // invalid value + if (blockAck->IsBasic ()) { for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; ) { - if (blockAck->IsFragmentReceived ((*queueIt).GetHeader ().GetSequenceNumber (), - (*queueIt).GetHeader ().GetFragmentNumber ())) + currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber (); + if (blockAck->IsFragmentReceived (currentSeq, + (*queueIt)->GetHeader ().GetFragmentNumber ())) { nSuccessfulMpdus++; - RemoveFromRetryQueue (recipient, tid, (*queueIt).GetHeader ().GetSequenceNumber ()); - queueIt = it->second.second.erase (queueIt); } - else + else if (!QosUtilsIsOldPacket (currentStartingSeq, currentSeq)) { if (!foundFirstLost) { foundFirstLost = true; - sequenceFirstLost = (*queueIt).GetHeader ().GetSequenceNumber (); - (*it).second.first.SetStartingSequence (sequenceFirstLost); + SetStartingSequence (recipient, tid, currentSeq); } nFailedMpdus++; - if (!AlreadyExists ((*queueIt).GetHeader ().GetSequenceNumber (), recipient, tid)) - { - InsertInRetryQueue (queueIt); - } - queueIt++; + InsertInRetryQueue (*queueIt); } + // in any case, this packet is no longer outstanding + queueIt = it->second.second.erase (queueIt); + } + // If all frames were acknowledged, move the transmit window past the last one + if (!foundFirstLost && currentSeq != SEQNO_SPACE_SIZE) + { + SetStartingSequence (recipient, tid, (currentSeq + 1) % SEQNO_SPACE_SIZE); } } else if (blockAck->IsCompressed () || blockAck->IsExtendedCompressed ()) { for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; ) { - uint16_t currentSeq = (*queueIt).GetHeader ().GetSequenceNumber (); + currentSeq = (*queueIt)->GetHeader ().GetSequenceNumber (); if (blockAck->IsPacketReceived (currentSeq)) { - while (queueIt != queueEnd - && (*queueIt).GetHeader ().GetSequenceNumber () == currentSeq) + nSuccessfulMpdus++; + if (!m_txOkCallback.IsNull ()) { - nSuccessfulMpdus++; - if (!m_txOkCallback.IsNull ()) - { - m_txOkCallback ((*queueIt).GetHeader ()); - } - RemoveFromRetryQueue (recipient, tid, currentSeq); - queueIt = it->second.second.erase (queueIt); + m_txOkCallback ((*queueIt)->GetHeader ()); } } - else + else if (!QosUtilsIsOldPacket (currentStartingSeq, currentSeq)) { if (!foundFirstLost) { foundFirstLost = true; - sequenceFirstLost = (*queueIt).GetHeader ().GetSequenceNumber (); - (*it).second.first.SetStartingSequence (sequenceFirstLost); + SetStartingSequence (recipient, tid, currentSeq); } nFailedMpdus++; if (!m_txFailedCallback.IsNull ()) { - m_txFailedCallback ((*queueIt).GetHeader ()); + m_txFailedCallback ((*queueIt)->GetHeader ()); } - if (!AlreadyExists ((*queueIt).GetHeader ().GetSequenceNumber (), recipient, tid)) - { - InsertInRetryQueue (queueIt); - } - queueIt++; + InsertInRetryQueue (*queueIt); } + // in any case, this packet is no longer outstanding + queueIt = it->second.second.erase (queueIt); + } + // If all frames were acknowledged, move the transmit window past the last one + if (!foundFirstLost && currentSeq != SEQNO_SPACE_SIZE) + { + SetStartingSequence (recipient, tid, (currentSeq + 1) % SEQNO_SPACE_SIZE); } } m_stationManager->ReportAmpduTxStatus (recipient, tid, nSuccessfulMpdus, nFailedMpdus, rxSnr, dataSnr); - uint16_t newSeq = m_txMiddle->GetNextSeqNumberByTidAndAddress (tid, recipient); - if ((foundFirstLost && !SwitchToBlockAckIfNeeded (recipient, tid, sequenceFirstLost)) - || (!foundFirstLost && !SwitchToBlockAckIfNeeded (recipient, tid, newSeq))) - { - it->second.first.CompleteExchange (); - } } } else @@ -663,16 +514,25 @@ BlockAckManager::NotifyMissedBlockAck (Mac48Address recipient, uint8_t tid) if (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)) { AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); - PacketQueueI queueEnd = it->second.second.end (); - for (PacketQueueI queueIt = it->second.second.begin (); queueIt != queueEnd; ++queueIt) + for (auto& item : it->second.second) { - //Queue previously transmitted packets that do not already exist in the retry queue. - //The first packet is not placed in the retry queue since it should be retransmitted by the invoker. - if (!AlreadyExists ((*queueIt).GetHeader ().GetSequenceNumber (), recipient, tid)) - { - InsertInRetryQueue (queueIt); - } + // Queue previously transmitted packets that do not already exist in the retry queue. + InsertInRetryQueue (item); } + // remove all packets from the queue of outstanding packets (they will be + // re-inserted if retransmitted) + it->second.second.clear (); + } +} + +void +BlockAckManager::DiscardOutstandingMpdus (Mac48Address recipient, uint8_t tid) +{ + NS_LOG_FUNCTION (this << recipient << +tid); + if (ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)) + { + AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); + it->second.second.clear (); } } @@ -683,20 +543,49 @@ BlockAckManager::SetBlockAckType (BlockAckType bAckType) m_blockAckType = bAckType; } -Ptr -BlockAckManager::ScheduleBlockAckReqIfNeeded (Mac48Address recipient, uint8_t tid) +void +BlockAckManager::NotifyDiscardedMpdu (Ptr mpdu) +{ + NS_LOG_FUNCTION (this << *mpdu); + + if (!mpdu->GetHeader ().IsQosData ()) + { + NS_LOG_DEBUG ("Not a QoS Data frame"); + return; + } + + Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); + uint8_t tid = mpdu->GetHeader ().GetQosTid (); + if (!ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)) + { + NS_LOG_DEBUG ("No established Block Ack agreement"); + return; + } + + AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); + uint16_t currStartingSeq = it->second.first.GetStartingSequence (); + if (QosUtilsIsOldPacket (currStartingSeq, mpdu->GetHeader ().GetSequenceNumber ())) + { + NS_LOG_DEBUG ("Discarded an old frame"); + return; + } + + // advance the transmit window past the discarded mpdu + SetStartingSequence (recipient, tid, (mpdu->GetHeader ().GetSequenceNumber () + 1) % SEQNO_SPACE_SIZE); + + // schedule a block ack request + NS_LOG_DEBUG ("Schedule a Block Ack Request for agreement (" << recipient << ", " << +tid << ")"); + ScheduleBlockAckReq (recipient, tid); +} + +void +BlockAckManager::ScheduleBlockAckReq (Mac48Address recipient, uint8_t tid) { - /* This method checks if a BlockAckRequest frame should be send to the recipient station. - Number of packets under block ack is specified in OriginatorBlockAckAgreement object but sometimes - this number could be incorrect. In fact is possible that a block ack agreement exists for n - packets but some of these packets are dropped due to MSDU lifetime expiration. - */ NS_LOG_FUNCTION (this << recipient << +tid); AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); OriginatorBlockAckAgreement &agreement = (*it).second.first; - agreement.CompleteExchange (); CtrlBAckRequestHeader reqHdr; reqHdr.SetType (m_blockAckType); @@ -705,7 +594,19 @@ BlockAckManager::ScheduleBlockAckReqIfNeeded (Mac48Address recipient, uint8_t ti Ptr bar = Create (); bar->AddHeader (reqHdr); - return bar; + Bar request (bar, recipient, tid, it->second.first.IsImmediateBlockAck ()); + + // if a BAR for the given agreement is present, replace it with the new one + for (std::list::const_iterator i = m_bars.begin (); i != m_bars.end (); i++) + { + if (i->recipient == recipient && i->tid == tid) + { + i = m_bars.erase (i); + m_bars.insert (i, request); + return; + } + } + m_bars.push_back (request); } void @@ -775,21 +676,9 @@ BlockAckManager::NotifyMpduTransmission (Mac48Address recipient, uint8_t tid, ui NS_LOG_FUNCTION (this << recipient << +tid << nextSeqNumber); AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); - uint16_t nextSeq; - if (GetNRetryNeededPackets (recipient, tid) > 0) - { - nextSeq = GetSeqNumOfNextRetryPacket (recipient, tid); - } - else - { - nextSeq = nextSeqNumber; - } - it->second.first.NotifyMpduTransmission (nextSeq); if (policy == WifiMacHeader::BLOCK_ACK) { - Ptr bar = ScheduleBlockAckReqIfNeeded (recipient, tid); - Bar request (bar, recipient, tid, it->second.first.IsImmediateBlockAck ()); - m_bars.push_back (request); + ScheduleBlockAckReq (recipient, tid); } } @@ -823,7 +712,6 @@ bool BlockAckManager::NeedBarRetransmission (uint8_t tid, uint16_t seqNumber, Ma //The standard says the BAR gets discarded when all MSDUs lifetime expires AgreementsI it = m_agreements.find (std::make_pair (recipient, tid)); NS_ASSERT (it != m_agreements.end ()); - CleanupBuffers (); if (QosUtilsIsOldPacket (it->second.first.GetStartingSequence (), seqNumber)) { return false; @@ -851,61 +739,82 @@ bool BlockAckManager::NeedBarRetransmission (uint8_t tid, uint16_t seqNumber, Ma void BlockAckManager::RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16_t seq) { - NS_LOG_FUNCTION (this << address << +tid << seq); - /* remove retry packet iterator if it's present in retry queue */ - std::list::const_iterator it = m_retryPackets.begin (); - while (it != m_retryPackets.end ()) + RemoveFromRetryQueue (address, tid, seq, seq); +} + +void +BlockAckManager::RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16_t startSeq, uint16_t endSeq) +{ + NS_LOG_FUNCTION (this << address << +tid << startSeq << endSeq); + + AgreementsI agreementIt = m_agreements.find (std::make_pair (address, tid)); + NS_ASSERT (agreementIt != m_agreements.end ()); + uint16_t startingSeq = agreementIt->second.first.GetStartingSequence (); + + /* remove retry packet iterators if they are present in retry queue */ + WifiMacQueue::ConstIterator it = m_retryPackets->PeekByTidAndAddress (tid, address); + + while (it != m_retryPackets->end ()) { - if ((*it)->GetHeader ().GetAddr1 () == address - && (*it)->GetHeader ().GetQosTid () == tid - && (*it)->GetHeader ().GetSequenceNumber () == seq) + uint16_t itSeq = (*it)->GetHeader ().GetSequenceNumber (); + + if ((itSeq - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE + >= (startSeq - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE + && (itSeq - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE + <= (endSeq - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE) { - it = m_retryPackets.erase (it); + NS_LOG_DEBUG ("Removing frame with seqnum = " << itSeq); + it = m_retryPackets->Remove (it); + it = m_retryPackets->PeekByTidAndAddress (tid, address, it); + } + else + { + it = m_retryPackets->PeekByTidAndAddress (tid, address, ++it); + } + } +} + +void +BlockAckManager::SetStartingSequence (Mac48Address recipient, uint8_t tid, uint16_t startingSeq) +{ + NS_LOG_FUNCTION (this << recipient << +tid << startingSeq); + + AgreementsI agreementIt = m_agreements.find (std::make_pair (recipient, tid)); + NS_ASSERT (agreementIt != m_agreements.end ()); + uint16_t currStartingSeq = agreementIt->second.first.GetStartingSequence (); + + NS_ABORT_MSG_IF ((startingSeq - currStartingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE >= SEQNO_SPACE_HALF_SIZE, + "The new starting sequence number is an old sequence number"); + + if (startingSeq == currStartingSeq) + { + return; + } + + // remove packets that will become old from the retransmission queue + uint16_t lastRemovedSeq = (startingSeq - 1 + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE; + RemoveFromRetryQueue (recipient, tid, currStartingSeq, lastRemovedSeq); + + // remove packets that will become old from the queue of outstanding packets + PacketQueueI it = agreementIt->second.second.begin (); + while (it != agreementIt->second.second.end ()) + { + uint16_t itSeq = (*it)->GetHeader ().GetSequenceNumber (); + + if ((itSeq - currStartingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE + <= (lastRemovedSeq - currStartingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE) + { + NS_LOG_DEBUG ("Removing frame with seqnum = " << itSeq); + it = agreementIt->second.second.erase (it); } else { it++; } } -} -void -BlockAckManager::CleanupBuffers (void) -{ - NS_LOG_FUNCTION (this); - for (AgreementsI j = m_agreements.begin (); j != m_agreements.end (); j++) - { - bool removed = false; - if (j->second.second.empty ()) - { - continue; - } - Time now = Simulator::Now (); - for (PacketQueueI i = j->second.second.begin (); i != j->second.second.end (); ) - { - if (i->GetTimeStamp () + m_maxDelay > now) - { - break; - } - else - { - RemoveFromRetryQueue (j->second.first.GetPeer (), - j->second.first.GetTid (), - i->GetHeader ().GetSequenceNumber ()); - j->second.first.SetStartingSequence ((i->GetHeader ().GetSequenceNumber () + 1) % 4096); - i = j->second.second.erase (i); - removed = true; - continue; - } - i++; - } - if (removed) - { - Ptr bar = ScheduleBlockAckReqIfNeeded (j->second.first.GetPeer (), j->second.first.GetTid ()); - Bar request (bar, j->second.first.GetPeer (), j->second.first.GetTid (), j->second.first.IsImmediateBlockAck ()); - m_bars.push_back (request); - } - } + // update the starting sequence number + agreementIt->second.first.SetStartingSequence (startingSeq); } void @@ -943,26 +852,6 @@ BlockAckManager::SetTxMiddle (const Ptr txMiddle) m_txMiddle = txMiddle; } -uint16_t -BlockAckManager::GetSeqNumOfNextRetryPacket (Mac48Address recipient, uint8_t tid) const -{ - NS_LOG_FUNCTION (this << recipient << +tid); - std::list::const_iterator it = m_retryPackets.begin (); - while (it != m_retryPackets.end ()) - { - if (!(*it)->GetHeader ().IsQosData ()) - { - NS_FATAL_ERROR ("Packet in blockAck manager retry queue is not Qos Data"); - } - if ((*it)->GetHeader ().GetAddr1 () == recipient && (*it)->GetHeader ().GetQosTid () == tid) - { - return (*it)->GetHeader ().GetSequenceNumber (); - } - it++; - } - return 4096; -} - void BlockAckManager::SetTxOkCallback (TxOk callback) { @@ -976,32 +865,47 @@ BlockAckManager::SetTxFailedCallback (TxFailed callback) } void -BlockAckManager::InsertInRetryQueue (PacketQueueI item) +BlockAckManager::InsertInRetryQueue (Ptr mpdu) { - NS_LOG_INFO ("Adding to retry queue " << (*item).GetHeader ().GetSequenceNumber ()); - if (m_retryPackets.size () == 0) + NS_LOG_INFO ("Adding to retry queue " << *mpdu); + NS_ASSERT (mpdu->GetHeader ().IsQosData ()); + + uint8_t tid = mpdu->GetHeader ().GetQosTid (); + Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); + + AgreementsI agreementIt = m_agreements.find (std::make_pair (recipient, tid)); + NS_ASSERT (agreementIt != m_agreements.end ()); + + uint16_t startingSeq = agreementIt->second.first.GetStartingSequence (); + uint16_t mpduDist = (mpdu->GetHeader ().GetSequenceNumber () - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE; + + if (mpduDist >= SEQNO_SPACE_HALF_SIZE) { - m_retryPackets.push_back (item); + NS_LOG_DEBUG ("Got an old packet. Do nothing"); + return; } - else + + WifiMacQueue::ConstIterator it = m_retryPackets->PeekByTidAndAddress (tid, recipient); + + while (it != m_retryPackets->end ()) { - for (std::list::const_iterator it = m_retryPackets.begin (); it != m_retryPackets.end (); ) + if (mpdu->GetHeader ().GetSequenceControl () == (*it)->GetHeader ().GetSequenceControl ()) { - if (((item->GetHeader ().GetSequenceNumber () - (*it)->GetHeader ().GetSequenceNumber () + 4096) % 4096) > 2047) - { - it = m_retryPackets.insert (it, item); - break; - } - else - { - it++; - if (it == m_retryPackets.end ()) - { - m_retryPackets.push_back (item); - } - } + NS_LOG_DEBUG ("Packet already in the retransmit queue"); + return; } + + uint16_t dist = ((*it)->GetHeader ().GetSequenceNumber () - startingSeq + SEQNO_SPACE_SIZE) % SEQNO_SPACE_SIZE; + + if (mpduDist < dist || + (mpduDist == dist && mpdu->GetHeader ().GetFragmentNumber () < (*it)->GetHeader ().GetFragmentNumber ())) + { + break; + } + + it = m_retryPackets->PeekByTidAndAddress (tid, recipient, ++it); } + m_retryPackets->Insert (it, mpdu); } uint16_t @@ -1016,4 +920,16 @@ BlockAckManager::GetRecipientBufferSize (Mac48Address recipient, uint8_t tid) co return size; } +uint16_t +BlockAckManager::GetOriginatorStartingSequence (Mac48Address recipient, uint8_t tid) const +{ + uint16_t seqNum = 0; + AgreementsCI it = m_agreements.find (std::make_pair (recipient, tid)); + if (it != m_agreements.end ()) + { + seqNum = it->second.first.GetStartingSequence (); + } + return seqNum; +} + } //namespace ns3 diff --git a/src/wifi/model/block-ack-manager.h b/src/wifi/model/block-ack-manager.h index c6d854cc8..8dee23882 100644 --- a/src/wifi/model/block-ack-manager.h +++ b/src/wifi/model/block-ack-manager.h @@ -152,24 +152,16 @@ public: * Stores mpdu for a possible future retransmission. Retransmission occurs * if the packet, in a block ack frame, is indicated by recipient as not received. */ - void StorePacket (Ptr mpdu); - /** - * \param removePacket flag to indicate whether the packet should be removed from the queue. - * - * \return the packet - * - * This methods returns a packet (if exists) indicated as not received in - * corresponding block ack bitmap. - */ - Ptr GetNextPacket (bool removePacket); + void StorePacket (Ptr mpdu); /** * Returns true if the BAR is scheduled. Returns false otherwise. * * \param bar + * \param remove true if the BAR has to be removed from the queue * * \return true if a BAR is scheduled, false otherwise */ - bool HasBar (Bar &bar); + bool HasBar (Bar &bar, bool remove = true); /** * Returns true if there are packets that need of retransmission or at least a * BAR is scheduled. Returns false otherwise. @@ -178,6 +170,24 @@ public: * false otherwise */ bool HasPackets (void) const; + /** + * Invoked upon receipt of an ack frame after the transmission of a QoS data frame + * sent under an established Block Ack agreement. Remove the acknowledged frame + * from the outstanding packets and update the starting sequence number of the + * transmit window, if needed. + * + * \param mpdu The acknowledged MPDU. + */ + void NotifyGotAck (Ptr mpdu); + /** + * Invoked upon missed reception of an ack frame after the transmission of a + * QoS data frame sent under an established Block Ack agreement. Remove the + * acknowledged frame from the outstanding packets and insert it in the + * retransmission queue. + * + * \param mpdu The unacknowledged MPDU. + */ + void NotifyMissedAck (Ptr mpdu); /** * \param blockAck The received block ack frame. * \param recipient Sender of block ack frame. @@ -200,26 +210,25 @@ public: * with ack policy set to Block Ack, should be placed in the retransmission queue. */ void NotifyMissedBlockAck (Mac48Address recipient, uint8_t tid); + /** + * \param recipient outstanding frames' receiver. + * \param tid Traffic ID. + * + * Discard all the outstanding MPDUs destined to the given receiver and belonging + * to the given TID. Typically, this function is called by ns3::QosTxop object + * when it gives up retransmitting either a Block Ack Request or the data frames. + */ + void DiscardOutstandingMpdus (Mac48Address recipient, uint8_t tid); /** * \param recipient Address of peer station involved in block ack mechanism. * \param tid Traffic ID. * * \return the number of packets buffered for a specified agreement * - * Returns number of packets buffered for a specified agreement. This methods doesn't return - * number of buffered MPDUs but number of buffered MSDUs. + * Returns the number of packets buffered for a specified agreement. This methods doesn't return + * the number of buffered MPDUs but the number of buffered MSDUs. */ uint32_t GetNBufferedPackets (Mac48Address recipient, uint8_t tid) const; - /** - * \param recipient Address of peer station involved in block ack mechanism. - * \param tid Traffic ID. - * - * \return the number of packets for a specific agreement that need retransmission - * - * Returns number of packets for a specific agreement that need retransmission. - * This method doesn't return number of MPDUs that need retransmission but number of MSDUs. - */ - uint32_t GetNRetryNeededPackets (Mac48Address recipient, uint8_t tid) const; /** * \param recipient Address of peer station involved in block ack mechanism. * \param tid Traffic ID of transmitted packet. @@ -265,13 +274,6 @@ public: * The nextSeqNumber parameter is used to block transmission of packets that are out of bitmap. */ void NotifyMpduTransmission (Mac48Address recipient, uint8_t tid, uint16_t nextSeqNumber, WifiMacHeader::QosAckPolicy policy); - /** - * \param recipient Address of peer station involved in block ack mechanism. - * \param tid Traffic ID of transmitted packet. - * - * This method to set the number of packets waiting for blockAck = 0 since the receiver will send the blockAck right away - */ - void CompleteAmpduExchange (Mac48Address recipient, uint8_t tid); /** * \param nPackets Minimum number of packets for use of block ack. * @@ -279,6 +281,12 @@ public: * and buffered packets) is greater of nPackets, they are transmitted using block ack mechanism. */ void SetBlockAckThreshold (uint8_t nPackets); + /** + * \return the retransmit queue. + * + * Return the retransmit queue. + */ + Ptr GetRetransmitQueue (void); /** * \param queue The WifiMacQueue object. @@ -335,47 +343,8 @@ public: */ bool SwitchToBlockAckIfNeeded (Mac48Address recipient, uint8_t tid, uint16_t startingSeq); /** - * \param recipient the destination address - * \param tid the Traffic ID - * - * \return the sequence number of the next retry packet for a specific agreement - * - * Returns the sequence number of the next retry packet for a specific agreement. - * If there are no packets that need retransmission for the specified agreement or - * the agreement doesn't exist the function returns 4096; - */ - uint16_t GetSeqNumOfNextRetryPacket (Mac48Address recipient, uint8_t tid) const; - /** - * Checks if the packet already exists in the retransmit queue or not if it does then it doesn't add it again - * - * \param currentSeq the current sequence - * \param recipient the destination address - * \param tid the Traffic ID - * \returns true if the packet already exists - */ - bool AlreadyExists (uint16_t currentSeq, Mac48Address recipient, uint8_t tid) const; - /** - * Remove a packet after you peek in the queue and get it - * \param tid the Traffic ID - * \param recipient the destination address - * \param seqnumber sequence number - * \returns true if a packet was removed - */ - bool RemovePacket (uint8_t tid, Mac48Address recipient, uint16_t seqnumber); - /** - * Peek in retransmit queue and get the next packet having address indicated - * by type equals to addr, and tid equals to tid. - * This method doesn't remove the packet from this queue. - * - * \param hdr wifi mac header - * \param tid Traffic ID - * \param timestamp timestamp - * - * \returns Ptr - */ - Ptr PeekNextPacketByTidAndAddress (uint8_t tid, Mac48Address recipient); - /** - * This function returns true if the lifetime of the packets a BAR refers to didn't expire yet else it returns false. + * This function returns true if the lifetime of the packets a BAR refers to didn't + * expire yet otherwise it returns false. * If it return false then the BAR will be discarded (i.e. will not be re-transmitted) * * \param tid Traffic ID @@ -394,6 +363,15 @@ public: * \returns the buffer size negociated with the recipient */ uint16_t GetRecipientBufferSize (Mac48Address recipient, uint8_t tid) const; + /** + * This function returns the starting sequence number of the transmit window. + * + * \param tid Traffic ID + * \param recipient MAC address + * + * \returns the starting sequence number of the transmit window (WinStartO) + */ + uint16_t GetOriginatorStartingSequence (Mac48Address recipient, uint8_t tid) const; /** * typedef for a callback to invoke when a @@ -426,25 +404,31 @@ public: */ typedef void (* AgreementStateTracedCallback)(Time now, Mac48Address recipient, uint8_t tid, OriginatorBlockAckAgreement::State state); + /** + * \param mpdu the discarded frame + * + * Notify the block ack manager that an MPDU has been discarded, e.g., because + * the MSDU lifetime expired. If there is an established block ack agreement, + * make the transmit window advance beyond the discarded frame. This also + * involves (i) the removal of frames that consequently become old from the + * retransmit queue and from the queue of the block ack agreement, and (ii) the + * scheduling of a block ack request. + */ + void NotifyDiscardedMpdu (Ptr mpdu); + + /** + * \param recipient the recipient + * \param tid the TID + * + * Enqueue a block ack request for the established BA agreement + * (recipient,tid) into the queue storing the next + * BAR frames to transmit. If a BAR for the given agreement is + * already present in the queue, it is replaced by the new one. + */ + void ScheduleBlockAckReq (Mac48Address recipient, uint8_t tid); + private: - /** - * \param recipient - * \param tid - * - * \return a packet - * - * Checks if all packets, for which a block ack agreement was established or refreshed, - * have been transmitted. If yes, adds a pair in m_bAckReqs to indicate that - * at next channel access a block ack request (for established agreement - * recipient,tid) is needed. - */ - Ptr ScheduleBlockAckReqIfNeeded (Mac48Address recipient, uint8_t tid); - - /** - * This method removes packets whose lifetime was exceeded. - */ - void CleanupBuffers (void); /** * Inactivity timeout function * \param recipient the recipient MAC address @@ -452,18 +436,30 @@ private: */ void InactivityTimeout (Mac48Address recipient, uint8_t tid); + /** + * Set the starting sequence number for the agreement with recipient equal to + * recipient and TID equal to tid to the given startingSeq. + * Also, remove packets that became old from the retransmit queue and from the + * queue of outstanding packets. + * + * \param recipient the recipient MAC address + * \param tid Traffic ID + * \param startingSeq the new starting sequence number + */ + void SetStartingSequence (Mac48Address recipient, uint8_t tid, uint16_t startingSeq); + /** * typedef for a list of WifiMacQueueItem. */ - typedef std::list PacketQueue; + typedef std::list> PacketQueue; /** * typedef for an iterator for PacketQueue. */ - typedef std::list::iterator PacketQueueI; + typedef std::list>::iterator PacketQueueI; /** * typedef for a const iterator for PacketQueue. */ - typedef std::list::const_iterator PacketQueueCI; + typedef std::list>::const_iterator PacketQueueCI; /** * typedef for a map between MAC address and block ACK agreement. */ @@ -481,15 +477,15 @@ private: std::pair >::const_iterator AgreementsCI; /** - * \param item + * \param mpdu the packet to insert in the retransmission queue * - * Insert item in retransmission queue. + * Insert mpdu in retransmission queue. * This method ensures packets are retransmitted in the correct order. */ - void InsertInRetryQueue (PacketQueueI item); + void InsertInRetryQueue (Ptr mpdu); /** - * Remove items from retransmission queue. + * Remove an item from retransmission queue. * This method should be called when packets are acknowledged. * * \param address recipient mac address of the packet to be removed @@ -498,6 +494,17 @@ private: */ void RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16_t seq); + /** + * Remove a range of items from retransmission queue. + * This method should be called when packets are acknowledged. + * + * \param address recipient mac address of the packet to be removed + * \param tid Traffic ID of the packet to be removed + * \param startSeq sequence number of the first packet to be removed + * \param endSeq sequence number of the last packet to be removed + */ + void RemoveFromRetryQueue (Mac48Address address, uint8_t tid, uint16_t startSeq, uint16_t endSeq); + /** * This data structure contains, for each block ack agreement (recipient, tid), a set of packets * for which an ack by block ack is requested. @@ -511,7 +518,7 @@ private: * A packet needs retransmission if it's indicated as not correctly received in a block ack * frame. */ - std::list m_retryPackets; + Ptr m_retryPackets; std::list m_bars; ///< list of BARs uint8_t m_blockAckThreshold; ///< block ack threshold diff --git a/src/wifi/model/mac-low-transmission-parameters.cc b/src/wifi/model/mac-low-transmission-parameters.cc index 4edee4688..f78ef548a 100644 --- a/src/wifi/model/mac-low-transmission-parameters.cc +++ b/src/wifi/model/mac-low-transmission-parameters.cc @@ -58,7 +58,7 @@ MacLowTransmissionParameters::EnableCompressedBlockAck (void) void MacLowTransmissionParameters::EnableExtendedCompressedBlockAck (void) { - m_waitAck = EXTENDED_BLOCK_ACK_COMPRESSED; + m_waitAck = BLOCK_ACK_EXTENDED_COMPRESSED; } void @@ -98,27 +98,47 @@ MacLowTransmissionParameters::MustWaitNormalAck (void) const } bool -MacLowTransmissionParameters::MustWaitBasicBlockAck (void) const +MacLowTransmissionParameters::MustWaitBlockAck (void) const { - return (m_waitAck == BLOCK_ACK_BASIC) ? true : false; + bool ret; + switch (m_waitAck) + { + case BLOCK_ACK_BASIC: + case BLOCK_ACK_COMPRESSED: + case BLOCK_ACK_EXTENDED_COMPRESSED: + case BLOCK_ACK_MULTI_TID: + ret = true; + break; + default: + ret = false; + break; + } + return ret; } -bool -MacLowTransmissionParameters::MustWaitCompressedBlockAck (void) const +BlockAckType +MacLowTransmissionParameters::GetBlockAckType (void) const { - return (m_waitAck == BLOCK_ACK_COMPRESSED) ? true : false; -} - -bool -MacLowTransmissionParameters::MustWaitExtendedCompressedBlockAck (void) const -{ - return (m_waitAck == EXTENDED_BLOCK_ACK_COMPRESSED) ? true : false; -} - -bool -MacLowTransmissionParameters::MustWaitMultiTidBlockAck (void) const -{ - return (m_waitAck == BLOCK_ACK_MULTI_TID) ? true : false; + BlockAckType type; + switch (m_waitAck) + { + case BLOCK_ACK_BASIC: + type = BlockAckType::BASIC_BLOCK_ACK; + break; + case BLOCK_ACK_COMPRESSED: + type = BlockAckType::COMPRESSED_BLOCK_ACK; + break; + case BLOCK_ACK_EXTENDED_COMPRESSED: + type = BlockAckType::EXTENDED_COMPRESSED_BLOCK_ACK; + break; + case BLOCK_ACK_MULTI_TID: + type = BlockAckType::MULTI_TID_BLOCK_ACK; + break; + default: + NS_FATAL_ERROR ("Block ack is not used"); + break; + } + return type; } bool @@ -160,7 +180,7 @@ std::ostream &operator << (std::ostream &os, const MacLowTransmissionParameters case MacLowTransmissionParameters::BLOCK_ACK_COMPRESSED: os << "compressed-block-ack"; break; - case MacLowTransmissionParameters::EXTENDED_BLOCK_ACK_COMPRESSED: + case MacLowTransmissionParameters::BLOCK_ACK_EXTENDED_COMPRESSED: os << "extended-compressed-block-ack"; break; case MacLowTransmissionParameters::BLOCK_ACK_MULTI_TID: diff --git a/src/wifi/model/mac-low-transmission-parameters.h b/src/wifi/model/mac-low-transmission-parameters.h index 632e29410..bcc5ead8b 100644 --- a/src/wifi/model/mac-low-transmission-parameters.h +++ b/src/wifi/model/mac-low-transmission-parameters.h @@ -24,6 +24,7 @@ #define MAC_LOW_TRANSMISSION_PARAMETERS_H #include "ns3/uinteger.h" +#include "block-ack-type.h" namespace ns3 { @@ -104,25 +105,13 @@ public: * * \sa EnableBlockAck */ - bool MustWaitBasicBlockAck (void) const; + bool MustWaitBlockAck (void) const; /** - * \returns true if compressed block ack mechanism is used, false otherwise. + * \returns the selected block ack variant. * - * \sa EnableCompressedBlockAck + * Only call this method if the block ack mechanism is used. */ - bool MustWaitCompressedBlockAck (void) const; - /** - * \returns true if extended compressed block ack mechanism is used, false otherwise. - * - * \sa EnableExtendedCompressedBlockAck - */ - bool MustWaitExtendedCompressedBlockAck (void) const; - /** - * \returns true if multi-tid block ack mechanism is used, false otherwise. - * - * \sa EnableMultiTidBlockAck - */ - bool MustWaitMultiTidBlockAck (void) const; + BlockAckType GetBlockAckType (void) const; /** * \returns true if RTS should be sent and CTS waited for before * sending data, false otherwise. @@ -147,7 +136,7 @@ private: ACK_NORMAL, BLOCK_ACK_BASIC, BLOCK_ACK_COMPRESSED, - EXTENDED_BLOCK_ACK_COMPRESSED, + BLOCK_ACK_EXTENDED_COMPRESSED, BLOCK_ACK_MULTI_TID } m_waitAck; //!< wait ack bool m_sendRts; //!< send an RTS? diff --git a/src/wifi/model/mac-low.cc b/src/wifi/model/mac-low.cc index 4b4b5122c..8cbf597ad 100644 --- a/src/wifi/model/mac-low.cc +++ b/src/wifi/model/mac-low.cc @@ -18,6 +18,7 @@ * * Authors: Mathieu Lacage * Mirko Banchi + * Stefano Avallone */ #include "ns3/simulator.h" @@ -125,16 +126,11 @@ MacLow::MacLow () m_lastBeacon (Seconds (0)), m_cfpForeshortening (Seconds (0)), m_promisc (false), - m_ampdu (false), m_phyMacLowListener (0), m_ctsToSelfSupported (false), m_cfAckInfo () { NS_LOG_FUNCTION (this); - for (uint8_t i = 0; i < 8; i++) - { - m_aggregateQueue[i] = CreateObject (); - } } MacLow::~MacLow () @@ -193,11 +189,6 @@ MacLow::DoDispose (void) delete m_phyMacLowListener; m_phyMacLowListener = 0; } - for (uint8_t i = 0; i < 8; i++) - { - m_aggregateQueue[i] = 0; - } - m_ampdu = false; } void @@ -495,12 +486,11 @@ MacLow::RegisterDcf (Ptr dcf) } void -MacLow::StartTransmission (Ptr packet, - const WifiMacHeader* hdr, +MacLow::StartTransmission (Ptr mpdu, MacLowTransmissionParameters params, Ptr txop) { - NS_LOG_FUNCTION (this << packet << hdr << params << txop); + NS_LOG_FUNCTION (this << *mpdu << params << txop); NS_ASSERT (!m_cfAckInfo.expectCfAck); if (m_phy->IsStateOff ()) { @@ -521,112 +511,52 @@ MacLow::StartTransmission (Ptr packet, * QapScheduler has taken access to the channel from * one of the Edca of the QAP. */ - m_currentPacket = Create (packet, *hdr); + m_currentPacket = Create (mpdu, false); + const WifiMacHeader& hdr = mpdu->GetHeader (); CancelAllEvents (); m_currentTxop = txop; m_txParams = params; - if (hdr->IsCtl ()) + if (hdr.IsCtl ()) { - m_currentTxVector = GetRtsTxVector (packet, hdr); + m_currentTxVector = GetRtsTxVector (mpdu); } else { - m_currentTxVector = GetDataTxVector (packet, hdr); + m_currentTxVector = GetDataTxVector (mpdu); } - if (NeedRts () && !IsCfPeriod ()) + /* The packet received by this function can be any of the following: + * (a) a management frame dequeued from the Txop + * (b) a non-QoS data frame dequeued from the Txop + * (c) a QoS data or DELBA Request frame dequeued from a QosTxop + * (d) a BlockAckReq or ADDBA Request frame + */ + if (hdr.IsQosData () && !hdr.GetAddr1 ().IsBroadcast () && m_mpduAggregator != 0) { - m_txParams.EnableRts (); - } - else - { - m_txParams.DisableRts (); - } - - if (!hdr->IsQosData () || hdr->GetAddr1 ().IsBroadcast ()) - { - //This is mainly encountered when a higher priority control or management frame is - //sent between A-MPDU transmissions. It avoids to unexpectedly flush the aggregate - //queue when previous RTS request has failed. - m_ampdu = false; - } - else if (hdr->IsQosData () && !m_aggregateQueue[GetTid (packet, *hdr)]->IsEmpty ()) - { - //m_aggregateQueue > 0 occurs when a RTS/CTS exchange failed before an A-MPDU transmission. - //In that case, we transmit the same A-MPDU as previously. - uint32_t sentMpdus = m_aggregateQueue[GetTid (packet, *hdr)]->GetNPackets (); - m_ampdu = true; - if (sentMpdus > 1) - { - AcIndex ac = QosUtilsMapTidToAc (GetTid (packet, *hdr)); - std::map >::const_iterator edcaIt = m_edca.find (ac); - if (edcaIt->second->GetBaBufferSize (hdr->GetAddr1 (), hdr->GetQosTid ()) > 64) - { - m_txParams.EnableExtendedCompressedBlockAck (); - } - else - { - m_txParams.EnableCompressedBlockAck (); - } - } - else if (hdr->IsQosData ()) - { - //VHT/HE single MPDUs are followed by normal ACKs - m_txParams.EnableAck (); - } - std::vector> mpduList; - for (uint32_t i = 0; i < sentMpdus; i++) - { - Ptr newPacket; - newPacket = Create (m_txPackets[GetTid (packet, *hdr)].at (i)->GetPacket (), - m_txPackets[GetTid (packet, *hdr)].at (i)->GetHeader ()); - mpduList.push_back (newPacket); - } - m_currentPacket = Create (mpduList); - m_currentTxVector = GetDataTxVector (packet, hdr); - } - else if (m_mpduAggregator != 0) - { - //Perform MPDU aggregation if possible - uint8_t tid = GetTid (packet, *hdr); + /* We get here if the received packet is any of the following: + * (a) a QoS data frame + * (b) a BlockAckRequest + */ + uint8_t tid = GetTid (mpdu->GetPacket (), hdr); Ptr qosTxop = m_edca.find (QosUtilsMapTidToAc (tid))->second; std::vector> mpduList; - mpduList = m_mpduAggregator->GetNextAmpdu (Create (packet, *hdr), - m_currentTxVector); + // if a TXOP limit exists, compute the remaining TXOP duration + Time txopLimit = Seconds (0); + if (m_currentTxop->GetTxopLimit ().IsStrictlyPositive ()) + { + txopLimit = m_currentTxop->GetTxopRemaining () - CalculateOverheadTxTime (mpdu, m_txParams); + NS_ASSERT (txopLimit.IsPositive ()); + } + + //Perform MPDU aggregation if possible + mpduList = m_mpduAggregator->GetNextAmpdu (mpdu, m_currentTxVector, txopLimit); if (mpduList.size () > 1) { - m_ampdu = true; - - for (auto& mpdu : mpduList) - { - // Store the MPDU in the aggregate queue - NS_LOG_DEBUG ("Adding packet with sequence number " << mpdu->GetHeader ().GetSequenceNumber () - << " to A-MPDU, packet size = " << mpdu->GetSize () - << ", A-MPDU size = " << m_currentPacket->GetSize ()); - m_aggregateQueue[tid]->Enqueue (mpdu); - - // Complete the processing of the MPDU - if (mpdu->GetHeader ().IsQosData ()) - { - if (!m_txParams.MustSendRts ()) - { - qosTxop->CompleteMpduTx (mpdu); - } - else - { - InsertInTxQueue (mpdu, tid); - } - } - } - m_currentPacket = Create (mpduList); - // assume implicit block ack for now - qosTxop->CompleteAmpduTransfer (hdr->GetAddr1 (), tid); - - if (qosTxop->GetBaBufferSize (hdr->GetAddr1 (), hdr->GetQosTid ()) > 64) + if (qosTxop->GetBaBufferSize (hdr.GetAddr1 (), tid) > 64) { m_txParams.EnableExtendedCompressedBlockAck (); } @@ -636,40 +566,21 @@ MacLow::StartTransmission (Ptr packet, } NS_LOG_DEBUG ("tx unicast A-MPDU containing " << mpduList.size () << " MPDUs"); - qosTxop->SetAmpduExist (hdr->GetAddr1 (), true); + qosTxop->SetAmpduExist (hdr.GetAddr1 (), true); } else if (m_currentTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_VHT || m_currentTxVector.GetMode ().GetModulationClass () == WIFI_MOD_CLASS_HE) { // VHT/HE single MPDU - m_ampdu = true; - Ptr mpdu = Create (packet, *hdr); - mpdu->GetHeader ().SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); m_currentPacket = Create (mpdu, true); - - // Store the MPDU in the aggregate queue - NS_LOG_DEBUG ("Adding packet with sequence number " << mpdu->GetHeader ().GetSequenceNumber () - << " to S-MPDU, packet size = " << mpdu->GetSize () - << ", S-MPDU size = " << m_currentPacket->GetSize ()); - m_aggregateQueue[tid]->Enqueue (mpdu); - - // Complete the processing of the MPDU - if (m_txParams.MustSendRts ()) - { - InsertInTxQueue (mpdu, tid); - } - - if (qosTxop->GetBaAgreementEstablished (hdr->GetAddr1 (), tid)) - { - qosTxop->CompleteAmpduTransfer (hdr->GetAddr1 (), tid); - } + m_currentPacket->SetAckPolicyForTid (tid, WifiMacHeader::NORMAL_ACK); //VHT/HE single MPDUs are followed by normal ACKs m_txParams.EnableAck (); - NS_LOG_DEBUG ("tx unicast S-MPDU with sequence number " << hdr->GetSequenceNumber ()); - qosTxop->SetAmpduExist (hdr->GetAddr1 (), true); + NS_LOG_DEBUG ("tx unicast S-MPDU with sequence number " << hdr.GetSequenceNumber ()); + qosTxop->SetAmpduExist (hdr.GetAddr1 (), true); } - else if (hdr->IsQosData () && !hdr->IsQosBlockAck () && !hdr->GetAddr1 ().IsGroup ()) + else if (hdr.IsQosData () && !hdr.IsQosBlockAck () && !hdr.GetAddr1 ().IsGroup ()) { m_txParams.EnableAck (); } @@ -698,18 +609,10 @@ MacLow::StartTransmission (Ptr packet, NS_ASSERT (m_phy->IsStateTx () || m_phy->IsStateOff ()); } -bool -MacLow::NeedRts (void) const -{ - WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket->GetPayload (0), &m_currentPacket->GetHeader (0)); - return m_stationManager->NeedRts (m_currentPacket->GetAddr1 (), &m_currentPacket->GetHeader (0), - m_currentPacket->GetPayload (0), dataTxVector); -} - bool MacLow::NeedCtsToSelf (void) const { - WifiTxVector dataTxVector = GetDataTxVector (m_currentPacket->GetPayload (0), &m_currentPacket->GetHeader (0)); + WifiTxVector dataTxVector = GetDataTxVector (*m_currentPacket->begin ()); return m_stationManager->NeedCtsToSelf (dataTxVector); } @@ -884,8 +787,7 @@ MacLow::ReceiveOk (Ptr packet, double rxSnr, WifiTxVector txVector, bool { m_currentTxop->GotAck (); } - if (m_txParams.HasNextPacket () && (!m_currentPacket->GetHeader (0).IsQosData () || - m_currentTxop->GetTxopLimit ().IsZero () || m_currentTxop->HasTxop ())) + if (m_txParams.HasNextPacket ()) { if (m_stationManager->GetRifsPermitted ()) { @@ -896,7 +798,8 @@ MacLow::ReceiveOk (Ptr packet, double rxSnr, WifiTxVector txVector, bool m_waitIfsEvent = Simulator::Schedule (GetSifs (), &MacLow::WaitIfsAfterEndTxFragment, this); } } - else if (m_currentPacket->GetHeader (0).IsQosData () && m_currentTxop->HasTxop ()) + else if (m_currentPacket->GetHeader (0).IsQosData () && m_currentTxop->IsQosTxop () && + m_currentTxop->GetTxopLimit ().IsStrictlyPositive () && m_currentTxop->GetTxopRemaining () > GetSifs ()) { if (m_stationManager->GetRifsPermitted ()) { @@ -907,27 +810,26 @@ MacLow::ReceiveOk (Ptr packet, double rxSnr, WifiTxVector txVector, bool m_waitIfsEvent = Simulator::Schedule (GetSifs (), &MacLow::WaitIfsAfterEndTxPacket, this); } } - m_ampdu = false; - if (m_currentPacket->GetHeader (0).IsQosData ()) + else if (m_currentTxop->IsQosTxop ()) { - FlushAggregateQueue (m_currentPacket->GetHeader (0).GetQosTid ()); + m_currentTxop->TerminateTxop (); } } else if (hdr.IsBlockAck () && hdr.GetAddr1 () == m_self - && (m_txParams.MustWaitBasicBlockAck () || m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ()) + && m_txParams.MustWaitBlockAck () && m_blockAckTimeoutEvent.IsRunning ()) { NS_LOG_DEBUG ("got block ack from " << hdr.GetAddr2 ()); SnrTag tag; packet->RemovePacketTag (tag); - FlushAggregateQueue (GetTid (packet, hdr)); CtrlBAckResponseHeader blockAck; packet->RemoveHeader (blockAck); m_blockAckTimeoutEvent.Cancel (); NotifyAckTimeoutResetNow (); m_currentTxop->GotBlockAck (&blockAck, hdr.GetAddr2 (), rxSnr, txVector.GetMode (), tag.Get ()); - m_ampdu = false; - if (m_currentPacket->GetHeader (0).IsQosData () && m_currentTxop->HasTxop ()) + // start next packet if TXOP remains, otherwise contend for accessing the channel again + if (m_currentTxop->IsQosTxop () && m_currentTxop->GetTxopLimit ().IsStrictlyPositive () + && m_currentTxop->GetTxopRemaining () > GetSifs ()) { if (m_stationManager->GetRifsPermitted ()) { @@ -938,6 +840,10 @@ MacLow::ReceiveOk (Ptr packet, double rxSnr, WifiTxVector txVector, bool m_waitIfsEvent = Simulator::Schedule (GetSifs (), &MacLow::WaitIfsAfterEndTxPacket, this); } } + else if (m_currentTxop->IsQosTxop ()) + { + m_currentTxop->TerminateTxop (); + } } else if (hdr.IsBlockAckReq () && hdr.GetAddr1 () == m_self) { @@ -1231,17 +1137,17 @@ MacLow::GetCtsDuration (WifiTxVector ctsTxVector) const } WifiTxVector -MacLow::GetRtsTxVector (Ptr packet, const WifiMacHeader *hdr) const +MacLow::GetRtsTxVector (Ptr item) const { - Mac48Address to = hdr->GetAddr1 (); - return m_stationManager->GetRtsTxVector (to, hdr, packet); + Mac48Address to = item->GetHeader ().GetAddr1 (); + return m_stationManager->GetRtsTxVector (to, &item->GetHeader (), item->GetPacket ()); } WifiTxVector -MacLow::GetDataTxVector (Ptr packet, const WifiMacHeader *hdr) const +MacLow::GetDataTxVector (Ptr item) const { - Mac48Address to = hdr->GetAddr1 (); - return m_stationManager->GetDataTxVector (to, hdr, packet); + Mac48Address to = item->GetHeader ().GetAddr1 (); + return m_stationManager->GetDataTxVector (to, &item->GetHeader (), item->GetPacket ()); } WifiMode @@ -1452,31 +1358,47 @@ MacLow::CalculateOverallTxTime (Ptr packet, const MacLowTransmissionParameters& params, uint32_t fragmentSize) const { - Time txTime = Seconds (0); - if (params.MustSendRts ()) - { - WifiTxVector rtsTxVector = GetRtsTxVector (packet, hdr); - txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, m_phy->GetFrequency ()); - txTime += GetCtsDuration (hdr->GetAddr1 (), rtsTxVector); - txTime += Time (GetSifs () * 2); - } - WifiTxVector dataTxVector = GetDataTxVector (packet, hdr); + Ptr item = Create (packet, *hdr); + Time txTime = CalculateOverheadTxTime (item, params); uint32_t dataSize; if (fragmentSize > 0) { Ptr fragment = Create (fragmentSize); - dataSize = GetSize (fragment, hdr, m_ampdu); + dataSize = GetSize (fragment, hdr, m_currentPacket && m_currentPacket->IsAggregate ()); } else { - dataSize = GetSize (packet, hdr, m_ampdu); + dataSize = GetSize (packet, hdr, m_currentPacket && m_currentPacket->IsAggregate ()); + } + txTime += m_phy->CalculateTxDuration (dataSize, GetDataTxVector (item), m_phy->GetFrequency ()); + return txTime; +} + +Time +MacLow::CalculateOverheadTxTime (Ptr item, + const MacLowTransmissionParameters& params) const +{ + Time txTime = Seconds (0); + if (params.MustSendRts ()) + { + WifiTxVector rtsTxVector = GetRtsTxVector (item); + txTime += m_phy->CalculateTxDuration (GetRtsSize (), rtsTxVector, m_phy->GetFrequency ()); + txTime += GetCtsDuration (item->GetHeader ().GetAddr1 (), rtsTxVector); + txTime += Time (GetSifs () * 2); } - txTime += m_phy->CalculateTxDuration (dataSize, dataTxVector, m_phy->GetFrequency ()); - txTime += GetSifs (); if (params.MustWaitNormalAck ()) { - txTime += GetAckDuration (hdr->GetAddr1 (), dataTxVector); + txTime += GetSifs (); + txTime += GetAckDuration (item->GetHeader ().GetAddr1 (), GetDataTxVector (item)); } + else if (params.MustWaitBlockAck ()) + { + txTime += GetSifs (); + WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (item->GetHeader ().GetAddr2 (), + GetDataTxVector (item).GetMode ()); + txTime += GetBlockAckDuration (blockAckReqTxVector, params.GetBlockAckType ()); + } + return txTime; } @@ -1488,7 +1410,7 @@ MacLow::CalculateTransmissionTime (Ptr packet, Time txTime = CalculateOverallTxTime (packet, hdr, params); if (params.HasNextPacket ()) { - WifiTxVector dataTxVector = GetDataTxVector (packet, hdr); + WifiTxVector dataTxVector = GetDataTxVector (Create (packet, *hdr)); txTime += GetSifs (); txTime += m_phy->CalculateTxDuration (params.GetNextPacketSize (), dataTxVector, m_phy->GetFrequency ()); } @@ -1528,7 +1450,7 @@ MacLow::NotifyNav (Ptr packet, const WifiMacHeader &hdr) */ WifiMacHeader cts; cts.SetType (WIFI_MAC_CTL_CTS); - WifiTxVector txVector = GetRtsTxVector (packet, &hdr); + WifiTxVector txVector = GetRtsTxVector (Create (packet, hdr)); Time navCounterResetCtsMissedDelay = m_phy->CalculateTxDuration (cts.GetSerializedSize (), txVector, m_phy->GetFrequency ()) + Time (2 * GetSifs ()) + Time (2 * GetSlotTime ()); @@ -1668,6 +1590,18 @@ MacLow::ForwardDown (Ptr psdu, WifiTxVector txVector) { NS_LOG_DEBUG ("Sending A-MPDU"); } + + if (psdu->GetNMpdus () > 1) + { + for (auto& mpdu : *PeekPointer (psdu)) + { + if (mpdu->GetHeader ().IsQosData ()) + { + auto edcaIt = m_edca.find (QosUtilsMapTidToAc (mpdu->GetHeader ().GetQosTid ())); + edcaIt->second->CompleteMpduTx (mpdu); + } + } + } } m_phy->SendPacket (psdu->GetPacket (), txVector); } @@ -1699,10 +1633,17 @@ MacLow::CtsTimeout (void) /// we should restart a new cts timeout now until the expected /// end of rx if there was a rx start before now. m_stationManager->ReportRtsFailed (m_currentPacket->GetAddr1 (), &m_currentPacket->GetHeader (0)); - Ptr txop = m_currentTxop; + + Ptr qosTxop = DynamicCast (m_currentTxop); + if (qosTxop != 0) + { + qosTxop->NotifyMissedCts (std::list> (m_currentPacket->begin (), m_currentPacket->end ())); + } + else + { + m_currentTxop->MissedCts (); + } m_currentTxop = 0; - m_ampdu = false; - txop->MissedCts (); } void @@ -1715,11 +1656,6 @@ MacLow::NormalAckTimeout (void) /// end of rx if there was a rx start before now. Ptr txop = m_currentTxop; m_currentTxop = 0; - m_ampdu = false; - if (m_currentPacket->GetHeader (0).IsQosData ()) - { - FlushAggregateQueue (GetTid (m_currentPacket->GetPayload (0), m_currentPacket->GetHeader (0))); - } txop->MissedAck (); } @@ -1730,10 +1666,7 @@ MacLow::BlockAckTimeout (void) NS_LOG_DEBUG ("block ack timeout"); Ptr txop = m_currentTxop; m_currentTxop = 0; - m_ampdu = false; - uint8_t tid = GetTid (m_currentPacket->GetPayload (0), m_currentPacket->GetHeader (0)); txop->MissedBlockAck (m_currentPacket->GetNMpdus ()); - FlushAggregateQueue (tid); } void @@ -1749,7 +1682,7 @@ MacLow::SendRtsForPacket (void) rts.SetNoMoreFragments (); rts.SetAddr1 (m_currentPacket->GetAddr1 ()); rts.SetAddr2 (m_self); - WifiTxVector rtsTxVector = GetRtsTxVector (m_currentPacket->GetPayload (0), &m_currentPacket->GetHeader (0)); + WifiTxVector rtsTxVector = GetRtsTxVector (*m_currentPacket->begin ()); Time duration = Seconds (0); duration += GetSifs (); @@ -1758,22 +1691,10 @@ MacLow::SendRtsForPacket (void) duration += m_phy->CalculateTxDuration (m_currentPacket->GetSize (), m_currentTxVector, m_phy->GetFrequency ()); duration += GetSifs (); - if (m_txParams.MustWaitBasicBlockAck ()) + if (m_txParams.MustWaitBlockAck ()) { WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ()); - duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK); - } - else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ()); - if (m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - duration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK); - } - else - { - duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK); - } + duration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ()); } else if (m_txParams.MustWaitNormalAck ()) { @@ -1812,14 +1733,16 @@ MacLow::StartDataTxTimers (WifiTxVector dataTxVector) NotifyAckTimeoutStartNow (timerDelay); m_normalAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::NormalAckTimeout, this); } - else if (m_txParams.MustWaitBasicBlockAck ()) + else if (m_txParams.MustWaitBlockAck () && m_txParams.GetBlockAckType () == BlockAckType::BASIC_BLOCK_ACK) { Time timerDelay = txDuration + GetBasicBlockAckTimeout (); NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ()); NotifyAckTimeoutStartNow (timerDelay); m_blockAckTimeoutEvent = Simulator::Schedule (timerDelay, &MacLow::BlockAckTimeout, this); } - else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ()) + else if (m_txParams.MustWaitBlockAck () && + (m_txParams.GetBlockAckType () == BlockAckType::COMPRESSED_BLOCK_ACK + || m_txParams.GetBlockAckType () == BlockAckType::EXTENDED_COMPRESSED_BLOCK_ACK)) { Time timerDelay = txDuration + GetCompressedBlockAckTimeout (); NS_ASSERT (m_blockAckTimeoutEvent.IsExpired ()); @@ -1840,9 +1763,9 @@ MacLow::StartDataTxTimers (WifiTxVector dataTxVector) } m_waitIfsEvent = Simulator::Schedule (delay, &MacLow::WaitIfsAfterEndTxFragment, this); } - else if (m_currentPacket->GetHeader (0).IsQosData () && m_currentPacket->GetHeader (0).IsQosBlockAck () - && m_currentTxop->HasTxop ()) - { + else if (m_currentPacket->GetHeader (0).IsQosData () && m_currentTxop->IsQosTxop () && + m_currentTxop->GetTxopLimit ().IsStrictlyPositive () && m_currentTxop->GetTxopRemaining () > GetSifs ()) + { Time delay = txDuration; if (m_stationManager->GetRifsPermitted ()) { @@ -1871,26 +1794,12 @@ MacLow::SendDataPacket (void) if (!IsCfPeriod ()) { Time duration = Seconds (0); - if (m_txParams.MustWaitBasicBlockAck ()) + if (m_txParams.MustWaitBlockAck ()) { duration += GetSifs (); WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ()); - duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK); - } - else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - duration += GetSifs (); - WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), - m_currentTxVector.GetMode ()); - if (m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - duration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK); - } - else - { - duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK); - } + duration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ()); } else if (m_txParams.MustWaitNormalAck ()) { @@ -1929,11 +1838,7 @@ MacLow::SendDataPacket (void) } } - if (m_ampdu) - { - NS_ASSERT (m_currentPacket->GetHeader (0).IsQosData ()); - } - else + if (!m_currentPacket->IsAggregate ()) { if (m_cfAckInfo.appendCfAck) { @@ -1966,7 +1871,7 @@ MacLow::SendDataPacket (void) //This should be later changed, at the latest once HCCA is implemented for HT/VHT/HE stations. WifiMacHeader tmpHdr = m_currentPacket->GetHeader (0); tmpHdr.SetAddr1 (m_cfAckInfo.address); - WifiTxVector tmpTxVector = GetDataTxVector (m_currentPacket->GetPayload (0), &tmpHdr); + WifiTxVector tmpTxVector = GetDataTxVector (Create (m_currentPacket->GetPayload (0), tmpHdr)); if (tmpTxVector.GetMode ().GetDataRate (tmpTxVector) < m_currentTxVector.GetMode ().GetDataRate (m_currentTxVector)) { m_currentTxVector = tmpTxVector; @@ -1995,32 +1900,18 @@ MacLow::SendCtsToSelf (void) cts.SetNoRetry (); cts.SetAddr1 (m_self); - WifiTxVector ctsTxVector = GetRtsTxVector (m_currentPacket->GetPayload (0), &m_currentPacket->GetHeader (0)); + WifiTxVector ctsTxVector = GetRtsTxVector (*m_currentPacket->begin ()); Time duration = Seconds (0); duration += GetSifs (); duration += m_phy->CalculateTxDuration (m_currentPacket->GetSize (), m_currentTxVector, m_phy->GetFrequency ()); - if (m_txParams.MustWaitBasicBlockAck ()) + if (m_txParams.MustWaitBlockAck ()) { duration += GetSifs (); WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ()); - duration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK); - } - else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - duration += GetSifs (); - WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), - m_currentTxVector.GetMode ()); - if (m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - duration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK); - } - else - { - duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK); - } + duration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ()); } else if (m_txParams.MustWaitNormalAck ()) { @@ -2032,19 +1923,12 @@ MacLow::SendCtsToSelf (void) duration += GetSifs (); duration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), m_currentTxVector, m_phy->GetFrequency ()); - if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ()) + if (m_txParams.MustWaitBlockAck ()) { duration += GetSifs (); WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ()); - if (m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - duration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK); - } - else - { - duration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK); - } + duration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ()); } else if (m_txParams.MustWaitNormalAck ()) { @@ -2105,40 +1989,13 @@ MacLow::SendDataAfterCts (Time duration) */ NS_ASSERT (m_currentPacket != 0); - if (m_currentPacket->GetHeader (0).IsQosData ()) - { - uint8_t tid = GetTid (m_currentPacket->GetPayload (0), m_currentPacket->GetHeader (0)); - if (!m_aggregateQueue[tid]->IsEmpty ()) - { - for (std::vector>::size_type i = 0; i != m_txPackets[tid].size (); i++) - { - AcIndex ac = QosUtilsMapTidToAc (tid); - std::map >::const_iterator edcaIt = m_edca.find (ac); - edcaIt->second->CompleteMpduTx (m_txPackets[tid].at (i)); - } - } - } - StartDataTxTimers (m_currentTxVector); Time newDuration = Seconds (0); - if (m_txParams.MustWaitBasicBlockAck ()) + if (m_txParams.MustWaitBlockAck ()) { newDuration += GetSifs (); WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ()); - newDuration += GetBlockAckDuration (blockAckReqTxVector, BASIC_BLOCK_ACK); - } - else if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - newDuration += GetSifs (); - WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ()); - if (m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - newDuration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK); - } - else - { - newDuration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK); - } + newDuration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ()); } else if (m_txParams.MustWaitNormalAck ()) { @@ -2156,18 +2013,11 @@ MacLow::SendDataAfterCts (Time duration) newDuration += GetSifs (); } newDuration += m_phy->CalculateTxDuration (m_txParams.GetNextPacketSize (), m_currentTxVector, m_phy->GetFrequency ()); - if (m_txParams.MustWaitCompressedBlockAck () || m_txParams.MustWaitExtendedCompressedBlockAck ()) + if (m_txParams.MustWaitBlockAck ()) { newDuration += GetSifs (); WifiTxVector blockAckReqTxVector = GetBlockAckTxVector (m_currentPacket->GetAddr2 (), m_currentTxVector.GetMode ()); - if (m_txParams.MustWaitExtendedCompressedBlockAck ()) - { - newDuration += GetBlockAckDuration (blockAckReqTxVector, EXTENDED_COMPRESSED_BLOCK_ACK); - } - else - { - newDuration += GetBlockAckDuration (blockAckReqTxVector, COMPRESSED_BLOCK_ACK); - } + newDuration += GetBlockAckDuration (blockAckReqTxVector, m_txParams.GetBlockAckType ()); } else if (m_txParams.MustWaitNormalAck ()) { @@ -2183,10 +2033,6 @@ MacLow::SendDataAfterCts (Time duration) duration = std::max (duration, newDuration); NS_ASSERT (duration.IsPositive ()); m_currentPacket->SetDuration (duration); - if (m_ampdu) - { - NS_ASSERT (m_currentPacket->GetHeader (0).IsQosData ()); - } ForwardDown (m_currentPacket, m_currentTxVector); } @@ -2753,25 +2599,6 @@ MacLow::DeaggregateAmpduAndReceive (Ptr aggregatedPacket, double rxSnr, } } -void -MacLow::FlushAggregateQueue (uint8_t tid) -{ - NS_LOG_FUNCTION (this << +tid); - if (!m_aggregateQueue[tid]->IsEmpty ()) - { - NS_LOG_DEBUG ("Flush aggregate queue"); - m_aggregateQueue[tid]->Flush (); - } - m_txPackets[tid].clear (); -} - -void -MacLow::InsertInTxQueue (Ptr mpdu, uint8_t tid) -{ - NS_LOG_FUNCTION (this); - m_txPackets[tid].push_back (mpdu); -} - Time MacLow::GetRemainingCfpDuration (void) const { diff --git a/src/wifi/model/mac-low.h b/src/wifi/model/mac-low.h index f64476a4d..3b22b1355 100644 --- a/src/wifi/model/mac-low.h +++ b/src/wifi/model/mac-low.h @@ -35,10 +35,6 @@ #include "block-ack-type.h" #include "wifi-mpdu-type.h" -class TwoLevelAggregationTest; -class AmpduAggregationTest; -class HeAggregationTest; - namespace ns3 { class WifiMac; @@ -63,10 +59,6 @@ class MpduAggregator; class MacLow : public Object { public: - /// Allow test cases to access private members - friend class ::TwoLevelAggregationTest; - friend class ::AmpduAggregationTest; - friend class ::HeAggregationTest; /** * typedef for a callback for MacLowRx @@ -304,7 +296,7 @@ public: * \param fragmentSize the packet fragment size (if fragmentation is used) * \return the transmission time that includes the time for the next packet transmission * - * This transmission time includes the time required for + * This transmission time does not include the time required for * the next packet transmission if one was selected. */ Time CalculateOverallTxTime (Ptr packet, @@ -313,16 +305,25 @@ public: uint32_t fragmentSize = 0) const; /** - * \param packet packet to send - * \param hdr 802.11 header for packet to send + * \param item packet to send (does not include the 802.11 MAC header and checksum) + * \param params transmission parameters of packet. + * + * This transmission time does not include the time required to transmit the frame. + * It only includes the time for the RTS/CTS exchange (if any) and for the Ack + * frame (if any). + */ + Time CalculateOverheadTxTime (Ptr item, + const MacLowTransmissionParameters& params) const; + + /** + * \param mpdu packet to send * \param parameters the transmission parameters to use for this packet. * \param txop pointer to the calling Txop. * * Start the transmission of the input packet and notify the listener * of transmission events. */ - virtual void StartTransmission (Ptr packet, - const WifiMacHeader* hdr, + virtual void StartTransmission (Ptr mpdu, MacLowTransmissionParameters parameters, Ptr txop); @@ -409,24 +410,16 @@ public: */ void DeaggregateAmpduAndReceive (Ptr aggregatedPacket, double rxSnr, WifiTxVector txVector, std::vector statusPerMpdu); - /** - * - * This function is called to flush the aggregate queue, which is used for A-MPDU - * \param tid the Traffic ID - * - */ - void FlushAggregateQueue (uint8_t tid); /** * Return a TXVECTOR for the DATA frame given the destination. * The function consults WifiRemoteStationManager, which controls the rate * to different destinations. * - * \param packet the packet being asked for TXVECTOR - * \param hdr the WifiMacHeader - * \return TXVECTOR for the given packet + * \param item the item being asked for TXVECTOR + * \return TXVECTOR for the given item */ - virtual WifiTxVector GetDataTxVector (Ptr packet, const WifiMacHeader *hdr) const; + virtual WifiTxVector GetDataTxVector (Ptr item) const; /** * Start NAV with the given duration. * @@ -493,11 +486,10 @@ private: * The function consults WifiRemoteStationManager, which controls the rate * to different destinations. * - * \param packet the packet being asked for RTS TXVECTOR - * \param hdr the WifiMacHeader - * \return TXVECTOR for the RTS of the given packet + * \param item the item being asked for RTS TXVECTOR + * \return TXVECTOR for the RTS of the given item */ - WifiTxVector GetRtsTxVector (Ptr packet, const WifiMacHeader *hdr) const; + WifiTxVector GetRtsTxVector (Ptr item) const; /** * Return a TXVECTOR for the CTS frame given the destination and the mode of the RTS * used by the sender. @@ -602,13 +594,6 @@ private: * \return the time required to transmit the Block ACK (including preamble and FCS) */ Time GetBlockAckDuration (WifiTxVector blockAckReqTxVector, BlockAckType type) const; - /** - * Check if the current packet should be sent with a RTS protection. - * - * \return true if RTS protection should be used, - * false otherwise - */ - bool NeedRts (void) const; /** * Check if CTS-to-self mechanism should be used for the current packet. * @@ -845,14 +830,6 @@ private: * \param phy the WifiPhy this MacLow is connected to */ void RemovePhyMacLowListener (Ptr phy); - /** - * Insert in a temporary queue. - * It is only used with a RTS/CTS exchange for an A-MPDU transmission. - * - * \param mpdu MPDU to be inserted in the A-MPDU tx queue - * \param tid the Traffic ID of the MPDU to be inserted in the A-MPDU tx queue - */ - void InsertInTxQueue (Ptr mpdu, uint8_t tid); Ptr m_phy; //!< Pointer to WifiPhy (actually send/receives frames) Ptr m_mac; //!< Pointer to WifiMac (to fetch configuration) @@ -917,7 +894,6 @@ private: Time m_cfpForeshortening; //!< The delay the current CF period should be foreshortened bool m_promisc; //!< Flag if the device is operating in promiscuous mode - bool m_ampdu; //!< Flag if the current transmission involves an A-MPDU class PhyMacLowListener * m_phyMacLowListener; //!< Listener needed to monitor when a channel switching occurs. @@ -943,8 +919,6 @@ private: QueueEdcas m_edca; //!< EDCA queues bool m_ctsToSelfSupported; //!< Flag whether CTS-to-self is supported - Ptr m_aggregateQueue[8]; //!< Queues per TID used for MPDU aggregation - std::vector> m_txPackets[8]; //!< Contain temporary items to be sent with the next A-MPDU transmission for a given TID, once RTS/CTS exchange has succeeded. WifiTxVector m_currentTxVector; //!< TXVECTOR used for the current packet transmission CfAckInfo m_cfAckInfo; //!< Info about piggyback ACKs used in PCF diff --git a/src/wifi/model/mpdu-aggregator.cc b/src/wifi/model/mpdu-aggregator.cc index 621709681..0ebde50f1 100644 --- a/src/wifi/model/mpdu-aggregator.cc +++ b/src/wifi/model/mpdu-aggregator.cc @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Ghada Badawy + * Stefano Avallone */ #include "ns3/log.h" @@ -317,6 +318,7 @@ std::vector> MpduAggregator::GetNextAmpdu (Ptr mpdu, WifiTxVector txVector, Time ppduDurationLimit) const { + NS_LOG_FUNCTION (this << *mpdu << ppduDurationLimit); std::vector> mpduList; Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); @@ -339,167 +341,58 @@ MpduAggregator::GetNextAmpdu (Ptr mpdu, WifiTxVector txV if (edcaIt->second->GetBaAgreementEstablished (recipient, tid)) { /* here is performed mpdu aggregation */ - uint16_t startingSequenceNumber = 0; - uint16_t currentSequenceNumber = 0; - uint8_t qosPolicy = 0; - bool retry = false; - Ptr nextMpdu = mpdu; - uint16_t nMpdus = 0; // number of aggregated MPDUs + uint16_t startingSequenceNumber = edcaIt->second->GetBaStartingSequence (recipient, tid); + Ptr nextMpdu; uint16_t maxMpdus = edcaIt->second->GetBaBufferSize (recipient, tid); uint32_t currentAmpduSize = 0; - Ptr queue = edcaIt->second->GetWifiMacQueue (); - Ptr phy = edcaIt->second->GetLow ()->GetPhy (); - // Get the maximum PPDU Duration based on the preamble type. It must be a - // non null value because aggregation is available for HT, VHT and HE, which - // also provide a limit on the maximum PPDU duration - Time maxPpduDuration = GetPpduMaxTime (txVector.GetPreambleType ()); - NS_ASSERT (maxPpduDuration.IsStrictlyPositive ()); - - // the limit on the PPDU duration is the minimum between the maximum PPDU - // duration (depending on the PPDU format) and the additional limit provided - // by the caller (if non-zero) - if (ppduDurationLimit.IsStrictlyPositive ()) + // check if the received MPDU meets the size and duration constraints + if (edcaIt->second->IsWithinSizeAndTimeLimits (mpdu, txVector, 0, ppduDurationLimit)) { - maxPpduDuration = std::min (maxPpduDuration, ppduDurationLimit); + // mpdu can be aggregated + nextMpdu = Copy (mpdu); } while (nextMpdu != 0) { - /* nextMpdu may be any of the following: - * (a) an A-MSDU (with all the constituent MSDUs dequeued from - * the EDCA queue) - * (b) an MSDU dequeued (1st iteration) or peeked (other iterations) - * from the EDCA queue - * (c) a retransmitted MSDU or A-MSDU dequeued (1st iteration) or - * peeked (other iterations) from the BA Manager queue - * (d) a control or management frame (only 1st iteration, for now) - */ + /* if we are here, nextMpdu can be aggregated to the A-MPDU. + * nextMpdu may be any of the following: + * (a) an A-MSDU (with all the constituent MSDUs dequeued from + * the EDCA queue) + * (b) an MSDU dequeued from the EDCA queue + * (c) a retransmitted MSDU or A-MSDU dequeued from the BA Manager queue + * (d) an MPDU that was aggregated in an A-MPDU which was not + * transmitted (e.g., because the RTS/CTS exchange failed) + */ - // Check if aggregating nextMpdu violates the constraints on the - // maximum A-MPDU size or on the maximum PPDU duration. This is - // guaranteed by MsduAggregator::Aggregate in the case of (a) + currentAmpduSize = GetSizeIfAggregated (nextMpdu->GetSize (), currentAmpduSize); - uint32_t ampduSize = GetSizeIfAggregated (nextMpdu->GetSize (), currentAmpduSize); + NS_LOG_DEBUG ("Adding packet with sequence number " << nextMpdu->GetHeader ().GetSequenceNumber () + << " to A-MPDU, packet size = " << nextMpdu->GetSize () + << ", A-MPDU size = " << currentAmpduSize); - if (ampduSize > maxAmpduSize || - phy->CalculateTxDuration (ampduSize, txVector, phy->GetFrequency ()) > maxPpduDuration) - { - NS_LOG_DEBUG ("No other MPDU can be aggregated: " << (ampduSize == 0 ? "size" : "time") - << " limit exceeded"); - break; - } + // Always use the Normal Ack policy (Implicit Block Ack), for now + nextMpdu->GetHeader ().SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); - // nextMpdu can be aggregated - nMpdus++; - currentAmpduSize = ampduSize; - - // Update the header of nextMpdu in case it is not a retransmitted packet - WifiMacHeader nextHeader = nextMpdu->GetHeader (); - - if (nMpdus == 1) // first MPDU - { - if (!mpdu->GetHeader ().IsBlockAckReq ()) - { - if (!mpdu->GetHeader ().IsBlockAck ()) - { - startingSequenceNumber = mpdu->GetHeader ().GetSequenceNumber (); - nextHeader.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); - } - else - { - NS_FATAL_ERROR ("BlockAck is not handled"); - } - - currentSequenceNumber = mpdu->GetHeader ().GetSequenceNumber (); - } - else - { - qosPolicy = 3; //if the last subframe is block ack req then set ack policy of all frames to blockack - CtrlBAckRequestHeader blockAckReq; - mpdu->GetPacket ()->PeekHeader (blockAckReq); - startingSequenceNumber = blockAckReq.GetStartingSequence (); - } - /// \todo We should also handle Ack and BlockAck - } - else if (retry == false) - { - currentSequenceNumber = edcaIt->second->GetNextSequenceNumberFor (&nextHeader); - nextHeader.SetSequenceNumber (currentSequenceNumber); - nextHeader.SetFragmentNumber (0); - nextHeader.SetNoMoreFragments (); - nextHeader.SetNoRetry (); - } - - if (qosPolicy == 0) - { - nextHeader.SetQosAckPolicy (WifiMacHeader::NORMAL_ACK); - } - else - { - nextHeader.SetQosAckPolicy (WifiMacHeader::BLOCK_ACK); - } - - mpduList.push_back (Create (nextMpdu->GetPacket (), nextHeader, - nextMpdu->GetTimeStamp ())); - - // Except for the first iteration, complete the processing of the - // current MPDU, which includes removal from the respective queue - // (needed for cases (b) and (c) because the packet was just peeked) - if (nMpdus >= 2 && nextHeader.IsQosData ()) - { - if (retry) - { - edcaIt->second->RemoveRetransmitPacket (tid, recipient, - nextHeader.GetSequenceNumber ()); - } - else if (nextHeader.IsQosData () && !nextHeader.IsQosAmsdu ()) - { - queue->Remove (nextMpdu->GetPacket ()); - } - } + mpduList.push_back (nextMpdu); // If allowed by the BA agreement, get the next MPDU nextMpdu = 0; - if ((nMpdus == 1 || retry) // check retransmit in the 1st iteration or if retry is true - && (nextMpdu = edcaIt->second->PeekNextRetransmitPacket (tid, recipient)) != 0) + Ptr peekedMpdu; + peekedMpdu = edcaIt->second->PeekNextFrame (tid, recipient); + if (peekedMpdu != 0) { - retry = true; - currentSequenceNumber = nextMpdu->GetHeader ().GetSequenceNumber (); + uint16_t currentSequenceNumber = peekedMpdu->GetHeader ().GetSequenceNumber (); - if (!IsInWindow (currentSequenceNumber, startingSequenceNumber, maxMpdus)) + if (IsInWindow (currentSequenceNumber, startingSequenceNumber, maxMpdus)) { - break; - } - } - else - { - retry = false; - nextMpdu = queue->PeekByTidAndAddress (tid, recipient); - - if (nextMpdu) - { - currentSequenceNumber = edcaIt->second->PeekNextSequenceNumberFor (&nextMpdu->GetHeader ()); - - if (!IsInWindow (currentSequenceNumber, startingSequenceNumber, maxMpdus)) - { - break; - } - - // Attempt A-MSDU aggregation - Ptr amsdu; - if (edcaIt->second->GetLow ()->GetMsduAggregator () != 0) - { - amsdu = edcaIt->second->GetLow ()->GetMsduAggregator ()->GetNextAmsdu (recipient, tid, - txVector, - currentAmpduSize, - maxPpduDuration); - if (amsdu) - { - nextMpdu = amsdu; - } - } + // dequeue the frame if constraints on size and duration limit are met. + // Note that the dequeued MPDU differs from the peeked MPDU if A-MSDU + // aggregation is performed during the dequeue + NS_LOG_DEBUG ("Trying to aggregate another MPDU"); + nextMpdu = edcaIt->second->DequeuePeekedFrame (peekedMpdu, txVector, true, + currentAmpduSize, ppduDurationLimit); } } } @@ -509,7 +402,6 @@ MpduAggregator::GetNextAmpdu (Ptr mpdu, WifiTxVector txV mpduList.clear (); } } - return mpduList; } diff --git a/src/wifi/model/msdu-aggregator.cc b/src/wifi/model/msdu-aggregator.cc index b9edc904d..af4d59ebe 100644 --- a/src/wifi/model/msdu-aggregator.cc +++ b/src/wifi/model/msdu-aggregator.cc @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Mirko Banchi + * Stefano Avallone */ #include "ns3/log.h" @@ -119,9 +120,9 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid, Ptr qosTxop = m_edca.find (QosUtilsMapTidToAc (tid))->second; Ptr queue = qosTxop->GetWifiMacQueue (); - Ptr peekedItem = queue->PeekByTidAndAddress (tid, recipient); + WifiMacQueue::ConstIterator peekedIt = queue->PeekByTidAndAddress (tid, recipient); - if (!peekedItem) + if (peekedIt == queue->end ()) { NS_LOG_DEBUG ("No packet with the given TID and address in the queue"); return 0; @@ -144,49 +145,21 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid, return 0; } - // Get the maximum size of the A-MPDU we can send to the recipient - uint32_t maxAmpduSize = 0; - Ptr mpduAggregator = qosTxop->GetLow ()->GetMpduAggregator (); - - if (mpduAggregator) - { - maxAmpduSize = mpduAggregator->GetMaxAmpduSize (recipient, tid, modulation); - } - - // If maxAmpduSize is 0, then the ampdu must be empty - NS_ASSERT (maxAmpduSize > 0 || ampduSize == 0); - - // Get the maximum PPDU Duration based on the preamble type. It must be a - // non null value because aggregation is available for HT, VHT and HE, which - // also provide a limit on the maximum PPDU duration - Time maxPpduDuration = GetPpduMaxTime (txVector.GetPreambleType ()); - NS_ASSERT (maxPpduDuration.IsStrictlyPositive ()); - - // the limit on the PPDU duration is the minimum between the maximum PPDU - // duration (depending on the PPDU format) and the additional limit provided - // by the caller (if non-zero) - if (ppduDurationLimit.IsStrictlyPositive ()) - { - maxPpduDuration = std::min (maxPpduDuration, ppduDurationLimit); - } - - Ptr phy = qosTxop->GetLow ()->GetPhy (); - NS_ASSERT (phy); Ptr amsdu = Create (); uint8_t nMsdu = 0; - WifiMacHeader header = peekedItem->GetHeader (); - Time tstamp = peekedItem->GetTimeStamp (); - // We need to keep track of the first MSDU. If it is dequeued but aggregation - // fails, we need to re-insert it in the queue - Ptr first = peekedItem; + WifiMacHeader header = (*peekedIt)->GetHeader (); + Time tstamp = (*peekedIt)->GetTimeStamp (); + // We need to keep track of the first MSDU. When it is processed, it is not known + // if aggregation will succeed or not. + WifiMacQueue::ConstIterator first = peekedIt; // TODO Add support for the Max Number Of MSDUs In A-MSDU field in the Extended // Capabilities element sent by the recipient - while (peekedItem != 0) // && nMsdu < maxNMsdus + while (peekedIt != queue->end ()) { // check if aggregating the peeked MSDU violates the A-MSDU size limit - uint16_t newAmsduSize = GetSizeIfAggregated (peekedItem->GetPacket ()->GetSize (), + uint16_t newAmsduSize = GetSizeIfAggregated ((*peekedIt)->GetPacket ()->GetSize (), amsdu->GetSize ()); if (newAmsduSize > maxAmsduSize) @@ -196,68 +169,51 @@ MsduAggregator::GetNextAmsdu (Mac48Address recipient, uint8_t tid, } // check if the A-MSDU obtained by aggregating the peeked MSDU violates - // the A-MPDU size limit and compute the PPDU payload size - uint32_t ppduPayloadSize; - - if (maxAmpduSize > 0) // A-MPDU aggregation enabled + // the A-MPDU size limit or the PPDU duration limit + if (!qosTxop->IsWithinSizeAndTimeLimits (header.GetSize () + newAmsduSize + WIFI_MAC_FCS_LENGTH, + recipient, tid, txVector, ampduSize, ppduDurationLimit)) { - ppduPayloadSize = mpduAggregator->GetSizeIfAggregated (header.GetSize () + newAmsduSize - + WIFI_MAC_FCS_LENGTH, ampduSize); - - if (ppduPayloadSize > maxAmpduSize) - { - NS_LOG_DEBUG ("No other MSDU can be aggregated: maximum A-MPDU size exceeded"); - break; - } - } - else if (modulation == WIFI_MOD_CLASS_HE || modulation == WIFI_MOD_CLASS_VHT) - { - // VHT and HE frames always use A-MPDU structure, thus take the size - // of the MPDU Delimiter (4 bytes) into account - ppduPayloadSize = 4 + header.GetSize () + newAmsduSize + WIFI_MAC_FCS_LENGTH; - } - else - { - ppduPayloadSize = header.GetSize () + newAmsduSize + WIFI_MAC_FCS_LENGTH; - } - - // check if the PPDU duration limit is exceeded - if (phy->CalculateTxDuration (ppduPayloadSize, txVector, phy->GetFrequency ()) > maxPpduDuration) - { - NS_LOG_DEBUG ("No other MSDU can be aggregated: maximum duration reached"); + NS_LOG_DEBUG ("No other MSDU can be aggregated"); break; } - // We can now safely aggregate the MSDU to the A-MSDU and remove it from the queue - Aggregate (peekedItem->GetPacket (), amsdu, + // We can now safely aggregate the MSDU to the A-MSDU + Aggregate ((*peekedIt)->GetPacket (), amsdu, qosTxop->MapSrcAddressForAggregation (header), qosTxop->MapDestAddressForAggregation (header)); - queue->Remove (peekedItem->GetPacket ()); - - nMsdu++; /* "The expiration of the A-MSDU lifetime timer occurs only when the lifetime * timer of all of the constituent MSDUs of the A-MSDU have expired" (Section * 10.12 of 802.11-2016) */ // The timestamp of the A-MSDU is the most recent among those of the MSDUs - tstamp = Max (tstamp, peekedItem->GetTimeStamp ()); + tstamp = Max (tstamp, (*peekedIt)->GetTimeStamp ()); - peekedItem = queue->PeekByTidAndAddress (tid, recipient); + // If it is the first MSDU, move to the next one + if (nMsdu == 0) + { + peekedIt++; + } + // otherwise, remove it from the queue + else + { + peekedIt = queue->Remove (peekedIt); + } + + nMsdu++; + + peekedIt = queue->PeekByTidAndAddress (tid, recipient, peekedIt); } if (nMsdu < 2) { NS_LOG_DEBUG ("Aggregation failed (could not aggregate at least two MSDUs)"); - - // re-insert the first MSDU in the queue if it was removed - if (nMsdu == 1) - { - queue->PushFront (Create (*first)); - } return 0; } + // Aggregation succeeded, we have to remove the first MSDU + queue->Remove (first); + header.SetQosAmsdu (); header.SetAddr3 (qosTxop->GetLow ()->GetBssid ()); diff --git a/src/wifi/model/originator-block-ack-agreement.cc b/src/wifi/model/originator-block-ack-agreement.cc index 440d6bf57..6a510e35f 100644 --- a/src/wifi/model/originator-block-ack-agreement.cc +++ b/src/wifi/model/originator-block-ack-agreement.cc @@ -25,9 +25,7 @@ namespace ns3 { OriginatorBlockAckAgreement::OriginatorBlockAckAgreement (Mac48Address recipient, uint8_t tid) : BlockAckAgreement (recipient, tid), - m_state (PENDING), - m_sentMpdus (0), - m_needBlockAckReq (false) + m_state (PENDING) { } @@ -39,11 +37,6 @@ void OriginatorBlockAckAgreement::SetState (State state) { m_state = state; - if (state == INACTIVE) - { - m_needBlockAckReq = false; - m_sentMpdus = 0; - } } bool @@ -58,12 +51,6 @@ OriginatorBlockAckAgreement::IsEstablished (void) const return (m_state == ESTABLISHED) ? true : false; } -bool -OriginatorBlockAckAgreement::IsInactive (void) const -{ - return (m_state == INACTIVE) ? true : false; -} - bool OriginatorBlockAckAgreement::IsRejected (void) const { @@ -82,29 +69,4 @@ OriginatorBlockAckAgreement::IsReset (void) const return (m_state == RESET) ? true : false; } -void -OriginatorBlockAckAgreement::NotifyMpduTransmission (uint16_t nextSeqNumber) -{ - NS_ASSERT (m_sentMpdus < m_bufferSize); - m_sentMpdus++; - uint16_t delta = (nextSeqNumber - m_startingSeq + 4096) % 4096; - if (delta >= m_bufferSize || m_sentMpdus == m_bufferSize) - { - m_needBlockAckReq = true; - } -} - -bool -OriginatorBlockAckAgreement::IsBlockAckRequestNeeded (void) const -{ - return m_needBlockAckReq; -} - -void -OriginatorBlockAckAgreement::CompleteExchange (void) -{ - m_needBlockAckReq = false; - m_sentMpdus = 0; -} - } //namespace ns3 diff --git a/src/wifi/model/originator-block-ack-agreement.h b/src/wifi/model/originator-block-ack-agreement.h index 2b065a0a4..d5666d880 100644 --- a/src/wifi/model/originator-block-ack-agreement.h +++ b/src/wifi/model/originator-block-ack-agreement.h @@ -31,19 +31,16 @@ namespace ns3 { * for an originator station. The state diagram is as follows: * \verbatim - -------------- - | INACTIVE | - -------------- - /------------\ send ADDBARequest ---------------- | ^ - | START |------------------>| PENDING |------- send a MPDU (normal ACK) | | receive BlockAck - \------------/ ---------------- \ retryPkts + queuePkts | | retryPkts + queuePkts - ^ receive / | \ >= | | < - | ADDBAResponse / | \ blockAckThreshold | | blockAckThreshold - | (failure) v | \ v | - | --------------- | ---------------------> ---------------- ------- receive BlockAck - | | REJECTED | | receive ADDBAResponse (success) | ESTABLISHED | | retryPkts + queuePkts - | --------------- | no --------------------> ---------------- <------- >= - | receive ^ | ADDBAResponse / blockAckThreshold + /------------\ send ADDBARequest ---------------- + | START |------------------>| PENDING |------- + \------------/ ---------------- \ + ^ receive / | \ + | ADDBAResponse / | \ + | (failure) v | \ + | --------------- | ---------------------> ---------------- + | | REJECTED | | receive ADDBAResponse (success) | ESTABLISHED | + | --------------- | no --------------------> ---------------- + | receive ^ | ADDBAResponse / | ADDBAResponse \ | / | (failure) \ v / | ---------------- / @@ -80,12 +77,6 @@ public: * The block ack is active and all packets relative to this agreement are transmitted * with ack policy set to block ack. * - * INACTIVE: - * In our implementation, block ack tear-down happens only if an inactivity timeout occurs - * so we could have an active block ack but a number of packets that doesn't reach the value of - * m_blockAckThreshold (see ns3::BlockAckManager). In these conditions the agreement becomes - * INACTIVE until that the number of packets reaches the value of m_blockAckThreshold again. - * * NO_REPLY * No reply after an ADDBA request. In this state the originator will send the rest of packets * in queue using normal MPDU. @@ -104,7 +95,6 @@ public: { PENDING, ESTABLISHED, - INACTIVE, NO_REPLY, RESET, REJECTED @@ -129,13 +119,6 @@ public: * false otherwise */ bool IsEstablished (void) const; - /** - * Check if the current state of this agreement is INACTIVE. - * - * \return true if the current state of this agreement is INACTIVE, - * false otherwise - */ - bool IsInactive (void) const; /** * Check if the current state of this agreement is NO_REPLY. * @@ -157,28 +140,9 @@ public: * false otherwise */ bool IsRejected (void) const; - /** - * Notifies a packet's transmission with ack policy Block Ack. - * - * \param nextSeqNumber - */ - void NotifyMpduTransmission (uint16_t nextSeqNumber); - /** - * Returns true if all packets for which a block ack was negotiated have been transmitted so - * a block ack request is needed in order to acknowledge them. - * - * \return true if all packets for which a block ack was negotiated have been transmitted, - * false otherwise - */ - bool IsBlockAckRequestNeeded (void) const; - /// Complete exchange function - void CompleteExchange (void); - private: State m_state; ///< state - uint16_t m_sentMpdus; ///< sent MPDUs - bool m_needBlockAckReq; ///< flag whether it needs a Block ACK request }; } //namespace ns3 diff --git a/src/wifi/model/qos-txop.cc b/src/wifi/model/qos-txop.cc index eb6308e73..e915927d1 100644 --- a/src/wifi/model/qos-txop.cc +++ b/src/wifi/model/qos-txop.cc @@ -18,6 +18,7 @@ * * Authors: Mathieu Lacage * Mirko Banchi + * Stefano Avallone */ #include "ns3/log.h" @@ -36,6 +37,7 @@ #include "msdu-aggregator.h" #include "mpdu-aggregator.h" #include "ctrl-headers.h" +#include "wifi-phy.h" #undef NS_LOG_APPEND_CONTEXT #define NS_LOG_APPEND_CONTEXT if (m_low != 0) { std::clog << "[mac=" << m_low->GetAddress () << "] "; } @@ -126,18 +128,18 @@ QosTxop::GetBaAgreementEstablished (Mac48Address address, uint8_t tid) const return m_baManager->ExistsAgreementInState (address, tid, OriginatorBlockAckAgreement::ESTABLISHED); } -void -QosTxop::CompleteAmpduTransfer (Mac48Address recipient, uint8_t tid) -{ - m_baManager->CompleteAmpduExchange (recipient, tid); -} - uint16_t QosTxop::GetBaBufferSize (Mac48Address address, uint8_t tid) const { return m_baManager->GetRecipientBufferSize (address, tid); } +uint16_t +QosTxop::GetBaStartingSequence (Mac48Address address, uint8_t tid) const +{ + return m_baManager->GetOriginatorStartingSequence (address, tid); +} + void QosTxop::SetWifiRemoteStationManager (const Ptr remoteManager) { @@ -171,16 +173,346 @@ QosTxop::PeekNextSequenceNumberFor (const WifiMacHeader *hdr) return m_txMiddle->PeekNextSequenceNumberFor (hdr); } -Ptr -QosTxop::PeekNextRetransmitPacket (uint8_t tid, Mac48Address recipient) +bool +QosTxop::IsQosOldPacket (Ptr mpdu) { - return m_baManager->PeekNextPacketByTidAndAddress (tid, recipient); + NS_LOG_FUNCTION (this << *mpdu); + + if (!mpdu->GetHeader ().IsQosData ()) + { + return false; + } + + Mac48Address recipient = mpdu->GetHeader ().GetAddr1 (); + uint8_t tid = mpdu->GetHeader ().GetQosTid (); + + if (!GetBaAgreementEstablished (recipient, tid)) + { + return false; + } + + if (QosUtilsIsOldPacket (GetBaStartingSequence (recipient, tid), + mpdu->GetHeader ().GetSequenceNumber ())) + { + return true; + } + return false; } -void -QosTxop::RemoveRetransmitPacket (uint8_t tid, Mac48Address recipient, uint16_t seqnumber) +Ptr +QosTxop::PeekNextFrame (uint8_t tid, Mac48Address recipient) { - m_baManager->RemovePacket (tid, recipient, seqnumber); + NS_LOG_FUNCTION (this); + WifiMacQueue::ConstIterator it = WifiMacQueue::EMPTY; + + // lambda to peek the next frame + auto peek = [this, &tid, &recipient, &it] (Ptr queue) + { + if (tid == 8 && recipient.IsBroadcast ()) // undefined TID and recipient + { + return queue->PeekFirstAvailable (m_qosBlockedDestinations, it); + } + return queue->PeekByTidAndAddress (tid, recipient, it); + }; + + // check if there is a packet in the BlockAckManager retransmit queue + it = peek (m_baManager->GetRetransmitQueue ()); + // remove old packets + while (it != m_baManager->GetRetransmitQueue ()->end () && IsQosOldPacket (*it)) + { + NS_LOG_DEBUG ("removing an old packet from BlockAckManager retransmit queue: " << **it); + it = m_baManager->GetRetransmitQueue ()->Remove (it); + it = peek (m_baManager->GetRetransmitQueue ()); + } + if (it != m_baManager->GetRetransmitQueue ()->end ()) + { + NS_LOG_DEBUG ("packet peeked from BlockAckManager retransmit queue: " << **it); + return *it; + } + + // otherwise, check if there is a packet in the EDCA queue + it = WifiMacQueue::EMPTY; + it = peek (m_queue); + if (it != m_queue->end ()) + { + // peek the next sequence number and check if it is within the transmit window + // in case of QoS data frame + uint16_t sequence = m_txMiddle->PeekNextSequenceNumberFor (&(*it)->GetHeader ()); + if ((*it)->GetHeader ().IsQosData ()) + { + Mac48Address recipient = (*it)->GetHeader ().GetAddr1 (); + uint8_t tid = (*it)->GetHeader ().GetQosTid (); + + if (GetBaAgreementEstablished (recipient, tid) + && !IsInWindow (sequence, GetBaStartingSequence (recipient, tid), GetBaBufferSize (recipient, tid))) + { + NS_LOG_DEBUG ("packet beyond the end of the current transmit window"); + return 0; + } + } + + WifiMacHeader hdr = (*it)->GetHeader (); + hdr.SetSequenceNumber (sequence); + hdr.SetFragmentNumber (0); + hdr.SetNoMoreFragments (); + hdr.SetNoRetry (); + Ptr item = Create ((*it)->GetPacket (), hdr, (*it)->GetTimeStamp ()); + NS_LOG_DEBUG ("packet peeked from EDCA queue: " << *item); + return item; + } + + return 0; +} + +bool +QosTxop::IsWithinSizeAndTimeLimits (Ptr mpdu, WifiTxVector txVector, + uint32_t ampduSize, Time ppduDurationLimit) +{ + NS_ASSERT (mpdu != 0 && mpdu->GetHeader ().IsQosData ()); + + return IsWithinSizeAndTimeLimits (mpdu->GetSize (), mpdu->GetHeader ().GetAddr1 (), + mpdu->GetHeader ().GetQosTid (), txVector, + ampduSize, ppduDurationLimit); +} + +bool +QosTxop::IsWithinSizeAndTimeLimits (uint32_t mpduSize, Mac48Address receiver, uint8_t tid, + WifiTxVector txVector, uint32_t ampduSize, Time ppduDurationLimit) +{ + NS_LOG_FUNCTION (this << mpduSize << receiver << +tid << txVector << ampduSize << ppduDurationLimit); + + WifiModulationClass modulation = txVector.GetMode ().GetModulationClass (); + + uint32_t maxAmpduSize = 0; + if (m_low->GetMpduAggregator ()) + { + maxAmpduSize = m_low->GetMpduAggregator ()->GetMaxAmpduSize (receiver, tid, modulation); + } + + // If maxAmpduSize is null, then ampduSize must be null as well + NS_ASSERT (maxAmpduSize || ampduSize == 0); + + uint32_t ppduPayloadSize = mpduSize; + + // compute the correct size for A-MPDUs and S-MPDUs + if (ampduSize > 0 || modulation == WIFI_MOD_CLASS_HE || modulation == WIFI_MOD_CLASS_VHT) + { + ppduPayloadSize = m_low->GetMpduAggregator ()->GetSizeIfAggregated (mpduSize, ampduSize); + } + + if (maxAmpduSize > 0 && ppduPayloadSize > maxAmpduSize) + { + NS_LOG_DEBUG ("the frame does not meet the constraint on max A-MPDU size"); + return false; + } + + // Get the maximum PPDU Duration based on the preamble type + Time maxPpduDuration = GetPpduMaxTime (txVector.GetPreambleType ()); + + Time txTime = m_low->GetPhy ()->CalculateTxDuration (ppduPayloadSize, txVector, + m_low->GetPhy ()->GetFrequency ()); + + if ((ppduDurationLimit.IsStrictlyPositive () && txTime > ppduDurationLimit) + || (maxPpduDuration.IsStrictlyPositive () && txTime > maxPpduDuration)) + { + NS_LOG_DEBUG ("the frame does not meet the constraint on max PPDU duration"); + return false; + } + + return true; +} + +Ptr +QosTxop::DequeuePeekedFrame (Ptr peekedItem, WifiTxVector txVector, + bool aggregate, uint32_t ampduSize, Time ppduDurationLimit) +{ + NS_LOG_FUNCTION (this << peekedItem << txVector << ampduSize << ppduDurationLimit); + NS_ASSERT (peekedItem != 0); + + // do not dequeue the frame if it is a QoS data frame that does not meet the + // max A-MPDU size limit (if applicable) or the duration limit (if applicable) + if (peekedItem->GetHeader ().IsQosData () && + !IsWithinSizeAndTimeLimits (peekedItem, txVector, ampduSize, ppduDurationLimit)) + { + return 0; + } + + Mac48Address recipient = peekedItem->GetHeader ().GetAddr1 (); + Ptr item; + Ptr testItem; + WifiMacQueue::ConstIterator testIt; + + // the packet can only have been peeked from the Block Ack manager retransmit + // queue if: + // - the peeked packet is a QoS Data frame AND + // - the peeked packet is not a broadcast frame AND + // - an agreement has been established + if (peekedItem->GetHeader ().IsQosData () && !recipient.IsBroadcast () + && GetBaAgreementEstablished (recipient, peekedItem->GetHeader ().GetQosTid ())) + { + uint8_t tid = peekedItem->GetHeader ().GetQosTid (); + testIt = m_baManager->GetRetransmitQueue ()->PeekByTidAndAddress (tid, recipient); + + if (testIt != m_baManager->GetRetransmitQueue ()->end ()) + { + testItem = *testIt; + // if not null, the test packet must equal the peeked packet + NS_ASSERT (testItem->GetPacket () == peekedItem->GetPacket ()); + // we should not be asked to dequeue an old packet + NS_ASSERT (!QosUtilsIsOldPacket (GetBaStartingSequence (recipient, tid), + testItem->GetHeader ().GetSequenceNumber ())); + item = m_baManager->GetRetransmitQueue ()->Dequeue (testIt); + NS_LOG_DEBUG ("dequeued from BA manager queue: " << *item); + return item; + } + } + + // the packet has been peeked from the EDCA queue. + uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&peekedItem->GetHeader ()); + + // If it is a QoS Data frame and it is not a broadcast frame, attempt A-MSDU + // aggregation if aggregate is true + if (peekedItem->GetHeader ().IsQosData ()) + { + uint8_t tid = peekedItem->GetHeader ().GetQosTid (); + testIt = m_queue->PeekByTidAndAddress (tid, recipient); + + NS_ASSERT (testIt != m_queue->end () && (*testIt)->GetPacket () == peekedItem->GetPacket ()); + + // check if the peeked packet is within the transmit window + if (GetBaAgreementEstablished (recipient, tid) + && !IsInWindow (sequence, GetBaStartingSequence (recipient, tid), GetBaBufferSize (recipient, tid))) + { + NS_LOG_DEBUG ("packet beyond the end of the current transmit window"); + return 0; + } + + // try A-MSDU aggregation + if (m_low->GetMsduAggregator () != 0 && !recipient.IsBroadcast () && aggregate) + { + item = m_low->GetMsduAggregator ()->GetNextAmsdu (recipient, tid, txVector, ampduSize, ppduDurationLimit); + } + + if (item != 0) + { + NS_LOG_DEBUG ("tx unicast A-MSDU"); + } + else // aggregation was not attempted or failed + { + item = m_queue->Dequeue (testIt); + } + } + else + { + // the peeked packet is a non-QoS Data frame (e.g., a DELBA Request), hence + // it was not peeked by TID, hence it must be the head of the queue + item = m_queue->DequeueFirstAvailable (m_qosBlockedDestinations); + NS_ASSERT (item != 0 && item->GetPacket () == peekedItem->GetPacket ()); + } + + // Assign a sequence number to the MSDU or A-MSDU dequeued from the EDCA queue + NS_ASSERT (item != 0); + item->GetHeader ().SetSequenceNumber (sequence); + item->GetHeader ().SetFragmentNumber (0); + item->GetHeader ().SetNoMoreFragments (); + item->GetHeader ().SetNoRetry (); + NS_LOG_DEBUG ("dequeued from EDCA queue: " << *item); + + return item; +} + +MacLowTransmissionParameters +QosTxop::GetTransmissionParameters (Ptr frame) const +{ + NS_LOG_FUNCTION (this << *frame); + + MacLowTransmissionParameters params; + Mac48Address recipient = frame->GetHeader ().GetAddr1 (); + + params.DisableNextData (); + + // broadcast frames + if (recipient.IsBroadcast ()) + { + params.DisableRts (); + params.DisableAck (); + return params; + } + if (frame->GetHeader ().IsMgt ()) + { + params.DisableRts (); + params.EnableAck (); + return params; + } + + // Enable/disable RTS + if (!frame->GetHeader ().IsBlockAckReq () + && m_stationManager->NeedRts (recipient, &frame->GetHeader (), + frame->GetPacket (), m_low->GetDataTxVector (frame)) + && !m_low->IsCfPeriod ()) + { + params.EnableRts (); + } + else + { + params.DisableRts (); + } + + uint8_t tid; + CtrlBAckRequestHeader baReqHdr; + if (frame->GetHeader ().IsBlockAckReq ()) + { + frame->GetPacket ()->PeekHeader (baReqHdr); + tid = baReqHdr.GetTidInfo (); + } + else if (frame->GetHeader ().IsQosData ()) + { + tid = frame->GetHeader ().GetQosTid (); + } + else + { + NS_ABORT_MSG ("Unexpected type of frame"); + } + + // Select ack technique. + if (frame->GetHeader ().IsQosData () && !GetBaAgreementEstablished (recipient, tid)) + { + // normal ack in case of QoS data frame with no agreement established + // TODO We should also arrive here in case of block ack request with delayed + // block ack, which is currently unsupported + params.EnableAck (); + } + else if (frame->GetHeader ().IsQosData () && frame->GetHeader ().IsQosBlockAck ()) + { + // no ack after a QoS data frame with explicit block ack policy + params.DisableAck (); + } + else + { + // assume a block ack variant. Later, if this frame is not aggregated, + // the acknowledgment type will be switched to normal ack + if (m_blockAckType == BASIC_BLOCK_ACK) + { + params.EnableBasicBlockAck (); + } + else if (m_blockAckType == COMPRESSED_BLOCK_ACK) + { + if (GetBaBufferSize (recipient, tid) > 64) + { + params.EnableExtendedCompressedBlockAck (); + } + else + { + params.EnableCompressedBlockAck (); + } + } + else if (m_blockAckType == MULTI_TID_BLOCK_ACK) + { + NS_FATAL_ERROR ("Multi-tid block ack is not supported"); + } + } + + return params; } void @@ -191,91 +523,77 @@ QosTxop::NotifyAccessGranted (void) m_accessRequested = false; m_isAccessRequestedForRts = false; m_startTxop = Simulator::Now (); + // discard the current packet if it is a QoS Data frame with expired lifetime + if (m_currentPacket != 0 && m_currentHdr.IsQosData () + && (m_currentPacketTimestamp + m_queue->GetMaxDelay () < Simulator::Now ())) + { + NS_LOG_DEBUG ("the lifetime of current packet expired"); + m_currentPacket = 0; + } if (m_currentPacket == 0) { - if (m_queue->IsEmpty () && !m_baManager->HasPackets ()) - { - NS_LOG_DEBUG ("queue is empty"); - return; - } if (m_baManager->HasBar (m_currentBar)) { SendBlockAckRequest (m_currentBar); return; } - /* check if packets need retransmission are stored in BlockAckManager */ - Ptr item = m_baManager->GetNextPacket (true); - if (item != 0) + Ptr peekedItem = PeekNextFrame (); + if (peekedItem == 0) { - m_currentPacket = item->GetPacket (); - m_currentHdr = item->GetHeader (); - m_currentPacketTimestamp = item->GetTimeStamp (); + NS_LOG_DEBUG ("no packets available for transmission"); + return; } - else + // check if a Block Ack agreement needs to be established + m_currentHdr = peekedItem->GetHeader (); + m_currentPacket = peekedItem->GetPacket (); + if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast () + && m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ()) + && (!m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()) + || m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), OriginatorBlockAckAgreement::RESET)) + && SetupBlockAckIfNeeded ()) { - item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations); - if (item == 0) - { - NS_LOG_DEBUG ("no available packets in the queue"); - return; - } - m_currentHdr = item->GetHeader (); - m_currentPacket = item->GetPacket (); - m_currentPacketTimestamp = item->GetTimeStamp (); - if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast () - && m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ()) - && (!m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()) - || m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), OriginatorBlockAckAgreement::RESET)) - && SetupBlockAckIfNeeded ()) - { - return; - } - // Try A-MSDU aggregation - WifiTxVector txVector = m_low->GetDataTxVector (item->GetPacket (), &item->GetHeader ()); - item = 0; - if (m_low->GetMsduAggregator () != 0 && m_currentHdr.IsQosData () - && !m_currentHdr.GetAddr1 ().IsBroadcast () && !NeedFragmentation ()) - { - item = m_low->GetMsduAggregator ()->GetNextAmsdu (m_currentHdr.GetAddr1 (), - m_currentHdr.GetQosTid (), txVector); - } - if (item != 0) - { - NS_LOG_DEBUG ("tx unicast A-MSDU"); - } - else // dequeue the packet if aggregation was not attempted or failed - { - item = m_queue->DequeueFirstAvailable (m_qosBlockedDestinations); - } - NS_ASSERT (item != 0); - m_currentPacket = item->GetPacket (); - m_currentHdr = item->GetHeader (); - m_currentPacketTimestamp = item->GetTimeStamp (); - NS_ASSERT (m_currentPacket != 0); + return; + } - uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr); - m_currentHdr.SetSequenceNumber (sequence); - m_stationManager->UpdateFragmentationThreshold (); - m_currentHdr.SetFragmentNumber (0); - m_currentHdr.SetNoMoreFragments (); - m_currentHdr.SetNoRetry (); - m_fragmentNumber = 0; - NS_LOG_DEBUG ("dequeued size=" << m_currentPacket->GetSize () << - ", to=" << m_currentHdr.GetAddr1 () << - ", seq=" << m_currentHdr.GetSequenceControl ()); - if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ()) - { - VerifyBlockAck (); - } + m_stationManager->UpdateFragmentationThreshold (); + Time ppduDurationLimit = Seconds (0); + + // compute the limit on the PPDU duration due to the TXOP duration, if any + if (peekedItem->GetHeader ().IsQosData () && GetTxopLimit ().IsStrictlyPositive ()) + { + MacLowTransmissionParameters params = GetTransmissionParameters (peekedItem); + ppduDurationLimit = GetTxopRemaining () - m_low->CalculateOverheadTxTime (peekedItem, params); + } + + // dequeue the peeked item if it fits within the TXOP duration, if any + Ptr item = DequeuePeekedFrame (peekedItem, m_low->GetDataTxVector (peekedItem), + !NeedFragmentation (), 0, ppduDurationLimit); + + if (item == 0) + { + NS_LOG_DEBUG ("Not enough time in the current TXOP"); + return; + } + m_currentPacket = item->GetPacket (); + m_currentHdr = item->GetHeader (); + m_currentPacketTimestamp = item->GetTimeStamp (); + NS_ASSERT (m_currentPacket != 0); + + m_fragmentNumber = 0; + if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ()) + { + VerifyBlockAck (); } } + Ptr mpdu = Create (m_currentPacket, m_currentHdr, + m_currentPacketTimestamp); if (m_currentHdr.GetAddr1 ().IsGroup ()) { m_currentParams.DisableRts (); m_currentParams.DisableAck (); m_currentParams.DisableNextData (); NS_LOG_DEBUG ("tx broadcast"); - m_low->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this); + m_low->StartTransmission (mpdu, m_currentParams, this); } else if (m_currentHdr.GetType () == WIFI_MAC_CTL_BACKREQ) { @@ -283,14 +601,17 @@ QosTxop::NotifyAccessGranted (void) } else { - if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ()) + m_currentParams = GetTransmissionParameters (mpdu); + + // check if the current frame meets the QoS TXOP Limit, if any + if (mpdu->GetHeader ().IsQosData () && GetTxopLimit ().IsStrictlyPositive () && + m_low->CalculateOverallTxTime (mpdu->GetPacket (), &mpdu->GetHeader (), + m_currentParams) > GetTxopRemaining ()) { - m_currentParams.DisableAck (); - } - else - { - m_currentParams.EnableAck (); + NS_LOG_DEBUG ("Not enough time in the current TXOP"); + return; } + //With COMPRESSED_BLOCK_ACK fragmentation must be avoided. if (((m_currentHdr.IsQosData () && !m_currentHdr.IsQosAmsdu ()) || (m_currentHdr.IsData () && !m_currentHdr.IsQosData ())) @@ -311,13 +632,13 @@ QosTxop::NotifyAccessGranted (void) NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ()); m_currentParams.EnableNextData (GetNextFragmentSize ()); } - m_low->StartTransmission (fragment, &hdr, m_currentParams, this); + m_low->StartTransmission (Create (fragment, hdr), + m_currentParams, this); } else { m_currentIsFragmented = false; - m_currentParams.DisableNextData (); - m_low->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this); + m_low->StartTransmission (mpdu, m_currentParams, this); if (!GetAmpduExist (m_currentHdr.GetAddr1 ())) { CompleteTx (); @@ -336,15 +657,7 @@ void QosTxop::NotifyInternalCollision (void) WifiMacHeader header; if (m_currentPacket == 0) { - Ptr item; - if (m_baManager->HasPackets ()) - { - item = m_baManager->GetNextPacket (false); - } - else - { - item = m_queue->Peek (); - } + Ptr item = PeekNextFrame (); if (item) { packet = item->GetPacket (); @@ -428,55 +741,25 @@ QosTxop::NotifyCollision (void) } void -QosTxop::MissedCts (void) +QosTxop::NotifyMissedCts (std::list> mpduList) { NS_LOG_FUNCTION (this); NS_LOG_DEBUG ("missed cts"); + NS_ASSERT (!mpduList.empty ()); if (!NeedRtsRetransmission (m_currentPacket, m_currentHdr)) { NS_LOG_DEBUG ("Cts Fail"); - bool resetCurrentPacket = true; m_stationManager->ReportFinalRtsFailed (m_currentHdr.GetAddr1 (), &m_currentHdr); if (!m_txFailedCallback.IsNull ()) { m_txFailedCallback (m_currentHdr); } - if (GetAmpduExist (m_currentHdr.GetAddr1 ()) || m_currentHdr.IsQosData ()) + for (auto& mpdu : mpduList) { - uint8_t tid = GetTid (m_currentPacket, m_currentHdr); - m_low->FlushAggregateQueue (tid); - - if (GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), tid)) - { - NS_LOG_DEBUG ("Transmit Block Ack Request"); - CtrlBAckRequestHeader reqHdr; - reqHdr.SetType (GetBaBufferSize (m_currentHdr.GetAddr1 (), tid) > 64 ? EXTENDED_COMPRESSED_BLOCK_ACK : COMPRESSED_BLOCK_ACK); - reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberFor (&m_currentHdr)); - reqHdr.SetTidInfo (tid); - reqHdr.SetHtImmediateAck (true); - Ptr bar = Create (); - bar->AddHeader (reqHdr); - Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ()); - m_currentBar = request; - WifiMacHeader hdr; - hdr.SetType (WIFI_MAC_CTL_BACKREQ); - hdr.SetAddr1 (request.recipient); - hdr.SetAddr2 (m_low->GetAddress ()); - hdr.SetAddr3 (m_low->GetBssid ()); - hdr.SetDsNotTo (); - hdr.SetDsNotFrom (); - hdr.SetNoRetry (); - hdr.SetNoMoreFragments (); - m_currentPacket = request.bar; - m_currentHdr = hdr; - resetCurrentPacket = false; - } + m_baManager->NotifyDiscardedMpdu (mpdu); } //to reset the dcf. - if (resetCurrentPacket == true) - { - m_currentPacket = 0; - } + m_currentPacket = 0; ResetCw (); m_cwTrace = GetCw (); } @@ -484,6 +767,20 @@ QosTxop::MissedCts (void) { UpdateFailedCw (); m_cwTrace = GetCw (); + // if a BA agreement is established, store the MPDUs in the block ack manager + // retransmission queue. Otherwise, this QosTxop will handle the retransmission + // of the (single) frame + if (mpduList.size () > 1 || + (mpduList.front ()->GetHeader ().IsQosData () + && GetBaAgreementEstablished (mpduList.front ()->GetHeader ().GetAddr1 (), + mpduList.front ()->GetHeader ().GetQosTid ()))) + { + for (auto it = mpduList.rbegin (); it != mpduList.rend (); it++) + { + m_baManager->GetRetransmitQueue ()->PushFront (*it); + } + m_currentPacket = 0; + } } m_backoff = m_rng->GetInteger (0, GetCw ()); m_backoffTrace (m_backoff); @@ -536,37 +833,18 @@ QosTxop::GotAck (void) } } } + if (m_currentHdr.IsQosData () && GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ())) + { + // notify the BA manager that the current packet was acknowledged + m_baManager->NotifyGotAck (Create (m_currentPacket, m_currentHdr, + m_currentPacketTimestamp)); + } m_currentPacket = 0; ResetCw (); - if (!HasTxop ()) - { - if (m_currentHdr.IsQosData () && GetTxopLimit ().IsStrictlyPositive ()) - { - m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop); - } - m_cwTrace = GetCw (); - m_backoff = m_rng->GetInteger (0, GetCw ()); - m_backoffTrace (m_backoff); - StartBackoffNow (m_backoff); - RestartAccessIfNeeded (); - } } else { NS_LOG_DEBUG ("got ack. tx not done, size=" << m_currentPacket->GetSize ()); - if (!HasTxop ()) - { - if (m_currentHdr.IsQosData () && GetTxopLimit ().IsStrictlyPositive ()) - { - m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop); - m_cwTrace = GetCw (); - m_backoff = m_rng->GetInteger (0, GetCw ()); - m_backoffTrace (m_backoff); - StartBackoffNow (m_backoff); - m_fragmentNumber++; - RestartAccessIfNeeded (); - } - } } } @@ -580,7 +858,6 @@ QosTxop::MissedAck (void) NS_LOG_DEBUG ("Ack Fail"); m_stationManager->ReportFinalDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr, m_currentPacket->GetSize ()); - bool resetCurrentPacket = true; if (!m_txFailedCallback.IsNull ()) { m_txFailedCallback (m_currentHdr); @@ -602,39 +879,9 @@ QosTxop::MissedAck (void) } if (GetAmpduExist (m_currentHdr.GetAddr1 ()) || m_currentHdr.IsQosData ()) { - uint8_t tid = GetTid (m_currentPacket, m_currentHdr); - if (GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), tid)) - { - //send Block ACK Request in order to shift WinStart at the receiver - NS_LOG_DEBUG ("Transmit Block Ack Request"); - CtrlBAckRequestHeader reqHdr; - reqHdr.SetType (GetBaBufferSize (m_currentHdr.GetAddr1 (), tid) > 64 ? EXTENDED_COMPRESSED_BLOCK_ACK : COMPRESSED_BLOCK_ACK); - reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberFor (&m_currentHdr)); - reqHdr.SetTidInfo (tid); - reqHdr.SetHtImmediateAck (true); - Ptr bar = Create (); - bar->AddHeader (reqHdr); - Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ()); - m_currentBar = request; - WifiMacHeader hdr; - hdr.SetType (WIFI_MAC_CTL_BACKREQ); - hdr.SetAddr1 (request.recipient); - hdr.SetAddr2 (m_low->GetAddress ()); - hdr.SetAddr3 (m_low->GetBssid ()); - hdr.SetDsNotTo (); - hdr.SetDsNotFrom (); - hdr.SetNoRetry (); - hdr.SetNoMoreFragments (); - m_currentPacket = request.bar; - m_currentHdr = hdr; - resetCurrentPacket = false; - } - } - //to reset the dcf. - if (resetCurrentPacket == true) - { - m_currentPacket = 0; + m_baManager->NotifyDiscardedMpdu (Create (m_currentPacket, m_currentHdr)); } + m_currentPacket = 0; ResetCw (); m_cwTrace = GetCw (); } @@ -644,6 +891,14 @@ QosTxop::MissedAck (void) m_stationManager->ReportDataFailed (m_currentHdr.GetAddr1 (), &m_currentHdr, m_currentPacket->GetSize ()); m_currentHdr.SetRetry (); + if (m_currentHdr.IsQosData () && GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ())) + { + // notify the BA manager that the current packet was not acknowledged + m_baManager->NotifyMissedAck (Create (m_currentPacket, m_currentHdr, + m_currentPacketTimestamp)); + // let the BA manager handle its retransmission + m_currentPacket = 0; + } UpdateFailedCw (); m_cwTrace = GetCw (); } @@ -657,6 +912,11 @@ void QosTxop::MissedBlockAck (uint8_t nMpdus) { NS_LOG_FUNCTION (this << +nMpdus); + /* + * If the BlockAck frame is lost, the originator may transmit a BlockAckReq + * frame to solicit an immediate BlockAck frame or it may retransmit the Data + * frames. (IEEE std 802.11-2016 sec. 10.24.7.7 + */ uint8_t tid = GetTid (m_currentPacket, m_currentHdr); if (GetAmpduExist (m_currentHdr.GetAddr1 ())) { @@ -666,71 +926,35 @@ QosTxop::MissedBlockAck (uint8_t nMpdus) { if (NeedBarRetransmission ()) { - if (!GetAmpduExist (m_currentHdr.GetAddr1 ())) + NS_LOG_DEBUG ("Retransmit block ack request"); + if (m_currentHdr.IsBlockAckReq ()) { - //should i report this to station addressed by ADDR1? - NS_LOG_DEBUG ("Retransmit block ack request"); m_currentHdr.SetRetry (); + UpdateFailedCw (); + m_cwTrace = GetCw (); } - else + else // missed block ack after data frame with Implicit BAR Ack policy { - //standard says when losing a BlockAck originator may send a BAR page 139 - NS_LOG_DEBUG ("Transmit Block Ack Request"); - CtrlBAckRequestHeader reqHdr; - reqHdr.SetType (GetBaBufferSize (m_currentHdr.GetAddr1 (), tid) > 64 ? EXTENDED_COMPRESSED_BLOCK_ACK : COMPRESSED_BLOCK_ACK); - if (m_currentHdr.IsQosData ()) - { - reqHdr.SetStartingSequence (m_currentHdr.GetSequenceNumber ()); - } - else if (m_currentHdr.IsBlockAckReq ()) - { - CtrlBAckRequestHeader baReqHdr; - m_currentPacket->PeekHeader (baReqHdr); - reqHdr.SetStartingSequence (baReqHdr.GetStartingSequence ()); - } - else if (m_currentHdr.IsBlockAck ()) - { - CtrlBAckResponseHeader baRespHdr; - m_currentPacket->PeekHeader (baRespHdr); - reqHdr.SetStartingSequence (m_currentHdr.GetSequenceNumber ()); - } - reqHdr.SetTidInfo (tid); - reqHdr.SetHtImmediateAck (true); - Ptr bar = Create (); - bar->AddHeader (reqHdr); - Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ()); - m_currentBar = request; - WifiMacHeader hdr; - hdr.SetType (WIFI_MAC_CTL_BACKREQ); - hdr.SetAddr1 (request.recipient); - hdr.SetAddr2 (m_low->GetAddress ()); - hdr.SetAddr3 (m_low->GetBssid ()); - hdr.SetDsNotTo (); - hdr.SetDsNotFrom (); - hdr.SetNoRetry (); - hdr.SetNoMoreFragments (); - - m_currentPacket = request.bar; - m_currentHdr = hdr; + m_baManager->ScheduleBlockAckReq (m_currentHdr.GetAddr1 (), tid); + m_currentPacket = 0; } - UpdateFailedCw (); - m_cwTrace = GetCw (); } else { NS_LOG_DEBUG ("Block Ack Request Fail"); //to reset the dcf. + m_baManager->DiscardOutstandingMpdus (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr)); m_currentPacket = 0; ResetCw (); m_cwTrace = GetCw (); } } - else //implicit BAR + else { + // implicit BAR and do not use BAR after missed block ack, hence try to retransmit data frames if (!NeedDataRetransmission (m_currentPacket, m_currentHdr)) { NS_LOG_DEBUG ("Block Ack Fail"); - bool resetCurrentPacket = true; if (!m_txFailedCallback.IsNull ()) { m_txFailedCallback (m_currentHdr); @@ -750,41 +974,9 @@ QosTxop::MissedBlockAck (uint8_t nMpdus) } } } - if (GetAmpduExist (m_currentHdr.GetAddr1 ()) || m_currentHdr.IsQosData ()) - { - uint8_t tid = GetTid (m_currentPacket, m_currentHdr); - if (GetBaAgreementEstablished (m_currentHdr.GetAddr1 (), tid)) - { - //send Block ACK Request in order to shift WinStart at the receiver - NS_LOG_DEBUG ("Transmit Block Ack Request"); - CtrlBAckRequestHeader reqHdr; - reqHdr.SetType (GetBaBufferSize (m_currentHdr.GetAddr1 (), tid) > 64 ? EXTENDED_COMPRESSED_BLOCK_ACK : COMPRESSED_BLOCK_ACK); - reqHdr.SetStartingSequence (m_txMiddle->PeekNextSequenceNumberFor (&m_currentHdr)); - reqHdr.SetTidInfo (tid); - reqHdr.SetHtImmediateAck (true); - Ptr bar = Create (); - bar->AddHeader (reqHdr); - Bar request (bar, m_currentHdr.GetAddr1 (), tid, reqHdr.MustSendHtImmediateAck ()); - m_currentBar = request; - WifiMacHeader hdr; - hdr.SetType (WIFI_MAC_CTL_BACKREQ); - hdr.SetAddr1 (request.recipient); - hdr.SetAddr2 (m_low->GetAddress ()); - hdr.SetAddr3 (m_low->GetBssid ()); - hdr.SetDsNotTo (); - hdr.SetDsNotFrom (); - hdr.SetNoRetry (); - hdr.SetNoMoreFragments (); - m_currentPacket = request.bar; - m_currentHdr = hdr; - resetCurrentPacket = false; - } - } //to reset the dcf. - if (resetCurrentPacket == true) - { - m_currentPacket = 0; - } + m_baManager->DiscardOutstandingMpdus (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr)); + m_currentPacket = 0; ResetCw (); m_cwTrace = GetCw (); } @@ -818,18 +1010,9 @@ QosTxop::RestartAccessIfNeeded (void) packet = m_currentPacket; hdr = m_currentHdr; } - else if (m_baManager->HasPackets ()) - { - Ptr item = m_baManager->GetNextPacket (false); - if (item) - { - packet = item->GetPacket (); - hdr = item->GetHeader (); - } - } else { - Ptr item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations); + Ptr item = PeekNextFrame (); if (item) { packet = item->GetPacket (); @@ -838,7 +1021,8 @@ QosTxop::RestartAccessIfNeeded (void) } if (packet != 0) { - m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr)); + m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, + m_low->GetDataTxVector (Create (packet, hdr))); } else { @@ -858,29 +1042,16 @@ QosTxop::StartAccessIfNeeded (void) { Ptr packet; WifiMacHeader hdr; - if (m_baManager->HasPackets ()) + Ptr item = PeekNextFrame (); + if (item) { - Ptr item = m_baManager->GetNextPacket (false); - if (item) - { - packet = item->GetPacket (); - hdr = item->GetHeader (); - m_currentPacketTimestamp = item->GetTimeStamp (); - } - } - else - { - Ptr item = m_queue->PeekFirstAvailable (m_qosBlockedDestinations); - if (item) - { - packet = item->GetPacket (); - hdr = item->GetHeader (); - m_currentPacketTimestamp = item->GetTimeStamp (); - } + packet = item->GetPacket (); + hdr = item->GetHeader (); } if (packet != 0) { - m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, m_low->GetDataTxVector (packet, &hdr)); + m_isAccessRequestedForRts = m_stationManager->NeedRts (hdr.GetAddr1 (), &hdr, packet, + m_low->GetDataTxVector (Create (packet, hdr))); } else { @@ -921,75 +1092,99 @@ void QosTxop::StartNextPacket (void) { NS_LOG_FUNCTION (this); - Time txopLimit = GetTxopLimit (); - NS_ASSERT (txopLimit.IsZero () || Simulator::Now () - m_startTxop <= txopLimit); - WifiMacHeader hdr = m_currentHdr; - Ptr peekedPacket; - Ptr peekedItem = m_baManager->GetNextPacket (true); - if (peekedItem) + NS_ASSERT (GetTxopLimit ().IsStrictlyPositive () && GetTxopRemaining ().IsStrictlyPositive ()); + + m_currentPacket = 0; + Ptr nextFrame; + + // peek the next BlockAckReq, if any + if (m_baManager->HasBar (m_currentBar, false)) { - peekedPacket = peekedItem->GetPacket (); - hdr = peekedItem->GetHeader (); + WifiMacHeader hdr; + hdr.SetType (WIFI_MAC_CTL_BACKREQ); + hdr.SetAddr1 (m_currentBar.recipient); + nextFrame = Create (m_currentBar.bar, hdr); } else { - peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (), m_currentHdr.GetAddr1 ()); - if (peekedItem) + nextFrame = PeekNextFrame (); + } + + if (nextFrame != 0) + { + MacLowTransmissionParameters params = GetTransmissionParameters (nextFrame); + + if (GetTxopRemaining () >= m_low->CalculateOverallTxTime (nextFrame->GetPacket (), &nextFrame->GetHeader (), params)) { - peekedPacket = peekedItem->GetPacket (); - hdr = peekedItem->GetHeader (); + if (nextFrame->GetHeader ().IsBlockAckReq ()) + { + NS_LOG_DEBUG ("start next BlockAckReq within the current TXOP"); + m_baManager->HasBar (m_currentBar); + SendBlockAckRequest (m_currentBar); + return; + } + + // check if a Block Ack agreement needs to be established + m_currentHdr = nextFrame->GetHeader (); + m_currentPacket = nextFrame->GetPacket (); + if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast () + && m_stationManager->GetQosSupported (m_currentHdr.GetAddr1 ()) + && (!m_baManager->ExistsAgreement (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid ()) + || m_baManager->ExistsAgreementInState (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), OriginatorBlockAckAgreement::RESET)) + && SetupBlockAckIfNeeded ()) + { + return; + } + + // when dequeuing the peeked packet, A-MSDU aggregation is attempted if the + // packet has been peeked from the EDCA queue. Thus, compute the max available + // time for the transmission of the PPDU + Time maxPpduDuration = GetTxopRemaining () - m_low->CalculateOverheadTxTime (nextFrame, params); + NS_ASSERT (maxPpduDuration.IsPositive ()); + + Ptr item = DequeuePeekedFrame (nextFrame, m_low->GetDataTxVector (nextFrame), + true, 0, maxPpduDuration); + NS_ASSERT (item != 0); + NS_LOG_DEBUG ("start next packet " << *item << " within the current TXOP"); + m_currentPacket = item->GetPacket (); + m_currentHdr = item->GetHeader (); + m_currentPacketTimestamp = item->GetTimeStamp (); + NS_ASSERT (m_currentPacket != 0); + + m_currentParams = params; + m_stationManager->UpdateFragmentationThreshold (); + m_fragmentNumber = 0; + if (m_currentHdr.IsQosData () && !m_currentHdr.GetAddr1 ().IsBroadcast ()) + { + VerifyBlockAck (); + } + GetLow ()->StartTransmission (item, m_currentParams, this); + if (!GetAmpduExist (m_currentHdr.GetAddr1 ())) + { + CompleteTx (); + } + return; } } - if ((m_currentHdr.IsQosBlockAck () && peekedPacket == 0) || m_baManager->HasBar (m_currentBar)) - { - SendBlockAckRequest (m_currentBar); - return; - } - else if (peekedPacket == 0) - { - if (txopLimit.IsStrictlyPositive ()) - { - NS_ASSERT (Simulator::Now () - m_startTxop <= txopLimit); - m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop); - } - return; - } - m_currentParams.DisableNextData (); - if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ()) - { - m_currentParams.DisableAck (); - } - else - { - m_currentParams.EnableAck (); - } - if (txopLimit >= GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, m_currentParams)) - { - NS_LOG_DEBUG ("start next packet"); - Ptr item = m_queue->DequeueByTidAndAddress (m_currentHdr.GetQosTid (), - m_currentHdr.GetAddr1 ()); - NS_ASSERT (item != 0); - m_currentPacket = item->GetPacket (); - m_currentHdr = item->GetHeader (); - NS_ASSERT (m_currentPacket != 0); - uint16_t sequence = m_txMiddle->GetNextSequenceNumberFor (&m_currentHdr); - m_currentHdr.SetSequenceNumber (sequence); - m_stationManager->UpdateFragmentationThreshold (); - m_currentHdr.SetFragmentNumber (0); - m_currentHdr.SetNoMoreFragments (); - m_currentHdr.SetNoRetry (); - m_fragmentNumber = 0; - VerifyBlockAck (); - GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this); - if (!GetAmpduExist (m_currentHdr.GetAddr1 ())) - { - CompleteTx (); - } - } - else if (txopLimit.IsStrictlyPositive ()) + + // terminate TXOP because no (suitable) frame was found + TerminateTxop (); +} + +void +QosTxop::TerminateTxop (void) +{ + NS_LOG_FUNCTION (this); + if (GetTxopLimit ().IsStrictlyPositive ()) { + NS_LOG_DEBUG ("Terminating TXOP. Duration = " << Simulator::Now () - m_startTxop); m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop); } + m_cwTrace = GetCw (); + m_backoff = m_rng->GetInteger (0, GetCw ()); + m_backoffTrace (m_backoff); + StartBackoffNow (m_backoff); + RestartAccessIfNeeded (); } Time @@ -1005,60 +1200,14 @@ QosTxop::GetTxopRemaining (void) const return remainingTxop; } -bool -QosTxop::HasTxop (void) const -{ - NS_LOG_FUNCTION (this); - WifiMacHeader hdr; - if (!m_currentHdr.IsQosData () || GetTxopLimit ().IsZero ()) - { - return false; - } - - Ptr peekedItem = m_queue->PeekByTidAndAddress (m_currentHdr.GetQosTid (), - m_currentHdr.GetAddr1 ()); - if (peekedItem == 0) - { - return false; - } - - Ptr peekedPacket = peekedItem->GetPacket (); - hdr = peekedItem->GetHeader (); - MacLowTransmissionParameters params = m_currentParams; - if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck ()) - { - params.DisableAck (); - } - else - { - params.EnableAck (); - } - - Time duration = GetLow ()->CalculateOverallTxTime (peekedPacket, &hdr, params); - if (m_currentPacket != 0) - { - //take into account current transmission in duration - duration += GetLow ()->CalculateOverallTxTime (m_currentPacket, &m_currentHdr, params); - } - return (GetTxopRemaining () >= duration); -} - void QosTxop::EndTxNoAck (void) { NS_LOG_FUNCTION (this); NS_LOG_DEBUG ("a transmission that did not require an ACK just finished"); - if (m_currentHdr.IsQosData () && m_currentHdr.IsQosBlockAck () && GetTxopLimit ().IsStrictlyPositive ()) - { - m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop); - } m_currentPacket = 0; ResetCw (); - m_cwTrace = GetCw (); - m_backoff = m_rng->GetInteger (0, GetCw ()); - m_backoffTrace (m_backoff); - StartBackoffNow (m_backoff); - StartAccessIfNeeded (); + TerminateTxop (); } bool @@ -1363,18 +1512,6 @@ QosTxop::GotBlockAck (const CtrlBAckResponseHeader *blockAck, Mac48Address recip } m_currentPacket = 0; ResetCw (); - if (!HasTxop ()) - { - if (m_currentHdr.IsQosData () && GetTxopLimit ().IsStrictlyPositive ()) - { - m_txopTrace (m_startTxop, Simulator::Now () - m_startTxop); - } - m_cwTrace = GetCw (); - m_backoff = m_rng->GetInteger (0, GetCw ()); - m_backoffTrace (m_backoff); - StartBackoffNow (m_backoff); - RestartAccessIfNeeded (); - } } void @@ -1383,12 +1520,8 @@ QosTxop::VerifyBlockAck (void) NS_LOG_FUNCTION (this); uint8_t tid = m_currentHdr.GetQosTid (); Mac48Address recipient = m_currentHdr.GetAddr1 (); - uint16_t sequence = m_currentHdr.GetSequenceNumber (); - if (m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::INACTIVE)) - { - m_baManager->SwitchToBlockAckIfNeeded (recipient, tid, sequence); - } - WifiModulationClass modulation = m_low->GetDataTxVector (m_currentPacket, &m_currentHdr).GetMode ().GetModulationClass (); + Ptr item = Create (m_currentPacket, m_currentHdr); + WifiModulationClass modulation = m_low->GetDataTxVector (item).GetMode ().GetModulationClass (); if ((m_baManager->ExistsAgreementInState (recipient, tid, OriginatorBlockAckAgreement::ESTABLISHED)) && (GetLow ()->GetMpduAggregator () == 0 || GetLow ()->GetMpduAggregator ()->GetMaxAmpduSize (m_currentHdr.GetAddr1 (), tid, modulation) == 0)) @@ -1422,8 +1555,8 @@ QosTxop::CompleteTx (void) { if (!m_currentHdr.IsRetry ()) { - m_baManager->StorePacket (Create (m_currentPacket, m_currentHdr, - m_currentPacketTimestamp)); + m_baManager->StorePacket (Create (m_currentPacket, m_currentHdr, + m_currentPacketTimestamp)); } m_baManager->NotifyMpduTransmission (m_currentHdr.GetAddr1 (), m_currentHdr.GetQosTid (), m_txMiddle->GetNextSeqNumberByTidAndAddress (m_currentHdr.GetQosTid (), @@ -1432,7 +1565,7 @@ QosTxop::CompleteTx (void) } void -QosTxop::CompleteMpduTx (Ptr mpdu) +QosTxop::CompleteMpduTx (Ptr mpdu) { NS_ASSERT (mpdu->GetHeader ().IsQosData ()); m_baManager->StorePacket (mpdu); @@ -1479,36 +1612,10 @@ QosTxop::SendBlockAckRequest (const Bar &bar) m_currentPacket = bar.bar; m_currentHdr = hdr; - m_currentParams.DisableRts (); - m_currentParams.DisableNextData (); - if (bar.immediate) - { - if (m_blockAckType == BASIC_BLOCK_ACK) - { - m_currentParams.EnableBasicBlockAck (); - } - else if (m_blockAckType == COMPRESSED_BLOCK_ACK) - { - if (GetBaBufferSize (m_currentHdr.GetAddr1 (), GetTid (m_currentPacket, m_currentHdr)) > 64) - { - m_currentParams.EnableExtendedCompressedBlockAck (); - } - else - { - m_currentParams.EnableCompressedBlockAck (); - } - } - else if (m_blockAckType == MULTI_TID_BLOCK_ACK) - { - NS_FATAL_ERROR ("Multi-tid block ack is not supported"); - } - } - else - { - //Delayed block ack - m_currentParams.EnableAck (); - } - m_low->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this); + Ptr mpdu = Create (m_currentPacket, m_currentHdr); + m_currentParams = GetTransmissionParameters (mpdu); + + m_low->StartTransmission (mpdu, m_currentParams, this); } void @@ -1600,7 +1707,7 @@ QosTxop::SendAddBaRequest (Mac48Address dest, uint8_t tid, uint16_t startSeq, m_currentParams.DisableRts (); m_currentParams.DisableNextData (); - m_low->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this); + m_low->StartTransmission (Create (m_currentPacket, m_currentHdr), m_currentParams, this); } void diff --git a/src/wifi/model/qos-txop.h b/src/wifi/model/qos-txop.h index 819daf648..d0cecf877 100644 --- a/src/wifi/model/qos-txop.h +++ b/src/wifi/model/qos-txop.h @@ -29,6 +29,7 @@ #include "qos-utils.h" class AmpduAggregationTest; +class TwoLevelAggregationTest; class HeAggregationTest; namespace ns3 { @@ -37,6 +38,7 @@ class QosBlockedDestinations; class MgtAddBaResponseHeader; class MgtDelBaHeader; class AggregationCapableTransmissionListener; +class WifiTxVector; /** * Enumeration for type of station @@ -91,6 +93,7 @@ class QosTxop : public Txop public: /// Allow test cases to access private members friend class ::AmpduAggregationTest; + friend class ::TwoLevelAggregationTest; friend class ::HeAggregationTest; std::map m_aMpduEnabled; //!< list containing flags whether A-MPDU is enabled for a given destination address @@ -140,14 +143,6 @@ public: * recipient for tid tid. */ bool GetBaAgreementEstablished (Mac48Address address, uint8_t tid) const; - /** - * \param recipient address of peer station involved in block ack mechanism. - * \param tid Ttraffic ID of transmitted packet. - * - * This function resets the status of OriginatorBlockAckAgreement after the transfer - * of an A-MPDU with ImmediateBlockAck policy (i.e. no BAR is scheduled). - */ - void CompleteAmpduTransfer (Mac48Address recipient, uint8_t tid); /** * \param address recipient address of the peer station * \param tid traffic ID. @@ -158,6 +153,17 @@ public: * recipient for tid tid. */ uint16_t GetBaBufferSize (Mac48Address address, uint8_t tid) const; + /** + * \param address recipient address of the peer station + * \param tid traffic ID. + * + * \return the starting sequence number of the originator transmit window. + * + * Returns the current starting sequence number of the transmit window on the + * originator (WinStartO) of the Block Ack agreement established with the given + * recipient for the given TID. + */ + uint16_t GetBaStartingSequence (Mac48Address address, uint8_t tid) const; /* dcf notifications forwarded here */ /** @@ -176,8 +182,10 @@ public: /* Event handlers */ /** * Event handler when a CTS timeout has occurred. + * + * \param mpduList the list of MPDUs that were not transmitted */ - void MissedCts (void); + void NotifyMissedCts (std::list> mpduList); /** * Event handler when an ACK is received. */ @@ -316,7 +324,7 @@ public: * * \param mpdu received MPDU. */ - void CompleteMpduTx (Ptr mpdu); + void CompleteMpduTx (Ptr mpdu); /** * Return whether A-MPDU is used to transmit data to a peer station. * @@ -374,21 +382,83 @@ public: */ uint16_t PeekNextSequenceNumberFor (const WifiMacHeader *hdr); /** - * Remove a packet after you peek in the retransmit queue and get it. - * - * \param tid traffic ID of the packet to be removed. - * \param recipient address of the recipient the packet was intended for. - * \param seqnumber sequence number of the packet to be removed. - */ - void RemoveRetransmitPacket (uint8_t tid, Mac48Address recipient, uint16_t seqnumber); - /** - * Peek in retransmit queue and get the next packet without removing it from the queue. + * Peek the next frame to transmit to the given receiver and of the given + * TID from the Block Ack manager retransmit queue first and, if not found, from + * the EDCA queue. If tid is equal to 8 (invalid value) and recipient + * is the broadcast address, the first available frame is returned. + * Note that A-MSDU aggregation is never attempted (this is relevant if the + * frame is peeked from the EDCA queue). If the frame is peeked from the EDCA + * queue, it is assigned a sequence number peeked from MacTxMiddle. * * \param tid traffic ID. * \param recipient the receiver station address. - * \returns the packet. + * \returns the peeked frame. */ - Ptr PeekNextRetransmitPacket (uint8_t tid, Mac48Address recipient); + Ptr PeekNextFrame (uint8_t tid = 8, Mac48Address recipient = Mac48Address::GetBroadcast ()); + /** + * Dequeue the frame that has been previously peeked by calling PeekNextFrame + * or PeekNextFrameByTidAndAddress. If the peeked frame is a QoS Data frame, + * it is actually dequeued if it meets the constraint on the maximum A-MPDU + * size (by assuming that the frame has to be aggregated to an existing A-MPDU + * of the given size) and its transmission time does not exceed the given + * PPDU duration limit (if strictly positive). If the peeked frame is a unicast + * QoS Data frame stored in the EDCA queue, attempt to perform A-MSDU aggregation + * (while meeting the constraints mentioned above) if aggregate is true + * and assign a sequence number to the dequeued frame. + * + * \param peekedItem the peeked frame. + * \param txVector the TX vector used to transmit the peeked frame + * \param ampduSize the size of the existing A-MPDU, if any + * \param ppduDurationLimit the limit on the PPDU duration + * \returns the dequeued frame. + */ + Ptr DequeuePeekedFrame (Ptr peekedItem, WifiTxVector txVector, + bool aggregate = true, uint32_t ampduSize = 0, + Time ppduDurationLimit = Seconds (0)); + /** + * Check whether the given MPDU, if transmitted according to the given TX vector, + * meets the constraint on the maximum A-MPDU size (by assuming that the frame + * has to be aggregated to an existing A-MPDU of the given size) and its + * transmission time exceeds neither the max PPDU duration (depending on the + * PPDU format) nor the given PPDU duration limit (if strictly positive). + * The given MPDU needs to be a QoS Data frame. + * + * \param mpdu the MPDU. + * \param txVector the TX vector used to transmit the MPDU + * \param ampduSize the size of the existing A-MPDU, if any + * \param ppduDurationLimit the limit on the PPDU duration + * \returns true if constraints on size and duration limit are met. + */ + bool IsWithinSizeAndTimeLimits (Ptr mpdu, WifiTxVector txVector, + uint32_t ampduSize, Time ppduDurationLimit); + /** + * Check whether an MPDU of the given size, destined to the given receiver and + * belonging to the given TID, if transmitted according to the given TX vector, + * meets the constraint on the maximum A-MPDU size (by assuming that the frame + * has to be aggregated to an existing A-MPDU of the given size) and its + * transmission time exceeds neither the max PPDU duration (depending on the + * PPDU format) nor the given PPDU duration limit (if strictly positive). + * + * \param mpduSize the MPDU size. + * \param receiver the receiver + * \param tid the TID + * \param txVector the TX vector used to transmit the MPDU + * \param ampduSize the size of the existing A-MPDU, if any + * \param ppduDurationLimit the limit on the PPDU duration + * \returns true if constraints on size and duration limit are met. + */ + bool IsWithinSizeAndTimeLimits (uint32_t mpduSize, Mac48Address receiver, uint8_t tid, + WifiTxVector txVector, uint32_t ampduSize, Time ppduDurationLimit); + /** + * Compute the MacLow transmission parameters for the given frame. Allowed frames + * are those handled by a QosTxop (QoS data frames, BlockAckReq frames, ADDBA + * Request/Response, DELBA Request). + * + * \param frame the given frame + * \return the MacLow transmission parameters. + */ + MacLowTransmissionParameters GetTransmissionParameters (Ptr frame) const; + /** * The packet we sent was successfully received by the receiver. * @@ -456,6 +526,15 @@ private: * \param bar the block ack request. */ void SendBlockAckRequest (const Bar &bar); + /** + * Check if the given MPDU is to be considered old according to the current + * starting sequence number of the transmit window, provided that a block ack + * agreement has been established with the recipient for the given TID. + * + * \param mpdu the given MPDU + * \return true if the MPDU is to be considered old, false otherwise + */ + bool IsQosOldPacket (Ptr mpdu); /** * For now is typically invoked to complete transmission of a packets sent with ack policy * Block Ack: the packet is buffered and dcf is reset. @@ -473,12 +552,9 @@ private: */ Time GetTxopRemaining (void) const; /** - * Check if the station has TXOP granted for the next MPDU. - * - * \return true if the station has TXOP granted for the next MPDU, - * false otherwise. + * Update backoff and restart access if needed. */ - bool HasTxop (void) const; + void TerminateTxop (void); /** * Calculate the size of the next fragment. diff --git a/src/wifi/model/txop.cc b/src/wifi/model/txop.cc index 617768e3c..a2d1aa2fa 100644 --- a/src/wifi/model/txop.cc +++ b/src/wifi/model/txop.cc @@ -498,13 +498,15 @@ Txop::NotifyAccessGranted (void) m_currentParams.DisableAck (); m_currentParams.DisableNextData (); NS_LOG_DEBUG ("tx broadcast"); - GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this); + GetLow ()->StartTransmission (Create (m_currentPacket, m_currentHdr), + m_currentParams, this); } else { m_currentParams.EnableAck (); if (NeedFragmentation ()) { + m_currentParams.DisableRts (); WifiMacHeader hdr; Ptr fragment = GetFragmentPacket (&hdr); if (IsLastFragment ()) @@ -517,12 +519,27 @@ Txop::NotifyAccessGranted (void) NS_LOG_DEBUG ("fragmenting size=" << fragment->GetSize ()); m_currentParams.EnableNextData (GetNextFragmentSize ()); } - GetLow ()->StartTransmission (fragment, &hdr, m_currentParams, this); + GetLow ()->StartTransmission (Create (fragment, hdr), + m_currentParams, this); } else { + WifiTxVector dataTxVector = m_stationManager->GetDataTxVector (m_currentHdr.GetAddr1 (), + &m_currentHdr, m_currentPacket); + + if (m_stationManager->NeedRts (m_currentHdr.GetAddr1 (), &m_currentHdr, + m_currentPacket, dataTxVector) + && !m_low->IsCfPeriod ()) + { + m_currentParams.EnableRts (); + } + else + { + m_currentParams.DisableRts (); + } m_currentParams.DisableNextData (); - GetLow ()->StartTransmission (m_currentPacket, &m_currentHdr, m_currentParams, this); + GetLow ()->StartTransmission (Create (m_currentPacket, m_currentHdr), + m_currentParams, this); } } } @@ -737,7 +754,7 @@ Txop::StartNextFragment (void) { m_currentParams.EnableNextData (GetNextFragmentSize ()); } - GetLow ()->StartTransmission (fragment, &hdr, m_currentParams, this); + GetLow ()->StartTransmission (Create (fragment, hdr), m_currentParams, this); } void @@ -867,10 +884,17 @@ Txop::MissedBlockAck (uint8_t nMpdus) NS_LOG_WARN ("MissedBlockAck should not be called for non QoS!"); } -bool -Txop::HasTxop (void) const +Time +Txop::GetTxopRemaining (void) const { - return false; + NS_LOG_WARN ("GetTxopRemaining should not be called for non QoS!"); + return Seconds (0); +} + +void +Txop::TerminateTxop (void) +{ + NS_LOG_WARN ("TerminateTxop should not be called for non QoS!"); } } //namespace ns3 diff --git a/src/wifi/model/txop.h b/src/wifi/model/txop.h index adf63841c..4fb09660b 100644 --- a/src/wifi/model/txop.h +++ b/src/wifi/model/txop.h @@ -306,12 +306,15 @@ public: virtual void EndTxNoAck (void); /** - * Check if the station has TXOP granted for the next MPDU. + * Return the remaining duration in the current TXOP. * - * \return true if the station has TXOP granted for the next MPDU, - * false otherwise + * \return the remaining duration in the current TXOP. */ - virtual bool HasTxop (void) const; + virtual Time GetTxopRemaining (void) const; + /** + * Update backoff and restart access if needed. + */ + virtual void TerminateTxop (void); /** * Check if the next PCF transmission can fit in the remaining CFP duration. diff --git a/src/wifi/model/wifi-mac-queue.cc b/src/wifi/model/wifi-mac-queue.cc index 0f6324b42..7224321d9 100644 --- a/src/wifi/model/wifi-mac-queue.cc +++ b/src/wifi/model/wifi-mac-queue.cc @@ -53,12 +53,16 @@ WifiMacQueue::GetTypeId (void) MakeEnumAccessor (&WifiMacQueue::m_dropPolicy), MakeEnumChecker (WifiMacQueue::DROP_OLDEST, "DropOldest", WifiMacQueue::DROP_NEWEST, "DropNewest")) + .AddTraceSource ("Expired", "MPDU dropped because its lifetime expired.", + MakeTraceSourceAccessor (&WifiMacQueue::m_traceExpired), + "ns3::WifiMacQueueItem::TracedCallback") ; return tid; } WifiMacQueue::WifiMacQueue () - : NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue") + : m_expiredPacketsPresent (false), + NS_LOG_TEMPLATE_DEFINE ("WifiMacQueue") { } @@ -67,6 +71,8 @@ WifiMacQueue::~WifiMacQueue () NS_LOG_FUNCTION_NOARGS (); } +const WifiMacQueue::ConstIterator WifiMacQueue::EMPTY = std::list> ().end (); + void WifiMacQueue::SetMaxQueueSize (QueueSize size) { @@ -102,6 +108,7 @@ WifiMacQueue::TtlExceeded (ConstIterator &it) { NS_LOG_DEBUG ("Removing packet that stayed in the queue for too long (" << Simulator::Now () - (*it)->GetTimeStamp () << ")"); + m_traceExpired (*it); auto curr = it++; DoRemove (curr); return true; @@ -112,66 +119,64 @@ WifiMacQueue::TtlExceeded (ConstIterator &it) bool WifiMacQueue::Enqueue (Ptr item) { - NS_LOG_FUNCTION (this << item); - NS_ASSERT_MSG (GetMaxSize ().GetUnit () == QueueSizeUnit::PACKETS, - "WifiMacQueues must be in packet mode"); + NS_LOG_FUNCTION (this << *item); - QueueBase::SetMaxSize (GetMaxQueueSize ()); //Make sure QueueBase has the same maximum queue size - - // if the queue is full, remove the first stale packet (if any) encountered - // starting from the head of the queue, in order to make room for the new packet. - if (QueueBase::GetNPackets () == GetMaxSize ().GetValue ()) - { - auto it = Head (); - while (it != Tail () && !TtlExceeded (it)) - { - it++; - } - } - - if (QueueBase::GetNPackets () == GetMaxSize ().GetValue () && m_dropPolicy == DROP_OLDEST) - { - NS_LOG_DEBUG ("Remove the oldest item in the queue"); - DoRemove (Head ()); - } - - return DoEnqueue (Tail (), item); + return Insert (end (), item); } bool WifiMacQueue::PushFront (Ptr item) { - NS_LOG_FUNCTION (this << item); + NS_LOG_FUNCTION (this << *item); + + return Insert (begin (), item); +} + +bool +WifiMacQueue::Insert (ConstIterator pos, Ptr item) +{ + NS_LOG_FUNCTION (this << *item); NS_ASSERT_MSG (GetMaxSize ().GetUnit () == QueueSizeUnit::PACKETS, "WifiMacQueues must be in packet mode"); QueueBase::SetMaxSize (GetMaxQueueSize ()); //Make sure QueueBase has the same maximum queue size - // if the queue is full, remove the first stale packet (if any) encountered - // starting from the head of the queue, in order to make room for the new packet. - if (QueueBase::GetNPackets () == GetMaxSize ().GetValue ()) + // insert the item if the queue is not full + if (QueueBase::GetNPackets () < GetMaxSize ().GetValue ()) { - auto it = Head (); - while (it != Tail () && !TtlExceeded (it)) - { - it++; - } + return DoEnqueue (pos, item); } - if (QueueBase::GetNPackets () == GetMaxSize ().GetValue () && m_dropPolicy == DROP_OLDEST) + // the queue is full; scan the list in the attempt to remove stale packets + ConstIterator it = begin (); + while (it != end ()) + { + if (it == pos && TtlExceeded (it)) + { + return DoEnqueue (it, item); + } + if (TtlExceeded (it)) + { + return DoEnqueue (pos, item); + } + it++; + } + + // the queue is still full, remove the oldest item if the policy is drop oldest + if (m_dropPolicy == DROP_OLDEST) { NS_LOG_DEBUG ("Remove the oldest item in the queue"); - DoRemove (Head ()); + DoRemove (begin ()); } - return DoEnqueue (Head (), item); + return DoEnqueue (pos, item); } Ptr WifiMacQueue::Dequeue (void) { NS_LOG_FUNCTION (this); - for (auto it = Head (); it != Tail (); ) + for (ConstIterator it = begin (); it != end (); ) { if (!TtlExceeded (it)) { @@ -186,62 +191,90 @@ Ptr WifiMacQueue::DequeueByAddress (Mac48Address dest) { NS_LOG_FUNCTION (this << dest); + ConstIterator it = PeekByAddress (dest); - for (auto it = Head (); it != Tail (); ) + if (it == end ()) { - if (!TtlExceeded (it)) - { - if ((*it)->GetHeader ().IsData () && (*it)->GetDestinationAddress () == dest) - { - return DoDequeue (it); - } - - it++; - } + return 0; } - NS_LOG_DEBUG ("The queue is empty"); - return 0; + return Dequeue (it); +} + +Ptr +WifiMacQueue::DequeueByTid (uint8_t tid) +{ + NS_LOG_FUNCTION (this << +tid); + ConstIterator it = PeekByTid (tid); + + if (it == end ()) + { + return 0; + } + return Dequeue (it); } Ptr WifiMacQueue::DequeueByTidAndAddress (uint8_t tid, Mac48Address dest) { - NS_LOG_FUNCTION (this << dest); - for (auto it = Head (); it != Tail (); ) - { - if (!TtlExceeded (it)) - { - if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest - && (*it)->GetHeader ().GetQosTid () == tid) - { - return DoDequeue (it); - } + NS_LOG_FUNCTION (this << +tid << dest); + ConstIterator it = PeekByTidAndAddress (tid, dest); - it++; - } + if (it == end ()) + { + return 0; } - NS_LOG_DEBUG ("The queue is empty"); - return 0; + return Dequeue (it); } Ptr WifiMacQueue::DequeueFirstAvailable (const Ptr blockedPackets) { NS_LOG_FUNCTION (this); - for (auto it = Head (); it != Tail (); ) - { - if (!TtlExceeded (it)) - { - if (!(*it)->GetHeader ().IsQosData () - || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ())) - { - return DoDequeue (it); - } + ConstIterator it = PeekFirstAvailable (blockedPackets); + if (it == end ()) + { + return 0; + } + return Dequeue (it); +} + +Ptr +WifiMacQueue::Dequeue (ConstIterator pos) +{ + NS_LOG_FUNCTION (this); + + if (!m_expiredPacketsPresent) + { + if (TtlExceeded (pos)) + { + NS_LOG_DEBUG ("Packet lifetime expired"); + return 0; + } + return DoDequeue (pos); + } + + // remove stale items queued before the given position + ConstIterator it = begin (); + while (it != end ()) + { + if (it == pos) + { + // reset the flag signaling the presence of expired packets before returning + m_expiredPacketsPresent = false; + + if (TtlExceeded (it)) + { + return 0; + } + return DoDequeue (it); + } + else if (!TtlExceeded (it)) + { it++; } } - NS_LOG_DEBUG ("The queue is empty"); + NS_LOG_DEBUG ("Invalid iterator"); return 0; } @@ -249,7 +282,7 @@ Ptr WifiMacQueue::Peek (void) const { NS_LOG_FUNCTION (this); - for (auto it = Head (); it != Tail (); it++) + for (auto it = begin (); it != end (); it++) { // skip packets that stayed in the queue for too long. They will be // actually removed from the queue by the next call to a non-const method @@ -257,51 +290,122 @@ WifiMacQueue::Peek (void) const { return DoPeek (it); } + // signal the presence of expired packets + m_expiredPacketsPresent = true; } NS_LOG_DEBUG ("The queue is empty"); return 0; } -Ptr -WifiMacQueue::PeekByTidAndAddress (uint8_t tid, Mac48Address dest) +WifiMacQueue::ConstIterator +WifiMacQueue::PeekByAddress (Mac48Address dest, ConstIterator pos) const { NS_LOG_FUNCTION (this << dest); - for (auto it = Head (); it != Tail (); ) + ConstIterator it = (pos != EMPTY ? pos : begin ()); + while (it != end ()) { - if (!TtlExceeded (it)) + // skip packets that stayed in the queue for too long. They will be + // actually removed from the queue by the next call to a non-const method + if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay) + { + if (((*it)->GetHeader ().IsData () || (*it)->GetHeader ().IsQosData ()) + && (*it)->GetDestinationAddress () == dest) + { + return it; + } + } + else + { + // signal the presence of expired packets + m_expiredPacketsPresent = true; + } + it++; + } + NS_LOG_DEBUG ("The queue is empty"); + return end (); +} + +WifiMacQueue::ConstIterator +WifiMacQueue::PeekByTid (uint8_t tid, ConstIterator pos) const +{ + NS_LOG_FUNCTION (this << +tid); + ConstIterator it = (pos != EMPTY ? pos : begin ()); + while (it != end ()) + { + // skip packets that stayed in the queue for too long. They will be + // actually removed from the queue by the next call to a non-const method + if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay) + { + if ((*it)->GetHeader ().IsQosData () && (*it)->GetHeader ().GetQosTid () == tid) + { + return it; + } + } + else + { + // signal the presence of expired packets + m_expiredPacketsPresent = true; + } + it++; + } + NS_LOG_DEBUG ("The queue is empty"); + return end (); +} + +WifiMacQueue::ConstIterator +WifiMacQueue::PeekByTidAndAddress (uint8_t tid, Mac48Address dest, ConstIterator pos) const +{ + NS_LOG_FUNCTION (this << +tid << dest); + ConstIterator it = (pos != EMPTY ? pos : begin ()); + while (it != end ()) + { + // skip packets that stayed in the queue for too long. They will be + // actually removed from the queue by the next call to a non-const method + if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay) { if ((*it)->GetHeader ().IsQosData () && (*it)->GetDestinationAddress () == dest && (*it)->GetHeader ().GetQosTid () == tid) { - return DoPeek (it); + return it; } - - it++; } + else + { + // signal the presence of expired packets + m_expiredPacketsPresent = true; + } + it++; } NS_LOG_DEBUG ("The queue is empty"); - return 0; + return end (); } -Ptr -WifiMacQueue::PeekFirstAvailable (const Ptr blockedPackets) +WifiMacQueue::ConstIterator +WifiMacQueue::PeekFirstAvailable (const Ptr blockedPackets, ConstIterator pos) const { NS_LOG_FUNCTION (this); - for (auto it = Head (); it != Tail (); ) + ConstIterator it = (pos != EMPTY ? pos : begin ()); + while (it != end ()) { - if (!TtlExceeded (it)) + // skip packets that stayed in the queue for too long. They will be + // actually removed from the queue by the next call to a non-const method + if (Simulator::Now () <= (*it)->GetTimeStamp () + m_maxDelay) { - if (!(*it)->GetHeader ().IsQosData () + if (!(*it)->GetHeader ().IsQosData () || !blockedPackets || !blockedPackets->IsBlocked ((*it)->GetHeader ().GetAddr1 (), (*it)->GetHeader ().GetQosTid ())) { - return DoPeek (it); + return it; } - - it++; } + else + { + // signal the presence of expired packets + m_expiredPacketsPresent = true; + } + it++; } NS_LOG_DEBUG ("The queue is empty"); - return 0; + return end (); } Ptr @@ -309,7 +413,7 @@ WifiMacQueue::Remove (void) { NS_LOG_FUNCTION (this); - for (auto it = Head (); it != Tail (); ) + for (ConstIterator it = begin (); it != end (); ) { if (!TtlExceeded (it)) { @@ -324,7 +428,7 @@ bool WifiMacQueue::Remove (Ptr packet) { NS_LOG_FUNCTION (this << packet); - for (auto it = Head (); it != Tail (); ) + for (ConstIterator it = begin (); it != end (); ) { if (!TtlExceeded (it)) { @@ -341,6 +445,40 @@ WifiMacQueue::Remove (Ptr packet) return false; } +WifiMacQueue::ConstIterator +WifiMacQueue::Remove (ConstIterator pos, bool removeExpired) +{ + NS_LOG_FUNCTION (this); + + if (!removeExpired) + { + ConstIterator curr = pos++; + DoRemove (curr); + return pos; + } + + // remove stale items queued before the given position + ConstIterator it = begin (); + while (it != end ()) + { + if (it == pos) + { + // reset the flag signaling the presence of expired packets before returning + m_expiredPacketsPresent = false; + + ConstIterator curr = pos++; + DoRemove (curr); + return pos; + } + else if (!TtlExceeded (it)) + { + it++; + } + } + NS_LOG_DEBUG ("Invalid iterator"); + return end (); +} + uint32_t WifiMacQueue::GetNPacketsByAddress (Mac48Address dest) { @@ -348,7 +486,7 @@ WifiMacQueue::GetNPacketsByAddress (Mac48Address dest) uint32_t nPackets = 0; - for (auto it = Head (); it != Tail (); ) + for (ConstIterator it = begin (); it != end (); ) { if (!TtlExceeded (it)) { @@ -369,7 +507,7 @@ WifiMacQueue::GetNPacketsByTidAndAddress (uint8_t tid, Mac48Address dest) { NS_LOG_FUNCTION (this << dest); uint32_t nPackets = 0; - for (auto it = Head (); it != Tail (); ) + for (ConstIterator it = begin (); it != end (); ) { if (!TtlExceeded (it)) { @@ -390,7 +528,7 @@ bool WifiMacQueue::IsEmpty (void) { NS_LOG_FUNCTION (this); - for (auto it = Head (); it != Tail (); ) + for (ConstIterator it = begin (); it != end (); ) { if (!TtlExceeded (it)) { @@ -407,7 +545,7 @@ WifiMacQueue::GetNPackets (void) { NS_LOG_FUNCTION (this); // remove packets that stayed in the queue for too long - for (auto it = Head (); it != Tail (); ) + for (ConstIterator it = begin (); it != end (); ) { if (!TtlExceeded (it)) { @@ -422,7 +560,7 @@ WifiMacQueue::GetNBytes (void) { NS_LOG_FUNCTION (this); // remove packets that stayed in the queue for too long - for (auto it = Head (); it != Tail (); ) + for (ConstIterator it = begin (); it != end (); ) { if (!TtlExceeded (it)) { diff --git a/src/wifi/model/wifi-mac-queue.h b/src/wifi/model/wifi-mac-queue.h index 130d62757..da41a9e03 100644 --- a/src/wifi/model/wifi-mac-queue.h +++ b/src/wifi/model/wifi-mac-queue.h @@ -72,6 +72,12 @@ public: DROP_OLDEST }; + /// allow the usage of iterators and const iterators + using Queue::ConstIterator; + using Queue::Iterator; + using Queue::begin; + using Queue::end; + /** * \brief Set the maximum size of this queue * @@ -111,6 +117,14 @@ public: * \return true if success, false if the packet has been dropped */ bool PushFront (Ptr item); + /** + * Enqueue the given Wifi MAC queue item before the given position. + * + * \param pos the position before which the item is to be inserted + * \param item the Wifi MAC queue item to be enqueued + * \return true if success, false if the packet has been dropped + */ + bool Insert (ConstIterator pos, Ptr item); /** * Dequeue the packet in the front of the queue. * @@ -118,8 +132,8 @@ public: */ Ptr Dequeue (void); /** - * Search and return, if present in the queue, the first packet having the - * address indicated by type equal to addr. + * Search and return, if present in the queue, the first packet (either Data + * frame or QoS Data frame) having the receiver address equal to addr. * This method removes the packet from the queue. * It is typically used by ns3::Txop during the CF period. * @@ -128,6 +142,16 @@ public: * \return the packet */ Ptr DequeueByAddress (Mac48Address dest); + /** + * Search and return, if present in the queue, the first packet having the + * tid equal to tid. + * This method removes the packet from the queue. + * + * \param tid the given tid + * + * \return the packet + */ + Ptr DequeueByTid (uint8_t tid); /** * Search and return, if present in the queue, the first packet having the * address indicated by type equal to addr, and tid @@ -153,35 +177,72 @@ public: * * \return packet */ - Ptr DequeueFirstAvailable (const Ptr blockedPackets); + Ptr DequeueFirstAvailable (const Ptr blockedPackets = nullptr); + /** + * Dequeue the item at position pos in the queue. Return a null + * pointer if the given iterator is invalid, the queue is empty or the + * lifetime of the item pointed to by the given iterator is expired. + * + * \param pos the position of the item to be dequeued + * \return the dequeued item, if any + */ + Ptr Dequeue (WifiMacQueue::ConstIterator pos); /** * Peek the packet in the front of the queue. The packet is not removed. * * \return the packet */ Ptr Peek (void) const; + /** + * Search and return, if present in the queue, the first packet (either Data + * frame or QoS Data frame) having the receiver address equal to addr. + * If pos is a valid iterator, the search starts from the packet pointed + * to by the given iterator. + * This method does not remove the packet from the queue. + * + * \param dest the given destination + * \param pos the iterator pointing to the packet the search starts from + * + * \return an iterator pointing to the peeked packet + */ + ConstIterator PeekByAddress (Mac48Address dest, ConstIterator pos = EMPTY) const; /** * Search and return, if present in the queue, the first packet having the - * address indicated by type equal to addr, and tid - * equal to tid. This method does not remove the packet from the queue. - * It is typically used by ns3::QosTxop in order to perform correct MSDU - * aggregation (A-MSDU). + * tid equal to tid. If pos is a valid iterator, the search starts + * from the packet pointed to by the given iterator. + * This method does not remove the packet from the queue. + * + * \param tid the given TID + * \param pos the iterator pointing to the packet the search starts from + * + * \return an iterator pointing to the peeked packet + */ + ConstIterator PeekByTid (uint8_t tid, ConstIterator pos = EMPTY) const; + /** + * Search and return, if present in the queue, the first packet having the + * receiver address equal to dest, and tid equal to tid. + * If pos is a valid iterator, the search starts from the packet pointed + * to by the given iterator. This method does not remove the packet from the queue. + * It is typically used by ns3::QosTxop in order to perform correct MSDU aggregation + * (A-MSDU). * * \param tid the given TID * \param dest the given destination + * \param pos the iterator pointing to the packet the search starts from * - * \return packet + * \return an iterator pointing to the peeked packet */ - Ptr PeekByTidAndAddress (uint8_t tid, - Mac48Address dest); + ConstIterator PeekByTidAndAddress (uint8_t tid, Mac48Address dest, ConstIterator pos = EMPTY) const; /** * Return first available packet for transmission. The packet is not removed from queue. * * \param blockedPackets + * \param pos the iterator pointing to the packet the search starts from * - * \return packet + * \return an iterator pointing to the peeked packet */ - Ptr PeekFirstAvailable (const Ptr blockedPackets); + ConstIterator PeekFirstAvailable (const Ptr blockedPackets = nullptr, + ConstIterator pos = EMPTY) const; /** * Remove the packet in the front of the queue. * @@ -198,6 +259,17 @@ public: * \return true if the packet was removed, false otherwise */ bool Remove (Ptr packet); + /** + * Remove the item at position pos in the queue and return an iterator + * pointing to the item following the removed one. If removeExpired is + * true, all the items in the queue from the head to the given position are + * removed if their lifetime expired. + * + * \param pos the position of the item to be removed + * \param removeExpired true to remove expired items + * \return an iterator pointing to the item following the removed one + */ + ConstIterator Remove (ConstIterator pos, bool removeExpired = false); /** * Return the number of packets having destination address specified by * dest. @@ -239,6 +311,8 @@ public: */ uint32_t GetNBytes (void); + static const ConstIterator EMPTY; //!< Invalid iterator to signal an empty queue + private: /** * Remove the item pointed to by the iterator it if it has been in the @@ -253,6 +327,10 @@ private: QueueSize m_maxSize; //!< max queue size Time m_maxDelay; //!< Time to live for packets in the queue DropPolicy m_dropPolicy; //!< Drop behavior of queue + mutable bool m_expiredPacketsPresent; //!> True if expired packets are in the queue + + /// Traced callback: fired when a packet is dropped due to lifetime expiration + TracedCallback > m_traceExpired; NS_LOG_TEMPLATE_DECLARE; //!< redefinition of the log component }; diff --git a/src/wifi/model/wifi-utils.h b/src/wifi/model/wifi-utils.h index a9ff9d911..d846911e6 100644 --- a/src/wifi/model/wifi-utils.h +++ b/src/wifi/model/wifi-utils.h @@ -194,6 +194,11 @@ bool IsAmpdu (Ptr packet); */ Time GetPpduMaxTime (WifiPreamble preamble); + /// Size of the space of sequence numbers + const uint16_t SEQNO_SPACE_SIZE = 4096; + + /// Size of the half the space of sequence numbers (used to determine old packets) + const uint16_t SEQNO_SPACE_HALF_SIZE = SEQNO_SPACE_SIZE / 2; } // namespace ns3 #endif /* WIFI_UTILS_H */ diff --git a/src/wifi/test/block-ack-test-suite.cc b/src/wifi/test/block-ack-test-suite.cc index 9825a8d11..4522bd836 100644 --- a/src/wifi/test/block-ack-test-suite.cc +++ b/src/wifi/test/block-ack-test-suite.cc @@ -19,8 +19,20 @@ */ #include "ns3/test.h" +#include "ns3/string.h" #include "ns3/qos-utils.h" #include "ns3/ctrl-headers.h" +#include "ns3/packet.h" +#include "ns3/wifi-net-device.h" +#include "ns3/ap-wifi-mac.h" +#include "ns3/wifi-mac-header.h" +#include "ns3/mobility-helper.h" +#include "ns3/yans-wifi-helper.h" +#include "ns3/packet-socket-server.h" +#include "ns3/packet-socket-client.h" +#include "ns3/packet-socket-helper.h" +#include "ns3/config.h" +#include "ns3/pointer.h" using namespace ns3; @@ -306,6 +318,225 @@ CtrlBAckResponseHeaderTest::DoRun (void) NS_TEST_EXPECT_MSG_EQ (m_blockAckHdr.IsPacketReceived (80), false, "error in compressed bitmap"); } + +/** + * \ingroup wifi-test + * \ingroup tests + * + * \brief Test for Block Ack Policy with aggregation disabled + * + * This test aims to check the Block Ack policy with "legacy" 802.11, i.e., prior + * to aggregation (802.11n). The block ack threshold is set to 2, hence a block ack + * agreement is established when there are at least two packets in the EDCA queue. + * Consequently, the first packet is sent with Normal Ack policy (because a BA agreement + * has not been established yet), while all other packets are sent with Block Ack + * policy and followed by a Block Ack Request and then a Block Ack. + */ +class BlockAckAggregationDisabledTest : public TestCase +{ + /** + * Keeps the maximum duration among all TXOPs + */ + struct TxopDurationTracer + { + void Trace (Time startTime, Time duration); + Time m_max {Seconds (0)}; + }; + +public: + BlockAckAggregationDisabledTest (); + virtual ~BlockAckAggregationDisabledTest (); + + virtual void DoRun (void); + + +private: + uint32_t m_received; ///< received packets + uint16_t m_txTotal; ///< transmitted data packets + uint16_t m_nBar; ///< transmitted BlockAckReq frames + uint16_t m_nBa; ///< received BlockAck frames + + /** + * Function to trace packets received by the server application + * \param context the context + * \param p the packet + * \param adr the address + */ + void L7Receive (std::string context, Ptr p, const Address &adr); + /** + * Callback invoked when PHY transmits a packet + * \param context the context + * \param p the packet + * \param power the tx power + */ + void Transmit (std::string context, Ptr p, double power); + /** + * Callback invoked when PHY receives a packet + * \param context the context + * \param p the packet + */ + void Receive (std::string context, Ptr p); +}; + +void +BlockAckAggregationDisabledTest::TxopDurationTracer::Trace (Time startTime, Time duration) +{ + if (duration > m_max) + { + m_max = duration; + } +} + +BlockAckAggregationDisabledTest::BlockAckAggregationDisabledTest () + : TestCase ("Test case for Block Ack Policy with aggregation disabled"), + m_received (0), + m_txTotal (0), + m_nBar (0), + m_nBa (0) +{ +} + +BlockAckAggregationDisabledTest::~BlockAckAggregationDisabledTest () +{ +} + +void +BlockAckAggregationDisabledTest::L7Receive (std::string context, Ptr p, const Address &adr) +{ + if (p->GetSize () == 1400) + { + m_received++; + } +} + +void +BlockAckAggregationDisabledTest::Transmit (std::string context, Ptr p, double power) +{ + WifiMacHeader hdr; + p->PeekHeader (hdr); + + if (hdr.IsQosData ()) + { + m_txTotal++; + NS_TEST_EXPECT_MSG_EQ ((m_txTotal == 1 || hdr.IsQosBlockAck ()), true, "Unexpected QoS ack policy"); + } + else if (hdr.IsBlockAckReq ()) + { + m_nBar++; + } +} + +void +BlockAckAggregationDisabledTest::Receive (std::string context, Ptr p) +{ + WifiMacHeader hdr; + p->PeekHeader (hdr); + + if (hdr.IsBlockAck ()) + { + m_nBa++; + } +} + +void +BlockAckAggregationDisabledTest::DoRun (void) +{ + NodeContainer wifiStaNode; + wifiStaNode.Create (1); + + NodeContainer wifiApNode; + wifiApNode.Create (1); + + YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); + YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); + phy.SetChannel (channel.Create ()); + + WifiHelper wifi; + wifi.SetStandard (WIFI_PHY_STANDARD_80211a); + wifi.SetRemoteStationManager ("ns3::IdealWifiManager"); + + WifiMacHelper mac; + Ssid ssid = Ssid ("ns-3-ssid"); + mac.SetType ("ns3::StaWifiMac", + "QosSupported", BooleanValue (true), + "Ssid", SsidValue (ssid), + /* setting blockack threshold for sta's BE queue */ + "BE_BlockAckThreshold", UintegerValue (2), + "ActiveProbing", BooleanValue (false)); + + NetDeviceContainer staDevices; + staDevices = wifi.Install (phy, mac, wifiStaNode); + + mac.SetType ("ns3::ApWifiMac", + "QosSupported", BooleanValue (true), + "Ssid", SsidValue (ssid), + "BeaconGeneration", BooleanValue (true)); + + NetDeviceContainer apDevices; + apDevices = wifi.Install (phy, mac, wifiApNode); + + MobilityHelper mobility; + Ptr positionAlloc = CreateObject (); + + positionAlloc->Add (Vector (0.0, 0.0, 0.0)); + positionAlloc->Add (Vector (1.0, 0.0, 0.0)); + mobility.SetPositionAllocator (positionAlloc); + + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (wifiApNode); + mobility.Install (wifiStaNode); + + Ptr ap_device = DynamicCast (apDevices.Get (0)); + Ptr sta_device = DynamicCast (staDevices.Get (0)); + + // Disable A-MPDU aggregation + sta_device->GetMac ()->SetAttribute ("BE_MaxAmpduSize", UintegerValue (0)); + TxopDurationTracer txopTracer; + + PacketSocketAddress socket; + socket.SetSingleDevice (sta_device->GetIfIndex ()); + socket.SetPhysicalAddress (ap_device->GetAddress ()); + socket.SetProtocol (1); + + // give packet socket powers to nodes. + PacketSocketHelper packetSocket; + packetSocket.Install (wifiStaNode); + packetSocket.Install (wifiApNode); + + Ptr client = CreateObject (); + client->SetAttribute ("PacketSize", UintegerValue (1400)); + client->SetAttribute ("MaxPackets", UintegerValue (14)); + client->SetAttribute ("Interval", TimeValue (MicroSeconds (0))); + client->SetRemote (socket); + wifiStaNode.Get (0)->AddApplication (client); + client->SetStartTime (Seconds (1)); + client->SetStopTime (Seconds (3.0)); + + Ptr server = CreateObject (); + server->SetLocal (socket); + wifiApNode.Get (0)->AddApplication (server); + server->SetStartTime (Seconds (0.0)); + server->SetStopTime (Seconds (4.0)); + + Config::Connect ("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx", MakeCallback (&BlockAckAggregationDisabledTest::L7Receive, this)); + Config::Connect ("/NodeList/0/DeviceList/0/Phy/PhyTxBegin", MakeCallback (&BlockAckAggregationDisabledTest::Transmit, this)); + Config::Connect ("/NodeList/0/DeviceList/0/Phy/PhyRxBegin", MakeCallback (&BlockAckAggregationDisabledTest::Receive, this)); + + Simulator::Stop (Seconds (5)); + Simulator::Run (); + + Simulator::Destroy (); + + // The client application generates 14 packets, so we expect that the wifi PHY + // layer transmits 14 MPDUs, the server application receives 14 packets, and + // a BAR is transmitted after each MPDU but the first one (because a BA agreement + // is established before transmitting the second MPDU). + NS_TEST_EXPECT_MSG_EQ (m_txTotal, 14, "Unexpected number of transmitted packets"); + NS_TEST_EXPECT_MSG_EQ (m_received, 14, "Unexpected number of received packets"); + NS_TEST_EXPECT_MSG_EQ (m_nBar, 13, "Unexpected number of Block Ack Requests"); + NS_TEST_EXPECT_MSG_EQ (m_nBa, 13, "Unexpected number of Block Ack Responses"); +} + /** * \ingroup wifi-test * \ingroup tests @@ -324,6 +555,7 @@ BlockAckTestSuite::BlockAckTestSuite () AddTestCase (new PacketBufferingCaseA, TestCase::QUICK); AddTestCase (new PacketBufferingCaseB, TestCase::QUICK); AddTestCase (new CtrlBAckResponseHeaderTest, TestCase::QUICK); + AddTestCase (new BlockAckAggregationDisabledTest, TestCase::QUICK); } static BlockAckTestSuite g_blockAckTestSuite; ///< the test suite diff --git a/src/wifi/test/wifi-aggregation-test.cc b/src/wifi/test/wifi-aggregation-test.cc index 07fa729f3..57d9c577a 100644 --- a/src/wifi/test/wifi-aggregation-test.cc +++ b/src/wifi/test/wifi-aggregation-test.cc @@ -142,15 +142,11 @@ AmpduAggregationTest::DoRun (void) /* * Test behavior when no other packets are in the queue */ - m_mac->GetBEQueue ()->GetLow ()->m_currentPacket = Create (pkt, hdr); - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector = m_mac->GetBEQueue ()->GetLow ()->GetDataTxVector - (m_mac->GetBEQueue ()->GetLow ()->m_currentPacket->GetPayload (0), - &m_mac->GetBEQueue ()->GetLow ()->m_currentPacket->GetHeader (0)); + WifiTxVector txVector = m_mac->GetBEQueue ()->GetLow ()->GetDataTxVector (Create (pkt, hdr)); - auto mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()-> GetNextAmpdu - (Create (pkt, hdr), m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector); + auto mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()->GetNextAmpdu (Create (pkt, hdr), + txVector); NS_TEST_EXPECT_MSG_EQ (mpduList.empty (), true, "a single packet should not result in an A-MPDU"); - NS_TEST_EXPECT_MSG_EQ (m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->GetNPackets (), 0, "aggregation queue is not flushed"); //----------------------------------------------------------------------------------------------------- @@ -174,30 +170,21 @@ AmpduAggregationTest::DoRun (void) m_mac->GetBEQueue ()->GetWifiMacQueue ()->Enqueue (Create (pkt1, hdr1)); m_mac->GetBEQueue ()->GetWifiMacQueue ()->Enqueue (Create (pkt2, hdr2)); - mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()-> GetNextAmpdu (Create (pkt, hdr), - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector); - m_mac->GetBEQueue ()->GetLow ()->m_currentPacket = Create (mpduList); - for (auto& mpdu : mpduList) - { - m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->Enqueue (Create (*mpdu)); - } + mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()->GetNextAmpdu (Create (pkt, hdr), + txVector); + Ptr psdu = Create (mpduList); - uint32_t aggregationQueueSize = m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->GetNPackets (); NS_TEST_EXPECT_MSG_EQ (mpduList.empty (), false, "MPDU aggregation failed"); - NS_TEST_EXPECT_MSG_EQ (m_mac->GetBEQueue ()->GetLow ()->m_currentPacket->GetSize (), 4606, "A-MPDU size is not correct"); - NS_TEST_EXPECT_MSG_EQ (aggregationQueueSize, 3, "aggregation queue should not be empty"); + NS_TEST_EXPECT_MSG_EQ (psdu->GetSize (), 4606, "A-MPDU size is not correct"); + NS_TEST_EXPECT_MSG_EQ (mpduList.size (), 3, "A-MPDU should contain 3 MPDUs"); NS_TEST_EXPECT_MSG_EQ (m_mac->GetBEQueue ()->GetWifiMacQueue ()->GetNPackets (), 0, "queue should be empty"); Ptr dequeuedItem; WifiMacHeader dequeuedHdr; - uint32_t i = 0; - for (; aggregationQueueSize > 0; aggregationQueueSize--, i++) + for (uint32_t i = 0; i < psdu->GetNMpdus (); i++) { - dequeuedItem = m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->Dequeue (); - dequeuedHdr = dequeuedItem->GetHeader (); - NS_TEST_EXPECT_MSG_EQ (dequeuedHdr.GetSequenceNumber (), i, "wrong sequence number"); + NS_TEST_EXPECT_MSG_EQ (psdu->GetHeader (i).GetSequenceNumber (), i, "wrong sequence number"); } - NS_TEST_EXPECT_MSG_EQ (aggregationQueueSize, 0, "aggregation queue should be empty"); //----------------------------------------------------------------------------------------------------- @@ -228,19 +215,17 @@ AmpduAggregationTest::DoRun (void) m_mac->GetBEQueue ()->GetWifiMacQueue ()->Enqueue (Create (pkt3, hdr3)); - mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()-> GetNextAmpdu (Create (pkt1, hdr1), - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector); + mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()->GetNextAmpdu (Create (pkt1, hdr1), + txVector); NS_TEST_EXPECT_MSG_EQ (mpduList.empty (), true, "a single packet for this destination should not result in an A-MPDU"); - NS_TEST_EXPECT_MSG_EQ (m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->GetNPackets (), 0, "aggregation queue is not flushed"); - m_mac->GetBEQueue ()->m_currentHdr = hdr2; - m_mac->GetBEQueue ()->m_currentPacket = pkt2->Copy (); - mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()-> GetNextAmpdu - (Create (pkt2, hdr2), m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector); + mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()->GetNextAmpdu (Create (pkt2, hdr2), + txVector); NS_TEST_EXPECT_MSG_EQ (mpduList.empty (), true, "no MPDU aggregation should be performed if there is no agreement"); - NS_TEST_EXPECT_MSG_EQ (m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->GetNPackets (), 0, "aggregation queue is not flushed"); m_manager->SetMaxSsrc (0); //set to 0 in order to fake that the maximum number of retries has been reached + m_mac->GetBEQueue ()->m_currentHdr = hdr2; + m_mac->GetBEQueue ()->m_currentPacket = pkt2->Copy (); m_mac->GetBEQueue ()->MissedAck (); NS_TEST_EXPECT_MSG_EQ (m_mac->GetBEQueue ()->m_currentPacket, 0, "packet should be discarded"); @@ -329,19 +314,18 @@ TwoLevelAggregationTest::DoRun (void) HtCapabilities htCapabilities; htCapabilities.SetMaxAmsduLength (7935); htCapabilities.SetMaxAmpduLength (65535); - m_manager->AddStationHtCapabilities (Mac48Address ("00:00:00:00:00:01"), htCapabilities); + m_manager->AddStationHtCapabilities (Mac48Address ("00:00:00:00:00:02"), htCapabilities); /* * Create dummy packets of 1500 bytes and fill mac header fields that will be used for the tests. */ Ptr pkt = Create (1500); Ptr currentAggregatedPacket = Create (); - WifiMacHeader hdr, peekedHdr; - hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:01")); - hdr.SetAddr2 (Mac48Address ("00:00:00:00:00:02")); + WifiMacHeader hdr; + hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:02")); + hdr.SetAddr2 (Mac48Address ("00:00:00:00:00:01")); hdr.SetType (WIFI_MAC_QOSDATA); hdr.SetQosTid (0); - Time tstamp; //----------------------------------------------------------------------------------------------------- @@ -355,18 +339,10 @@ TwoLevelAggregationTest::DoRun (void) m_mac->GetBEQueue ()->GetWifiMacQueue ()->Enqueue (Create (pkt, hdr)); m_mac->GetBEQueue ()->GetWifiMacQueue ()->Enqueue (Create (pkt, hdr)); - Ptr peekedItem = m_mac->GetBEQueue ()->GetWifiMacQueue ()->PeekByTidAndAddress (0, hdr.GetAddr1 ()); - Ptr peekedPacket = peekedItem->GetPacket (); - peekedHdr = peekedItem->GetHeader (); - tstamp = peekedItem->GetTimeStamp (); - m_mac->GetBEQueue ()->GetLow ()->m_currentPacket = Create (peekedPacket, peekedHdr); - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector = m_mac->GetBEQueue ()->GetLow ()->GetDataTxVector - (m_mac->GetBEQueue ()->GetLow ()->m_currentPacket->GetPayload (0), - &m_mac->GetBEQueue ()->GetLow ()->m_currentPacket->GetHeader (0)); + WifiTxVector txVector = m_mac->GetBEQueue ()->GetLow ()->GetDataTxVector (Create (pkt, hdr)); Ptr item; - item = m_mac->GetBEQueue ()->GetLow ()->GetMsduAggregator ()->GetNextAmsdu (hdr.GetAddr1 (), 0, - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector, + item = m_mac->GetBEQueue ()->GetLow ()->GetMsduAggregator ()->GetNextAmsdu (hdr.GetAddr1 (), 0, txVector, currentAggregatedPacket->GetSize ()); bool result = (item != 0); NS_TEST_EXPECT_MSG_EQ (result, true, "aggregation failed"); @@ -385,8 +361,7 @@ TwoLevelAggregationTest::DoRun (void) m_mac->GetBEQueue ()->GetWifiMacQueue ()->Enqueue (Create (pkt, hdr)); - item = m_mac->GetBEQueue ()->GetLow ()->GetMsduAggregator ()->GetNextAmsdu (hdr.GetAddr1 (), 0, - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector, + item = m_mac->GetBEQueue ()->GetLow ()->GetMsduAggregator ()->GetNextAmsdu (hdr.GetAddr1 (), 0, txVector, currentAggregatedPacket->GetSize ()); result = (item != 0); NS_TEST_EXPECT_MSG_EQ (result, false, "maximum aggregated frame size check failed"); @@ -403,13 +378,74 @@ TwoLevelAggregationTest::DoRun (void) m_mac->GetBEQueue ()->GetWifiMacQueue ()->Remove (pkt); m_mac->GetBEQueue ()->GetWifiMacQueue ()->Remove (pkt); - item = m_mac->GetBEQueue ()->GetLow ()->GetMsduAggregator ()->GetNextAmsdu (hdr.GetAddr1 (), 0, - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector, + item = m_mac->GetBEQueue ()->GetLow ()->GetMsduAggregator ()->GetNextAmsdu (hdr.GetAddr1 (), 0, txVector, currentAggregatedPacket->GetSize ()); result = (item != 0); NS_TEST_EXPECT_MSG_EQ (result, false, "aggregation failed to stop as queue is empty"); + //----------------------------------------------------------------------------------------------------- + + /* + * Aggregation of MPDUs is stopped to prevent that the PPDU duration exceeds the TXOP limit. + * In this test, the VI AC is used, which has a default TXOP limit of 3008 microseconds. + */ + + // Establish agreement. + uint8_t tid = 5; + MgtAddBaRequestHeader reqHdr; + reqHdr.SetImmediateBlockAck (); + reqHdr.SetTid (tid); + reqHdr.SetBufferSize (64); + reqHdr.SetTimeout (0); + reqHdr.SetStartingSequence (0); + m_mac->GetVIQueue ()->m_baManager->CreateAgreement (&reqHdr, hdr.GetAddr1 ()); + m_mac->GetVIQueue ()->m_baManager->NotifyAgreementEstablished (hdr.GetAddr1 (), tid, 0); + + m_mac->SetAttribute ("VI_MaxAmsduSize", UintegerValue (3050)); // max 2 MSDUs per A-MSDU + m_mac->SetAttribute ("VI_MaxAmpduSize", UintegerValue (65535)); + m_manager->SetAttribute ("DataMode", StringValue ("HtMcs2")); // 19.5Mbps + + pkt = Create (1400); + hdr.SetQosTid (tid); + + // Add 10 MSDUs to the EDCA queue + for (uint8_t i = 0; i < 10; i++) + { + m_mac->GetVIQueue ()->GetWifiMacQueue ()->Enqueue (Create (pkt, hdr)); + } + + txVector = m_mac->GetVIQueue ()->GetLow ()->GetDataTxVector (Create (pkt, hdr)); + Time txopLimit = m_mac->GetVIQueue ()->GetTxopLimit (); // 3.008 ms + + // Compute the first MPDU to be aggregated in an A-MPDU. It must contain an A-MSDU + // aggregating two MSDUs + Ptr mpdu = m_mac->GetVIQueue ()->GetLow ()->GetMsduAggregator ()->GetNextAmsdu (hdr.GetAddr1 (), tid, + txVector, 0, txopLimit); + NS_TEST_EXPECT_MSG_EQ (m_mac->GetVIQueue ()->GetWifiMacQueue ()->GetNPackets (), 8, "There must be 8 MSDUs left in EDCA queue"); + + auto mpduList = m_mac->GetVIQueue ()->GetLow ()->GetMpduAggregator ()->GetNextAmpdu (mpdu, txVector, txopLimit); + + // The maximum number of bytes that can be transmitted in a TXOP is (approximately, as we + // do not consider that the preamble is transmitted at a different rate): + // 19.5 Mbps * 3.008 ms = 7332 bytes + // Given that the max A-MSDU size is set to 3050, an A-MSDU will contain two MSDUs and have + // a size of 2 * 1400 (MSDU size) + 2 * 14 (A-MSDU subframe header size) + 2 (one padding field) = 2830 bytes + // Hence, we expect that the A-MPDU will consist of: + // - 2 MPDUs containing each an A-MSDU. The size of each MPDU is 2830 (A-MSDU) + 30 (header+trailer) = 2860 + // - 1 MPDU containing a single MSDU. The size of such MPDU is 1400 (MSDU) + 30 (header+trailer) = 1430 + // The size of the A-MPDU is 4 + 2860 + 4 + 2860 + 4 + 1430 = 7162 + NS_TEST_EXPECT_MSG_EQ (mpduList.empty (), false, "aggregation failed"); + NS_TEST_EXPECT_MSG_EQ (mpduList.size (), 3, "Unexpected number of MPDUs in the A-MPDU"); + NS_TEST_EXPECT_MSG_EQ (mpduList.at (0)->GetSize (), 2860, "Unexpected size of the first MPDU"); + NS_TEST_EXPECT_MSG_EQ (mpduList.at (1)->GetSize (), 2860, "Unexpected size of the second MPDU"); + NS_TEST_EXPECT_MSG_EQ (mpduList.at (2)->GetSize (), 1430, "Unexpected size of the first MPDU"); + NS_TEST_EXPECT_MSG_EQ (m_mac->GetVIQueue ()->GetWifiMacQueue ()->GetNPackets (), 5, + "Unexpected number of MSDUs left in the EDCA queue"); + + Ptr psdu = Create (mpduList); + NS_TEST_EXPECT_MSG_EQ (psdu->GetSize (), 7162, "Unexpected size of the A-MPDU"); + Simulator::Destroy (); m_device->Dispose (); @@ -520,14 +556,6 @@ HeAggregationTest::DoRunSubTest (uint16_t bufferSize) m_mac->GetBEQueue ()->m_baManager->CreateAgreement (&reqHdr, hdr.GetAddr1 ()); m_mac->GetBEQueue ()->m_baManager->NotifyAgreementEstablished (hdr.GetAddr1 (), 0, 0); - /* - * Prepare MacLow for transmission - */ - m_mac->GetBEQueue ()->GetLow ()->m_currentPacket = Create (pkt, hdr); - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector = m_mac->GetBEQueue ()->GetLow ()->GetDataTxVector - (m_mac->GetBEQueue ()->GetLow ()->m_currentPacket->GetPayload (0), - &m_mac->GetBEQueue ()->GetLow ()->m_currentPacket->GetHeader (0)); - /* * Test behavior when 300 packets are ready for transmission but negociated buffer size is 64 */ @@ -544,16 +572,12 @@ HeAggregationTest::DoRunSubTest (uint16_t bufferSize) m_mac->GetBEQueue ()->GetWifiMacQueue ()->Enqueue (Create (pkt, hdr)); } - auto mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()-> GetNextAmpdu (Create (pkt, hdr), - m_mac->GetBEQueue ()->GetLow ()->m_currentTxVector); - for (auto& mpdu : mpduList) - { - m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->Enqueue (Create (*mpdu)); - } + WifiTxVector txVector = m_mac->GetBEQueue ()->GetLow ()->GetDataTxVector (Create (pkt, hdr)); + auto mpduList = m_mac->GetBEQueue ()->GetLow ()->GetMpduAggregator ()-> GetNextAmpdu (Create (pkt, hdr), + txVector); NS_TEST_EXPECT_MSG_EQ (mpduList.empty (), false, "MPDU aggregation failed"); - uint32_t aggregationQueueSize = m_mac->GetBEQueue ()->GetLow ()->m_aggregateQueue[0]->GetNPackets (); - NS_TEST_EXPECT_MSG_EQ (aggregationQueueSize, bufferSize, "aggregation queue should countain " << bufferSize << " MPDUs"); + NS_TEST_EXPECT_MSG_EQ (mpduList.size (), bufferSize, "A-MPDU should countain " << bufferSize << " MPDUs"); uint16_t expectedRemainingPacketsInQueue = 300 - bufferSize + 1; NS_TEST_EXPECT_MSG_EQ (m_mac->GetBEQueue ()->GetWifiMacQueue ()->GetNPackets (), expectedRemainingPacketsInQueue, "queue should contain 300 - "<< bufferSize - 1 << " = "<< expectedRemainingPacketsInQueue << " packets"); diff --git a/src/wifi/test/wifi-test.cc b/src/wifi/test/wifi-test.cc index 37c02ed20..9557dc550 100644 --- a/src/wifi/test/wifi-test.cc +++ b/src/wifi/test/wifi-test.cc @@ -689,6 +689,169 @@ Bug730TestCase::DoRun (void) NS_TEST_ASSERT_MSG_EQ (result, true, "packet reception unexpectedly stopped after adapting fragmentation threshold!"); } +//----------------------------------------------------------------------------- +/** + * Make sure that fragmentation works with QoS stations. + * + * The scenario considers a TCP transmission between an 802.11n station and an 802.11n + * access point. + */ + +class QosFragmentationTestCase : public TestCase +{ +public: + QosFragmentationTestCase (); + virtual ~QosFragmentationTestCase (); + + virtual void DoRun (void); + + +private: + uint32_t m_received; ///< received packets + uint32_t m_fragments; ///< transmitted fragments + + /** + * Receive function + * \param context the context + * \param p the packet + * \param adr the address + */ + void Receive (std::string context, Ptr p, const Address &adr); + + /** + * Callback invoked when PHY transmits a packet + * \param context the context + * \param p the packet + * \param power the tx power + */ + void Transmit (std::string context, Ptr p, double power); +}; + +QosFragmentationTestCase::QosFragmentationTestCase () + : TestCase ("Test case for fragmentation with QoS stations"), + m_received (0), + m_fragments (0) +{ +} + +QosFragmentationTestCase::~QosFragmentationTestCase () +{ +} + +void +QosFragmentationTestCase::Receive (std::string context, Ptr p, const Address &adr) +{ + if (p->GetSize () == 1400) + { + m_received++; + } +} + +void +QosFragmentationTestCase::Transmit (std::string context, Ptr p, double power) +{ + WifiMacHeader hdr; + p->PeekHeader (hdr); + if (hdr.IsQosData ()) + { + NS_TEST_EXPECT_MSG_LT_OR_EQ (p->GetSize (), 400, "Unexpected fragment size"); + m_fragments++; + } +} + +void +QosFragmentationTestCase::DoRun (void) +{ + NodeContainer wifiStaNode; + wifiStaNode.Create (1); + + NodeContainer wifiApNode; + wifiApNode.Create (1); + + YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); + YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); + phy.SetChannel (channel.Create ()); + + WifiHelper wifi; + wifi.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ); + wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", + "DataMode", StringValue ("HtMcs7")); + + WifiMacHelper mac; + Ssid ssid = Ssid ("ns-3-ssid"); + mac.SetType ("ns3::StaWifiMac", + "Ssid", SsidValue (ssid), + "ActiveProbing", BooleanValue (false)); + + NetDeviceContainer staDevices; + staDevices = wifi.Install (phy, mac, wifiStaNode); + + mac.SetType ("ns3::ApWifiMac", + "Ssid", SsidValue (ssid), + "BeaconGeneration", BooleanValue (true)); + + NetDeviceContainer apDevices; + apDevices = wifi.Install (phy, mac, wifiApNode); + + MobilityHelper mobility; + Ptr positionAlloc = CreateObject (); + + positionAlloc->Add (Vector (0.0, 0.0, 0.0)); + positionAlloc->Add (Vector (1.0, 0.0, 0.0)); + mobility.SetPositionAllocator (positionAlloc); + + mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel"); + mobility.Install (wifiApNode); + mobility.Install (wifiStaNode); + + Ptr ap_device = DynamicCast (apDevices.Get (0)); + Ptr sta_device = DynamicCast (staDevices.Get (0)); + + // set the TXOP limit on BE AC + Ptr sta_mac = DynamicCast (sta_device->GetMac ()); + NS_ASSERT (sta_mac); + PointerValue ptr; + sta_mac->GetAttribute ("BE_Txop", ptr); + ptr.Get ()->SetTxopLimit (MicroSeconds (3008)); + + PacketSocketAddress socket; + socket.SetSingleDevice (sta_device->GetIfIndex ()); + socket.SetPhysicalAddress (ap_device->GetAddress ()); + socket.SetProtocol (1); + + // give packet socket powers to nodes. + PacketSocketHelper packetSocket; + packetSocket.Install (wifiStaNode); + packetSocket.Install (wifiApNode); + + Ptr client = CreateObject (); + client->SetAttribute ("PacketSize", UintegerValue (1400)); + client->SetAttribute ("MaxPackets", UintegerValue (1)); + client->SetRemote (socket); + wifiStaNode.Get (0)->AddApplication (client); + client->SetStartTime (Seconds (1)); + client->SetStopTime (Seconds (3.0)); + + Ptr server = CreateObject (); + server->SetLocal (socket); + wifiApNode.Get (0)->AddApplication (server); + server->SetStartTime (Seconds (0.0)); + server->SetStopTime (Seconds (4.0)); + + Config::Connect ("/NodeList/*/ApplicationList/0/$ns3::PacketSocketServer/Rx", MakeCallback (&QosFragmentationTestCase::Receive, this)); + + Config::Set ("/NodeList/0/DeviceList/0/RemoteStationManager/FragmentationThreshold", StringValue ("400")); + Config::Connect ("/NodeList/0/DeviceList/0/Phy/PhyTxBegin", MakeCallback (&QosFragmentationTestCase::Transmit, this)); + + Simulator::Stop (Seconds (5)); + Simulator::Run (); + + Simulator::Destroy (); + + NS_TEST_ASSERT_MSG_EQ (m_received, 1, "Unexpected number of received packets"); + NS_TEST_ASSERT_MSG_EQ (m_fragments, 4, "Unexpected number of transmitted fragments"); +} + /** * \ingroup wifi-test * \ingroup tests @@ -1778,7 +1941,6 @@ private: uint8_t m_receivedNormalMpduCount; ///< Count received normal MPDU packets on STA uint8_t m_receivedAmpduCount; ///< Count received A-MPDU packets on STA uint8_t m_droppedActionCount; ///< Count dropped ADDBA request/response - uint8_t m_addbaInactiveCount; ///< Count number of times ADDBA state machine is in inactive state uint8_t m_addbaEstablishedCount; ///< Count number of times ADDBA state machine is in established state uint8_t m_addbaPendingCount; ///< Count number of times ADDBA state machine is in pending state uint8_t m_addbaRejectedCount; ///< Count number of times ADDBA state machine is in rejected state @@ -1791,7 +1953,6 @@ Bug2470TestCase::Bug2470TestCase () m_receivedNormalMpduCount (0), m_receivedAmpduCount (0), m_droppedActionCount (0), - m_addbaInactiveCount (0), m_addbaEstablishedCount (0), m_addbaPendingCount (0), m_addbaRejectedCount (0), @@ -1809,9 +1970,6 @@ Bug2470TestCase::AddbaStateChangedCallback (std::string context, Time t, Mac48Ad { switch (state) { - case OriginatorBlockAckAgreement::INACTIVE: - m_addbaInactiveCount++; - break; case OriginatorBlockAckAgreement::ESTABLISHED: m_addbaEstablishedCount++; break; @@ -1958,7 +2116,6 @@ Bug2470TestCase::DoRun (void) NS_TEST_ASSERT_MSG_EQ (m_receivedNormalMpduCount, 2, "Receiving incorrect number of normal MPDU packet on subtest 1"); NS_TEST_ASSERT_MSG_EQ (m_receivedAmpduCount, 8, "Receiving incorrect number of A-MPDU packet on subtest 1"); - NS_TEST_ASSERT_MSG_EQ (m_addbaInactiveCount, 0, "Incorrect number of times the ADDBA state machine was in inactive state on subtest 1"); NS_TEST_ASSERT_MSG_EQ (m_addbaEstablishedCount, 1, "Incorrect number of times the ADDBA state machine was in established state on subtest 1"); NS_TEST_ASSERT_MSG_EQ (m_addbaPendingCount, 1, "Incorrect number of times the ADDBA state machine was in pending state on subtest 1"); NS_TEST_ASSERT_MSG_EQ (m_addbaRejectedCount, 0, "Incorrect number of times the ADDBA state machine was in rejected state on subtest 1"); @@ -1969,7 +2126,6 @@ Bug2470TestCase::DoRun (void) m_receivedNormalMpduCount = 0; m_receivedAmpduCount = 0; m_droppedActionCount = 0; - m_addbaInactiveCount = 0; m_addbaEstablishedCount = 0; m_addbaPendingCount = 0; m_addbaRejectedCount = 0; @@ -1991,7 +2147,6 @@ Bug2470TestCase::DoRun (void) NS_TEST_ASSERT_MSG_EQ (m_receivedNormalMpduCount, 6, "Receiving incorrect number of normal MPDU packet on subtest 2"); NS_TEST_ASSERT_MSG_EQ (m_receivedAmpduCount, 4, "Receiving incorrect number of A-MPDU packet on subtest 2"); - NS_TEST_ASSERT_MSG_EQ (m_addbaInactiveCount, 0, "Incorrect number of times the ADDBA state machine was in inactive state on subtest 2"); NS_TEST_ASSERT_MSG_EQ (m_addbaEstablishedCount, 1, "Incorrect number of times the ADDBA state machine was in established state on subtest 2"); NS_TEST_ASSERT_MSG_EQ (m_addbaPendingCount, 1, "Incorrect number of times the ADDBA state machine was in pending state on subtest 2"); NS_TEST_ASSERT_MSG_EQ (m_addbaRejectedCount, 0, "Incorrect number of times the ADDBA state machine was in rejected state on subtest 2"); @@ -2023,6 +2178,7 @@ WifiTestSuite::WifiTestSuite () AddTestCase (new InterferenceHelperSequenceTest, TestCase::QUICK); //Bug 991 AddTestCase (new DcfImmediateAccessBroadcastTestCase, TestCase::QUICK); AddTestCase (new Bug730TestCase, TestCase::QUICK); //Bug 730 + AddTestCase (new QosFragmentationTestCase, TestCase::QUICK); AddTestCase (new SetChannelFrequencyTest, TestCase::QUICK); AddTestCase (new Bug2222TestCase, TestCase::QUICK); //Bug 2222 AddTestCase (new Bug2843TestCase, TestCase::QUICK); //Bug 2843