1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation;
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17 // Network topology
18 //
19 // n0 n1 n2 n3
20 // | | | |
21 // =================
22 // LAN
23 //
24 // This program demonstrates some basic use of the Object names capability
25 //
26
27 #include "ns3/core-module.h"
28 #include "ns3/csma-module.h"
29 #include "ns3/applications-module.h"
30 #include "ns3/internet-module.h"
31
32 using namespace ns3;
33
34 NS_LOG_COMPONENT_DEFINE ("ObjectNamesExample");
35
36 uint32_t bytesReceived = 0;
37
38 void
RxEvent(std::string context,Ptr<const Packet> packet)39 RxEvent (std::string context, Ptr<const Packet> packet)
40 {
41 std::cout << Simulator::Now ().GetSeconds () << "s " << context << " packet size " << packet->GetSize () << std::endl;
42 bytesReceived += packet->GetSize ();
43 }
44
45 int
main(int argc,char * argv[])46 main (int argc, char *argv[])
47 {
48 bool outputValidated = true;
49
50 CommandLine cmd (__FILE__);
51 cmd.Parse (argc, argv);
52
53 NodeContainer n;
54 n.Create (4);
55
56 //
57 // We're going to use the zeroth node in the container as the client, and
58 // the first node as the server. Add some "human readable" names for these
59 // nodes. The names below will go into the name system as "/Names/clientZero"
60 // and "/Names/server", but note that the Add function assumes that if you
61 // omit the leading "/Names/" the remaining string is assumed to be rooted
62 // in the "/Names" namespace. The following calls,
63 //
64 // Names::Add ("clientZero", n.Get (0));
65 // Names::Add ("/Names/clientZero", n.Get (0));
66 //
67 // will produce identical results.
68 //
69 Names::Add ("clientZero", n.Get (0));
70 Names::Add ("/Names/server", n.Get (1));
71
72 //
73 // It is possible to rename a node that has been previously named. This is
74 // useful in automatic name generation. You can automatically generate node
75 // names such as, "node-0", "node-1", etc., and then go back and change
76 // the name of some distinguished node to another value -- "access-point"
77 // for example. We illustrate this by just changing the client's name.
78 // As is typical of the object name service, you can either provide or elide
79 // the "/Names" prefix as you choose.
80 //
81 Names::Rename ("clientZero", "client");
82
83 InternetStackHelper internet;
84 internet.Install (n);
85
86 CsmaHelper csma;
87 csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate (5000000)));
88 csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
89 csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
90 NetDeviceContainer d = csma.Install (n);
91
92 //
93 // Add some human readable names for the devices we'll be interested in.
94 // We add the names to the name space "under" the nodes we created above.
95 // This has the effect of making "/Names/client/eth0" and "/Names/server/eth0".
96 // In this case, we again omit the "/Names/" prefix on one call to illustrate
97 // the shortcut.
98 //
99 Names::Add ("/Names/client/eth0", d.Get (0));
100 Names::Add ("server/eth0", d.Get (1));
101
102 //
103 // You can use the object names that you've assigned in calls to the Config
104 // system to set Object Attributes. For example, you can set the Mtu
105 // Attribute of a Csma devices using the object naming service. Note that
106 // in this case, the "/Names" prefix is always required since the _Config_
107 // system always expects to see a fully qualified path name.
108 //
109
110 Ptr<CsmaNetDevice> csmaNetDevice = d.Get (0)->GetObject<CsmaNetDevice> ();
111 UintegerValue val;
112 csmaNetDevice->GetAttribute ("Mtu", val);
113 std::cout << "MTU on device 0 before configuration is " << val.Get () << std::endl;
114
115 Config::Set ("/Names/client/eth0/Mtu", UintegerValue (1234));
116
117 // Check the attribute again
118 csmaNetDevice->GetAttribute ("Mtu", val);
119 std::cout << "MTU on device 0 after configuration is " << val.Get () << std::endl;
120
121 if (val.Get () != 1234)
122 {
123 outputValidated = false;
124 }
125
126 //
127 // You can mix and match names and Attributes in calls to the Config system.
128 // For example, if "eth0" is a named object, you can get to its parent through
129 // a different namespace. For example, you could use the NodeList namespace
130 // to get to the server node, and then continue seamlessly adding named objects
131 // in the path. This is not nearly as readable as the previous version, but it
132 // illustrates how you can mix and match object names and Attribute names.
133 // Note that the config path now begins with a path in the "/NodeList"
134 // namespace.
135 //
136 Config::Set ("/NodeList/1/eth0/Mtu", UintegerValue (1234));
137
138 Ipv4AddressHelper ipv4;
139 ipv4.SetBase ("10.1.1.0", "255.255.255.0");
140 Ipv4InterfaceContainer i = ipv4.Assign (d);
141
142 uint16_t port = 9;
143 UdpEchoServerHelper server (port);
144 //
145 // Install the UdpEchoServer application on the server node using its name
146 // directly.
147 //
148 ApplicationContainer apps = server.Install ("/Names/server");
149 apps.Start (Seconds (1.0));
150 apps.Stop (Seconds (10.0));
151
152 uint32_t packetSize = 1024;
153 uint32_t maxPacketCount = 1;
154 Time interPacketInterval = Seconds (1.);
155 UdpEchoClientHelper client (i.GetAddress (1), port);
156 client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
157 client.SetAttribute ("Interval", TimeValue (interPacketInterval));
158 client.SetAttribute ("PacketSize", UintegerValue (packetSize));
159 //
160 // Install the UdpEchoClient application on the server node using its name
161 // directly.
162 //
163 apps = client.Install ("/Names/client");
164 apps.Start (Seconds (2.0));
165 apps.Stop (Seconds (10.0));
166
167 //
168 // Use the Config system to connect a trace source using the object name
169 // service to specify the path. Note that in this case, the "/Names"
170 // prefix is always required since the _Config_ system always expects to
171 // see a fully qualified path name
172 //
173 Config::Connect ("/Names/client/eth0/MacRx", MakeCallback (&RxEvent));
174
175 //
176 // Set up some pcap tracing on the CSMA devices. The names of the trace
177 // files will automatically correspond to the object names if present.
178 // In this case, you will find trace files called:
179 //
180 // object-names-client-eth0.pcap
181 // object-names-server-eth0.pcap
182 //
183 // since those nodes and devices have had names associated with them. You
184 // will also see:
185 //
186 // object-names-2-1.pcap
187 // object-names-3-1.pcap
188 //
189 // since nodes two and three have no associated names.
190 //
191 csma.EnablePcapAll ("object-names");
192
193 //
194 // We can also create a trace file with a name we completely control by
195 // overriding a couple of default parameters.
196 //
197 csma.EnablePcap ("client-device.pcap", d.Get (0), false, true);
198
199 std::cout << "Running simulation..." << std::endl;
200 Simulator::Run ();
201 Simulator::Destroy ();
202
203 // Expected to see ARP exchange and one packet
204 // 64 bytes (minimum Ethernet frame size) x 2, plus (1024 + 8 + 20 + 18)
205 if (bytesReceived != (64 + 64 + 1070))
206 {
207 outputValidated = false;
208 }
209
210 if (outputValidated == false)
211 {
212 std::cerr << "Program internal checking failed; returning with error" << std::endl;
213 return (1);
214 }
215 }
216