A Discrete-Event Network Simulator
API
mesh-point-device.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2008,2009 IITP RAS
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 * Author: Kirill Andreev <andreev@iitp.ru>
19 * Pavel Boyko <boyko@iitp.ru>
20 */
21
22#include "ns3/packet.h"
23#include "ns3/log.h"
24#include "ns3/simulator.h"
25#include "ns3/string.h"
26#include "ns3/pointer.h"
27#include "ns3/mesh-point-device.h"
28#include "ns3/wifi-net-device.h"
29#include "ns3/mesh-wifi-interface-mac.h"
30
31namespace ns3 {
32
33NS_LOG_COMPONENT_DEFINE ("MeshPointDevice");
34
35NS_OBJECT_ENSURE_REGISTERED (MeshPointDevice);
36
37TypeId
39{
40 static TypeId tid = TypeId ("ns3::MeshPointDevice")
42 .SetGroupName ("Mesh")
43 .AddConstructor<MeshPointDevice> ()
44 .AddAttribute ("Mtu", "The MAC-level Maximum Transmission Unit",
45 UintegerValue (0xffff),
48 MakeUintegerChecker<uint16_t> ())
49 .AddAttribute ( "RoutingProtocol",
50 "The mesh routing protocol used by this mesh point.",
51 PointerValue (),
56 .AddAttribute ("ForwardingDelay",
57 "A random variable to account for processing time (microseconds) to forward a frame.",
58 StringValue ("ns3::UniformRandomVariable[Min=300.0|Max=400.0]"),
60 MakePointerChecker<RandomVariableStream> ());
61 return tid;
62}
63
65 m_ifIndex (0)
66{
67 NS_LOG_FUNCTION (this);
68 m_channel = CreateObject<BridgeChannel> ();
69}
70
72{
73 NS_LOG_FUNCTION (this);
74 m_node = 0;
75 m_channel = 0;
77}
78
79void
81{
82 NS_LOG_FUNCTION (this);
83 for (std::vector<Ptr<NetDevice> >::iterator iter = m_ifaces.begin (); iter != m_ifaces.end (); iter++)
84 {
85 *iter = 0;
86 }
87 m_ifaces.clear ();
88 m_node = 0;
89 m_channel = 0;
92
93}
94
95//-----------------------------------------------------------------------------
96// NetDevice interface implementation
97//-----------------------------------------------------------------------------
98
99void
101 Address const &src, Address const &dst, PacketType packetType)
102{
103 NS_LOG_FUNCTION (this << incomingPort << packet);
104 NS_LOG_DEBUG ("UID is " << packet->GetUid ());
105 const Mac48Address src48 = Mac48Address::ConvertFrom (src);
106 const Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
107 uint16_t& realProtocol = protocol;
108 NS_LOG_DEBUG ("SRC=" << src48 << ", DST = " << dst48 << ", I am: " << m_address);
110 {
111 m_promiscRxCallback (this, packet, protocol, src, dst, packetType);
112 }
113 if (dst48.IsGroup ())
114 {
115 Ptr<Packet> packet_copy = packet->Copy ();
116 if (m_routingProtocol->RemoveRoutingStuff (incomingPort->GetIfIndex (), src48, dst48, packet_copy, realProtocol))
117 {
118 m_rxCallback (this, packet_copy, realProtocol, src);
121 Time forwardingDelay = GetForwardingDelay ();
122 NS_LOG_DEBUG ("Forwarding broadcast from " << src48 << " to " << dst48
123 << " with delay " << forwardingDelay.As (Time::US));
124 Simulator::Schedule (forwardingDelay, &MeshPointDevice::Forward, this, incomingPort, packet, protocol, src48, dst48);
125 }
126 return;
127 }
128 if (dst48 == m_address)
129 {
130 Ptr<Packet> packet_copy = packet->Copy ();
131 if (m_routingProtocol->RemoveRoutingStuff (incomingPort->GetIfIndex (), src48, dst48, packet_copy, realProtocol))
132 {
133 m_rxCallback (this, packet_copy, realProtocol, src);
135 m_rxStats.unicastDataBytes += packet->GetSize ();
136 }
137 return;
138 }
139 else
140 {
141 Time forwardingDelay = GetForwardingDelay ();
142 Simulator::Schedule (forwardingDelay, &MeshPointDevice::Forward, this, incomingPort, packet->Copy (), protocol, src48, dst48);
143 NS_LOG_DEBUG ("Forwarding unicast from " << src48 << " to " << dst48
144 << " with delay " << forwardingDelay.As (Time::US));
145 }
146}
147
148void
150 const Mac48Address src, const Mac48Address dst)
151{
152 NS_LOG_FUNCTION (this << inport << packet << protocol << src << dst);
153 // pass through routing protocol
154 NS_LOG_DEBUG ("Forwarding from " << src << " to " << dst << " at " << m_address);
155 bool result = m_routingProtocol->RequestRoute (inport->GetIfIndex (), src, dst, packet, protocol, MakeCallback (
157 if (result == false)
158 {
159 NS_LOG_DEBUG ("Request to forward packet " << packet << " to destination " << dst << " failed; dropping packet");
160 }
161}
162
163void
165{
166 NS_LOG_FUNCTION (this);
167 m_ifIndex = index;
168}
169
172{
173 NS_LOG_FUNCTION (this);
174 return m_ifIndex;
175}
176
179{
180 NS_LOG_FUNCTION (this);
181 return m_channel;
182}
183
186{
187 NS_LOG_FUNCTION (this);
188 return m_address;
189}
190
191void
193{
194 NS_LOG_FUNCTION (this);
195 NS_LOG_WARN ("Manual changing mesh point address can cause routing errors.");
197}
198
199bool
200MeshPointDevice::SetMtu (const uint16_t mtu)
201{
202 NS_LOG_FUNCTION (this);
203 m_mtu = mtu;
204 return true;
205}
206
207uint16_t
209{
210 NS_LOG_FUNCTION (this);
211 return m_mtu;
212}
213
214bool
216{
217 NS_LOG_FUNCTION (this);
218 return true;
219}
220
221void
223{
224 NS_LOG_FUNCTION (this);
225 // do nothing
226 NS_LOG_WARN ("AddLinkChangeCallback does nothing");
227}
228
229bool
231{
232 NS_LOG_FUNCTION (this);
233 return true;
234}
235
238{
239 NS_LOG_FUNCTION (this);
240 return Mac48Address ("ff:ff:ff:ff:ff:ff");
241}
242
243bool
245{
246 NS_LOG_FUNCTION (this);
247 return true;
248}
249
252{
253 NS_LOG_FUNCTION (this << multicastGroup);
254 Mac48Address multicast = Mac48Address::GetMulticast (multicastGroup);
255 return multicast;
256}
257
258bool
260{
261 NS_LOG_FUNCTION (this);
262 return false;
263}
264
265bool
267{
268 NS_LOG_FUNCTION (this);
269 return false;
270}
271
272bool
273MeshPointDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
274{
275 NS_LOG_FUNCTION (this);
276 const Mac48Address dst48 = Mac48Address::ConvertFrom (dest);
277 return m_routingProtocol->RequestRoute (m_ifIndex, m_address, dst48, packet, protocolNumber, MakeCallback (
279}
280
281bool
282MeshPointDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest,
283 uint16_t protocolNumber)
284{
285 NS_LOG_FUNCTION (this);
286 const Mac48Address src48 = Mac48Address::ConvertFrom (src);
287 const Mac48Address dst48 = Mac48Address::ConvertFrom (dest);
288 return m_routingProtocol->RequestRoute (m_ifIndex, src48, dst48, packet, protocolNumber, MakeCallback (
290}
291
294{
295 NS_LOG_FUNCTION (this);
296 return m_node;
297}
298
299void
301{
302 NS_LOG_FUNCTION (this);
303 m_node = node;
304}
305
306bool
308{
309 NS_LOG_FUNCTION (this);
310 return true;
311}
312
313void
315{
316 NS_LOG_FUNCTION (this);
317 m_rxCallback = cb;
318}
319
320void
322{
323 NS_LOG_FUNCTION (this);
325}
326
327bool
329{
330 NS_LOG_FUNCTION (this);
331 return false; // don't allow to bridge mesh network with something else.
332}
333
336{
337 NS_LOG_FUNCTION (this << addr);
338 return Mac48Address::GetMulticast (addr);
339}
340
341//-----------------------------------------------------------------------------
342// Interfaces
343//-----------------------------------------------------------------------------
346{
347 NS_LOG_FUNCTION (this);
348 return m_ifaces.size ();
349}
350
353{
354 NS_LOG_FUNCTION (this << n);
355 for (std::vector<Ptr<NetDevice> >::const_iterator i = m_ifaces.begin (); i != m_ifaces.end (); i++)
356 {
357 if ((*i)->GetIfIndex () == n)
358 {
359 return (*i);
360 }
361 }
362 NS_FATAL_ERROR ("Mesh point interface is not found by index");
363 return 0;
364}
365std::vector<Ptr<NetDevice> >
367{
368 return m_ifaces;
369}
370void
372{
373 NS_LOG_FUNCTION (this << iface);
374
375 NS_ASSERT (iface != this);
376 if (!Mac48Address::IsMatchingType (iface->GetAddress ()))
377 {
378 NS_FATAL_ERROR ("Device does not support eui 48 addresses: cannot be used as a mesh point interface.");
379 }
380 if (!iface->SupportsSendFrom ())
381 {
382 NS_FATAL_ERROR ("Device does not support SendFrom: cannot be used as a mesh point interface.");
383 }
384
385 // Mesh point has MAC address of it's first interface
386 if (m_ifaces.empty ())
387 {
388 m_address = Mac48Address::ConvertFrom (iface->GetAddress ());
389 }
390 Ptr<WifiNetDevice> wifiNetDev = iface->GetObject<WifiNetDevice> ();
391 if (!wifiNetDev)
392 {
393 NS_FATAL_ERROR ("Device is not a WiFi NIC: cannot be used as a mesh point interface.");
394 }
395 Ptr<MeshWifiInterfaceMac> ifaceMac = wifiNetDev->GetMac ()->GetObject<MeshWifiInterfaceMac> ();
396 if (!ifaceMac)
397 {
399 "WiFi device doesn't have correct MAC installed: cannot be used as a mesh point interface.");
400 }
401 ifaceMac->SetMeshPointAddress (m_address);
402
403 // Receive frames from this interface
405 true);
406 m_ifaces.push_back (iface);
407 m_channel->AddChannel (iface->GetChannel ());
408}
409
410//-----------------------------------------------------------------------------
411// Protocols
412//-----------------------------------------------------------------------------
413
414void
416{
417 NS_LOG_FUNCTION (this << protocol);
418 NS_ASSERT_MSG (PeekPointer (protocol->GetMeshPoint ()) == this,
419 "Routing protocol must be installed on mesh point to be useful.");
420 m_routingProtocol = protocol;
421}
422
425{
426 NS_LOG_FUNCTION (this);
427 return m_routingProtocol;
428}
429
430void
432 uint16_t protocol, uint32_t outIface)
433{
434 NS_LOG_FUNCTION (this << success << packet << src << dst << protocol << outIface);
435 if (!success)
436 {
437 NS_LOG_DEBUG ("Resolve failed");
438 return;
439 }
440
441 // Count statistics
442 Statistics * stats = ((src == m_address) ? &m_txStats : &m_fwdStats);
443
444 if (dst.IsBroadcast ())
445 {
446 stats->broadcastData++;
447 stats->broadcastDataBytes += packet->GetSize ();
448 }
449 else
450 {
451 stats->unicastData++;
452 stats->unicastDataBytes += packet->GetSize ();
453 }
454
455 // Send
456 if (outIface != 0xffffffff)
457 {
458 GetInterface (outIface)->SendFrom (packet, src, dst, protocol);
459 }
460 else
461 {
462 for (std::vector<Ptr<NetDevice> >::iterator i = m_ifaces.begin (); i != m_ifaces.end (); i++)
463 {
464 (*i)->SendFrom (packet->Copy (), src, dst, protocol);
465 }
466 }
467}
469 unicastData (0), unicastDataBytes (0), broadcastData (0), broadcastDataBytes (0)
470{
471 NS_LOG_FUNCTION (this);
472}
473
474void
475MeshPointDevice::Report (std::ostream & os) const
476{
477 NS_LOG_FUNCTION (this);
478 os << "<Statistics" << std::endl <<
479 "txUnicastData=\"" << m_txStats.unicastData << "\"" << std::endl <<
480 "txUnicastDataBytes=\"" << m_txStats.unicastDataBytes << "\"" << std::endl <<
481 "txBroadcastData=\"" << m_txStats.broadcastData << "\"" << std::endl <<
482 "txBroadcastDataBytes=\"" << m_txStats.broadcastDataBytes << "\"" << std::endl <<
483 "rxUnicastData=\"" << m_rxStats.unicastData << "\"" << std::endl <<
484 "rxUnicastDataBytes=\"" << m_rxStats.unicastDataBytes << "\"" << std::endl <<
485 "rxBroadcastData=\"" << m_rxStats.broadcastData << "\"" << std::endl <<
486 "rxBroadcastDataBytes=\"" << m_rxStats.broadcastDataBytes << "\"" << std::endl <<
487 "fwdUnicastData=\"" << m_fwdStats.unicastData << "\"" << std::endl <<
488 "fwdUnicastDataBytes=\"" << m_fwdStats.unicastDataBytes << "\"" << std::endl <<
489 "fwdBroadcastData=\"" << m_fwdStats.broadcastData << "\"" << std::endl <<
490 "fwdBroadcastDataBytes=\"" << m_fwdStats.broadcastDataBytes << "\"" << std::endl <<
491 "/>" << std::endl;
492}
493
494void
496{
497 NS_LOG_FUNCTION (this);
501}
502
503int64_t
505{
506 NS_LOG_FUNCTION (this << stream);
508 return 1;
509}
510
511Time
513{
515}
516
517} // namespace ns3
a polymophic address class
Definition: address.h:91
bool IsNull(void) const
Check for null implementation.
Definition: callback.h:532
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
Describes an IPv6 address.
Definition: ipv6-address.h:50
an EUI-48 address
Definition: mac48-address.h:44
static Mac48Address GetMulticast(Ipv4Address address)
static bool IsMatchingType(const Address &address)
bool IsGroup(void) const
bool IsBroadcast(void) const
static Mac48Address ConvertFrom(const Address &address)
Interface for L2 mesh routing protocol and mesh point communication.
Virtual net device modeling mesh point.
void AddInterface(Ptr< NetDevice > port)
Attach new interface to the station.
void DoSend(bool success, Ptr< Packet > packet, Mac48Address src, Mac48Address dst, uint16_t protocol, uint32_t iface)
Response callback for L2 routing protocol.
virtual bool IsLinkUp() const
virtual Ptr< Channel > GetChannel() const
virtual bool NeedsArp() const
virtual bool IsPointToPoint() const
Return true if the net device is on a point-to-point link.
uint32_t m_ifIndex
If index.
virtual bool IsBridge() const
Return true if the net device is acting as a bridge.
virtual bool IsBroadcast() const
uint16_t m_mtu
MTU in bytes.
Ptr< Node > m_node
Parent node.
void SetRoutingProtocol(Ptr< MeshL2RoutingProtocol > protocol)
Register routing protocol to be used.
virtual bool IsMulticast() const
virtual void SetPromiscReceiveCallback(NetDevice::PromiscReceiveCallback cb)
Ptr< RandomVariableStream > m_forwardingRandomVariable
Random variable used for forwarding delay and jitter.
void ReceiveFromDevice(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, Address const &source, Address const &destination, PacketType packetType)
Receive packet from interface.
virtual bool SetMtu(const uint16_t mtu)
Ptr< BridgeChannel > m_channel
Virtual channel for upper layers.
virtual uint32_t GetIfIndex() const
virtual void SetIfIndex(const uint32_t index)
std::vector< Ptr< NetDevice > > m_ifaces
List of interfaces.
Ptr< NetDevice > GetInterface(uint32_t id) const
virtual void DoDispose()
Destructor implementation.
NetDevice::ReceiveCallback m_rxCallback
Receive action.
Statistics m_fwdStats
forward statistics
std::vector< Ptr< NetDevice > > GetInterfaces() const
virtual Address GetMulticast(Ipv4Address multicastGroup) const
Make and return a MAC multicast address using the provided multicast group.
void Forward(Ptr< NetDevice > incomingPort, Ptr< const Packet > packet, uint16_t protocol, const Mac48Address src, const Mac48Address dst)
Forward packet down to interfaces.
MeshPointDevice()
C-tor create empty (without interfaces and protocols) mesh point.
virtual ~MeshPointDevice()
D-tor.
static TypeId GetTypeId()
Get the type ID.
void Report(std::ostream &os) const
Print statistics counters.
NetDevice::PromiscReceiveCallback m_promiscRxCallback
Promisc receive action.
virtual Address GetAddress() const
Statistics m_rxStats
receive statistics
virtual Ptr< Node > GetNode() const
virtual void SetReceiveCallback(NetDevice::ReceiveCallback cb)
Statistics m_txStats
transmit statistics
Mac48Address m_address
Mesh point MAC address, supposed to be the address of the first added interface.
virtual void SetNode(Ptr< Node > node)
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.
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
uint32_t GetNInterfaces() const
virtual uint16_t GetMtu() const
virtual void SetAddress(Address a)
Set the address of this interface.
virtual Address GetBroadcast() const
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.
virtual bool SupportsSendFrom() const
virtual bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber)
virtual void AddLinkChangeCallback(Callback< void > callback)
Basic MAC of mesh point Wi-Fi interface.
Network layer to device interface.
Definition: net-device.h:96
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:297
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:229
virtual void DoDispose(void)
Destructor implementation.
Definition: object.cc:346
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:390
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:121
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:856
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:555
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
@ US
microsecond
Definition: nstime.h:117
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
Hold together all Wifi-related objects.
Ptr< WifiMac > GetMac(void) 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:67
#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:88
Ptr< AttributeChecker > MakePointerChecker(void)
Create a PointerChecker for a type.
Definition: pointer.h:231
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:45
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:206
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:274
#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:266
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1261
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:489
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:661
uint32_t broadcastData
broadcast data
uint32_t unicastDataBytes
unicast data bytes
uint32_t broadcastDataBytes
broadcast data bytes