A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
sixlowpan-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Universita' di Firenze, Italy
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Tommaso Pecorella <tommaso.pecorella@unifi.it>
7 * Boh Jie Qi <jieqiboh5836@gmail.com>
8 */
9
10#include "sixlowpan-helper.h"
11
12#include "ns3/boolean.h"
13#include "ns3/ipv6-address-helper.h"
14#include "ns3/ipv6-interface-container.h"
15#include "ns3/ipv6-l3-protocol.h"
16#include "ns3/log.h"
17#include "ns3/loopback-net-device.h"
18#include "ns3/names.h"
19#include "ns3/net-device.h"
20#include "ns3/node-list.h"
21#include "ns3/node.h"
22#include "ns3/sixlowpan-nd-protocol.h"
23#include "ns3/sixlowpan-net-device.h"
24#include "ns3/uinteger.h"
25
26#include <iomanip>
27
28namespace ns3
29{
30
31class Address;
32
33NS_LOG_COMPONENT_DEFINE("SixLowPanHelper");
34
36{
37 NS_LOG_FUNCTION(this);
38 m_deviceFactory.SetTypeId("ns3::SixLowPanNetDevice");
39}
40
41void
43{
44 NS_LOG_FUNCTION(this);
45 m_deviceFactory.Set(n1, v1);
46}
47
50{
51 NS_LOG_FUNCTION(this);
52
54
55 for (uint32_t i = 0; i < c.GetN(); ++i)
56 {
57 Ptr<NetDevice> device = c.Get(i);
58 NS_ASSERT_MSG(device, "No NetDevice found in the node " << int(i));
59
60 Ptr<Node> node = device->GetNode();
61 NS_LOG_LOGIC("**** Install 6LoWPAN on node " << node->GetId());
62
64 devs.Add(dev);
65 node->AddDevice(dev);
66 dev->SetNetDevice(device);
67 }
68 return devs;
69}
70
71void
73 uint8_t contextId,
74 Ipv6Prefix context,
75 Time validity)
76{
77 NS_LOG_FUNCTION(this << +contextId << context << validity);
78
79 for (uint32_t i = 0; i < c.GetN(); ++i)
80 {
81 Ptr<NetDevice> device = c.Get(i);
83 if (sixDevice)
84 {
85 sixDevice->AddContext(contextId, context, true, validity);
86 }
87 }
88}
89
90void
92{
93 NS_LOG_FUNCTION(this << +contextId << validity);
94
95 for (uint32_t i = 0; i < c.GetN(); ++i)
96 {
97 Ptr<NetDevice> device = c.Get(i);
99 if (sixDevice)
100 {
101 sixDevice->RenewContext(contextId, validity);
102 }
103 }
104}
105
106void
108{
109 NS_LOG_FUNCTION(this << +contextId);
110
111 for (uint32_t i = 0; i < c.GetN(); ++i)
112 {
113 Ptr<NetDevice> device = c.Get(i);
115 if (sixDevice)
116 {
117 sixDevice->InvalidateContext(contextId);
118 }
119 }
120}
121
122void
124{
125 NS_LOG_FUNCTION(this << +contextId);
126
127 for (uint32_t i = 0; i < c.GetN(); ++i)
128 {
129 Ptr<NetDevice> device = c.Get(i);
131 if (sixDevice)
132 {
133 sixDevice->RemoveContext(contextId);
134 }
135 }
136}
137
138int64_t
140{
141 int64_t currentStream = stream;
142 Ptr<NetDevice> netDevice;
143 for (auto i = c.Begin(); i != c.End(); ++i)
144 {
145 netDevice = (*i);
147 if (dev)
148 {
149 currentStream += dev->AssignStreams(currentStream);
150 }
151 }
152 return (currentStream - stream);
153}
154
157{
158 InstallSixLowPanNd(c, true);
159
161 ipv6.SetBase(baseAddr, Ipv6Prefix(64));
162 Ipv6InterfaceContainer deviceInterfaces;
163 deviceInterfaces = ipv6.AssignWithoutOnLink(c);
164
165 for (uint32_t index = 0; index < c.GetN(); index++)
166 {
167 Ptr<Node> node = c.Get(index)->GetNode();
168 Ptr<Ipv6L3Protocol> ipv6l3 = node->GetObject<Ipv6L3Protocol>();
169 ipv6l3->SetAttribute("SendIcmpv6Redirect", BooleanValue(false));
170
171 Ptr<SixLowPanNetDevice> sixLowPanNetDevice = DynamicCast<SixLowPanNetDevice>(c.Get(index));
172 Ptr<SixLowPanNdProtocol> sixLowPanNdProtocol = node->GetObject<SixLowPanNdProtocol>();
173 if (sixLowPanNdProtocol->IsBorderRouterOnInterface(sixLowPanNetDevice))
174 {
175 NS_ABORT_MSG("Interface " << sixLowPanNetDevice
176 << " has been already initialized, aborting.");
177 }
178 sixLowPanNdProtocol->SetInterfaceAs6lbr(sixLowPanNetDevice);
179 }
180 return deviceInterfaces;
181}
182
185{
186 InstallSixLowPanNd(c, false);
187
189 Ipv6InterfaceContainer deviceInterfaces;
190 deviceInterfaces = ipv6.AssignWithoutAddress(c);
191
192 // Initialize ROVR for each node
193 for (uint32_t i = 0; i < c.GetN(); ++i)
194 {
195 Ptr<NetDevice> dev = c.Get(i);
196 Ptr<Node> node = dev->GetNode();
197 InitializeRovr(node);
198 }
199
200 // Schedule Multicast RS here
201 for (uint32_t i = 0; i < deviceInterfaces.GetN(); ++i)
202 {
203 Ipv6Address linkLocalAddr = deviceInterfaces.GetLinkLocalAddress(i);
204
205 Ptr<NetDevice> dev = c.Get(i);
206 Ptr<Node> node = dev->GetNode();
207
208 Ptr<SixLowPanNdProtocol> icmpv6 = node->GetObject<SixLowPanNdProtocol>();
209
212 icmpv6,
213 linkLocalAddr,
214 dev->GetAddress());
215 }
216
217 return deviceInterfaces;
218}
219
220void
222{
223 for (uint32_t i = 0; i < c.GetN(); ++i)
224 {
225 Ptr<NetDevice> device = c.Get(i);
226 Ptr<Node> node = device->GetNode();
228 Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol>();
229 int32_t interfaceId = ipv6->GetInterfaceForDevice(dev);
230
231 if (interfaceId == -1)
232 {
233 interfaceId = ipv6->AddInterface(dev);
234 }
235
236 Ptr<SixLowPanNdProtocol> sixLowPanNdProtocol = node->GetObject<SixLowPanNdProtocol>();
237 if (!sixLowPanNdProtocol)
238 {
239 sixLowPanNdProtocol = CreateObject<SixLowPanNdProtocol>();
240 sixLowPanNdProtocol->SetAttribute("DAD", BooleanValue(false));
241 sixLowPanNdProtocol->SetAttribute("RsMaxRetransmissionCount", UintegerValue(3));
242 // sixLowPanNdProtocol->SetAttribute ("RtrSolicitationInterval", TimeValue (Seconds
243 // (10)));
244 node->AggregateObject(sixLowPanNdProtocol);
245 }
246 ipv6->Insert(sixLowPanNdProtocol, interfaceId);
247
248 if (borderRouter)
249 {
250 // Get the IPv6 interface
251 Ptr<Ipv6Interface> interface = ipv6->GetInterface(interfaceId);
252
253 // Create binding table for border router functionality
254 sixLowPanNdProtocol->CreateBindingTable(dev, interface);
255
256 ipv6->SetForwarding(interfaceId, true);
257 }
258 }
259}
260
261void
263{
264 NS_LOG_FUNCTION(this << nd << prefix.ConvertToIpv6Address() << prefix);
265
266 Ptr<Node> node = nd->GetNode();
267
269 if (sixLowPanNetDevice)
270 {
271 Ptr<SixLowPanNdProtocol> sixLowPanNdProtocol = node->GetObject<SixLowPanNdProtocol>();
272 if (!sixLowPanNdProtocol)
273 {
274 NS_ABORT_MSG("Can not add a Prefix to a 6LBR on a node because I can not find "
275 "6LoWPAN-ND protocol");
276 }
277 sixLowPanNdProtocol->SetAdvertisedPrefix(sixLowPanNetDevice, prefix);
278 }
279 else
280 {
281 NS_LOG_WARN("Not a SixLowPan NetDevice - doing nothing");
282 }
283}
284
285void
287{
288 NS_LOG_FUNCTION(this << nd << context.ConvertToIpv6Address() << context);
289
290 Ptr<Node> node = nd->GetNode();
291
293 if (sixLowPanNetDevice)
294 {
295 Ptr<SixLowPanNdProtocol> sixLowPanNdProtocol = node->GetObject<SixLowPanNdProtocol>();
296 if (!sixLowPanNdProtocol)
297 {
298 NS_ABORT_MSG("Can not add a Context to a 6LBR on a node because I can not find "
299 "6LoWPAN-ND protocol");
300 }
301
302 sixLowPanNdProtocol->AddAdvertisedContext(sixLowPanNetDevice, context);
303 }
304 else
305 {
306 NS_LOG_WARN("Not a SixLowPan NetDevice - doing nothing");
307 }
308}
309
310void
312{
313 NS_LOG_FUNCTION(this << nd << context.ConvertToIpv6Address() << context);
314
315 Ptr<Node> node = nd->GetNode();
316
318 if (sixLowPanNetDevice)
319 {
320 Ptr<SixLowPanNdProtocol> sixLowPanNdProtocol = node->GetObject<SixLowPanNdProtocol>();
321 if (!sixLowPanNdProtocol)
322 {
323 NS_ABORT_MSG("Can not remove a Context from a 6LBR on a node because I can not find "
324 "6LoWPAN-ND protocol");
325 }
326
327 sixLowPanNdProtocol->RemoveAdvertisedContext(sixLowPanNetDevice, context);
328 }
329 else
330 {
331 NS_LOG_WARN("Not a SixLowPan NetDevice - doing nothing");
332 }
333}
334
335void
337{
338 Ptr<SixLowPanNdProtocol> sixLowPanNdProtocol = node->GetObject<SixLowPanNdProtocol>();
339 NS_ASSERT_MSG(sixLowPanNdProtocol, "6LoWPAN ND protocol not found on node");
340
341 Address macAddress;
342 uint32_t maxLen = 0;
343
344 for (uint32_t i = 0; i < node->GetNDevices(); i++)
345 {
346 Ptr<NetDevice> dev = node->GetDevice(i);
347
348 // Skip loopback
350 {
351 continue;
352 }
353
354 Address addr = dev->GetAddress();
355 if (addr.GetLength() > maxLen)
356 {
357 macAddress = addr;
358 maxLen = addr.GetLength();
359 }
360 }
361
362 NS_ASSERT_MSG(!macAddress.IsInvalid(), "No valid MAC address found for ROVR");
363
364 // Create ROVR vector (16 bytes, zero-padded)
365 std::vector<uint8_t> rovr(16, 0);
366 macAddress.CopyTo(rovr.data());
367
368 NS_LOG_INFO("ROVR for node " << node->GetId() << " set from MAC: " << macAddress);
369 sixLowPanNdProtocol->SetRovr(rovr);
370}
371
372void
375 Time::Unit unit /* = Time::S */)
376{
377 for (uint32_t i = 0; i < NodeList::GetNNodes(); i++)
378 {
380 Simulator::Schedule(printTime, &SixLowPanHelper::PrintBindingTable, node, stream, unit);
381 }
382}
383
384void
387 Time::Unit unit /* = Time::S */)
388{
389 Ptr<SixLowPanNdProtocol> protocol = node->GetObject<SixLowPanNdProtocol>();
390 if (protocol)
391 {
392 std::ostream* os = stream->GetStream();
393
394 *os << "6LoWPAN-ND Binding Table of node ";
395 std::string found = Names::FindName(node);
396 if (!Names::FindName(node).empty())
397 {
398 *os << found;
399 }
400 else
401 {
402 *os << static_cast<int>(node->GetId());
403 }
404 *os << " at time " << Simulator::Now().As(unit) << "\n";
405
406 // Get all binding tables for this node
407 Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol>();
408 if (ipv6)
409 {
410 for (uint32_t i = 0; i < ipv6->GetNInterfaces(); i++)
411 {
412 Ptr<Ipv6Interface> interface = ipv6->GetInterface(i);
413 Ptr<SixLowPanNdBindingTable> bindingTable = protocol->FindBindingTable(interface);
414 if (bindingTable)
415 {
416 *os << "Interface " << i << ":\n";
417 bindingTable->PrintBindingTable(stream);
418 }
419 }
420 }
421 }
422 else
423 {
424 std::ostream* os = stream->GetStream();
425 *os << "Node " << node->GetId() << " does not have 6LoWPAN-ND protocol installed\n";
426 }
427}
428
429} // namespace ns3
a polymophic address class
Definition address.h:114
bool IsInvalid() const
Definition address.cc:55
uint8_t GetLength() const
Get the length of the underlying address.
Definition address.cc:62
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition address.cc:70
Hold a value for an Attribute.
Definition attribute.h:59
AttributeValue implementation for Boolean.
Definition boolean.h:26
Helper class to auto-assign global IPv6 unicast addresses.
Ipv6InterfaceContainer AssignWithoutAddress(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer but do not assign any IPv6 addresses.
void SetBase(Ipv6Address network, Ipv6Prefix prefix, Ipv6Address base=Ipv6Address("::1"))
Set the base network number, network prefix, and base interface ID.
Ipv6InterfaceContainer AssignWithoutOnLink(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses, but do not set the on-link property ...
Describes an IPv6 address.
Keep track of a set of IPv6 interfaces.
Ipv6Address GetLinkLocalAddress(uint32_t i)
Get the link-local address for the specified index.
IPv6 layer implementation.
Describes an IPv6 prefix.
Ipv6Address ConvertToIpv6Address() const
Convert the Prefix into an IPv6 Address.
static std::string FindName(Ptr< Object > object)
Given a pointer to an object, look to see if that object has a name associated with it and,...
Definition names.cc:818
holds a vector of ns3::NetDevice pointers
uint32_t GetN() const
Get the number of Ptr<NetDevice> stored in this container.
Iterator Begin() const
Get an iterator which refers to the first NetDevice in the container.
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Iterator End() const
Get an iterator which indicates past-the-last NetDevice in the container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
static uint32_t GetNNodes()
Definition node-list.cc:247
static Ptr< Node > GetNode(uint32_t n)
Definition node-list.cc:240
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:191
ObjectFactory m_deviceFactory
Object factory.
void SetDeviceAttribute(std::string n1, const AttributeValue &v1)
Set an attribute on each ns3::SixlowpanNetDevice created by SixlowpanHelper::Install.
static void PrintBindingTable(Ptr< Node > node, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
Print the binding table of a node.
Ipv6InterfaceContainer InstallSixLowPanNdNode(NetDeviceContainer c)
Install the SixLoWPAN-ND stack, associate it with a NetDevice, and set it as a 6LN.
void InstallSixLowPanNd(NetDeviceContainer c, bool borderRouter)
Install the SixLoWPAN-ND stack in the node and associates it with a NetDevice.
NetDeviceContainer Install(NetDeviceContainer c)
Install the SixLoWPAN stack on top of an existing NetDevice.
void RemoveContext(NetDeviceContainer c, uint8_t contextId)
Remove a compression Context in a set of NetDevices.
static void PrintBindingTableAllAt(Time printTime, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
Print the binding table of all nodes at a specific time.
void RenewContext(NetDeviceContainer c, uint8_t contextId, Time validity)
Renew a compression Context in a set of NetDevices.
void SetAdvertisedPrefix(const Ptr< NetDevice > nd, Ipv6Prefix prefix)
Add a new prefix to be advertised by 6LoWPAN-ND.
void RemoveAdvertisedContext(const Ptr< NetDevice > nd, Ipv6Prefix context)
Remove a context advertised by 6LoWPAN-ND.
Ipv6InterfaceContainer InstallSixLowPanNdBorderRouter(NetDeviceContainer c, Ipv6Address baseAddr)
Install the SixLoWPAN-ND stack, associate it with a NetDevice, and set it as a 6LBR.
int64_t AssignStreams(NetDeviceContainer c, int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void InvalidateContext(NetDeviceContainer c, uint8_t contextId)
Invalidates a compression Context in a set of NetDevices.
void AddContext(NetDeviceContainer c, uint8_t contextId, Ipv6Prefix context, Time validity)
Adds a compression Context to a set of NetDevices.
void InitializeRovr(Ptr< Node > node)
Initialize the ROVR for a node.
void AddAdvertisedContext(const Ptr< NetDevice > nd, Ipv6Prefix context)
Add a new context to be advertised by 6LoWPAN-ND.
An optimization of the ND protocol for 6LoWPANs.
void SendSixLowPanMulticastRS(Ipv6Address src, Address hardwareAddress)
Send a Multicast RS (+ 6CIO) (RFC6775 5.3).
Shim performing 6LoWPAN compression, decompression and fragmentation.
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:408
Unit
The unit to use to interpret a number representing time.
Definition nstime.h:101
Hold an unsigned integer type.
Definition uinteger.h:34
#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
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
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:253
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:267
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:605