1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2016 Tom Henderson
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: Tom Henderson <tomh@tomh.org>
19 */
20
21 // This example shows (and tests) some possible configurations for
22 // the Wi-Fi physical layer, particularly the interaction between
23 // WifiHelper.SetStandard () and the physical layer channel number,
24 // center frequency, and channel width.
25
26 #include "ns3/log.h"
27 #include "ns3/command-line.h"
28 #include "ns3/config-store.h"
29 #include "ns3/config.h"
30 #include "ns3/boolean.h"
31 #include "ns3/uinteger.h"
32 #include "ns3/string.h"
33 #include "ns3/ssid.h"
34 #include "ns3/yans-wifi-phy.h"
35 #include "ns3/yans-wifi-helper.h"
36 #include "ns3/wifi-net-device.h"
37
38 using namespace ns3;
39
40 NS_LOG_COMPONENT_DEFINE ("WifiPhyConfigurationExample");
41
42 Ptr<YansWifiPhy>
GetYansWifiPhyPtr(const NetDeviceContainer & nc)43 GetYansWifiPhyPtr (const NetDeviceContainer &nc)
44 {
45 Ptr<WifiNetDevice> wnd = nc.Get (0)->GetObject<WifiNetDevice> ();
46 Ptr<WifiPhy> wp = wnd->GetPhy ();
47 return wp->GetObject<YansWifiPhy> ();
48 }
49
50 void
PrintAttributesIfEnabled(bool enabled)51 PrintAttributesIfEnabled (bool enabled)
52 {
53 if (enabled)
54 {
55 ConfigStore outputConfig;
56 outputConfig.ConfigureAttributes ();
57 }
58 }
59
main(int argc,char * argv[])60 int main (int argc, char *argv[])
61 {
62 uint32_t testCase = 0;
63 bool printAttributes = false;
64 bool exceptionThrown = false;
65
66 CommandLine cmd (__FILE__);
67 cmd.AddValue ("testCase", "Test case", testCase);
68 cmd.AddValue ("printAttributes", "If true, print out attributes", printAttributes);
69 cmd.Parse (argc, argv);
70
71 NodeContainer wifiStaNode;
72 wifiStaNode.Create (1);
73 NodeContainer wifiApNode;
74 wifiApNode.Create (1);
75
76 YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
77 YansWifiPhyHelper phy;
78 phy.SetChannel (channel.Create ());
79 WifiHelper wifi;
80 wifi.SetRemoteStationManager ("ns3::IdealWifiManager");
81
82 // Configure and declare other generic components of this example
83 Ssid ssid;
84 ssid = Ssid ("wifi-phy-configuration");
85 WifiMacHelper macSta;
86 macSta.SetType ("ns3::StaWifiMac",
87 "Ssid", SsidValue (ssid),
88 "ActiveProbing", BooleanValue (false));
89 WifiMacHelper macAp;
90 macAp.SetType ("ns3::ApWifiMac",
91 "Ssid", SsidValue (ssid),
92 "BeaconInterval", TimeValue (MicroSeconds (102400)),
93 "BeaconGeneration", BooleanValue (true));
94 NetDeviceContainer staDevice;
95 NetDeviceContainer apDevice;
96 Ptr<YansWifiPhy> phySta;
97 Config::SetDefault ("ns3::ConfigStore::Filename", StringValue ("output-attributes-" + std::to_string (testCase) + ".txt"));
98 Config::SetDefault ("ns3::ConfigStore::FileFormat", StringValue ("RawText"));
99 Config::SetDefault ("ns3::ConfigStore::Mode", StringValue ("Save"));
100
101 switch (testCase)
102 {
103 case 0:
104 // Default configuration, without WifiHelper::SetStandard or WifiHelper
105 phySta = CreateObject<YansWifiPhy> ();
106 // The default results in an invalid configuration
107 NS_ASSERT (!phySta->GetOperatingChannel ().IsSet ());
108 PrintAttributesIfEnabled (printAttributes);
109 break;
110
111 // The following cases test the setting of WifiPhyStandard alone;
112 // i.e. without further channel number/width/frequency configuration
113
114 case 1:
115 // By default, WifiHelper will use WIFI_STANDARD_80211a
116 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
117 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
118 phySta = GetYansWifiPhyPtr (staDevice);
119 // We expect channel 36, width 20, frequency 5180
120 NS_ASSERT (phySta->GetChannelNumber () == 36);
121 NS_ASSERT (phySta->GetChannelWidth () == 20);
122 NS_ASSERT (phySta->GetFrequency () == 5180);
123 PrintAttributesIfEnabled (printAttributes);
124 break;
125 case 2:
126 wifi.SetStandard (WIFI_STANDARD_80211b);
127 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
128 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
129 phySta = GetYansWifiPhyPtr (staDevice);
130 // We expect channel 1, width 22, frequency 2412
131 NS_ASSERT (phySta->GetChannelNumber () == 1);
132 NS_ASSERT (phySta->GetChannelWidth () == 22);
133 NS_ASSERT (phySta->GetFrequency () == 2412);
134 PrintAttributesIfEnabled (printAttributes);
135 break;
136 case 3:
137 wifi.SetStandard (WIFI_STANDARD_80211g);
138 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
139 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
140 phySta = GetYansWifiPhyPtr (staDevice);
141 // We expect channel 1, width 20, frequency 2412
142 NS_ASSERT (phySta->GetChannelNumber () == 1);
143 NS_ASSERT (phySta->GetChannelWidth () == 20);
144 NS_ASSERT (phySta->GetFrequency () == 2412);
145 PrintAttributesIfEnabled (printAttributes);
146 break;
147 case 4:
148 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
149 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
150 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
151 phySta = GetYansWifiPhyPtr (staDevice);
152 // We expect channel 36, width 20, frequency 5180
153 NS_ASSERT (phySta->GetChannelNumber () == 36);
154 NS_ASSERT (phySta->GetChannelWidth () == 20);
155 NS_ASSERT (phySta->GetFrequency () == 5180);
156 PrintAttributesIfEnabled (printAttributes);
157 break;
158 case 5:
159 wifi.SetStandard (WIFI_STANDARD_80211n_2_4GHZ);
160 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
161 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
162 phySta = GetYansWifiPhyPtr (staDevice);
163 // We expect channel 1, width 20, frequency 2412
164 NS_ASSERT (phySta->GetChannelNumber () == 1);
165 NS_ASSERT (phySta->GetChannelWidth () == 20);
166 NS_ASSERT (phySta->GetFrequency () == 2412);
167 PrintAttributesIfEnabled (printAttributes);
168 break;
169 case 6:
170 wifi.SetStandard (WIFI_STANDARD_80211ac);
171 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
172 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
173 phySta = GetYansWifiPhyPtr (staDevice);
174 // We expect channel 42, width 80, frequency 5210
175 NS_ASSERT (phySta->GetChannelNumber () == 42);
176 NS_ASSERT (phySta->GetChannelWidth () == 80);
177 NS_ASSERT (phySta->GetFrequency () == 5210);
178 PrintAttributesIfEnabled (printAttributes);
179 break;
180 case 7:
181 wifi.SetStandard (WIFI_STANDARD_80211ax_2_4GHZ);
182 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
183 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
184 phySta = GetYansWifiPhyPtr (staDevice);
185 // We expect channel 1, width 20, frequency 2412
186 NS_ASSERT (phySta->GetChannelNumber () == 1);
187 NS_ASSERT (phySta->GetChannelWidth () == 20);
188 NS_ASSERT (phySta->GetFrequency () == 2412);
189 PrintAttributesIfEnabled (printAttributes);
190 break;
191 case 8:
192 wifi.SetStandard (WIFI_STANDARD_80211ax_5GHZ);
193 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
194 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
195 phySta = GetYansWifiPhyPtr (staDevice);
196 // We expect channel 42, width 80, frequency 5210
197 NS_ASSERT (phySta->GetChannelNumber () == 42);
198 NS_ASSERT (phySta->GetChannelWidth () == 80);
199 NS_ASSERT (phySta->GetFrequency () == 5210);
200 PrintAttributesIfEnabled (printAttributes);
201 break;
202 case 9:
203 wifi.SetStandard (WIFI_STANDARD_80211ax_6GHZ);
204 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
205 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
206 phySta = GetYansWifiPhyPtr (staDevice);
207 // We expect channel 7, width 80, frequency 5975
208 NS_ASSERT (phySta->GetChannelNumber () == 7);
209 NS_ASSERT (phySta->GetChannelWidth () == 80);
210 NS_ASSERT (phySta->GetFrequency () == 5975);
211 PrintAttributesIfEnabled (printAttributes);
212 break;
213 case 10:
214 wifi.SetStandard (WIFI_STANDARD_80211p);
215 phy.Set ("ChannelWidth", UintegerValue (10));
216 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
217 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
218 phySta = GetYansWifiPhyPtr (staDevice);
219 // We expect channel 172, width 10, frequency 5860
220 NS_ASSERT (phySta->GetChannelNumber () == 172);
221 NS_ASSERT (phySta->GetChannelWidth () == 10);
222 NS_ASSERT (phySta->GetFrequency () == 5860);
223 PrintAttributesIfEnabled (printAttributes);
224 break;
225 case 11:
226 wifi.SetStandard (WIFI_STANDARD_80211p);
227 phy.Set ("ChannelWidth", UintegerValue (5));
228 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
229 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
230 phySta = GetYansWifiPhyPtr (staDevice);
231 // We expect channel 171, width 5, frequency 5860
232 NS_ASSERT (phySta->GetChannelNumber () == 171);
233 NS_ASSERT (phySta->GetChannelWidth () == 5);
234 NS_ASSERT (phySta->GetFrequency () == 5860);
235 PrintAttributesIfEnabled (printAttributes);
236 break;
237 case 12:
238 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
239 phy.Set ("ChannelNumber", UintegerValue (44));
240 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
241 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
242 phySta = GetYansWifiPhyPtr (staDevice);
243 // We expect channel 44, width 20, frequency 5220
244 NS_ASSERT (phySta->GetChannelNumber () == 44);
245 NS_ASSERT (phySta->GetChannelWidth () == 20);
246 NS_ASSERT (phySta->GetFrequency () == 5220);
247 PrintAttributesIfEnabled (printAttributes);
248 break;
249 case 13:
250 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
251 phy.Set ("ChannelNumber", UintegerValue (44));
252 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
253 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
254 phySta = GetYansWifiPhyPtr (staDevice);
255 // Post-install reconfiguration to channel number 40
256 Config::Set ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelNumber", UintegerValue (40));
257 Config::Set ("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelNumber", UintegerValue (40));
258 // We expect channel 40, width 20, frequency 5200
259 NS_ASSERT (phySta->GetChannelNumber () == 40);
260 NS_ASSERT (phySta->GetChannelWidth () == 20);
261 NS_ASSERT (phySta->GetFrequency () == 5200);
262 PrintAttributesIfEnabled (printAttributes);
263 break;
264 case 14:
265 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
266 phy.Set ("ChannelNumber", UintegerValue (44));
267 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
268 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
269 phySta = GetYansWifiPhyPtr (staDevice);
270 // Post-install reconfiguration to a 40 MHz channel
271 Config::Set ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelNumber", UintegerValue (46));
272 Config::Set ("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelNumber", UintegerValue (46));
273 NS_ASSERT (phySta->GetChannelNumber () == 46);
274 NS_ASSERT (phySta->GetChannelWidth () == 40);
275 NS_ASSERT (phySta->GetFrequency () == 5230);
276 PrintAttributesIfEnabled (printAttributes);
277 break;
278 case 15:
279 Config::SetDefault ("ns3::WifiPhy::ChannelNumber", UintegerValue (44));
280 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
281 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
282 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
283 phySta = GetYansWifiPhyPtr (staDevice);
284 // Post-install reconfiguration to a 40 MHz channel
285 Config::Set ("/NodeList/0/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelNumber", UintegerValue (46));
286 Config::Set ("/NodeList/1/DeviceList/*/$ns3::WifiNetDevice/Phy/$ns3::YansWifiPhy/ChannelNumber", UintegerValue (46));
287 NS_ASSERT (phySta->GetChannelNumber () == 46);
288 NS_ASSERT (phySta->GetChannelWidth () == 40);
289 NS_ASSERT (phySta->GetFrequency () == 5230);
290 PrintAttributesIfEnabled (printAttributes);
291 break;
292 case 16:
293 // Test that setting Frequency to a non-standard value will throw an exception
294 Config::SetDefault ("ns3::WifiPhy::Frequency", UintegerValue (5281));
295 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
296 exceptionThrown = false;
297 try
298 {
299 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
300 }
301 catch (const std::runtime_error&)
302 {
303 exceptionThrown = true;
304 }
305 NS_ASSERT (exceptionThrown);
306 exceptionThrown = false;
307 try
308 {
309 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
310 }
311 catch (const std::runtime_error&)
312 {
313 exceptionThrown = true;
314 }
315 NS_ASSERT (exceptionThrown);
316 PrintAttributesIfEnabled (printAttributes);
317 break;
318 case 17:
319 // Test that setting Frequency to a standard value will set the
320 // channel number correctly
321 Config::SetDefault ("ns3::WifiPhy::Frequency", UintegerValue (5500));
322 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
323 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
324 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
325 phySta = GetYansWifiPhyPtr (staDevice);
326 // We expect channel number to be 100 due to frequency 5500
327 NS_ASSERT (phySta->GetChannelNumber () == 100);
328 NS_ASSERT (phySta->GetChannelWidth () == 20);
329 NS_ASSERT (phySta->GetFrequency () == 5500);
330 PrintAttributesIfEnabled (printAttributes);
331 break;
332 case 18:
333 // Set a wrong channel after initialization
334 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
335 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
336 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
337 phySta = GetYansWifiPhyPtr (staDevice);
338 exceptionThrown = false;
339 try
340 {
341 phySta->SetOperatingChannel (99, 5185, 40);
342 }
343 catch (const std::runtime_error&)
344 {
345 exceptionThrown = true;
346 }
347 NS_ASSERT (exceptionThrown);
348 PrintAttributesIfEnabled (printAttributes);
349 break;
350 case 19:
351 // Test how channel number behaves when frequency is non-standard
352 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
353 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
354 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
355 phySta = GetYansWifiPhyPtr (staDevice);
356 exceptionThrown = false;
357 try
358 {
359 phySta->SetAttribute ("Frequency", UintegerValue (5181));
360 }
361 catch (const std::runtime_error&)
362 {
363 exceptionThrown = true;
364 }
365 // We expect that an exception is thrown due to unknown center frequency 5181
366 NS_ASSERT (exceptionThrown);
367 phySta->SetAttribute ("Frequency", UintegerValue (5180));
368 // We expect channel number to be 36 due to known center frequency 5180
369 NS_ASSERT (phySta->GetChannelNumber () == 36);
370 NS_ASSERT (phySta->GetChannelWidth () == 20);
371 NS_ASSERT (phySta->GetFrequency () == 5180);
372 exceptionThrown = false;
373 try
374 {
375 phySta->SetAttribute ("Frequency", UintegerValue (5179));
376 }
377 catch (const std::runtime_error&)
378 {
379 exceptionThrown = true;
380 }
381 // We expect that an exception is thrown due to unknown center frequency 5179
382 NS_ASSERT (exceptionThrown);
383 phySta->SetAttribute ("ChannelNumber", UintegerValue (36));
384 NS_ASSERT (phySta->GetChannelNumber () == 36);
385 NS_ASSERT (phySta->GetChannelWidth () == 20);
386 NS_ASSERT (phySta->GetFrequency () == 5180);
387 PrintAttributesIfEnabled (printAttributes);
388 break;
389 case 20:
390 // Set both channel and frequency to consistent values before initialization
391 Config::SetDefault ("ns3::WifiPhy::Frequency", UintegerValue (5200));
392 Config::SetDefault ("ns3::WifiPhy::ChannelNumber", UintegerValue (40));
393 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
394 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
395 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
396 phySta = GetYansWifiPhyPtr (staDevice);
397 NS_ASSERT (phySta->GetChannelNumber () == 40);
398 NS_ASSERT (phySta->GetChannelWidth () == 20);
399 NS_ASSERT (phySta->GetFrequency () == 5200);
400 // Set both channel and frequency to consistent values after initialization
401 wifi.SetStandard (WIFI_STANDARD_80211n_5GHZ);
402 staDevice = wifi.Install (phy, macSta, wifiStaNode.Get (0));
403 apDevice = wifi.Install (phy, macAp, wifiApNode.Get (0));
404 phySta = GetYansWifiPhyPtr (staDevice);
405 phySta->SetAttribute ("Frequency", UintegerValue (5200));
406 phySta->SetAttribute ("ChannelNumber", UintegerValue (40));
407 NS_ASSERT (phySta->GetChannelNumber () == 40);
408 NS_ASSERT (phySta->GetChannelWidth () == 20);
409 NS_ASSERT (phySta->GetFrequency () == 5200);
410 // Set both channel and frequency to inconsistent values
411 phySta->SetAttribute ("Frequency", UintegerValue (5200));
412 phySta->SetAttribute ("ChannelNumber", UintegerValue (36));
413 // We expect channel number to be 36
414 NS_ASSERT (phySta->GetChannelNumber () == 36);
415 NS_ASSERT (phySta->GetChannelWidth () == 20);
416 NS_ASSERT (phySta->GetFrequency () == 5180);
417 phySta->SetAttribute ("ChannelNumber", UintegerValue (36));
418 phySta->SetAttribute ("Frequency", UintegerValue (5200));
419 // We expect channel number to be 40
420 NS_ASSERT (phySta->GetChannelNumber () == 40);
421 NS_ASSERT (phySta->GetChannelWidth () == 20);
422 NS_ASSERT (phySta->GetFrequency () == 5200);
423 exceptionThrown = false;
424 try
425 {
426 phySta->SetAttribute ("Frequency", UintegerValue (5179));
427 }
428 catch (const std::runtime_error&)
429 {
430 exceptionThrown = true;
431 }
432 phySta->SetAttribute ("ChannelNumber", UintegerValue (36));
433 // We expect channel number to be 36 and an exception to be thrown
434 NS_ASSERT (phySta->GetChannelNumber () == 36);
435 NS_ASSERT (phySta->GetChannelWidth () == 20);
436 NS_ASSERT (phySta->GetFrequency () == 5180);
437 NS_ASSERT (exceptionThrown);
438 phySta->SetAttribute ("ChannelNumber", UintegerValue (36));
439 exceptionThrown = false;
440 try
441 {
442 phySta->SetAttribute ("Frequency", UintegerValue (5179));
443 }
444 catch (const std::runtime_error&)
445 {
446 exceptionThrown = true;
447 }
448 // We expect channel number to be 36 and an exception to be thrown
449 NS_ASSERT (phySta->GetChannelNumber () == 36);
450 NS_ASSERT (phySta->GetChannelWidth () == 20);
451 NS_ASSERT (phySta->GetFrequency () == 5180);
452 NS_ASSERT (exceptionThrown);
453 PrintAttributesIfEnabled (printAttributes);
454 break;
455 default:
456 std::cerr << "Invalid testcase number " << testCase << std::endl;
457 exit (1);
458 break;
459 }
460
461 // No need to Simulator::Run (); this is a configuration example
462 Simulator::Destroy ();
463 }
464