|
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
|
2 /* |
|
3 * Copyright (c) 2015 |
|
4 * |
|
5 * This program is free software; you can redistribute it and/or modify |
|
6 * it under the terms of the GNU General Public License version 2 as |
|
7 * published by the Free Software Foundation; |
|
8 * |
|
9 * This program is distributed in the hope that it will be useful, |
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 * GNU General Public License for more details. |
|
13 * |
|
14 * You should have received a copy of the GNU General Public License |
|
15 * along with this program; if not, write to the Free Software |
|
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 * |
|
18 * Author: Sébastien Deronne <sebastien.deronne@gmail.com> |
|
19 */ |
|
20 |
|
21 #include "ns3/string.h" |
|
22 #include "ns3/test.h" |
|
23 #include "ns3/object-factory.h" |
|
24 #include "ns3/wifi-mac-queue.h" |
|
25 #include "ns3/mac-low.h" |
|
26 #include "ns3/edca-txop-n.h" |
|
27 #include "ns3/yans-wifi-phy.h" |
|
28 |
|
29 using namespace ns3; |
|
30 |
|
31 class TwoLevelAggregationTest : public TestCase |
|
32 { |
|
33 public: |
|
34 TwoLevelAggregationTest (); |
|
35 |
|
36 private: |
|
37 virtual void DoRun (void); |
|
38 Ptr<MacLow> m_low; |
|
39 Ptr<YansWifiPhy> m_phy; |
|
40 Ptr<EdcaTxopN> m_edca; |
|
41 Ptr<WifiRemoteStationManager> m_manager; |
|
42 ObjectFactory m_factory; |
|
43 Ptr<MpduAggregator> m_mpduAggregator; |
|
44 Ptr<MsduAggregator> m_msduAggregator; |
|
45 }; |
|
46 |
|
47 TwoLevelAggregationTest::TwoLevelAggregationTest () |
|
48 : TestCase ("Check the correctness of two-level aggregation operations") |
|
49 { |
|
50 } |
|
51 |
|
52 void |
|
53 TwoLevelAggregationTest::DoRun (void) |
|
54 { |
|
55 /* |
|
56 * Create and configure phy layer. |
|
57 */ |
|
58 m_phy = CreateObject<YansWifiPhy> (); |
|
59 m_phy->ConfigureStandard (WIFI_PHY_STANDARD_80211n_5GHZ); |
|
60 |
|
61 /* |
|
62 * Create and configure manager. |
|
63 */ |
|
64 m_factory = ObjectFactory (); |
|
65 m_factory.SetTypeId ("ns3::ConstantRateWifiManager"); |
|
66 m_factory.Set ("DataMode", StringValue ("OfdmRate65MbpsBW20MHz")); |
|
67 m_manager = m_factory.Create<WifiRemoteStationManager> (); |
|
68 m_manager->SetupPhy(m_phy); |
|
69 |
|
70 /* |
|
71 * Create and configure maclayer. |
|
72 */ |
|
73 m_low = CreateObject<MacLow> (); |
|
74 m_low->SetPhy(m_phy); |
|
75 m_low->SetWifiRemoteStationManager (m_manager); |
|
76 |
|
77 m_edca = CreateObject<EdcaTxopN> (); |
|
78 m_edca->SetLow (m_low); |
|
79 m_edca->SetAccessCategory (AC_BE); |
|
80 m_edca->SetWifiRemoteStationManager (m_manager); |
|
81 m_edca->CompleteConfig (); |
|
82 |
|
83 /* |
|
84 * Configure aggregation. |
|
85 */ |
|
86 m_factory = ObjectFactory (); |
|
87 m_factory.SetTypeId ("ns3::MsduStandardAggregator"); |
|
88 m_factory.Set ("MaxAmsduSize", UintegerValue(4095)); |
|
89 m_msduAggregator = m_factory.Create<MsduAggregator> (); |
|
90 m_edca->SetMsduAggregator (m_msduAggregator); |
|
91 |
|
92 m_factory = ObjectFactory (); |
|
93 m_factory.SetTypeId ("ns3::MpduStandardAggregator"); |
|
94 m_factory.Set ("MaxAmpduSize", UintegerValue(65535)); |
|
95 m_mpduAggregator = m_factory.Create<MpduAggregator> (); |
|
96 m_low->SetMpduAggregator (m_mpduAggregator); |
|
97 |
|
98 /* |
|
99 * Create dummy packets of 1500 bytes and fill mac header fields that will be used for the tests. |
|
100 */ |
|
101 Ptr<const Packet> pkt = Create<Packet> (1500); |
|
102 Ptr<Packet> currentAggregatedPacket = Create<Packet> (); |
|
103 WifiMacHeader hdr, peekedHdr; |
|
104 hdr.SetAddr1 (Mac48Address ("00:00:00:00:00:01")); |
|
105 hdr.SetAddr2 (Mac48Address ("00:00:00:00:00:02")); |
|
106 hdr.SetType (WIFI_MAC_QOSDATA); |
|
107 hdr.SetQosTid (0); |
|
108 Time tstamp; |
|
109 |
|
110 //----------------------------------------------------------------------------------------------------- |
|
111 |
|
112 /* |
|
113 * Test MSDU aggregation of two packets using MacLow::PerformMsduAggregation. |
|
114 * It checks whether aggregation succeeded: |
|
115 * - returned packet should be different from 0; |
|
116 * - A-MSDU frame size should be 3030 bytes (= 2 packets + headers + padding); |
|
117 * - one packet should be removed from the queue (the other packet is removed later in MacLow::AggregateToAmpdu) . |
|
118 */ |
|
119 m_edca->GetEdcaQueue()->Enqueue(pkt, hdr); |
|
120 m_edca->GetEdcaQueue()->Enqueue(pkt, hdr); |
|
121 |
|
122 Ptr<const Packet> peekedPacket = m_edca->GetEdcaQueue()->PeekByTidAndAddress (&peekedHdr, 0, |
|
123 WifiMacHeader::ADDR1, |
|
124 hdr.GetAddr1 (), |
|
125 &tstamp); |
|
126 m_low->m_currentPacket = peekedPacket->Copy (); |
|
127 m_low->m_currentHdr = peekedHdr; |
|
128 |
|
129 Ptr<Packet> packet = m_low->PerformMsduAggregation(peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, 0); |
|
130 |
|
131 bool result = (packet != 0); |
|
132 NS_TEST_EXPECT_MSG_EQ (result, true, "aggregation failed"); |
|
133 NS_TEST_EXPECT_MSG_EQ (packet->GetSize(), 3030, "wrong packet size"); |
|
134 NS_TEST_EXPECT_MSG_EQ (m_edca->GetEdcaQueue()->GetSize(), 1, "removing packet from EDCA queue failed"); |
|
135 |
|
136 //----------------------------------------------------------------------------------------------------- |
|
137 |
|
138 /* |
|
139 * Aggregation is refused when the maximum size is reached. |
|
140 * It checks whether MSDU aggregation has been rejected because the maximum MPDU size is set to 0 (returned packet should be equal to 0). |
|
141 * This test is needed to ensure that no packets are removed from the queue in MacLow::PerformMsduAggregation, since aggregation will no occur in MacLow::AggregateToAmpdu. |
|
142 */ |
|
143 m_factory = ObjectFactory (); |
|
144 m_factory.SetTypeId ("ns3::MpduStandardAggregator"); |
|
145 m_factory.Set ("MaxAmpduSize", UintegerValue(0)); |
|
146 m_mpduAggregator = m_factory.Create<MpduAggregator> (); |
|
147 m_low->SetMpduAggregator (m_mpduAggregator); |
|
148 |
|
149 m_edca->GetEdcaQueue()->Enqueue(pkt, hdr); |
|
150 packet = m_low->PerformMsduAggregation(peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, 0); |
|
151 |
|
152 result = (packet != 0); |
|
153 NS_TEST_EXPECT_MSG_EQ (result, false, "maximum aggregated frame size check failed"); |
|
154 |
|
155 //----------------------------------------------------------------------------------------------------- |
|
156 |
|
157 /* |
|
158 * Aggregation does not occur zhen there is no more packets in the queue. |
|
159 * It checks whether MSDU aggregation has been rejected because there is no packets ready in the queue (returned packet should be equal to 0). |
|
160 * This test is needed to ensure that there is no issue when the queue is empty. |
|
161 */ |
|
162 m_factory = ObjectFactory (); |
|
163 m_factory.SetTypeId ("ns3::MpduStandardAggregator"); |
|
164 m_factory.Set ("MaxAmpduSize", UintegerValue(4095)); |
|
165 m_mpduAggregator = m_factory.Create<MpduAggregator> (); |
|
166 m_low->SetMpduAggregator (m_mpduAggregator); |
|
167 |
|
168 m_edca->GetEdcaQueue()->Remove(pkt); |
|
169 m_edca->GetEdcaQueue()->Remove(pkt); |
|
170 packet = m_low->PerformMsduAggregation(peekedPacket, &peekedHdr, &tstamp, currentAggregatedPacket, 0); |
|
171 |
|
172 result = (packet != 0); |
|
173 NS_TEST_EXPECT_MSG_EQ (result, false, "aggregation failed to stop as queue is empty"); |
|
174 } |
|
175 |
|
176 //----------------------------------------------------------------------------- |
|
177 class WifiAggregationTestSuite : public TestSuite |
|
178 { |
|
179 public: |
|
180 WifiAggregationTestSuite (); |
|
181 }; |
|
182 |
|
183 WifiAggregationTestSuite::WifiAggregationTestSuite () |
|
184 : TestSuite ("aggregation-wifi", UNIT) |
|
185 { |
|
186 AddTestCase (new TwoLevelAggregationTest, TestCase::QUICK); |
|
187 } |
|
188 |
|
189 static WifiAggregationTestSuite g_wifiAggregationTestSuite; |