wifi: Add a test for 802.11e Block Ack policy

This commit is contained in:
Stefano Avallone
2019-05-09 12:44:27 +02:00
parent 7f5efd1d2d
commit 54a0e0f467

View File

@@ -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<const Packet> 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<const Packet> p, double power);
/**
* Callback invoked when PHY receives a packet
* \param context the context
* \param p the packet
*/
void Receive (std::string context, Ptr<const Packet> 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<const Packet> p, const Address &adr)
{
if (p->GetSize () == 1400)
{
m_received++;
}
}
void
BlockAckAggregationDisabledTest::Transmit (std::string context, Ptr<const Packet> 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<const Packet> 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<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
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<WifiNetDevice> ap_device = DynamicCast<WifiNetDevice> (apDevices.Get (0));
Ptr<WifiNetDevice> sta_device = DynamicCast<WifiNetDevice> (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<PacketSocketClient> client = CreateObject<PacketSocketClient> ();
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<PacketSocketServer> server = CreateObject<PacketSocketServer> ();
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