A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
mesh-point-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008,2009 IITP RAS
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Kirill Andreev <andreev@iitp.ru>
7 * Pavel Boyko <boyko@iitp.ru>
8 */
9
10#include "mesh-point-device.h"
11
13
14#include "ns3/log.h"
15#include "ns3/packet.h"
16#include "ns3/pointer.h"
17#include "ns3/simulator.h"
18#include "ns3/string.h"
19#include "ns3/wifi-net-device.h"
20
21namespace ns3
22{
23
24NS_LOG_COMPONENT_DEFINE("MeshPointDevice");
25
26NS_OBJECT_ENSURE_REGISTERED(MeshPointDevice);
27
28TypeId
30{
31 static TypeId tid =
32 TypeId("ns3::MeshPointDevice")
34 .SetGroupName("Mesh")
35 .AddConstructor<MeshPointDevice>()
36 .AddAttribute("Mtu",
37 "The MAC-level Maximum Transmission Unit",
38 UintegerValue(0xffff),
41 .AddAttribute("RoutingProtocol",
42 "The mesh routing protocol used by this mesh point.",
47 .AddAttribute("ForwardingDelay",
48 "A random variable to account for processing time (microseconds) to "
49 "forward a frame.",
50 StringValue("ns3::UniformRandomVariable[Min=300.0|Max=400.0]"),
53 return tid;
54}
55
62
64{
65 NS_LOG_FUNCTION(this);
66 m_node = nullptr;
67 m_channel = nullptr;
68 m_routingProtocol = nullptr;
69}
70
71void
73{
74 NS_LOG_FUNCTION(this);
75 for (auto iter = m_ifaces.begin(); iter != m_ifaces.end(); iter++)
76 {
77 *iter = nullptr;
78 }
79 m_ifaces.clear();
80 m_node = nullptr;
81 m_channel = nullptr;
82 m_routingProtocol = nullptr;
84}
85
86//-----------------------------------------------------------------------------
87// NetDevice interface implementation
88//-----------------------------------------------------------------------------
89
90void
92 Ptr<const Packet> packet,
93 uint16_t protocol,
94 const Address& src,
95 const Address& dst,
96 PacketType packetType)
97{
98 NS_LOG_FUNCTION(this << incomingPort << packet);
99 NS_LOG_DEBUG("UID is " << packet->GetUid());
100 const Mac48Address src48 = Mac48Address::ConvertFrom(src);
101 const Mac48Address dst48 = Mac48Address::ConvertFrom(dst);
102 uint16_t& realProtocol = protocol;
103 NS_LOG_DEBUG("SRC=" << src48 << ", DST = " << dst48 << ", I am: " << m_address);
105 {
106 m_promiscRxCallback(this, packet, protocol, src, dst, packetType);
107 }
108 if (dst48.IsGroup())
109 {
110 Ptr<Packet> packet_copy = packet->Copy();
111 if (m_routingProtocol->RemoveRoutingStuff(incomingPort->GetIfIndex(),
112 src48,
113 dst48,
114 packet_copy,
115 realProtocol))
116 {
117 m_rxCallback(this, packet_copy, realProtocol, src);
119 m_rxStats.broadcastDataBytes += packet->GetSize();
120 Time forwardingDelay = GetForwardingDelay();
121 NS_LOG_DEBUG("Forwarding broadcast from " << src48 << " to " << dst48 << " with delay "
122 << forwardingDelay.As(Time::US));
123 Simulator::Schedule(forwardingDelay,
125 this,
126 incomingPort,
127 packet,
128 protocol,
129 src48,
130 dst48);
131 }
132 return;
133 }
134 if (dst48 == m_address)
135 {
136 Ptr<Packet> packet_copy = packet->Copy();
137 if (m_routingProtocol->RemoveRoutingStuff(incomingPort->GetIfIndex(),
138 src48,
139 dst48,
140 packet_copy,
141 realProtocol))
142 {
143 m_rxCallback(this, packet_copy, realProtocol, src);
145 m_rxStats.unicastDataBytes += packet->GetSize();
146 }
147 return;
148 }
149 else
150 {
151 Time forwardingDelay = GetForwardingDelay();
152 Simulator::Schedule(forwardingDelay,
154 this,
155 incomingPort,
156 packet->Copy(),
157 protocol,
158 src48,
159 dst48);
160 NS_LOG_DEBUG("Forwarding unicast from " << src48 << " to " << dst48 << " with delay "
161 << forwardingDelay.As(Time::US));
162 }
163}
164
165void
167 Ptr<const Packet> packet,
168 uint16_t protocol,
169 const Mac48Address src,
170 const Mac48Address dst)
171{
172 NS_LOG_FUNCTION(this << incomingPort << packet << protocol << src << dst);
173 // pass through routing protocol
174 NS_LOG_DEBUG("Forwarding from " << src << " to " << dst << " at " << m_address);
175 bool result = m_routingProtocol->RequestRoute(incomingPort->GetIfIndex(),
176 src,
177 dst,
178 packet,
179 protocol,
181 if (!result)
182 {
183 NS_LOG_DEBUG("Request to forward packet " << packet << " to destination " << dst
184 << " failed; dropping packet");
185 }
186}
187
188void
190{
191 NS_LOG_FUNCTION(this);
192 m_ifIndex = index;
193}
194
197{
198 NS_LOG_FUNCTION(this);
199 return m_ifIndex;
200}
201
204{
205 NS_LOG_FUNCTION(this);
206 return m_channel;
207}
208
211{
212 NS_LOG_FUNCTION(this);
213 return m_address;
214}
215
216void
218{
219 NS_LOG_FUNCTION(this);
220 NS_LOG_WARN("Manual changing mesh point address can cause routing errors.");
222}
223
224bool
225MeshPointDevice::SetMtu(const uint16_t mtu)
226{
227 NS_LOG_FUNCTION(this);
228 m_mtu = mtu;
229 return true;
230}
231
232uint16_t
234{
235 NS_LOG_FUNCTION(this);
236 return m_mtu;
237}
238
239bool
241{
242 NS_LOG_FUNCTION(this);
243 return true;
244}
245
246void
248{
249 NS_LOG_FUNCTION(this);
250 // do nothing
251 NS_LOG_WARN("AddLinkChangeCallback does nothing");
252}
253
254bool
256{
257 NS_LOG_FUNCTION(this);
258 return true;
259}
260
267
268bool
270{
271 NS_LOG_FUNCTION(this);
272 return true;
273}
274
277{
278 NS_LOG_FUNCTION(this << multicastGroup);
279 Mac48Address multicast = Mac48Address::GetMulticast(multicastGroup);
280 return multicast;
281}
282
283bool
285{
286 NS_LOG_FUNCTION(this);
287 return false;
288}
289
290bool
292{
293 NS_LOG_FUNCTION(this);
294 return false;
295}
296
297bool
298MeshPointDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
299{
300 NS_LOG_FUNCTION(this);
301 const Mac48Address dst48 = Mac48Address::ConvertFrom(dest);
302 return m_routingProtocol->RequestRoute(m_ifIndex,
303 m_address,
304 dst48,
305 packet,
306 protocolNumber,
308}
309
310bool
312 const Address& src,
313 const Address& dest,
314 uint16_t protocolNumber)
315{
316 NS_LOG_FUNCTION(this);
317 const Mac48Address src48 = Mac48Address::ConvertFrom(src);
318 const Mac48Address dst48 = Mac48Address::ConvertFrom(dest);
319 return m_routingProtocol->RequestRoute(m_ifIndex,
320 src48,
321 dst48,
322 packet,
323 protocolNumber,
325}
326
329{
330 NS_LOG_FUNCTION(this);
331 return m_node;
332}
333
334void
336{
337 NS_LOG_FUNCTION(this);
338 m_node = node;
339}
340
341bool
343{
344 NS_LOG_FUNCTION(this);
345 return true;
346}
347
348void
354
355void
361
362bool
364{
365 NS_LOG_FUNCTION(this);
366 return false; // don't allow to bridge mesh network with something else.
367}
368
371{
372 NS_LOG_FUNCTION(this << addr);
373 return Mac48Address::GetMulticast(addr);
374}
375
376//-----------------------------------------------------------------------------
377// Interfaces
378//-----------------------------------------------------------------------------
381{
382 NS_LOG_FUNCTION(this);
383 return m_ifaces.size();
384}
385
388{
389 NS_LOG_FUNCTION(this << n);
390 for (auto i = m_ifaces.begin(); i != m_ifaces.end(); i++)
391 {
392 if ((*i)->GetIfIndex() == n)
393 {
394 return *i;
395 }
396 }
397 NS_FATAL_ERROR("Mesh point interface is not found by index");
398 return nullptr;
399}
400
401std::vector<Ptr<NetDevice>>
403{
404 return m_ifaces;
405}
406
407void
409{
410 NS_LOG_FUNCTION(this << iface);
411
412 NS_ASSERT(iface != this);
413 if (!Mac48Address::IsMatchingType(iface->GetAddress()))
414 {
416 "Device does not support eui 48 addresses: cannot be used as a mesh point interface.");
417 }
418 if (!iface->SupportsSendFrom())
419 {
421 "Device does not support SendFrom: cannot be used as a mesh point interface.");
422 }
423
424 // Mesh point has MAC address of it's first interface
425 if (m_ifaces.empty())
426 {
427 m_address = Mac48Address::ConvertFrom(iface->GetAddress());
428 }
429 Ptr<WifiNetDevice> wifiNetDev = iface->GetObject<WifiNetDevice>();
430 if (!wifiNetDev)
431 {
432 NS_FATAL_ERROR("Device is not a WiFi NIC: cannot be used as a mesh point interface.");
433 }
434 Ptr<MeshWifiInterfaceMac> ifaceMac = wifiNetDev->GetMac()->GetObject<MeshWifiInterfaceMac>();
435 if (!ifaceMac)
436 {
437 NS_FATAL_ERROR("WiFi device doesn't have correct MAC installed: cannot be used as a mesh "
438 "point interface.");
439 }
440 ifaceMac->SetMeshPointAddress(m_address);
441
442 // Receive frames from this interface
444 0,
445 iface, /*promiscuous = */
446 true);
447 m_ifaces.push_back(iface);
448 m_channel->AddChannel(iface->GetChannel());
449}
450
451//-----------------------------------------------------------------------------
452// Protocols
453//-----------------------------------------------------------------------------
454
455void
457{
458 NS_LOG_FUNCTION(this << protocol);
459 NS_ASSERT_MSG(PeekPointer(protocol->GetMeshPoint()) == this,
460 "Routing protocol must be installed on mesh point to be useful.");
461 m_routingProtocol = protocol;
462}
463
470
471void
473 Ptr<Packet> packet,
474 Mac48Address src,
475 Mac48Address dst,
476 uint16_t protocol,
477 uint32_t outIface)
478{
479 NS_LOG_FUNCTION(this << success << packet << src << dst << protocol << outIface);
480 if (!success)
481 {
482 NS_LOG_DEBUG("Resolve failed");
483 return;
484 }
485
486 // Count statistics
487 Statistics* stats = ((src == m_address) ? &m_txStats : &m_fwdStats);
488
489 if (dst.IsBroadcast())
490 {
491 stats->broadcastData++;
492 stats->broadcastDataBytes += packet->GetSize();
493 }
494 else
495 {
496 stats->unicastData++;
497 stats->unicastDataBytes += packet->GetSize();
498 }
499
500 // Send
501 if (outIface != 0xffffffff)
502 {
503 GetInterface(outIface)->SendFrom(packet, src, dst, protocol);
504 }
505 else
506 {
507 for (auto i = m_ifaces.begin(); i != m_ifaces.end(); i++)
508 {
509 (*i)->SendFrom(packet->Copy(), src, dst, protocol);
510 }
511 }
512}
513
515 : unicastData(0),
516 unicastDataBytes(0),
517 broadcastData(0),
518 broadcastDataBytes(0)
519{
520 NS_LOG_FUNCTION(this);
521}
522
523void
524MeshPointDevice::Report(std::ostream& os) const
525{
526 NS_LOG_FUNCTION(this);
527 os << "<Statistics" << std::endl
528 << "txUnicastData=\"" << m_txStats.unicastData << "\"" << std::endl
529 << "txUnicastDataBytes=\"" << m_txStats.unicastDataBytes << "\"" << std::endl
530 << "txBroadcastData=\"" << m_txStats.broadcastData << "\"" << std::endl
531 << "txBroadcastDataBytes=\"" << m_txStats.broadcastDataBytes << "\"" << std::endl
532 << "rxUnicastData=\"" << m_rxStats.unicastData << "\"" << std::endl
533 << "rxUnicastDataBytes=\"" << m_rxStats.unicastDataBytes << "\"" << std::endl
534 << "rxBroadcastData=\"" << m_rxStats.broadcastData << "\"" << std::endl
535 << "rxBroadcastDataBytes=\"" << m_rxStats.broadcastDataBytes << "\"" << std::endl
536 << "fwdUnicastData=\"" << m_fwdStats.unicastData << "\"" << std::endl
537 << "fwdUnicastDataBytes=\"" << m_fwdStats.unicastDataBytes << "\"" << std::endl
538 << "fwdBroadcastData=\"" << m_fwdStats.broadcastData << "\"" << std::endl
539 << "fwdBroadcastDataBytes=\"" << m_fwdStats.broadcastDataBytes << "\"" << std::endl
540 << "/>" << std::endl;
541}
542
543void
551
552int64_t
554{
555 NS_LOG_FUNCTION(this << stream);
557 return 1;
558}
559
560Time
565
566} // namespace ns3
a polymophic address class
Definition address.h:90
Callback template class.
Definition callback.h:422
bool IsNull() const
Check for null implementation.
Definition callback.h:555
Ipv4 addresses are stored in host order in this class.
Describes an IPv6 address.
an EUI-48 address
static Mac48Address GetMulticast(Ipv4Address address)
bool IsGroup() const
static bool IsMatchingType(const Address &address)
static Mac48Address ConvertFrom(const Address &address)
static Mac48Address GetBroadcast()
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:87
PacketType
Packet types are used as they are in Linux.
Definition net-device.h:289
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition node.cc:220
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
AttributeValue implementation for Pointer.
Smart pointer class similar to boost::intrusive_ptr.
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:560
Hold variables of type string.
Definition string.h:45
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
@ US
microsecond
Definition nstime.h:107
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
Hold together all Wifi-related objects.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition pointer.h:248
Ptr< AttributeChecker > MakePointerChecker()
Create a PointerChecker for a type.
Definition pointer.h:269
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition uinteger.h:35
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:250
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time MicroSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
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:684
uint32_t broadcastData
broadcast data
uint32_t unicastDataBytes
unicast data bytes
uint32_t broadcastDataBytes
broadcast data bytes