|
|
| 26 |
#include "ns3/mac-low.h" |
26 |
#include "ns3/mac-low.h" |
| 27 |
#include "ns3/edca-txop-n.h" |
27 |
#include "ns3/edca-txop-n.h" |
| 28 |
#include "ns3/yans-wifi-phy.h" |
28 |
#include "ns3/yans-wifi-phy.h" |
|
|
29 |
#include "ns3/mac-tx-middle.h" |
| 30 |
#include "ns3/dcf-manager.h" |
| 31 |
#include "ns3/ampdu-tag.h" |
| 32 |
#include "ns3/wifi-mac-trailer.h" |
| 33 |
#include "ns3/log.h" |
| 29 |
|
34 |
|
| 30 |
using namespace ns3; |
35 |
using namespace ns3; |
| 31 |
|
36 |
|
|
|
37 |
class AmpduAggregationTest : public TestCase |
| 38 |
{ |
| 39 |
public: |
| 40 |
AmpduAggregationTest (); |
| 41 |
|
| 42 |
private: |
| 43 |
virtual void DoRun (void); |
| 44 |
Ptr<MacLow> m_low; |
| 45 |
Ptr<YansWifiPhy> m_phy; |
| 46 |
Ptr<EdcaTxopN> m_edca; |
| 47 |
MacTxMiddle *m_txMiddle; |
| 48 |
Ptr<WifiRemoteStationManager> m_manager; |
| 49 |
ObjectFactory m_factory; |
| 50 |
Ptr<MpduAggregator> m_mpduAggregator; |
| 51 |
DcfManager *m_dcfManager; |
| 52 |
}; |
| 53 |
|
| 54 |
AmpduAggregationTest::AmpduAggregationTest () |
| 55 |
: TestCase ("Check the correctness of MPDU aggregation operations") |
| 56 |
{ |
| 57 |
} |
| 58 |
|
| 59 |
void |
| 60 |
AmpduAggregationTest::DoRun (void) |
| 61 |
{ |
| 62 |
LogComponentEnable("MacLow", LOG_LEVEL_ALL); |
| 63 |
LogComponentEnable("EdcaTxopN", LOG_LEVEL_ALL); |
| 64 |
|
| 65 |
/* |
| 66 |
* Create and configure phy layer. |
| 67 |
*/ |
| 68 |
m_phy = CreateObject<YansWifiPhy> (); |
| 69 |
m_phy->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ); |
| 70 |
|
| 71 |
/* |
| 72 |
* Create and configure manager. |
| 73 |
*/ |
| 74 |
m_factory = ObjectFactory (); |
| 75 |
m_factory.SetTypeId ("ns3::ConstantRateWifiManager"); |
| 76 |
m_factory.Set ("DataMode", StringValue ("HtMcs7")); |
| 77 |
m_manager = m_factory.Create<WifiRemoteStationManager> (); |
| 78 |
m_manager->SetupPhy (m_phy); |
| 79 |
m_manager->SetHtSupported (true); |
| 80 |
|
| 81 |
/* |
| 82 |
* Create and configure mac layer. |
| 83 |
*/ |
| 84 |
m_low = CreateObject<MacLow> (); |
| 85 |
m_low->SetPhy (m_phy); |
| 86 |
m_low->SetWifiRemoteStationManager (m_manager); |
| 87 |
m_low->SetAddress (Mac48Address ("00:00:00:00:00:01")); |
| 88 |
|
| 89 |
m_dcfManager = new DcfManager (); |
| 90 |
m_dcfManager->SetupLowListener (m_low); |
| 91 |
m_dcfManager->SetupPhyListener (m_phy); |
| 92 |
m_dcfManager->SetSlot (MicroSeconds (9)); |
| 93 |
|
| 94 |
m_edca = CreateObject<EdcaTxopN> (); |
| 95 |
m_edca->SetLow (m_low); |
| 96 |
m_edca->SetAccessCategory (AC_BE); |
| 97 |
m_edca->SetWifiRemoteStationManager (m_manager); |
| 98 |
m_edca->SetManager (m_dcfManager); |
| 99 |
|
| 100 |
m_txMiddle = new MacTxMiddle (); |
| 101 |
m_edca->SetTxMiddle (m_txMiddle); |
| 102 |
m_edca->CompleteConfig (); |
| 103 |
|
| 104 |
/* |
| 105 |
* Configure MPDU aggregation. |
| 106 |
*/ |
| 107 |
m_factory = ObjectFactory (); |
| 108 |
m_factory.SetTypeId ("ns3::MpduStandardAggregator"); |
| 109 |
m_factory.Set ("MaxAmpduSize", UintegerValue (65535)); |
| 110 |
m_mpduAggregator = m_factory.Create<MpduAggregator> (); |
| 111 |
m_low->SetMpduAggregator (m_mpduAggregator); |
| 112 |
|
| 113 |
/* |
| 114 |
* Create a dummy packet of 1500 bytes and fill mac header fields. |
| 115 |
*/ |
| 116 |
Ptr<const Packet> pkt = Create<Packet> (1500); |
| 117 |
Ptr<Packet> currentAggregatedPacket = Create<Packet> (); |
| 118 |
WifiMacHeader hdr; |
| 119 |
hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:02")); |
| 120 |
hdr.SetAddr2 (Mac48Address ("00:00:00:00:00:01")); |
| 121 |
hdr.SetType (WIFI_MAC_QOSDATA); |
| 122 |
hdr.SetQosTid (0); |
| 123 |
uint16_t sequence = m_txMiddle->GetNextSequenceNumberfor (&hdr); |
| 124 |
hdr.SetSequenceNumber (sequence); |
| 125 |
hdr.SetFragmentNumber (0); |
| 126 |
hdr.SetNoMoreFragments (); |
| 127 |
hdr.SetNoRetry (); |
| 128 |
|
| 129 |
/* |
| 130 |
* Establish agreement. |
| 131 |
*/ |
| 132 |
MgtAddBaRequestHeader reqHdr; |
| 133 |
reqHdr.SetImmediateBlockAck (); |
| 134 |
reqHdr.SetTid (0); |
| 135 |
reqHdr.SetBufferSize (0); |
| 136 |
reqHdr.SetTimeout (0); |
| 137 |
reqHdr.SetStartingSequence (0); |
| 138 |
m_edca->m_baManager->CreateAgreement (&reqHdr, hdr.GetAddr1 ()); |
| 139 |
|
| 140 |
//----------------------------------------------------------------------------------------------------- |
| 141 |
|
| 142 |
/* |
| 143 |
* Test behavior when no other packets are in the queue |
| 144 |
*/ |
| 145 |
m_low->m_currentHdr = hdr; |
| 146 |
m_low->m_currentPacket = pkt->Copy(); |
| 147 |
bool isAmpdu = m_low->IsAmpdu (pkt, hdr); |
| 148 |
NS_TEST_EXPECT_MSG_EQ (isAmpdu, false, "a single packet should not result in an A-MPDU"); |
| 149 |
NS_TEST_EXPECT_MSG_EQ (m_low->m_aggregateQueue->GetSize (), 0, "aggregation queue is not flushed"); |
| 150 |
|
| 151 |
//----------------------------------------------------------------------------------------------------- |
| 152 |
|
| 153 |
/* |
| 154 |
* Test behavior when 2 more packets are in the queue |
| 155 |
*/ |
| 156 |
Ptr<const Packet> pkt1 = Create<Packet> (1500); |
| 157 |
Ptr<const Packet> pkt2 = Create<Packet> (1500); |
| 158 |
WifiMacHeader hdr1, hdr2; |
| 159 |
|
| 160 |
hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:02")); |
| 161 |
hdr1.SetAddr2 (Mac48Address ("00:00:00:00:00:01")); |
| 162 |
hdr1.SetType (WIFI_MAC_QOSDATA); |
| 163 |
hdr1.SetQosTid (0); |
| 164 |
|
| 165 |
hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:02")); |
| 166 |
hdr2.SetAddr2 (Mac48Address ("00:00:00:00:00:01")); |
| 167 |
hdr2.SetType (WIFI_MAC_QOSDATA); |
| 168 |
hdr2.SetQosTid (0); |
| 169 |
|
| 170 |
m_edca->GetEdcaQueue ()->Enqueue (pkt1, hdr1); |
| 171 |
m_edca->GetEdcaQueue ()->Enqueue (pkt2, hdr2); |
| 172 |
|
| 173 |
isAmpdu = m_low->IsAmpdu (pkt, hdr); |
| 174 |
uint32_t aggregationQueueSize = m_low->m_aggregateQueue->GetSize (); |
| 175 |
NS_TEST_EXPECT_MSG_EQ (isAmpdu, true, "MPDU aggregation failed"); |
| 176 |
NS_TEST_EXPECT_MSG_EQ (m_low->m_currentPacket->GetSize (), 4606, "A-MPDU size is not correct"); |
| 177 |
NS_TEST_EXPECT_MSG_EQ (aggregationQueueSize, 3, "aggregation queue should not be empty"); |
| 178 |
NS_TEST_EXPECT_MSG_EQ (m_edca->GetEdcaQueue ()->GetSize (), 0, "queue should be empty"); |
| 179 |
|
| 180 |
Ptr <const Packet> dequeuedPacket; |
| 181 |
WifiMacHeader dequeuedHdr; |
| 182 |
uint32_t i = 0; |
| 183 |
for (; aggregationQueueSize > 0; aggregationQueueSize--, i++) |
| 184 |
{ |
| 185 |
dequeuedPacket = m_low->m_aggregateQueue->Dequeue (&dequeuedHdr); |
| 186 |
NS_TEST_EXPECT_MSG_EQ (dequeuedHdr.GetSequenceNumber (), i, "wrong sequence number"); |
| 187 |
} |
| 188 |
NS_TEST_EXPECT_MSG_EQ (aggregationQueueSize, 0, "aggregation queue should be empty"); |
| 189 |
|
| 190 |
//----------------------------------------------------------------------------------------------------- |
| 191 |
|
| 192 |
/* |
| 193 |
* Test behavior when the 802.11n station and another non-QoS station are associated to the AP. |
| 194 |
* The AP sends an A-MPDU to the 802.11n station followed by the last retransmission of a non-QoS data frame to the non-QoS station. |
| 195 |
* This is used to reproduce bug 2224. |
| 196 |
*/ |
| 197 |
pkt1 = Create<Packet> (1500); |
| 198 |
pkt2 = Create<Packet> (1500); |
| 199 |
hdr1.SetAddr1 (Mac48Address ("00:00:00:00:00:02")); |
| 200 |
hdr1.SetAddr2 (Mac48Address ("00:00:00:00:00:01")); |
| 201 |
hdr1.SetType (WIFI_MAC_QOSDATA); |
| 202 |
hdr1.SetQosTid (0); |
| 203 |
hdr1.SetSequenceNumber (3); |
| 204 |
hdr2.SetAddr1 (Mac48Address ("00:00:00:00:00:03")); |
| 205 |
hdr2.SetAddr2 (Mac48Address ("00:00:00:00:00:01")); |
| 206 |
hdr2.SetType (WIFI_MAC_DATA); |
| 207 |
hdr2.SetQosTid (0); |
| 208 |
|
| 209 |
Ptr<const Packet> pkt3 = Create<Packet> (1500); |
| 210 |
WifiMacHeader hdr3; |
| 211 |
hdr3.SetSequenceNumber (0); |
| 212 |
hdr3.SetAddr1 (Mac48Address ("00:00:00:00:00:03")); |
| 213 |
hdr3.SetAddr2 (Mac48Address ("00:00:00:00:00:01")); |
| 214 |
hdr3.SetType (WIFI_MAC_DATA); |
| 215 |
hdr3.SetQosTid (0); |
| 216 |
|
| 217 |
m_edca->GetEdcaQueue ()->Enqueue (pkt3, hdr3); |
| 218 |
|
| 219 |
isAmpdu = m_low->IsAmpdu (pkt1, hdr1); |
| 220 |
NS_TEST_EXPECT_MSG_EQ (isAmpdu, false, "a single packet for this destination should not result in an A-MPDU"); |
| 221 |
NS_TEST_EXPECT_MSG_EQ (m_low->m_aggregateQueue->GetSize (), 0, "aggregation queue is not flushed"); |
| 222 |
|
| 223 |
m_edca->m_currentHdr = hdr2; |
| 224 |
m_edca->m_currentPacket = pkt2->Copy (); |
| 225 |
isAmpdu = m_low->IsAmpdu (pkt2, hdr2); |
| 226 |
NS_TEST_EXPECT_MSG_EQ (isAmpdu, false, "no MPDU aggregation should be performed if there is no agreement"); |
| 227 |
NS_TEST_EXPECT_MSG_EQ (m_low->m_aggregateQueue->GetSize (), 0, "aggregation queue is not flushed"); |
| 228 |
|
| 229 |
m_manager->SetMaxSlrc (0); //set to 0 in order to fake that the maximum number of retries has been reached |
| 230 |
m_edca->MissedAck(); |
| 231 |
|
| 232 |
NS_TEST_EXPECT_MSG_EQ (m_edca->m_currentPacket, 0, "packet should be discarded"); |
| 233 |
m_edca->GetEdcaQueue ()->Remove (pkt3); |
| 234 |
|
| 235 |
Simulator::Destroy (); |
| 236 |
} |
| 237 |
|
| 238 |
|
| 32 |
class TwoLevelAggregationTest : public TestCase |
239 |
class TwoLevelAggregationTest : public TestCase |
| 33 |
{ |
240 |
{ |
| 34 |
public: |
241 |
public: |
|
|
| 186 |
WifiAggregationTestSuite::WifiAggregationTestSuite () |
393 |
WifiAggregationTestSuite::WifiAggregationTestSuite () |
| 187 |
: TestSuite ("aggregation-wifi", UNIT) |
394 |
: TestSuite ("aggregation-wifi", UNIT) |
| 188 |
{ |
395 |
{ |
|
|
396 |
AddTestCase (new AmpduAggregationTest, TestCase::QUICK); |
| 189 |
AddTestCase (new TwoLevelAggregationTest, TestCase::QUICK); |
397 |
AddTestCase (new TwoLevelAggregationTest, TestCase::QUICK); |
| 190 |
} |
398 |
} |
| 191 |
|
399 |
|