Intelligent Wireless Network Group Department of Computer Engineering Faculty of Engineering, Kasetsart University http://iwing.cpe.ku.ac.th ns-3 Tutorial (Part IV) Wireless & Tracing System and Visualizing Results JCSSE 2011's tutorials and workshops Wednesday, 11 May 2011, 9:00-16:00
Time Table 09:00-10:15 ns-3 Introduction & Installation 10:15-10.30 Break 10:30-12:00 Hands-On: Point-to-point and CSMA (Ethernet) 12:00-13:00 Lunch 13:00-14:15 Hands-On: Wireless & Tracing System and Visualizing Results 14:15-14:30 Break 14:30-15:30 Demonstation: ns-3 protocol stack modification 15:30-16:00 Q&A 2
Outline Wireless modules overview Tracing with Trace Helpers Creating custom tracers Visualizing and analyzing results Walk-through examples Hands-on exercise 3
Tracing Overview ns-3 provides a set of pre-configured trace sources Users provide trace sinks and attach to the trace source Multiple trace sources can connect to a trace sink 4
ns-3 Tracing Model Decouple trace sources from trace sinks: 5
ns-3 Trace Sources 6
Multiple Levels of Tracing High-level Use a helper to hook a predefined trace source to an existing trace sink (e.g., ascii, pcap) Mid-level Hook an existing trace source to a custom trace sink Low-level Add a new trace source and connect it to a special trace sink 7
Trace Helpers Ascii Trace Helper Pcap Trace Helper 8
Custom Trace Sink void DevTxTrace( std::string context, Ptr<const Packet> p, Mac48Address address) { std::cout << " TX to=" << address << " p: " << *p << std::endl; } : Config::Connect( "/NodeList/*/DeviceList/*/Mac/MacTx", MakeCallback(&DevTxTrace)); Name of trace sink function Path to trace source 9
Walk-Through Example I (1) Task: model the network topology below in ns-3 and capture ECHO packets transmitted from N7 to N4 N2 N3 N4 N5 N0 10.1.1.0/24 N1 ECHO 10.1.2.0/24 N6 N7 10.1.3.0/24 We can start from tutorials/third.cc 10
Dissecting third.cc CommandLine class allows processing of command-line arguments Supply default values of various attributes and variables main (int argc, char *argv[]) { bool verbose = true; uint32_t ncsma = 3; uint32_t nwifi = 3; CommandLine cmd; cmd.addvalue ("ncsma", "Number of \"extra\" CSMA nodes/devices", ncsma); cmd.addvalue ("nwifi", "Number of wifi STA devices", nwifi); cmd.addvalue ("verbose", "Tell echo applications to log if true", verbose); cmd.parse (argc,argv); 11
Dissecting third.cc Various Helpers are available to help create wireless channel/physical/mac models NodeContainer wifistanodes; wifistanodes.create (nwifi); NodeContainer wifiapnode = p2pnodes.get (0); YansWifiChannelHelper channel = YansWifiChannelHelper::Default (); YansWifiPhyHelper phy = YansWifiPhyHelper::Default (); phy.setchannel (channel.create ()); WifiHelper wifi = WifiHelper::Default (); wifi.setremotestationmanager ("ns3::aarfwifimanager"); 12
Dissecting third.cc WiFi MAC layer NodeContainer wifiapnode = p2pnodes.get (0); NqosWifiMacHelper mac = NqosWifiMacHelper::Default (); Ssid ssid = Ssid ("ns-3-ssid"); mac.settype ("ns3::stawifimac", "Ssid", SsidValue (ssid), "ActiveProbing", BooleanValue (false)); Configure all nodes in wifistanodes container to be of type station NetDeviceContainer stadevices; stadevices = wifi.install (phy, mac, wifistanodes); mac.settype ("ns3::apwifimac", "Ssid", SsidValue (ssid)); NetDeviceContainer apdevices; apdevices = wifi.install (phy, mac, wifiapnode); Configure first node of point-to-point link to be WiFi AP 13
Dissecting third.cc All wireless nodes must be associated with mobility MobilityHelper provides a lot of help MobilityHelper mobility; mobility.setpositionallocator ("ns3::gridpositionallocator", DeltaY "MinX", DoubleValue (0.0), "MinY", DoubleValue (0.0), "DeltaX", DoubleValue (5.0), "DeltaY", DoubleValue (10.0), "GridWidth", UintegerValue (3), "LayoutType", StringValue ("RowFirst")); mobility.setmobilitymodel ("ns3::randomwalk2dmobilitymodel", "Bounds", RectangleValue (Rectangle (-50, 50, -50, 50))); mobility.install (wifistanodes); mobility.setmobilitymodel ("ns3::constantpositionmobilitymodel"); mobility.install (wifiapnode); (MinX, MinY) 1 2 3 4 DeltaX 14
Walk-Through Example I (2) Create a copy of third.cc into the scratch dir and rename it to pm-ex1.cc $ cp examples/tutorials/third.cc scratch/pm-ex1.cc Edit the source Change port number from 9 to 7 (standard ECHO port) UdpEchoServerHelper echoserver (7); : UdpEchoClientHelper echoclient (csmainterfaces.getaddress (ncsma), 7); Change PCAP file prefix to pm-ex1 pointtopoint.enablepcapall ("pm-ex1"); phy.enablepcap ("pm-ex1", apdevices.get (0)); csma.enablepcap ("pm-ex1", csmadevices.get (0), true); 15
Walk-Through Example I (3) Run the script $./waf --run pm-ex1 Open the pcap files with WireShark $ ls *.pcap pm-ex1-0-0.pcap pm-ex1-0-1.pcap pm-ex1-1-0.pcap pm-ex1-1-1.pcap $ wireshark pm-ex1-0-0.pcap 16
Walk-Through Example I (4) Visualize the simulation by adding option --visualize $./waf --run pm-ex1 --visualize Press F3 to start the simulation 17
Walk-Through Example I (5) Attributes can be configured and explored before the simulation starts #include "ns3/gtk-config-store.h" GtkConfigStore config; config.configureattributes(); Simulator::Run (); 18
Walk-Through Example I (6) GtkConfigStore can also be invoked in PyViz using Ipython shell Ipython must be installed 19
Walk-Through Example II (1) Task: Using the previous topology, replace ECHO traffic with CBR (Constant Bit Rate) traffic N2 N3 N4 N5 N0 10.1.1.0/24 N1 CBR (512 Kbps) 10.1.2.0/24 N6 N7 10.1.3.0/24 20
Walk-Through Example II (2) Create pm-ex2.cc from pm-ex1.cc $ cp scratch/pm-ex1.cc scratch/pm-ex2.cc Use OnOffHelper to generate CBR traffic from the client uint16_t port = 9; OnOffHelper onoff( "ns3::udpsocketfactory", InetSocketAddress("10.1.2.4", port)); onoff.setattribute("ontime", StringValue("Constant:1")); onoff.setattribute("offtime", StringValue("Constant:0")); onoff.setattribute("datarate", StringValue("512Kbps")); onoff.setattribute("packetsize", StringValue("512")); Install app on node N7 only ApplicationContainer apps = onoff.install(wifistanodes.get(nwifi-1)); apps.start(seconds(5.0)); apps.stop(seconds(20.0)); 21
Walk-Through Example II (3) Create a packet sink on the server PacketSinkHelper sink( "ns3::udpsocketfactory", InetSocketAddress("10.1.2.4", port)); sink.install(csmanodes.get(ncsma)); Set simulation time to 30 seconds Install PacketSink on node N4 Simulator::Stop(Seconds(25.0)); Don't forget to change the PCAP trace prefix 22
Walk-Through Example III (1) Task: calculate average throughput from previous scenario Idea: Connect a custom trace sink to PacketSink's Rx trace source Compute average throughput from first and last packets' timestamps total bytes received 23
Finding Path to Trace Source How to determine what trace source PacketSink provides? And how to get to it? In ns-3 Doxygen, look for ns3::packetsink (either via Class List or List of Trace Sources) Look at the documentation for GetTypeId 24
Connecting Trace Source/Sink We now know that PacketSink object already comes with a trace source, called Rx We need to write a callback function to serve as a trace sink PacketSink Object Trace Source 25 Trace Sink Callback Function
Callback Signature Quoted from ns-3 Tutorial: always try to copy someone else's working code $ find examples/ -name "*.cc" -exec grep -H PacketSink/Rx {} \; examples/csma/csma-ping.cc: Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", examples/csma/csma-packet-socket.cc: Config::Connect ("/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx", examples/csma/csma-raw-ip-socket.cc: Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", : : Opening examples/csma/csma-ping.cc reveals Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&SinkRx)); Then look at definition of SinkRx function: static void SinkRx (Ptr<const Packet> p, const Address &ad) { //std::cout << *p << std::endl; } 26
Callback Signature If no example can be found, look at ns-3 source code! $ find. -name "*.h" -exec grep -H TracedCallback {} \; :./src/applications/udp-echo/udp-echo-client.h: TracedCallback<Ptr<const Packet> > m_txtrace;./src/applications/v4ping/v4ping.h: TracedCallback<Time> m_tracertt;./src/applications/packet-sink/packet-sink.h: TracedCallback<Ptr<const Packet>, const Address &> m_rxtrace;./src/mobility/mobility-model.h: TracedCallback<Ptr<const MobilityModel> > m_coursechangetrace;./src/routing/olsr/model/olsr-routing-protocol.h: TracedCallback <const PacketHeader &, : Either way, we now know that our callback's signature should be: void Callback(Ptr<const Packet>, const Address &) Note: An additional std::string parameter is required if connection is made with context 27
Walk-Through Example III (2) Create pm-ex3.cc from pm-ex2.cc $ cp scratch/pm-ex2.cc scratch/pm-ex3.cc Prepare trace sink callback and necessary statistical variables double firstrxtime = -1.0, lastrxtime; uint32_t bytestotal = 0; void SinkRxTrace(Ptr<const Packet> pkt, const Address &addr) { if (firstrxtime < 0) firstrxtime = Simulator::Now().GetSeconds(); } lastrxtime = Simulator::Now().GetSeconds(); bytestotal += pkt->getsize(); 28
Walk-Through Example III (3) Connect trace source with trace sink Config::ConnectWithoutContext( "/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx", MakeCallback(&SinkRxTrace)); Produce statistical report at the end of the script cout << "Avg throughput = " << bytestotal*8/(lastrxtime-firstrxtime)/1024 << " kbits/sec" << endl; Run the simulation script 29
Walk-Through Example IV (1) Task: study impact of number of clients on average throughput Experiment setup 2-14 mobile clients UDP CBR stream 512 Kbps per client Packet size: 512 bytes 30
Walk-Through Example IV (2) Create pm-ex4.cc from pm-ex3.cc $ cp scratch/pm-ex3.cc scratch/pm-ex4.cc Modify the source so that OnOff application is installed on all WiFi stations Change the line: ApplicationContainer apps = onoff.install(wifistanodes.get(nwifi-1)); to ApplicationContainer apps = onoff.install(wifistanodes); 31
Walk-Through Example IV (3) Report the number of WiFi stations in addition to the average throughput cout << "Num clients = " << nwifi << " " << "Avg throughput = " << bytestotal*8/(lastrxtime-firstrxtime)/1024 << " kbits/sec" << endl; Try running the script with various values specified for nwifi argument suppress stderr messages $ waf --run "pm-ex4 --nwifi=1" 2> /dev/null Num clients = 1 Avg throughput = 512.96 kbits/sec $ waf --run "pm-ex4 --nwifi=2" 2> /dev/null Num clients = 2 Avg throughput = 1025.54 kbits/sec 32
Walk-Through Example IV (4) Create a shell-script, named run-all.sh, that runs the simulation with different values for nwifi #!/bin/bash for ((i=2; i<=14; i += 2)); do waf --run "pm-ex4 --nwifi=$i" done Run the shell-script and redirect all stdout messages to a file $ bash run-all.sh > results.dat 33
Walk-Through Example IV (5) Visualize results with gnuplot $ gnuplot gnuplot> plot 'results.dat' using 4:8 with lines 34
Walk-Through Example IV (6) Create a script, genplot.gnuplot, for generating a plot as a PNG file Also Change x-axis to load, Polish the plot: turn on grid, turn off legend #!/usr/bin/gnuplot set terminal png set output 'graph.png' set xrange [0:] set yrange [0:] set xlabel 'Load (kb/s)' set ylabel 'Average Throughput (kb/s)' set grid plot 'results.dat' using ($4*512):8 with lines notitle 35
Walk-Through Example IV (7) Run the plotting script $ gnuplot genplot.gnuplot 36
Running Multiple Replications Publication-quality results should be obtained from many replications in each scenario Use --RngRun=<run-number> to change random sequence $ waf --run "pm-ex4 --nwifi=10 --RngRun=3" 37
Hands-on Exercise Study impact of number of mobile stations to packet delivery ratio 38