A Discrete-Event Network Simulator
API
mesh-point-device.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008,2009 IITP RAS
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Kirill Andreev <andreev@iitp.ru>
18  * Pavel Boyko <boyko@iitp.ru>
19  */
20 
21 #include "mesh-point-device.h"
22 
24 
25 #include "ns3/log.h"
26 #include "ns3/packet.h"
27 #include "ns3/pointer.h"
28 #include "ns3/simulator.h"
29 #include "ns3/string.h"
30 #include "ns3/wifi-net-device.h"
31 
32 namespace ns3
33 {
34 
35 NS_LOG_COMPONENT_DEFINE("MeshPointDevice");
36 
37 NS_OBJECT_ENSURE_REGISTERED(MeshPointDevice);
38 
39 TypeId
41 {
42  static TypeId tid =
43  TypeId("ns3::MeshPointDevice")
45  .SetGroupName("Mesh")
46  .AddConstructor<MeshPointDevice>()
47  .AddAttribute("Mtu",
48  "The MAC-level Maximum Transmission Unit",
49  UintegerValue(0xffff),
51  MakeUintegerChecker<uint16_t>())
52  .AddAttribute("RoutingProtocol",
53  "The mesh routing protocol used by this mesh point.",
54  PointerValue(),
57  MakePointerChecker<MeshL2RoutingProtocol>())
58  .AddAttribute("ForwardingDelay",
59  "A random variable to account for processing time (microseconds) to "
60  "forward a frame.",
61  StringValue("ns3::UniformRandomVariable[Min=300.0|Max=400.0]"),
63  MakePointerChecker<RandomVariableStream>());
64  return tid;
65 }
66 
68  : m_ifIndex(0)
69 {
70  NS_LOG_FUNCTION(this);
71  m_channel = CreateObject<BridgeChannel>();
72 }
73 
75 {
76  NS_LOG_FUNCTION(this);
77  m_node = nullptr;
78  m_channel = nullptr;
79  m_routingProtocol = nullptr;
80 }
81 
82 void
84 {
85  NS_LOG_FUNCTION(this);
86  for (auto iter = m_ifaces.begin(); iter != m_ifaces.end(); iter++)
87  {
88  *iter = nullptr;
89  }
90  m_ifaces.clear();
91  m_node = nullptr;
92  m_channel = nullptr;
93  m_routingProtocol = nullptr;
95 }
96 
97 //-----------------------------------------------------------------------------
98 // NetDevice interface implementation
99 //-----------------------------------------------------------------------------
100 
101 void
103  Ptr<const Packet> packet,
104  uint16_t protocol,
105  const Address& src,
106  const Address& dst,
107  PacketType packetType)
108 {
109  NS_LOG_FUNCTION(this << incomingPort << packet);
110  NS_LOG_DEBUG("UID is " << packet->GetUid());
111  const Mac48Address src48 = Mac48Address::ConvertFrom(src);
112  const Mac48Address dst48 = Mac48Address::ConvertFrom(dst);
113  uint16_t& realProtocol = protocol;
114  NS_LOG_DEBUG("SRC=" << src48 << ", DST = " << dst48 << ", I am: " << m_address);
116  {
117  m_promiscRxCallback(this, packet, protocol, src, dst, packetType);
118  }
119  if (dst48.IsGroup())
120  {
121  Ptr<Packet> packet_copy = packet->Copy();
122  if (m_routingProtocol->RemoveRoutingStuff(incomingPort->GetIfIndex(),
123  src48,
124  dst48,
125  packet_copy,
126  realProtocol))
127  {
128  m_rxCallback(this, packet_copy, realProtocol, src);
130  m_rxStats.broadcastDataBytes += packet->GetSize();
131  Time forwardingDelay = GetForwardingDelay();
132  NS_LOG_DEBUG("Forwarding broadcast from " << src48 << " to " << dst48 << " with delay "
133  << forwardingDelay.As(Time::US));
134  Simulator::Schedule(forwardingDelay,
136  this,
137  incomingPort,
138  packet,
139  protocol,
140  src48,
141  dst48);
142  }
143  return;
144  }
145  if (dst48 == m_address)
146  {
147  Ptr<Packet> packet_copy = packet->Copy();
148  if (m_routingProtocol->RemoveRoutingStuff(incomingPort->GetIfIndex(),
149  src48,
150  dst48,
151  packet_copy,
152  realProtocol))
153  {
154  m_rxCallback(this, packet_copy, realProtocol, src);
156  m_rxStats.unicastDataBytes += packet->GetSize();
157  }
158  return;
159  }
160  else
161  {
162  Time forwardingDelay = GetForwardingDelay();
163  Simulator::Schedule(forwardingDelay,
165  this,
166  incomingPort,
167  packet->Copy(),
168  protocol,
169  src48,
170  dst48);
171  NS_LOG_DEBUG("Forwarding unicast from " << src48 << " to " << dst48 << " with delay "
172  << forwardingDelay.As(Time::US));
173  }
174 }
175 
176 void
178  Ptr<const Packet> packet,
179  uint16_t protocol,
180  const Mac48Address src,
181  const Mac48Address dst)
182 {
183  NS_LOG_FUNCTION(this << incomingPort << packet << protocol << src << dst);
184  // pass through routing protocol
185  NS_LOG_DEBUG("Forwarding from " << src << " to " << dst << " at " << m_address);
186  bool result = m_routingProtocol->RequestRoute(incomingPort->GetIfIndex(),
187  src,
188  dst,
189  packet,
190  protocol,
192  if (!result)
193  {
194  NS_LOG_DEBUG("Request to forward packet " << packet << " to destination " << dst
195  << " failed; dropping packet");
196  }
197 }
198 
199 void
200 MeshPointDevice::SetIfIndex(const uint32_t index)
201 {
202  NS_LOG_FUNCTION(this);
203  m_ifIndex = index;
204 }
205 
206 uint32_t
208 {
209  NS_LOG_FUNCTION(this);
210  return m_ifIndex;
211 }
212 
215 {
216  NS_LOG_FUNCTION(this);
217  return m_channel;
218 }
219 
220 Address
222 {
223  NS_LOG_FUNCTION(this);
224  return m_address;
225 }
226 
227 void
229 {
230  NS_LOG_FUNCTION(this);
231  NS_LOG_WARN("Manual changing mesh point address can cause routing errors.");
233 }
234 
235 bool
236 MeshPointDevice::SetMtu(const uint16_t mtu)
237 {
238  NS_LOG_FUNCTION(this);
239  m_mtu = mtu;
240  return true;
241 }
242 
243 uint16_t
245 {
246  NS_LOG_FUNCTION(this);
247  return m_mtu;
248 }
249 
250 bool
252 {
253  NS_LOG_FUNCTION(this);
254  return true;
255 }
256 
257 void
259 {
260  NS_LOG_FUNCTION(this);
261  // do nothing
262  NS_LOG_WARN("AddLinkChangeCallback does nothing");
263 }
264 
265 bool
267 {
268  NS_LOG_FUNCTION(this);
269  return true;
270 }
271 
272 Address
274 {
275  NS_LOG_FUNCTION(this);
276  return Mac48Address("ff:ff:ff:ff:ff:ff");
277 }
278 
279 bool
281 {
282  NS_LOG_FUNCTION(this);
283  return true;
284 }
285 
286 Address
288 {
289  NS_LOG_FUNCTION(this << multicastGroup);
290  Mac48Address multicast = Mac48Address::GetMulticast(multicastGroup);
291  return multicast;
292 }
293 
294 bool
296 {
297  NS_LOG_FUNCTION(this);
298  return false;
299 }
300 
301 bool
303 {
304  NS_LOG_FUNCTION(this);
305  return false;
306 }
307 
308 bool
309 MeshPointDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
310 {
311  NS_LOG_FUNCTION(this);
312  const Mac48Address dst48 = Mac48Address::ConvertFrom(dest);
313  return m_routingProtocol->RequestRoute(m_ifIndex,
314  m_address,
315  dst48,
316  packet,
317  protocolNumber,
319 }
320 
321 bool
323  const Address& src,
324  const Address& dest,
325  uint16_t protocolNumber)
326 {
327  NS_LOG_FUNCTION(this);
328  const Mac48Address src48 = Mac48Address::ConvertFrom(src);
329  const Mac48Address dst48 = Mac48Address::ConvertFrom(dest);
330  return m_routingProtocol->RequestRoute(m_ifIndex,
331  src48,
332  dst48,
333  packet,
334  protocolNumber,
336 }
337 
338 Ptr<Node>
340 {
341  NS_LOG_FUNCTION(this);
342  return m_node;
343 }
344 
345 void
347 {
348  NS_LOG_FUNCTION(this);
349  m_node = node;
350 }
351 
352 bool
354 {
355  NS_LOG_FUNCTION(this);
356  return true;
357 }
358 
359 void
361 {
362  NS_LOG_FUNCTION(this);
363  m_rxCallback = cb;
364 }
365 
366 void
368 {
369  NS_LOG_FUNCTION(this);
370  m_promiscRxCallback = cb;
371 }
372 
373 bool
375 {
376  NS_LOG_FUNCTION(this);
377  return false; // don't allow to bridge mesh network with something else.
378 }
379 
380 Address
382 {
383  NS_LOG_FUNCTION(this << addr);
384  return Mac48Address::GetMulticast(addr);
385 }
386 
387 //-----------------------------------------------------------------------------
388 // Interfaces
389 //-----------------------------------------------------------------------------
390 uint32_t
392 {
393  NS_LOG_FUNCTION(this);
394  return m_ifaces.size();
395 }
396 
399 {
400  NS_LOG_FUNCTION(this << n);
401  for (auto i = m_ifaces.begin(); i != m_ifaces.end(); i++)
402  {
403  if ((*i)->GetIfIndex() == n)
404  {
405  return *i;
406  }
407  }
408  NS_FATAL_ERROR("Mesh point interface is not found by index");
409  return nullptr;
410 }
411 
412 std::vector<Ptr<NetDevice>>
414 {
415  return m_ifaces;
416 }
417 
418 void
420 {
421  NS_LOG_FUNCTION(this << iface);
422 
423  NS_ASSERT(iface != this);
424  if (!Mac48Address::IsMatchingType(iface->GetAddress()))
425  {
427  "Device does not support eui 48 addresses: cannot be used as a mesh point interface.");
428  }
429  if (!iface->SupportsSendFrom())
430  {
432  "Device does not support SendFrom: cannot be used as a mesh point interface.");
433  }
434 
435  // Mesh point has MAC address of it's first interface
436  if (m_ifaces.empty())
437  {
438  m_address = Mac48Address::ConvertFrom(iface->GetAddress());
439  }
440  Ptr<WifiNetDevice> wifiNetDev = iface->GetObject<WifiNetDevice>();
441  if (!wifiNetDev)
442  {
443  NS_FATAL_ERROR("Device is not a WiFi NIC: cannot be used as a mesh point interface.");
444  }
445  Ptr<MeshWifiInterfaceMac> ifaceMac = wifiNetDev->GetMac()->GetObject<MeshWifiInterfaceMac>();
446  if (!ifaceMac)
447  {
448  NS_FATAL_ERROR("WiFi device doesn't have correct MAC installed: cannot be used as a mesh "
449  "point interface.");
450  }
451  ifaceMac->SetMeshPointAddress(m_address);
452 
453  // Receive frames from this interface
455  0,
456  iface, /*promiscuous = */
457  true);
458  m_ifaces.push_back(iface);
459  m_channel->AddChannel(iface->GetChannel());
460 }
461 
462 //-----------------------------------------------------------------------------
463 // Protocols
464 //-----------------------------------------------------------------------------
465 
466 void
468 {
469  NS_LOG_FUNCTION(this << protocol);
470  NS_ASSERT_MSG(PeekPointer(protocol->GetMeshPoint()) == this,
471  "Routing protocol must be installed on mesh point to be useful.");
472  m_routingProtocol = protocol;
473 }
474 
477 {
478  NS_LOG_FUNCTION(this);
479  return m_routingProtocol;
480 }
481 
482 void
484  Ptr<Packet> packet,
485  Mac48Address src,
486  Mac48Address dst,
487  uint16_t protocol,
488  uint32_t outIface)
489 {
490  NS_LOG_FUNCTION(this << success << packet << src << dst << protocol << outIface);
491  if (!success)
492  {
493  NS_LOG_DEBUG("Resolve failed");
494  return;
495  }
496 
497  // Count statistics
498  Statistics* stats = ((src == m_address) ? &m_txStats : &m_fwdStats);
499 
500  if (dst.IsBroadcast())
501  {
502  stats->broadcastData++;
503  stats->broadcastDataBytes += packet->GetSize();
504  }
505  else
506  {
507  stats->unicastData++;
508  stats->unicastDataBytes += packet->GetSize();
509  }
510 
511  // Send
512  if (outIface != 0xffffffff)
513  {
514  GetInterface(outIface)->SendFrom(packet, src, dst, protocol);
515  }
516  else
517  {
518  for (auto i = m_ifaces.begin(); i != m_ifaces.end(); i++)
519  {
520  (*i)->SendFrom(packet->Copy(), src, dst, protocol);
521  }
522  }
523 }
524 
526  : unicastData(0),
527  unicastDataBytes(0),
528  broadcastData(0),
529  broadcastDataBytes(0)
530 {
531  NS_LOG_FUNCTION(this);
532 }
533 
534 void
535 MeshPointDevice::Report(std::ostream& os) const
536 {
537  NS_LOG_FUNCTION(this);
538  os << "<Statistics" << std::endl
539  << "txUnicastData=\"" << m_txStats.unicastData << "\"" << std::endl
540  << "txUnicastDataBytes=\"" << m_txStats.unicastDataBytes << "\"" << std::endl
541  << "txBroadcastData=\"" << m_txStats.broadcastData << "\"" << std::endl
542  << "txBroadcastDataBytes=\"" << m_txStats.broadcastDataBytes << "\"" << std::endl
543  << "rxUnicastData=\"" << m_rxStats.unicastData << "\"" << std::endl
544  << "rxUnicastDataBytes=\"" << m_rxStats.unicastDataBytes << "\"" << std::endl
545  << "rxBroadcastData=\"" << m_rxStats.broadcastData << "\"" << std::endl
546  << "rxBroadcastDataBytes=\"" << m_rxStats.broadcastDataBytes << "\"" << std::endl
547  << "fwdUnicastData=\"" << m_fwdStats.unicastData << "\"" << std::endl
548  << "fwdUnicastDataBytes=\"" << m_fwdStats.unicastDataBytes << "\"" << std::endl
549  << "fwdBroadcastData=\"" << m_fwdStats.broadcastData << "\"" << std::endl
550  << "fwdBroadcastDataBytes=\"" << m_fwdStats.broadcastDataBytes << "\"" << std::endl
551  << "/>" << std::endl;
552 }
553 
554 void
556 {
557  NS_LOG_FUNCTION(this);
558  m_rxStats = Statistics();
559  m_txStats = Statistics();
561 }
562 
563 int64_t
565 {
566  NS_LOG_FUNCTION(this << stream);
568  return 1;
569 }
570 
571 Time
573 {
575 }
576 
577 } // namespace ns3
a polymophic address class
Definition: address.h:101
bool IsNull() const
Check for null implementation.
Definition: callback.h:569
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Describes an IPv6 address.
Definition: ipv6-address.h:49
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
static bool IsMatchingType(const Address &address)
static Mac48Address ConvertFrom(const Address &address)
bool IsBroadcast() const
Virtual net device modeling mesh point.
void AddInterface(Ptr< NetDevice > port)
Attach new interface to the station.
Ptr< Node > GetNode() const override
void DoSend(bool success, Ptr< Packet > packet, Mac48Address src, Mac48Address dst, uint16_t protocol, uint32_t iface)
Response callback for L2 routing protocol.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
uint32_t m_ifIndex
If index.
void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb) override
uint16_t m_mtu
MTU in bytes.
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
Ptr< Node > m_node
Parent node.
bool IsPointToPoint() const override
Return true if the net device is on a point-to-point link.
void SetRoutingProtocol(Ptr< MeshL2RoutingProtocol > protocol)
Register routing protocol to be used.
void SetIfIndex(const uint32_t index) override
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
void DoDispose() override
Destructor implementation.
bool SupportsSendFrom() const override
Ptr< Channel > GetChannel() const override
Ptr< RandomVariableStream > m_forwardingRandomVariable
Random variable used for forwarding delay and jitter.
Ptr< BridgeChannel > m_channel
Virtual channel for upper layers.
void SetAddress(Address a) override
Set the address of this interface.
Ptr< NetDevice > GetInterface(uint32_t id) const
NetDevice::ReceiveCallback m_rxCallback
Receive action.
bool IsMulticast() const override
Statistics m_fwdStats
forward statistics
std::vector< Ptr< NetDevice > > GetInterfaces() const
void AddLinkChangeCallback(Callback< void > callback) override
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
std::vector< Ptr< NetDevice > > m_ifaces
List of interfaces.
void Forward(Ptr< NetDevice > incomingPort, Ptr< const Packet > packet, uint16_t protocol, const Mac48Address src, const Mac48Address dst)
Forward packet down to interfaces.
bool IsLinkUp() const override
void ReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &source, const Address &destination, PacketType packetType)
Receive packet from interface.
MeshPointDevice()
C-tor create empty (without interfaces and protocols) mesh point.
static TypeId GetTypeId()
Get the type ID.
uint16_t GetMtu() const override
bool IsBroadcast() const override
void Report(std::ostream &os) const
Print statistics counters.
NetDevice::PromiscReceiveCallback m_promiscRxCallback
Promisc receive action.
Statistics m_rxStats
receive statistics
bool IsBridge() const override
Return true if the net device is acting as a bridge.
uint32_t GetIfIndex() const override
bool SetMtu(const uint16_t mtu) override
void SetNode(Ptr< Node > node) override
Statistics m_txStats
transmit statistics
Mac48Address m_address
Mesh point MAC address, supposed to be the address of the first added interface.
Address GetAddress() const override
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
Ptr< MeshL2RoutingProtocol > m_routingProtocol
Current routing protocol, used mainly by GetRoutingProtocol.
uint32_t GetNInterfaces() const
Address GetBroadcast() const override
void ResetStats()
Reset statistics counters.
Time GetForwardingDelay() const
Return a (random) forwarding delay value from the random variable ForwardingDelay attribute.
Ptr< MeshL2RoutingProtocol > GetRoutingProtocol() const
Access current routing protocol.
~MeshPointDevice() override
D-tor.
bool NeedsArp() const override
Basic MAC of mesh point Wi-Fi interface.
Network layer to device interface.
Definition: net-device.h:98
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:300
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:238
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint64_t GetUid() const
Returns the packet's Uid.
Definition: packet.cc:412
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
virtual uint32_t GetInteger()
Get the next random value drawn from the distribution.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ US
microsecond
Definition: nstime.h:118
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac() const
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1350
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:449
uint32_t broadcastData
broadcast data
uint32_t unicastDataBytes
unicast data bytes
uint32_t broadcastDataBytes
broadcast data bytes