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 * 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
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("MeshPointDevice");
36
37NS_OBJECT_ENSURE_REGISTERED(MeshPointDevice);
38
39TypeId
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.",
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
82void
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
101void
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
176void
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
199void
201{
202 NS_LOG_FUNCTION(this);
203 m_ifIndex = index;
204}
205
208{
209 NS_LOG_FUNCTION(this);
210 return m_ifIndex;
211}
212
215{
216 NS_LOG_FUNCTION(this);
217 return m_channel;
218}
219
222{
223 NS_LOG_FUNCTION(this);
224 return m_address;
225}
226
227void
229{
230 NS_LOG_FUNCTION(this);
231 NS_LOG_WARN("Manual changing mesh point address can cause routing errors.");
233}
234
235bool
236MeshPointDevice::SetMtu(const uint16_t mtu)
237{
238 NS_LOG_FUNCTION(this);
239 m_mtu = mtu;
240 return true;
241}
242
243uint16_t
245{
246 NS_LOG_FUNCTION(this);
247 return m_mtu;
248}
249
250bool
252{
253 NS_LOG_FUNCTION(this);
254 return true;
255}
256
257void
259{
260 NS_LOG_FUNCTION(this);
261 // do nothing
262 NS_LOG_WARN("AddLinkChangeCallback does nothing");
263}
264
265bool
267{
268 NS_LOG_FUNCTION(this);
269 return true;
270}
271
274{
275 NS_LOG_FUNCTION(this);
277}
278
279bool
281{
282 NS_LOG_FUNCTION(this);
283 return true;
284}
285
288{
289 NS_LOG_FUNCTION(this << multicastGroup);
290 Mac48Address multicast = Mac48Address::GetMulticast(multicastGroup);
291 return multicast;
292}
293
294bool
296{
297 NS_LOG_FUNCTION(this);
298 return false;
299}
300
301bool
303{
304 NS_LOG_FUNCTION(this);
305 return false;
306}
307
308bool
309MeshPointDevice::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
321bool
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
340{
341 NS_LOG_FUNCTION(this);
342 return m_node;
343}
344
345void
347{
348 NS_LOG_FUNCTION(this);
349 m_node = node;
350}
351
352bool
354{
355 NS_LOG_FUNCTION(this);
356 return true;
357}
358
359void
361{
362 NS_LOG_FUNCTION(this);
363 m_rxCallback = cb;
364}
365
366void
368{
369 NS_LOG_FUNCTION(this);
371}
372
373bool
375{
376 NS_LOG_FUNCTION(this);
377 return false; // don't allow to bridge mesh network with something else.
378}
379
382{
383 NS_LOG_FUNCTION(this << addr);
384 return Mac48Address::GetMulticast(addr);
385}
386
387//-----------------------------------------------------------------------------
388// Interfaces
389//-----------------------------------------------------------------------------
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
412std::vector<Ptr<NetDevice>>
414{
415 return m_ifaces;
416}
417
418void
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
466void
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
482void
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
534void
535MeshPointDevice::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
554void
556{
557 NS_LOG_FUNCTION(this);
561}
562
563int64_t
565{
566 NS_LOG_FUNCTION(this << stream);
568 return 1;
569}
570
571Time
573{
575}
576
577} // namespace ns3
a polymophic address class
Definition: address.h:101
Callback template class.
Definition: callback.h:438
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)
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: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:231
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:444
AttributeValue implementation for Pointer.
Definition: pointer.h:48
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:932
Hold an unsigned integer type.
Definition: uinteger.h:45
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: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
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#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.
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:454
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
uint32_t broadcastData
broadcast data
uint32_t unicastDataBytes
unicast data bytes
uint32_t broadcastDataBytes
broadcast data bytes