1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 University of Washington
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  */
19 
20 //
21 // This program configures a grid (default 5x5) of nodes on an
22 // 802.11b physical layer, with
23 // 802.11b NICs in adhoc mode, and by default, sends one packet of 1000
24 // (application) bytes to node 1.
25 //
26 // The default layout is like this, on a 2-D grid.
27 //
28 // n20  n21  n22  n23  n24
29 // n15  n16  n17  n18  n19
30 // n10  n11  n12  n13  n14
31 // n5   n6   n7   n8   n9
32 // n0   n1   n2   n3   n4
33 //
34 // the layout is affected by the parameters given to GridPositionAllocator;
35 // by default, GridWidth is 5 and numNodes is 25..
36 //
37 // There are a number of command-line options available to control
38 // the default behavior.  The list of available command-line options
39 // can be listed with the following command:
40 // ./waf --run "wifi-simple-adhoc-grid --help"
41 //
42 // Note that all ns-3 attributes (not just the ones exposed in the below
43 // script) can be changed at command line; see the ns-3 documentation.
44 //
45 // For instance, for this configuration, the physical layer will
46 // stop successfully receiving packets when distance increases beyond
47 // the default of 500m.
48 // To see this effect, try running:
49 //
50 // ./waf --run "wifi-simple-adhoc-grid --distance=500"
51 // ./waf --run "wifi-simple-adhoc-grid --distance=1000"
52 // ./waf --run "wifi-simple-adhoc-grid --distance=1500"
53 //
54 // The source node and sink node can be changed like this:
55 //
56 // ./waf --run "wifi-simple-adhoc-grid --sourceNode=20 --sinkNode=10"
57 //
58 // This script can also be helpful to put the Wifi layer into verbose
59 // logging mode; this command will turn on all wifi logging:
60 //
61 // ./waf --run "wifi-simple-adhoc-grid --verbose=1"
62 //
63 // By default, trace file writing is off-- to enable it, try:
64 // ./waf --run "wifi-simple-adhoc-grid --tracing=1"
65 //
66 // When you are done tracing, you will notice many pcap trace files
67 // in your directory.  If you have tcpdump installed, you can try this:
68 //
69 // tcpdump -r wifi-simple-adhoc-grid-0-0.pcap -nn -tt
70 //
71 
72 #include "ns3/command-line.h"
73 #include "ns3/config.h"
74 #include "ns3/uinteger.h"
75 #include "ns3/double.h"
76 #include "ns3/string.h"
77 #include "ns3/log.h"
78 #include "ns3/yans-wifi-helper.h"
79 #include "ns3/mobility-helper.h"
80 #include "ns3/ipv4-address-helper.h"
81 #include "ns3/yans-wifi-channel.h"
82 #include "ns3/mobility-model.h"
83 #include "ns3/olsr-helper.h"
84 #include "ns3/ipv4-static-routing-helper.h"
85 #include "ns3/ipv4-list-routing-helper.h"
86 #include "ns3/internet-stack-helper.h"
87 
88 using namespace ns3;
89 
90 NS_LOG_COMPONENT_DEFINE ("WifiSimpleAdhocGrid");
91 
ReceivePacket(Ptr<Socket> socket)92 void ReceivePacket (Ptr<Socket> socket)
93 {
94   while (socket->Recv ())
95     {
96       NS_LOG_UNCOND ("Received one packet!");
97     }
98 }
99 
GenerateTraffic(Ptr<Socket> socket,uint32_t pktSize,uint32_t pktCount,Time pktInterval)100 static void GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize,
101                              uint32_t pktCount, Time pktInterval )
102 {
103   if (pktCount > 0)
104     {
105       socket->Send (Create<Packet> (pktSize));
106       Simulator::Schedule (pktInterval, &GenerateTraffic,
107                            socket, pktSize,pktCount - 1, pktInterval);
108     }
109   else
110     {
111       socket->Close ();
112     }
113 }
114 
115 
main(int argc,char * argv[])116 int main (int argc, char *argv[])
117 {
118   std::string phyMode ("DsssRate1Mbps");
119   double distance = 500;  // m
120   uint32_t packetSize = 1000; // bytes
121   uint32_t numPackets = 1;
122   uint32_t numNodes = 25;  // by default, 5x5
123   uint32_t sinkNode = 0;
124   uint32_t sourceNode = 24;
125   double interval = 1.0; // seconds
126   bool verbose = false;
127   bool tracing = false;
128 
129   CommandLine cmd (__FILE__);
130   cmd.AddValue ("phyMode", "Wifi Phy mode", phyMode);
131   cmd.AddValue ("distance", "distance (m)", distance);
132   cmd.AddValue ("packetSize", "size of application packet sent", packetSize);
133   cmd.AddValue ("numPackets", "number of packets generated", numPackets);
134   cmd.AddValue ("interval", "interval (seconds) between packets", interval);
135   cmd.AddValue ("verbose", "turn on all WifiNetDevice log components", verbose);
136   cmd.AddValue ("tracing", "turn on ascii and pcap tracing", tracing);
137   cmd.AddValue ("numNodes", "number of nodes", numNodes);
138   cmd.AddValue ("sinkNode", "Receiver node number", sinkNode);
139   cmd.AddValue ("sourceNode", "Sender node number", sourceNode);
140   cmd.Parse (argc, argv);
141   // Convert to time object
142   Time interPacketInterval = Seconds (interval);
143 
144   // Fix non-unicast data rate to be the same as that of unicast
145   Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
146                       StringValue (phyMode));
147 
148   NodeContainer c;
149   c.Create (numNodes);
150 
151   // The below set of helpers will help us to put together the wifi NICs we want
152   WifiHelper wifi;
153   if (verbose)
154     {
155       wifi.EnableLogComponents ();  // Turn on all Wifi logging
156     }
157 
158   YansWifiPhyHelper wifiPhy;
159   // set it to zero; otherwise, gain will be added
160   wifiPhy.Set ("RxGain", DoubleValue (-10) );
161   // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
162   wifiPhy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);
163 
164   YansWifiChannelHelper wifiChannel;
165   wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
166   wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel");
167   wifiPhy.SetChannel (wifiChannel.Create ());
168 
169   // Add an upper mac and disable rate control
170   WifiMacHelper wifiMac;
171   wifi.SetStandard (WIFI_STANDARD_80211b);
172   wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
173                                 "DataMode",StringValue (phyMode),
174                                 "ControlMode",StringValue (phyMode));
175   // Set it to adhoc mode
176   wifiMac.SetType ("ns3::AdhocWifiMac");
177   NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);
178 
179   MobilityHelper mobility;
180   mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
181                                  "MinX", DoubleValue (0.0),
182                                  "MinY", DoubleValue (0.0),
183                                  "DeltaX", DoubleValue (distance),
184                                  "DeltaY", DoubleValue (distance),
185                                  "GridWidth", UintegerValue (5),
186                                  "LayoutType", StringValue ("RowFirst"));
187   mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
188   mobility.Install (c);
189 
190   // Enable OLSR
191   OlsrHelper olsr;
192   Ipv4StaticRoutingHelper staticRouting;
193 
194   Ipv4ListRoutingHelper list;
195   list.Add (staticRouting, 0);
196   list.Add (olsr, 10);
197 
198   InternetStackHelper internet;
199   internet.SetRoutingHelper (list); // has effect on the next Install ()
200   internet.Install (c);
201 
202   Ipv4AddressHelper ipv4;
203   NS_LOG_INFO ("Assign IP Addresses.");
204   ipv4.SetBase ("10.1.1.0", "255.255.255.0");
205   Ipv4InterfaceContainer i = ipv4.Assign (devices);
206 
207   TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
208   Ptr<Socket> recvSink = Socket::CreateSocket (c.Get (sinkNode), tid);
209   InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 80);
210   recvSink->Bind (local);
211   recvSink->SetRecvCallback (MakeCallback (&ReceivePacket));
212 
213   Ptr<Socket> source = Socket::CreateSocket (c.Get (sourceNode), tid);
214   InetSocketAddress remote = InetSocketAddress (i.GetAddress (sinkNode, 0), 80);
215   source->Connect (remote);
216 
217   if (tracing == true)
218     {
219       AsciiTraceHelper ascii;
220       wifiPhy.EnableAsciiAll (ascii.CreateFileStream ("wifi-simple-adhoc-grid.tr"));
221       wifiPhy.EnablePcap ("wifi-simple-adhoc-grid", devices);
222       // Trace routing tables
223       Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper> ("wifi-simple-adhoc-grid.routes", std::ios::out);
224       olsr.PrintRoutingTableAllEvery (Seconds (2), routingStream);
225       Ptr<OutputStreamWrapper> neighborStream = Create<OutputStreamWrapper> ("wifi-simple-adhoc-grid.neighbors", std::ios::out);
226       olsr.PrintNeighborCacheAllEvery (Seconds (2), neighborStream);
227 
228       // To do-- enable an IP-level trace that shows forwarding events only
229     }
230 
231   // Give OLSR time to converge-- 30 seconds perhaps
232   Simulator::Schedule (Seconds (30.0), &GenerateTraffic,
233                        source, packetSize, numPackets, interPacketInterval);
234 
235   // Output what we are doing
236   NS_LOG_UNCOND ("Testing from node " << sourceNode << " to " << sinkNode << " with grid distance " << distance);
237 
238   Simulator::Stop (Seconds (33.0));
239   Simulator::Run ();
240   Simulator::Destroy ();
241 
242   return 0;
243 }
244 
245