LEFT | RIGHT |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * Copyright (c) 2008 INRIA | 3 * Copyright (c) 2008 INRIA |
4 * | 4 * |
5 * This program is free software; you can redistribute it and/or modify | 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 | 6 * it under the terms of the GNU General Public License version 2 as |
7 * published by the Free Software Foundation; | 7 * published by the Free Software Foundation; |
8 * | 8 * |
9 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
13 * | 13 * |
14 * You should have received a copy of the GNU General Public License | 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 | 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 | 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 * | 17 * |
18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> | 18 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr> |
19 */ | 19 */ |
20 #include "point-to-point-helper.h" | 20 |
| 21 #include "ns3/abort.h" |
| 22 #include "ns3/log.h" |
21 #include "ns3/simulator.h" | 23 #include "ns3/simulator.h" |
22 #include "ns3/point-to-point-net-device.h" | 24 #include "ns3/point-to-point-net-device.h" |
23 #include "ns3/point-to-point-channel.h" | 25 #include "ns3/point-to-point-channel.h" |
24 #include "ns3/point-to-point-remote-channel.h" | 26 #include "ns3/point-to-point-remote-channel.h" |
25 #include "ns3/queue.h" | 27 #include "ns3/queue.h" |
26 #include "ns3/config.h" | 28 #include "ns3/config.h" |
27 #include "ns3/packet.h" | 29 #include "ns3/packet.h" |
28 #include "ns3/names.h" | 30 #include "ns3/names.h" |
29 #include "ns3/mpi-interface.h" | 31 #include "ns3/mpi-interface.h" |
30 #include "ns3/pcap-writer.h" | 32 |
31 #include "ns3/ascii-writer.h" | 33 #include "trace-helper.h" |
| 34 #include "point-to-point-helper.h" |
| 35 |
| 36 NS_LOG_COMPONENT_DEFINE ("PointToPointHelper"); |
32 | 37 |
33 namespace ns3 { | 38 namespace ns3 { |
34 | |
35 | 39 |
36 PointToPointHelper::PointToPointHelper () | 40 PointToPointHelper::PointToPointHelper () |
37 { | 41 { |
38 m_queueFactory.SetTypeId ("ns3::DropTailQueue"); | 42 m_queueFactory.SetTypeId ("ns3::DropTailQueue"); |
39 m_deviceFactory.SetTypeId ("ns3::PointToPointNetDevice"); | 43 m_deviceFactory.SetTypeId ("ns3::PointToPointNetDevice"); |
40 m_channelFactory.SetTypeId ("ns3::PointToPointChannel"); | 44 m_channelFactory.SetTypeId ("ns3::PointToPointChannel"); |
41 m_remoteChannelFactory.SetTypeId ("ns3::PointToPointRemoteChannel"); | 45 m_remoteChannelFactory.SetTypeId ("ns3::PointToPointRemoteChannel"); |
42 } | 46 } |
43 | 47 |
44 void· | 48 void· |
(...skipping 17 matching lines...) Expand all Loading... |
62 } | 66 } |
63 | 67 |
64 void· | 68 void· |
65 PointToPointHelper::SetChannelAttribute (std::string n1, const AttributeValue &v
1) | 69 PointToPointHelper::SetChannelAttribute (std::string n1, const AttributeValue &v
1) |
66 { | 70 { |
67 m_channelFactory.Set (n1, v1); | 71 m_channelFactory.Set (n1, v1); |
68 m_remoteChannelFactory.Set (n1, v1); | 72 m_remoteChannelFactory.Set (n1, v1); |
69 } | 73 } |
70 | 74 |
71 void· | 75 void· |
72 PointToPointHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t
deviceid) | 76 PointToPointHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, b
ool promiscuous, bool explicitFilename) |
73 { | 77 { |
| 78 // |
| 79 // All of the Pcap enable functions vector through here including the ones |
| 80 // that are wandering through all of devices on perhaps all of the nodes in |
| 81 // the system. We can only deal with devices of type PointToPointNetDevice. |
| 82 // |
| 83 Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice> (); |
| 84 if (device == 0) |
| 85 { |
| 86 NS_LOG_INFO ("PointToPointHelper::EnablePcapInternal(): Device " << device
<< " not of type ns3::PointToPointNetDevice"); |
| 87 return; |
| 88 } |
| 89 |
| 90 PcapHelper pcapHelper; |
| 91 |
| 92 std::string filename; |
| 93 if (explicitFilename) |
| 94 { |
| 95 filename = prefix; |
| 96 } |
| 97 else |
| 98 { |
| 99 filename = pcapHelper.GetFilenameFromDevice (prefix, device); |
| 100 } |
| 101 |
| 102 Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, "w", PcapHelper::
DLT_PPP); |
| 103 pcapHelper.HookDefaultSink<PointToPointNetDevice> (device, "PromiscSniffer", f
ile); |
| 104 } |
| 105 |
| 106 void· |
| 107 PointToPointHelper::EnableAsciiInternal ( |
| 108 Ptr<OutputStreamWrapper> stream,· |
| 109 std::string prefix,· |
| 110 Ptr<NetDevice> nd, |
| 111 bool explicitFilename) |
| 112 { |
| 113 // |
| 114 // All of the ascii enable functions vector through here including the ones |
| 115 // that are wandering through all of devices on perhaps all of the nodes in |
| 116 // the system. We can only deal with devices of type PointToPointNetDevice. |
| 117 // |
| 118 Ptr<PointToPointNetDevice> device = nd->GetObject<PointToPointNetDevice> (); |
| 119 if (device == 0) |
| 120 { |
| 121 NS_LOG_INFO ("PointToPointHelper::EnableAsciiInternal(): Device " << devic
e <<· |
| 122 " not of type ns3::PointToPointNetDevice"); |
| 123 return; |
| 124 } |
| 125 |
| 126 // |
| 127 // Our default trace sinks are going to use packet printing, so we have to· |
| 128 // make sure that is turned on. |
| 129 // |
| 130 Packet::EnablePrinting (); |
| 131 |
| 132 // |
| 133 // If we are not provided an OutputStreamWrapper, we are expected to create· |
| 134 // one using the usual trace filename conventions and do a Hook*WithoutContext |
| 135 // since there will be one file per context and therefore the context would |
| 136 // be redundant. |
| 137 // |
| 138 if (stream == 0) |
| 139 { |
| 140 // |
| 141 // Set up an output stream object to deal with private ofstream copy· |
| 142 // constructor and lifetime issues. Let the helper decide the actual |
| 143 // name of the file given the prefix. |
| 144 // |
| 145 AsciiTraceHelper asciiTraceHelper; |
| 146 |
| 147 std::string filename; |
| 148 if (explicitFilename) |
| 149 { |
| 150 filename = prefix; |
| 151 } |
| 152 else |
| 153 { |
| 154 filename = asciiTraceHelper.GetFilenameFromDevice (prefix, device); |
| 155 } |
| 156 |
| 157 Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (fi
lename, "w"); |
| 158 |
| 159 // |
| 160 // The MacRx trace source provides our "r" event. |
| 161 // |
| 162 asciiTraceHelper.HookDefaultReceiveSinkWithoutContext<PointToPointNetDevic
e> (device, "MacRx", theStream); |
| 163 |
| 164 // |
| 165 // The "+", '-', and 'd' events are driven by trace sources actually in th
e |
| 166 // transmit queue. |
| 167 // |
| 168 Ptr<Queue> queue = device->GetQueue (); |
| 169 asciiTraceHelper.HookDefaultEnqueueSinkWithoutContext<Queue> (queue, "Enqu
eue", theStream); |
| 170 asciiTraceHelper.HookDefaultDropSinkWithoutContext<Queue> (queue, "Drop",
theStream); |
| 171 asciiTraceHelper.HookDefaultDequeueSinkWithoutContext<Queue> (queue, "Dequ
eue", theStream); |
| 172 |
| 173 return; |
| 174 } |
| 175 |
| 176 // |
| 177 // If we are provided an OutputStreamWrapper, we are expected to use it, and |
| 178 // to providd a context. We are free to come up with our own context if we |
| 179 // want, and use the AsciiTraceHelper Hook*WithContext functions, but for· |
| 180 // compatibility and simplicity, we just use Config::Connect and let it deal |
| 181 // with the context. |
| 182 // |
| 183 // Note that we are going to use the default trace sinks provided by the· |
| 184 // ascii trace helper. There is actually no AsciiTraceHelper in sight here, |
| 185 // but the default trace sinks are actually publicly available static· |
| 186 // functions that are always there waiting for just such a case. |
| 187 // |
| 188 uint32_t nodeid = nd->GetNode ()->GetId (); |
| 189 uint32_t deviceid = nd->GetIfIndex (); |
74 std::ostringstream oss; | 190 std::ostringstream oss; |
75 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointTo
PointNetDevice/"; | 191 |
76 Config::MatchContainer matches = Config::LookupMatches (oss.str ()); | 192 oss << "/NodeList/" << nd->GetNode ()->GetId () << "/DeviceList/" << deviceid
<< "/$ns3::PointToPointNetDevice/MacRx"; |
77 if (matches.GetN () == 0) | 193 Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultRece
iveSinkWithContext, stream)); |
78 { | 194 |
79 return; | |
80 } | |
81 oss.str (""); | |
82 oss << filename << "-" << nodeid << "-" << deviceid << ".pcap"; | |
83 Ptr<PcapWriter> pcap = CreateObject<PcapWriter> (); | |
84 pcap->Open (oss.str ()); | |
85 pcap->WritePppHeader (); | |
86 oss.str (""); | |
87 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid; | |
88 oss << "/$ns3::PointToPointNetDevice/PromiscSniffer"; | |
89 Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHel
per::SniffEvent, pcap)); | |
90 } | |
91 | |
92 void· | |
93 PointToPointHelper::EnablePcap (std::string filename, Ptr<NetDevice> nd) | |
94 { | |
95 EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ()); | |
96 } | |
97 | |
98 void· | |
99 PointToPointHelper::EnablePcap (std::string filename, std::string ndName) | |
100 { | |
101 Ptr<NetDevice> nd = Names::Find<NetDevice> (ndName); | |
102 EnablePcap (filename, nd->GetNode ()->GetId (), nd->GetIfIndex ()); | |
103 } | |
104 | |
105 void· | |
106 PointToPointHelper::EnablePcap (std::string filename, NetDeviceContainer d) | |
107 { | |
108 for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i) | |
109 { | |
110 Ptr<NetDevice> dev = *i; | |
111 EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ()); | |
112 } | |
113 } | |
114 | |
115 void | |
116 PointToPointHelper::EnablePcap (std::string filename, NodeContainer n) | |
117 { | |
118 NetDeviceContainer devs; | |
119 for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) | |
120 { | |
121 Ptr<Node> node = *i; | |
122 for (uint32_t j = 0; j < node->GetNDevices (); ++j) | |
123 { | |
124 devs.Add (node->GetDevice (j)); | |
125 } | |
126 } | |
127 EnablePcap (filename, devs); | |
128 } | |
129 | |
130 void | |
131 PointToPointHelper::EnablePcapAll (std::string filename) | |
132 { | |
133 EnablePcap (filename, NodeContainer::GetGlobal ()); | |
134 } | |
135 | |
136 void· | |
137 PointToPointHelper::EnableAscii (std::ostream &os, uint32_t nodeid, uint32_t dev
iceid) | |
138 { | |
139 Ptr<AsciiWriter> writer = AsciiWriter::Get (os); | |
140 Packet::EnablePrinting (); | |
141 std::ostringstream oss; | |
142 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointTo
PointNetDevice/MacRx"; | |
143 Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiRxEv
ent, writer)); | |
144 oss.str (""); | 195 oss.str (""); |
145 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointTo
PointNetDevice/TxQueue/Enqueue"; | 196 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointTo
PointNetDevice/TxQueue/Enqueue"; |
146 Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiEnqu
eueEvent, writer)); | 197 Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultEnqu
eueSinkWithContext, stream)); |
| 198 |
147 oss.str (""); | 199 oss.str (""); |
148 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointTo
PointNetDevice/TxQueue/Dequeue"; | 200 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointTo
PointNetDevice/TxQueue/Dequeue"; |
149 Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiDequ
eueEvent, writer)); | 201 Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDequ
eueSinkWithContext, stream)); |
| 202 |
150 oss.str (""); | 203 oss.str (""); |
151 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointTo
PointNetDevice/TxQueue/Drop"; | 204 oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointTo
PointNetDevice/TxQueue/Drop"; |
152 Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiDrop
Event, writer)); | 205 Config::Connect (oss.str (), MakeBoundCallback (&AsciiTraceHelper::DefaultDrop
SinkWithContext, stream)); |
153 } | |
154 | |
155 void· | |
156 PointToPointHelper::EnableAscii (std::ostream &os, NetDeviceContainer d) | |
157 { | |
158 for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i) | |
159 { | |
160 Ptr<NetDevice> dev = *i; | |
161 EnableAscii (os, dev->GetNode ()->GetId (), dev->GetIfIndex ()); | |
162 } | |
163 } | |
164 | |
165 void | |
166 PointToPointHelper::EnableAscii (std::ostream &os, NodeContainer n) | |
167 { | |
168 NetDeviceContainer devs; | |
169 for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i) | |
170 { | |
171 Ptr<Node> node = *i; | |
172 for (uint32_t j = 0; j < node->GetNDevices (); ++j) | |
173 { | |
174 devs.Add (node->GetDevice (j)); | |
175 } | |
176 } | |
177 EnableAscii (os, devs); | |
178 } | |
179 | |
180 void | |
181 PointToPointHelper::EnableAsciiAll (std::ostream &os) | |
182 { | |
183 EnableAscii (os, NodeContainer::GetGlobal ()); | |
184 } | 206 } |
185 | 207 |
186 NetDeviceContainer· | 208 NetDeviceContainer· |
187 PointToPointHelper::Install (NodeContainer c) | 209 PointToPointHelper::Install (NodeContainer c) |
188 { | 210 { |
189 NS_ASSERT (c.GetN () == 2); | 211 NS_ASSERT (c.GetN () == 2); |
190 return Install (c.Get (0), c.Get (1)); | 212 return Install (c.Get (0), c.Get (1)); |
191 } | 213 } |
192 | 214 |
193 NetDeviceContainer· | 215 NetDeviceContainer· |
194 PointToPointHelper::Install (Ptr<Node> a, Ptr<Node> b) | 216 PointToPointHelper::Install (Ptr<Node> a, Ptr<Node> b) |
195 { | 217 { |
196 NetDeviceContainer container; | 218 NetDeviceContainer container; |
197 | 219 |
198 Ptr<PointToPointNetDevice> devA = m_deviceFactory.Create<PointToPointNetDevice
> (); | 220 Ptr<PointToPointNetDevice> devA = m_deviceFactory.Create<PointToPointNetDevice
> (); |
199 devA->SetAddress (Mac48Address::Allocate ()); | 221 devA->SetAddress (Mac48Address::Allocate ()); |
200 a->AddDevice (devA); | 222 a->AddDevice (devA); |
201 Ptr<Queue> queueA = m_queueFactory.Create<Queue> (); | 223 Ptr<Queue> queueA = m_queueFactory.Create<Queue> (); |
202 devA->SetQueue (queueA); | 224 devA->SetQueue (queueA); |
203 Ptr<PointToPointNetDevice> devB = m_deviceFactory.Create<PointToPointNetDevice
> (); | 225 Ptr<PointToPointNetDevice> devB = m_deviceFactory.Create<PointToPointNetDevice
> (); |
204 devB->SetAddress (Mac48Address::Allocate ()); | 226 devB->SetAddress (Mac48Address::Allocate ()); |
205 b->AddDevice (devB); | 227 b->AddDevice (devB); |
206 Ptr<Queue> queueB = m_queueFactory.Create<Queue> (); | 228 Ptr<Queue> queueB = m_queueFactory.Create<Queue> (); |
207 devB->SetQueue (queueB); | 229 devB->SetQueue (queueB); |
208 // If MPI is enabled, we need to see if both nodes are on the same rank, and | 230 // If MPI is enabled, we need to see if both nodes have the same system id |
209 // the rank is the same as this instance. If both are true, use a normal | 231 // (rank), and the rank is the same as this instance. If both are true, |
210 // p2p channel, otherwise use a remote channel | 232 //use a normal p2p channel, otherwise use a remote channel |
211 bool useNormalChannel = true; | 233 bool useNormalChannel = true; |
212 Ptr<PointToPointChannel> channel = 0; | 234 Ptr<PointToPointChannel> channel = 0; |
213 if (MPIInterface::IsEnabled()) | 235 if (MpiInterface::IsEnabled()) |
214 { | 236 { |
215 uint32_t n1System = a->GetSystemId (); | 237 uint32_t n1SystemId = a->GetSystemId (); |
216 uint32_t n2System = b->GetSystemId (); | 238 uint32_t n2SystemId = b->GetSystemId (); |
217 uint32_t rank = MPIInterface::Rank (); | 239 uint32_t currSystemId = MpiInterface::GetSystemId (); |
218 if (n1System != rank || n2System != rank) useNormalChannel = false; | 240 if (n1SystemId != currSystemId || n2SystemId != currSystemId)· |
| 241 { |
| 242 useNormalChannel = false; |
| 243 } |
219 } | 244 } |
220 if (useNormalChannel) | 245 if (useNormalChannel) |
221 { | 246 { |
222 channel = m_channelFactory.Create<PointToPointChannel> (); | 247 channel = m_channelFactory.Create<PointToPointChannel> (); |
223 } | 248 } |
224 else | 249 else |
225 { | 250 { |
226 channel = m_remoteChannelFactory.Create<PointToPointRemoteChannel> (); | 251 channel = m_remoteChannelFactory.Create<PointToPointRemoteChannel> (); |
227 } | 252 } |
228 ···· | 253 ···· |
(...skipping 20 matching lines...) Expand all Loading... |
249 } | 274 } |
250 | 275 |
251 NetDeviceContainer· | 276 NetDeviceContainer· |
252 PointToPointHelper::Install (std::string aName, std::string bName) | 277 PointToPointHelper::Install (std::string aName, std::string bName) |
253 { | 278 { |
254 Ptr<Node> a = Names::Find<Node> (aName); | 279 Ptr<Node> a = Names::Find<Node> (aName); |
255 Ptr<Node> b = Names::Find<Node> (bName); | 280 Ptr<Node> b = Names::Find<Node> (bName); |
256 return Install (a, b); | 281 return Install (a, b); |
257 } | 282 } |
258 | 283 |
259 void· | |
260 PointToPointHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet
) | |
261 { | |
262 writer->WritePacket (packet); | |
263 } | |
264 | |
265 void | |
266 PointToPointHelper::AsciiEnqueueEvent (Ptr<AsciiWriter> writer, std::string path
, | |
267 Ptr<const Packet> packet) | |
268 { | |
269 writer->WritePacket (AsciiWriter::ENQUEUE, path, packet); | |
270 } | |
271 | |
272 void | |
273 PointToPointHelper::AsciiDequeueEvent (Ptr<AsciiWriter> writer, std::string path
, Ptr<const Packet> packet) | |
274 { | |
275 writer->WritePacket (AsciiWriter::DEQUEUE, path, packet); | |
276 } | |
277 | |
278 void | |
279 PointToPointHelper::AsciiDropEvent (Ptr<AsciiWriter> writer, std::string path, P
tr<const Packet> packet) | |
280 { | |
281 writer->WritePacket (AsciiWriter::DROP, path, packet); | |
282 } | |
283 | |
284 void | |
285 PointToPointHelper::AsciiRxEvent (Ptr<AsciiWriter> writer, std::string path, Ptr
<const Packet> packet) | |
286 { | |
287 writer->WritePacket (AsciiWriter::RX, path, packet); | |
288 } | |
289 | |
290 } // namespace ns3 | 284 } // namespace ns3 |
LEFT | RIGHT |