JCSSE 2011's tutorials and workshops
Wednesday, 11 May 2011, 9:00 - 16:00
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
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
Wireless modules overview Tracing with Trace Helpers Creating custom tracers
Visualizing and analyzing results Walk-through examples
Hands-on exercise
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
Decouple trace sources from trace sinks:
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
Ascii Trace Helper Pcap Trace Helper
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
Task: model the network topology below in ns-3 and
capture ECHO packets transmitted from N7 to N4
We can start from tutorials/third.cc
Walk-Through Example I (1)
N2 N3 N4 N0 N1 10.1.1.0/24 10.1.2.0/24 10.1.3.0/24 N5 N6 N7 ECHO CommandLine class allows processing of command-line
arguments
Supply default values of various attributes and variables
Dissecting third.cc
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);
Various Helpers are available to help create wireless
channel/physical/mac models
Dissecting third.cc
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 MAC layer
Dissecting third.cc
NqosWifiMacHelper mac = NqosWifiMacHelper::Default (); Ssid ssid = Ssid ("ns-3-ssid");
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false)); NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiStaNodes); mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid)); NetDeviceContainer apDevices;
Configure all nodes in wifiStaNodes container to be of
type “station”
Configure first node of point-to-point link
All wireless nodes must be associated with mobility MobilityHelper provides a lot of help
MobilityHelper mobility; mobility.SetPositionAllocator ("ns3::GridPositionAllocator", "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);
Dissecting third.cc
1 2 3 4(MinX, MinY) DeltaX
Create a copy of third.cc into the scratch dir and rename
it to pm-ex1.cc
Edit the source
Change port number from 9 to 7 (standard ECHO port)
Change PCAP file prefix to pm-ex1
Walk-Through Example I (2)
$ cp examples/tutorials/third.cc scratch/pm-ex1.cc
UdpEchoServerHelper echoServer (7); :
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 7);
pointToPoint.EnablePcapAll ("pm-ex1");
phy.EnablePcap ("pm-ex1", apDevices.Get (0));
Run the script
Open the pcap files with WireShark
Walk-Through Example I (3)
$ 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
Visualize the simulation by adding option
--visualize
Press F3 to start the simulation
Walk-Through Example I (4)
Attributes can be configured and explored before the simulation starts
Walk-Through Example I (5)
#include "ns3/gtk-config-store.h" GtkConfigStore config; config.ConfigureAttributes(); Simulator::Run (); GtkConfigStore can also be invoked in PyViz using Ipython
shell
Ipython must be installed
Task: Using the previous topology, replace ECHO traffic
with CBR (Constant Bit Rate) traffic
Walk-Through Example II (1)
N2 N3 N4 N0 N1 10.1.1.0/24 10.1.2.0/24 10.1.3.0/24 N5 N6 N7 CBR (512 Kbps) Create pm-ex2.cc from pm-ex1.cc
Use OnOffHelper to generate CBR traffic from the client
Walk-Through Example II (2)
$ cp scratch/pm-ex1.cc scratch/pm-ex2.cc 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"));ApplicationContainer apps = onoff.Install(wifiStaNodes.Get(nWifi-1)); apps.Start(Seconds(5.0));
Install app on node N7 only
Create a packet sink on the server
Set simulation time to 30 seconds
Don't forget to change the PCAP trace prefix
Walk-Through Example II (3)
PacketSinkHelper sink( "ns3::UdpSocketFactory", InetSocketAddress("10.1.2.4", port)); sink.Install(csmaNodes.Get(nCsma)); Simulator::Stop(Seconds(25.0)); Install PacketSink on node N4
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
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
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
Connecting Trace Source/Sink
PacketSink Object
Quoted from ns-3 Tutorial:
“…always try to copy someone else's working code…”
Opening examples/csma/csma-ping.cc reveals
Then look at definition of SinkRx function:
Callback Signature
$ 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", :
:
Config::ConnectWithoutContext ("/NodeList/3/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&SinkRx));
If no example can be found, look at ns-3 source code!
Either way, we now know that our callback's signature
should be:
Callback Signature
$ 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 &,
:
Create pm-ex3.cc from pm-ex2.cc
Prepare trace sink callback and necessary statistical
variables
Walk-Through Example III (2)
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(); } $ cp scratch/pm-ex2.cc scratch/pm-ex3.cc
Connect trace source with trace sink
Produce statistical report at the end of the script
Run the simulation script
Walk-Through Example III (3)
Config::ConnectWithoutContext(
"/NodeList/*/ApplicationList/*/$ns3::PacketSink/Rx", MakeCallback(&SinkRxTrace));
cout << "Avg throughput = "
<< bytesTotal*8/(lastRxTime-firstRxTime)/1024 << " kbits/sec" << endl;
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
Create pm-ex4.cc from pm-ex3.cc
Modify the source so that OnOff application is installed
on all WiFi stations
Change the line:
to
Walk-Through Example IV (2)
$ cp scratch/pm-ex3.cc scratch/pm-ex4.cc
ApplicationContainer apps = onoff.Install(wifiStaNodes);
Report the number of WiFi stations in addition to the
average throughput
Try running the script with various values specified for nWifi argument
Walk-Through Example IV (3)
cout << "Num clients = " << nWifi << " " << "Avg throughput = "
<< bytesTotal*8/(lastRxTime-firstRxTime)/1024 << " kbits/sec" << endl;
$ 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
suppress stderr messages
Create a shell-script, named run-all.sh, that runs the
simulation with different values for nWifi
Run the shell-script and redirect all stdout messages to a
file
Walk-Through Example IV (4)
#!/bin/bash
for ((i=2; i<=14; i += 2)); do waf --run "pm-ex4 --nWifi=$i" done
Visualize results with gnuplot
Walk-Through Example IV (5)
$ gnuplot
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
Walk-Through Example IV (6)
#!/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
Run the plotting script
Walk-Through Example IV (7)
Publication-quality results should be obtained from many
replications in each scenario
Use --RngRun=<run-number> to change random
sequence
Running Multiple Replications
Study impact of number of mobile stations to packet
delivery ratio