45 // -----------| router | -----------| router | |
45 // -----------| router | -----------| router | |
46 // --------- --------- |
46 // --------- --------- |
47 // | | |
47 // | | |
48 // +----------------+ +----------------+ |
48 // +----------------+ +----------------+ |
49 // | 802.11 | | 802.11 | |
49 // | 802.11 | | 802.11 | |
50 // | net | | net | |
50 // | infra net | | infra net | |
51 // | K-1 hosts | | K-1 hosts | |
51 // | K-1 hosts | | K-1 hosts | |
52 // +----------------+ +----------------+ |
52 // +----------------+ +----------------+ |
53 // |
53 // |
|
54 // We'll send data from the first wired LAN node on the first wired LAN |
|
55 // to the last wireless STA on the last infrastructure net, thereby |
|
56 // causing packets to traverse CSMA to adhoc to infrastructure links |
|
57 // |
|
58 // Note that certain mobility patterns may cause packet forwarding |
|
59 // to fail (if nodes become disconnected) |
54 |
60 |
55 #include <fstream> |
61 #include <fstream> |
|
62 #include <string> |
56 #include "ns3/core-module.h" |
63 #include "ns3/core-module.h" |
57 #include "ns3/common-module.h" |
64 #include "ns3/common-module.h" |
58 #include "ns3/node-module.h" |
65 #include "ns3/node-module.h" |
59 #include "ns3/helper-module.h" |
66 #include "ns3/helper-module.h" |
60 #include "ns3/mobility-module.h" |
67 #include "ns3/mobility-module.h" |
61 #include "ns3/contrib-module.h" |
68 #include "ns3/contrib-module.h" |
62 #include "ns3/wifi-module.h" |
69 #include "ns3/wifi-module.h" |
|
70 #include "ns3/global-route-manager.h" |
63 |
71 |
64 using namespace ns3; |
72 using namespace ns3; |
65 |
73 |
66 // |
74 // |
67 // Define logging keyword for this file |
75 // Define logging keyword for this file |
89 uint32_t backboneNodes = 10; |
97 uint32_t backboneNodes = 10; |
90 uint32_t infraNodes = 5; |
98 uint32_t infraNodes = 5; |
91 uint32_t lanNodes = 5; |
99 uint32_t lanNodes = 5; |
92 uint32_t stopTime = 10; |
100 uint32_t stopTime = 10; |
93 bool useCourseChangeCallback = false; |
101 bool useCourseChangeCallback = false; |
|
102 bool enableTracing = false; |
94 |
103 |
95 // |
104 // |
96 // Simulation defaults are typically set next, before command line |
105 // Simulation defaults are typically set next, before command line |
97 // arguments are parsed. |
106 // arguments are parsed. |
98 // |
107 // |
99 Config::SetDefault ("ns3::OnOffApplication::PacketSize", StringValue ("210")); |
108 Config::SetDefault ("ns3::OnOffApplication::PacketSize", StringValue ("210")); |
100 Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s")); |
109 Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("10kb/s")); |
101 |
110 |
102 // |
111 // |
103 // For convenience, we add the local variables to the command line argument |
112 // For convenience, we add the local variables to the command line argument |
104 // system so that they can be overridden with flags such as |
113 // system so that they can be overridden with flags such as |
105 // "--backboneNodes=20" |
114 // "--backboneNodes=20" |
108 cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes); |
117 cmd.AddValue("backboneNodes", "number of backbone nodes", backboneNodes); |
109 cmd.AddValue ("infraNodes", "number of leaf nodes", infraNodes); |
118 cmd.AddValue ("infraNodes", "number of leaf nodes", infraNodes); |
110 cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes); |
119 cmd.AddValue("lanNodes", "number of LAN nodes", lanNodes); |
111 cmd.AddValue("stopTime", "simulation stop time (seconds)", stopTime); |
120 cmd.AddValue("stopTime", "simulation stop time (seconds)", stopTime); |
112 cmd.AddValue("useCourseChangeCallback", "whether to enable course change tracing", useCourseChangeCallback); |
121 cmd.AddValue("useCourseChangeCallback", "whether to enable course change tracing", useCourseChangeCallback); |
|
122 cmd.AddValue("enableTracing", "enable tracing", enableTracing); |
113 |
123 |
114 // |
124 // |
115 // The system global variables and the local values added to the argument |
125 // The system global variables and the local values added to the argument |
116 // system can be overridden by command line arguments by using this call. |
126 // system can be overridden by command line arguments by using this call. |
117 // |
127 // |
167 positionAlloc->Add (Vector (x, 0.0, 0.0)); |
177 positionAlloc->Add (Vector (x, 0.0, 0.0)); |
168 x += 5.0; |
178 x += 5.0; |
169 } |
179 } |
170 mobility.SetPositionAllocator (positionAlloc); |
180 mobility.SetPositionAllocator (positionAlloc); |
171 mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel", |
181 mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel", |
172 "Bounds", RectangleValue (Rectangle (0, 1000, 0, 1000)), |
182 "Bounds", RectangleValue (Rectangle (0, 20, 0, 20)), |
173 "Speed", RandomVariableValue (ConstantVariable (2000)), |
183 "Speed", RandomVariableValue (ConstantVariable (2)), |
174 "Pause", RandomVariableValue (ConstantVariable (0.2))); |
184 "Pause", RandomVariableValue (ConstantVariable (0.2))); |
175 mobility.Install (backbone); |
185 mobility.Install (backbone); |
176 |
186 |
177 /////////////////////////////////////////////////////////////////////////// |
187 /////////////////////////////////////////////////////////////////////////// |
178 // // |
188 // // |
238 // |
248 // |
239 // Create a container to manage the nodes of the LAN. We need |
249 // Create a container to manage the nodes of the LAN. We need |
240 // two containers here; one with all of the new nodes, and one |
250 // two containers here; one with all of the new nodes, and one |
241 // with all of the nodes including new and existing nodes |
251 // with all of the nodes including new and existing nodes |
242 // |
252 // |
243 NodeContainer newInfraNodes; |
253 NodeContainer stas; |
244 newInfraNodes.Create (infraNodes - 1); |
254 stas.Create (infraNodes - 1); |
245 // Now, create the container with all nodes on this link |
255 // Now, create the container with all nodes on this link |
246 NodeContainer infra (backbone.Get (i), newInfraNodes); |
256 NodeContainer infra (backbone.Get (i), stas); |
247 // |
257 // |
248 // Create another ad hoc network and devices |
258 // Create an infrastructure network |
249 // |
259 // |
250 WifiHelper wifiInfra = WifiHelper::Default (); |
260 WifiHelper wifiInfra = WifiHelper::Default (); |
251 wifiPhy.SetChannel (wifiChannel.Create ()); |
261 wifiPhy.SetChannel (wifiChannel.Create ()); |
252 NetDeviceContainer infraDevices = wifiInfra.Install (wifiPhy, infra); |
262 // Create unique ssids for these networks |
|
263 std::string ssidString("wifi-infra"); |
|
264 std::stringstream ss; |
|
265 ss << i; |
|
266 ssidString += ss.str(); |
|
267 Ssid ssid = Ssid (ssidString); |
|
268 wifiInfra.SetRemoteStationManager ("ns3::ArfWifiManager"); |
|
269 // setup stas |
|
270 wifiInfra.SetMac ("ns3::NqstaWifiMac", |
|
271 "Ssid", SsidValue (ssid), |
|
272 "ActiveProbing", BooleanValue (false)); |
|
273 NetDeviceContainer staDevices = wifiInfra.Install (wifiPhy, stas); |
|
274 // setup ap. |
|
275 wifiInfra.SetMac ("ns3::NqapWifiMac", "Ssid", SsidValue (ssid), |
|
276 "BeaconGeneration", BooleanValue (true), |
|
277 "BeaconInterval", TimeValue (Seconds (2.5))); |
|
278 NetDeviceContainer apDevices = wifiInfra.Install (wifiPhy, backbone.Get (i)); |
|
279 // Collect all of these new devices |
|
280 NetDeviceContainer infraDevices (apDevices, staDevices); |
253 |
281 |
254 // Add the IPv4 protocol stack to the nodes in our container |
282 // Add the IPv4 protocol stack to the nodes in our container |
255 // |
283 // |
256 internet.Install (newInfraNodes); |
284 internet.Install (stas); |
257 // |
285 // |
258 // Assign IPv4 addresses to the device drivers (actually to the associated |
286 // Assign IPv4 addresses to the device drivers (actually to the associated |
259 // IPv4 interfaces) we just created. |
287 // IPv4 interfaces) we just created. |
260 // |
288 // |
261 ipAddrs.Assign (infraDevices); |
289 ipAddrs.Assign (infraDevices); |
275 subnetAlloc->Add (Vector (0.0, j, 0.0)); |
303 subnetAlloc->Add (Vector (0.0, j, 0.0)); |
276 } |
304 } |
277 mobility.PushReferenceMobilityModel (backbone.Get (i)); |
305 mobility.PushReferenceMobilityModel (backbone.Get (i)); |
278 mobility.SetPositionAllocator (subnetAlloc); |
306 mobility.SetPositionAllocator (subnetAlloc); |
279 mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel", |
307 mobility.SetMobilityModel ("ns3::RandomDirection2dMobilityModel", |
280 "Bounds", RectangleValue (Rectangle (-25, 25, -25, 25)), |
308 "Bounds", RectangleValue (Rectangle (-10, 10, -10, 10)), |
281 "Speed", RandomVariableValue (ConstantVariable (30)), |
309 "Speed", RandomVariableValue (ConstantVariable (3)), |
282 "Pause", RandomVariableValue (ConstantVariable (0.4))); |
310 "Pause", RandomVariableValue (ConstantVariable (0.4))); |
283 mobility.Install (infra); |
311 mobility.Install (infra); |
284 } |
312 } |
285 /////////////////////////////////////////////////////////////////////////// |
313 /////////////////////////////////////////////////////////////////////////// |
286 // // |
314 // // |
287 // Routing configuration // |
315 // Routing configuration // |
288 // // |
316 // // |
289 /////////////////////////////////////////////////////////////////////////// |
317 /////////////////////////////////////////////////////////////////////////// |
290 |
318 |
|
319 // The below global routing does not take into account wireless effects. |
|
320 // However, it is useful for setting default routes for all of the nodes |
|
321 // such as the LAN nodes. |
|
322 NS_LOG_INFO ("Enabling global routing on all nodes"); |
|
323 GlobalRouteManager::PopulateRoutingTables (); |
|
324 |
|
325 // We enable OLSR (which will be consulted at a higher priority than |
|
326 // the global routing above) on the backbone ad hoc nodes |
291 NS_LOG_INFO ("Enabling OLSR routing on all backbone nodes"); |
327 NS_LOG_INFO ("Enabling OLSR routing on all backbone nodes"); |
292 OlsrHelper olsr; |
328 OlsrHelper olsr; |
293 olsr.Install (backbone); |
329 olsr.Install (backbone); |
294 |
330 |
295 /////////////////////////////////////////////////////////////////////////// |
331 /////////////////////////////////////////////////////////////////////////// |
297 // Application configuration // |
333 // Application configuration // |
298 // // |
334 // // |
299 /////////////////////////////////////////////////////////////////////////// |
335 /////////////////////////////////////////////////////////////////////////// |
300 |
336 |
301 // Create the OnOff application to send UDP datagrams of size |
337 // Create the OnOff application to send UDP datagrams of size |
302 // 210 bytes at a rate of 448 Kb/s, between two nodes |
338 // 210 bytes at a rate of 10 Kb/s, between two nodes |
|
339 // We'll send data from the first wired LAN node on the first wired LAN |
|
340 // to the last wireless STA on the last infrastructure net, thereby |
|
341 // causing packets to traverse CSMA to adhoc to infrastructure links |
|
342 |
303 NS_LOG_INFO ("Create Applications."); |
343 NS_LOG_INFO ("Create Applications."); |
304 uint16_t port = 9; // Discard port (RFC 863) |
344 uint16_t port = 9; // Discard port (RFC 863) |
305 |
345 |
306 // Let's make sure that the user does not define too few LAN nodes |
346 // Let's make sure that the user does not define too few nodes |
307 // to make this example work. We need lanNodes >= 5 |
347 // to make this example work. We need lanNodes > 1 and infraNodes > 1 |
308 NS_ASSERT (lanNodes >= 5); |
348 NS_ASSERT (lanNodes > 1 && infraNodes > 1); |
309 Ptr<Node> appSource = NodeList::GetNode (11); |
349 // We want the source to be the first node created outside of the backbone |
310 Ptr<Node> appSink = NodeList::GetNode (13); |
350 // Conveniently, the variable "backboneNodes" holds this node index value |
311 Ipv4Address remoteAddr = Ipv4Address ("172.16.0.5"); |
351 Ptr<Node> appSource = NodeList::GetNode (backboneNodes); |
|
352 // We want the sink to be the last node created in the topology. |
|
353 uint32_t lastNodeIndex = backboneNodes + backboneNodes*(lanNodes - 1) + backboneNodes*(infraNodes - 1) - 1; |
|
354 Ptr<Node> appSink = NodeList::GetNode (lastNodeIndex); |
|
355 // Let's fetch the IP address of the last node, which is on Ipv4Interface 1 |
|
356 Ipv4Address remoteAddr = appSink->GetObject<Ipv4> ()->GetAddress(1); |
312 |
357 |
313 OnOffHelper onoff ("ns3::UdpSocketFactory", |
358 OnOffHelper onoff ("ns3::UdpSocketFactory", |
314 Address (InetSocketAddress (remoteAddr, port))); |
359 Address (InetSocketAddress (remoteAddr, port))); |
315 onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); |
360 onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); |
316 onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); |
361 onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); |
329 // Tracing configuration // |
374 // Tracing configuration // |
330 // // |
375 // // |
331 /////////////////////////////////////////////////////////////////////////// |
376 /////////////////////////////////////////////////////////////////////////// |
332 |
377 |
333 NS_LOG_INFO ("Configure Tracing."); |
378 NS_LOG_INFO ("Configure Tracing."); |
334 // |
|
335 // Let's set up some ns-2-like ascii traces, using another helper class |
|
336 // |
|
337 std::ofstream ascii; |
379 std::ofstream ascii; |
338 ascii.open ("mixed-wireless.tr"); |
380 if (enableTracing == true) |
339 YansWifiPhyHelper::EnableAsciiAll (ascii); |
381 { |
340 CsmaHelper::EnableAsciiAll (ascii); |
382 // |
341 // Look at nodes 11, 13 only |
383 // Let's set up some ns-2-like ascii traces, using another helper class |
342 //WifiHelper::EnableAscii (ascii, 11, 0); |
384 // |
343 //WifiHelper::EnableAscii (ascii, 13, 0); |
385 ascii.open ("mixed-wireless.tr"); |
344 |
386 YansWifiPhyHelper::EnableAsciiAll (ascii); |
345 // Let's do a pcap trace on the backbone devices |
387 CsmaHelper::EnableAsciiAll (ascii); |
346 YansWifiPhyHelper::EnablePcap ("mixed-wireless", backboneDevices); |
388 InternetStackHelper::EnableAsciiAll (ascii); |
347 // Let's additionally trace the application Sink, ifIndex 0 |
389 |
348 CsmaHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0); |
390 // Let's do a pcap trace on the application source and sink, ifIndex 0 |
|
391 CsmaHelper::EnablePcap ("mixed-wireless", appSource->GetId (), 0); |
|
392 YansWifiPhyHelper::EnablePcap ("mixed-wireless", appSink->GetId (), 0); |
|
393 YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 2); |
|
394 YansWifiPhyHelper::EnablePcap ("mixed-wireless", 9, 0); |
|
395 } |
349 |
396 |
350 if (useCourseChangeCallback == true) |
397 if (useCourseChangeCallback == true) |
351 { |
398 { |
352 Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", MakeCallback (&CourseChangeCallback)); |
399 Config::Connect ("/NodeList/*/$ns3::MobilityModel/CourseChange", MakeCallback (&CourseChangeCallback)); |
353 } |
400 } |