A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lr-wpan-net-device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 The Boeing Company
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:
18 * Tom Henderson <thomas.r.henderson@boeing.com>
19 * Tommaso Pecorella <tommaso.pecorella@unifi.it>
20 * Margherita Filippetti <morag87@gmail.com>
21 */
22#include "lr-wpan-net-device.h"
23
24#include "lr-wpan-csmaca.h"
25#include "lr-wpan-error-model.h"
26#include "lr-wpan-phy.h"
27
28#include <ns3/abort.h>
29#include <ns3/boolean.h>
30#include <ns3/log.h>
31#include <ns3/node.h>
32#include <ns3/packet.h>
33#include <ns3/pointer.h>
34#include <ns3/spectrum-channel.h>
35
36namespace ns3
37{
38namespace lrwpan
39{
40
41NS_LOG_COMPONENT_DEFINE("LrWpanNetDevice");
43
44TypeId
46{
47 static TypeId tid =
48 TypeId("ns3::LrWpanNetDevice")
50 .SetGroupName("LrWpan")
51 .AddConstructor<LrWpanNetDevice>()
52 .AddAttribute("Channel",
53 "The channel attached to this device",
56 MakePointerChecker<SpectrumChannel>())
57 .AddAttribute("Phy",
58 "The PHY layer attached to this device.",
61 MakePointerChecker<LrWpanPhy>())
62 .AddAttribute("Mac",
63 "The MAC layer attached to this device.",
66 MakePointerChecker<LrWpanMac>())
67 .AddAttribute("UseAcks",
68 "Request acknowledgments for data frames.",
69 BooleanValue(true),
72 .AddAttribute(
73 "PseudoMacAddressMode",
74 "Build the pseudo-MAC Address according to RFC 4944 or RFC 6282 "
75 "(default: RFC 6282).",
77 MakeEnumAccessor<PseudoMacAddressMode_e>(&LrWpanNetDevice::m_pseudoMacMode),
79 "RFC 6282 (don't use PanId)",
81 "RFC 4944 (use PanId)"));
82 return tid;
83}
84
86 : m_configComplete(false)
87{
88 NS_LOG_FUNCTION(this);
89 m_mac = CreateObject<LrWpanMac>();
90 m_phy = CreateObject<LrWpanPhy>();
91 m_csmaca = CreateObject<LrWpanCsmaCa>();
93}
94
96{
97 NS_LOG_FUNCTION(this);
98}
99
100void
102{
103 NS_LOG_FUNCTION(this);
104 m_mac->Dispose();
105 m_phy->Dispose();
106 m_csmaca->Dispose();
107 m_phy = nullptr;
108 m_mac = nullptr;
109 m_csmaca = nullptr;
110 m_node = nullptr;
111 // chain up.
113}
114
115void
117{
118 NS_LOG_FUNCTION(this);
119 m_phy->Initialize();
120 m_mac->Initialize();
122}
123
124void
126{
127 NS_LOG_FUNCTION(this);
128 if (!m_mac || !m_phy || !m_csmaca || !m_node || m_configComplete)
129 {
130 return;
131 }
132 m_mac->SetPhy(m_phy);
133 m_mac->SetCsmaCa(m_csmaca);
134 m_mac->SetMcpsDataIndicationCallback(MakeCallback(&LrWpanNetDevice::McpsDataIndication, this));
135 m_csmaca->SetMac(m_mac);
136
137 Ptr<LrWpanErrorModel> model = CreateObject<LrWpanErrorModel>();
138 m_phy->SetErrorModel(model);
139 m_phy->SetDevice(this);
140
141 m_phy->SetPdDataIndicationCallback(MakeCallback(&LrWpanMac::PdDataIndication, m_mac));
142 m_phy->SetPdDataConfirmCallback(MakeCallback(&LrWpanMac::PdDataConfirm, m_mac));
143 m_phy->SetPlmeEdConfirmCallback(MakeCallback(&LrWpanMac::PlmeEdConfirm, m_mac));
144 m_phy->SetPlmeGetAttributeConfirmCallback(
146 m_phy->SetPlmeSetTRXStateConfirmCallback(
148 m_phy->SetPlmeSetAttributeConfirmCallback(
150
151 m_csmaca->SetLrWpanMacStateCallback(MakeCallback(&LrWpanMac::SetLrWpanMacState, m_mac));
152 m_phy->SetPlmeCcaConfirmCallback(MakeCallback(&LrWpanCsmaCa::PlmeCcaConfirm, m_csmaca));
153 m_configComplete = true;
154}
155
156void
158{
159 NS_LOG_FUNCTION(this);
160 m_mac = mac;
162}
163
164void
166{
167 NS_LOG_FUNCTION(this);
168 m_phy = phy;
170}
171
172void
174{
175 NS_LOG_FUNCTION(this);
176 m_csmaca = csmaca;
178}
179
180void
182{
183 NS_LOG_FUNCTION(this << channel);
184 m_phy->SetChannel(channel);
185 channel->AddRx(m_phy);
187}
188
191{
192 // NS_LOG_FUNCTION (this);
193 return m_mac;
194}
195
198{
199 NS_LOG_FUNCTION(this);
200 return m_phy;
201}
202
205{
206 NS_LOG_FUNCTION(this);
207 return m_csmaca;
208}
209
210void
212{
213 NS_LOG_FUNCTION(this << index);
214 m_ifIndex = index;
215}
216
219{
220 NS_LOG_FUNCTION(this);
221 return m_ifIndex;
222}
223
226{
227 NS_LOG_FUNCTION(this);
228 return m_phy->GetChannel();
229}
230
231void
233{
234 NS_LOG_FUNCTION(this);
235 m_linkUp = true;
237}
238
239void
241{
242 NS_LOG_FUNCTION(this);
243 m_linkUp = false;
245}
246
249{
250 NS_LOG_FUNCTION(this);
251 return m_phy->GetChannel();
252}
253
254void
256{
257 NS_LOG_FUNCTION(this);
258 if (Mac16Address::IsMatchingType(address))
259 {
260 m_mac->SetShortAddress(Mac16Address::ConvertFrom(address));
261 }
262 else if (Mac64Address::IsMatchingType(address))
263 {
264 m_mac->SetExtendedAddress(Mac64Address::ConvertFrom(address));
265 }
266 else if (Mac48Address::IsMatchingType(address))
267 {
268 uint8_t buf[6];
270 addr.CopyTo(buf);
271 Mac16Address addr16;
272 addr16.CopyFrom(buf + 4);
273 m_mac->SetShortAddress(addr16);
274 uint16_t panId;
275 panId = buf[0];
276 panId <<= 8;
277 panId |= buf[1];
278 m_mac->SetPanId(panId);
279 }
280 else
281 {
282 NS_ABORT_MSG("LrWpanNetDevice::SetAddress - address is not of a compatible type");
283 }
284}
285
288{
289 NS_LOG_FUNCTION(this);
290
291 if (m_mac->GetShortAddress() == Mac16Address("00:00"))
292 {
293 return m_mac->GetExtendedAddress();
294 }
295
296 Mac48Address pseudoAddress = BuildPseudoMacAddress(m_mac->GetPanId(), m_mac->GetShortAddress());
297
298 return pseudoAddress;
299}
300
301void
303 Mac64Address coordExtAddr,
304 Mac16Address coordShortAddr,
305 Mac16Address assignedShortAddr)
306{
307 NS_LOG_FUNCTION(this);
308 m_mac->SetPanId(panId);
309 m_mac->SetAssociatedCoor(coordExtAddr);
310 m_mac->SetAssociatedCoor(coordShortAddr);
311 m_mac->SetShortAddress(assignedShortAddr);
312}
313
314bool
315LrWpanNetDevice::SetMtu(const uint16_t mtu)
316{
317 NS_ABORT_MSG("Unsupported");
318 return false;
319}
320
321uint16_t
323{
324 NS_LOG_FUNCTION(this);
325 // Maximum payload size is: max psdu - frame control - seqno - addressing - security - fcs
326 // = 127 - 2 - 1 - (2+2+2+2) - 0 - 2
327 // = 114
328 // assuming no security and addressing with only 16 bit addresses without pan id compression.
329 return 114;
330}
331
332bool
334{
335 NS_LOG_FUNCTION(this);
336 return m_phy && m_linkUp;
337}
338
339void
341{
342 NS_LOG_FUNCTION(this);
344}
345
346bool
348{
349 NS_LOG_FUNCTION(this);
350 return true;
351}
352
355{
356 NS_LOG_FUNCTION(this);
357
358 Mac48Address pseudoAddress =
360
361 return pseudoAddress;
362}
363
364bool
366{
367 NS_LOG_FUNCTION(this);
368 return true;
369}
370
373{
374 NS_ABORT_MSG("Unsupported");
375 return Address();
376}
377
380{
381 NS_LOG_FUNCTION(this << addr);
382
383 Mac48Address pseudoAddress =
385
386 return pseudoAddress;
387}
388
389bool
391{
392 NS_LOG_FUNCTION(this);
393 return false;
394}
395
396bool
398{
399 NS_LOG_FUNCTION(this);
400 return false;
401}
402
403bool
404LrWpanNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
405{
406 // This method basically assumes an 802.3-compliant device, but a raw
407 // 802.15.4 device does not have an ethertype, and requires specific
408 // McpsDataRequest parameters.
409 // For further study: how to support these methods somehow, such as
410 // inventing a fake ethertype and packet tag for McpsDataRequest
411 NS_LOG_FUNCTION(this << packet << dest << protocolNumber);
412
413 if (packet->GetSize() > GetMtu())
414 {
415 NS_LOG_ERROR("Fragmentation is needed for this packet, drop the packet ");
416 return false;
417 }
418
419 McpsDataRequestParams m_mcpsDataRequestParams;
420
421 Mac16Address dst16;
423 {
424 uint8_t buf[6];
425 dest.CopyTo(buf);
426 dst16.CopyFrom(buf + 4);
427 }
428 else
429 {
430 dst16 = Mac16Address::ConvertFrom(dest);
431 }
432 m_mcpsDataRequestParams.m_dstAddr = dst16;
433 m_mcpsDataRequestParams.m_dstAddrMode = SHORT_ADDR;
434 m_mcpsDataRequestParams.m_dstPanId = m_mac->GetPanId();
435 m_mcpsDataRequestParams.m_srcAddrMode = SHORT_ADDR;
436 // Using ACK requests for broadcast destinations is ok here. They are disabled
437 // by the MAC.
438 if (m_useAcks)
439 {
440 m_mcpsDataRequestParams.m_txOptions = TX_OPTION_ACK;
441 }
442 m_mcpsDataRequestParams.m_msduHandle = 0;
443 m_mac->McpsDataRequest(m_mcpsDataRequestParams, packet);
444 return true;
445}
446
447bool
449 const Address& source,
450 const Address& dest,
451 uint16_t protocolNumber)
452{
453 NS_ABORT_MSG("Unsupported");
454 // TODO: To support SendFrom, the MACs McpsDataRequest has to use the provided source address,
455 // instead of to local one.
456 return false;
457}
458
461{
462 NS_LOG_FUNCTION(this);
463 return m_node;
464}
465
466void
468{
469 NS_LOG_FUNCTION(this);
470 m_node = node;
472}
473
474bool
476{
477 NS_LOG_FUNCTION(this);
478 return true;
479}
480
481void
483{
484 NS_LOG_FUNCTION(this);
486}
487
488void
490{
491 // This method basically assumes an 802.3-compliant device, but a raw
492 // 802.15.4 device does not have an ethertype, and requires specific
493 // McpsDataIndication parameters.
494 // For further study: how to support these methods somehow, such as
495 // inventing a fake ethertype and packet tag for McpsDataRequest
496 NS_LOG_WARN("Unsupported; use LrWpan MAC APIs instead");
497}
498
499void
501{
502 NS_LOG_FUNCTION(this);
503 // TODO: Use the PromiscReceiveCallback if the MAC is in promiscuous mode.
504
505 if (params.m_dstAddrMode == SHORT_ADDR)
506 {
507 m_receiveCallback(this, pkt, 0, BuildPseudoMacAddress(params.m_srcPanId, params.m_srcAddr));
508 }
509 else
510 {
511 m_receiveCallback(this, pkt, 0, params.m_srcExtAddr);
512 }
513}
514
515bool
517{
519 return false;
520}
521
524{
525 NS_LOG_FUNCTION(this);
526
527 uint8_t buf[6];
528
530 {
531 buf[0] = panId >> 8;
532 // Make sure the U/L bit is set
533 buf[0] |= 0x02;
534 buf[1] = panId & 0xff;
535 }
536 else
537 {
538 // Make sure the U/L bit is set
539 buf[0] = 0x02;
540 buf[1] = 0x00;
541 }
542 buf[2] = 0;
543 buf[3] = 0;
544 shortAddr.CopyTo(buf + 4);
545
546 Mac48Address pseudoAddress;
547 pseudoAddress.CopyFrom(buf);
548
549 return pseudoAddress;
550}
551
552int64_t
554{
555 NS_LOG_FUNCTION(stream);
556 int64_t streamIndex = stream;
557 streamIndex += m_csmaca->AssignStreams(stream);
558 streamIndex += m_phy->AssignStreams(stream);
559 NS_LOG_DEBUG("Number of assigned RV streams: " << (streamIndex - stream));
560 return (streamIndex - stream);
561}
562
563} // namespace lrwpan
564} // namespace ns3
a polymophic address class
Definition: address.h:101
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition: address.cc:86
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Callback template class.
Definition: callback.h:438
Hold variables of type enum.
Definition: enum.h:62
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Describes an IPv6 address.
Definition: ipv6-address.h:49
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
static Mac16Address GetMulticast(Ipv6Address address)
Returns the multicast address associated with an IPv6 address according to RFC 4944 Section 9.
static bool IsMatchingType(const Address &address)
static Mac16Address ConvertFrom(const Address &address)
void CopyTo(uint8_t buffer[2]) const
void CopyFrom(const uint8_t buffer[2])
static Mac16Address GetBroadcast()
an EUI-48 address
Definition: mac48-address.h:46
static bool IsMatchingType(const Address &address)
void CopyFrom(const uint8_t buffer[6])
static Mac48Address ConvertFrom(const Address &address)
void CopyTo(uint8_t buffer[6]) const
an EUI-64 address
Definition: mac64-address.h:46
static bool IsMatchingType(const Address &address)
static Mac64Address ConvertFrom(const Address &address)
Network layer to device interface.
Definition: net-device.h:98
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:451
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
void ConnectWithoutContext(const CallbackBase &callback)
Append a Callback to the chain (without a context).
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
void PlmeCcaConfirm(PhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.2.2 PLME-CCA.confirm status.
void PdDataConfirm(PhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.1.2 Confirm the end of transmission of an MPDU to MAC.
void SetLrWpanMacState(MacState macState)
CSMA-CA algorithm calls back the MAC after executing channel assessment.
void PdDataIndication(uint32_t psduLength, Ptr< Packet > p, uint8_t lqi)
IEEE 802.15.4-2006 section 6.2.1.3 PD-DATA.indication Indicates the transfer of an MPDU from PHY to M...
void PlmeGetAttributeConfirm(PhyEnumeration status, PhyPibAttributeIdentifier id, Ptr< PhyPibAttributes > attribute)
IEEE 802.15.4-2006 section 6.2.2.6 PLME-GET.confirm Get attributes per definition from Table 23 in se...
void PlmeSetAttributeConfirm(PhyEnumeration status, PhyPibAttributeIdentifier id)
IEEE 802.15.4-2006 section 6.2.2.10 PLME-SET.confirm Set attributes per definition from Table 23 in s...
void PlmeSetTRXStateConfirm(PhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.2.8 PLME-SET-TRX-STATE.confirm Set PHY state.
void PlmeEdConfirm(PhyEnumeration status, uint8_t energyLevel)
IEEE 802.15.4-2006 section 6.2.2.4 PLME-ED.confirm status and energy level.
Network layer to device interface.
bool SupportsSendFrom() const override
void LinkDown()
Mark NetDevice link as down.
Address GetMulticast(Ipv4Address multicastGroup) const override
Make and return a MAC multicast address using the provided multicast group.
bool Send(Ptr< Packet > packet, const Address &dest, uint16_t protocolNumber) override
Ptr< LrWpanPhy > m_phy
The PHY for this NetDevice.
bool NeedsArp() const override
uint32_t m_ifIndex
The interface index of this NetDevice.
void LinkUp()
Mark NetDevice link as up.
PseudoMacAddressMode_e m_pseudoMacMode
How the pseudo MAC address is created.
Ptr< LrWpanMac > m_mac
The MAC for this NetDevice.
Ptr< LrWpanMac > GetMac() const
Get the MAC used by this NetDevice.
uint16_t GetMtu() const override
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void SetIfIndex(const uint32_t index) override
bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber) override
void SetAddress(Address address) override
This method indirects to LrWpanMac::SetShortAddress ()
ReceiveCallback m_receiveCallback
Upper layer callback used for notification of new data packet arrivals.
bool m_configComplete
True if MAC, PHY and CSMA/CA where successfully configured and the NetDevice is ready for being used.
bool SetMtu(const uint16_t mtu) override
Ptr< SpectrumChannel > DoGetChannel() const
Attribute accessor method for the "Channel" attribute.
bool m_useAcks
Configure the NetDevice to request MAC layer acknowledgments when sending packets using the Send() AP...
void SetPanAssociation(uint16_t panId, Mac64Address coordExtAddr, Mac16Address coordShortAddr, Mac16Address assignedShortAddr)
This method is use to manually configure the coordinator through which the device or coordinator is a...
Address GetAddress() const override
This method indirects to LrWpanMac::SetShortAddress ()
bool IsLinkUp() const override
void AddLinkChangeCallback(Callback< void > callback) override
uint32_t GetIfIndex() const override
@ RFC4944
YYYY:0000:XXXX (with U/L bit set to local)
void SetCsmaCa(Ptr< LrWpanCsmaCa > csmaca)
Set the CSMA/CA implementation to be used by the MAC and this NetDevice.
bool IsBroadcast() const override
void CompleteConfig()
Configure PHY, MAC and CSMA/CA.
void SetPromiscReceiveCallback(PromiscReceiveCallback cb) override
Ptr< LrWpanCsmaCa > m_csmaca
The CSMA/CA implementation for this NetDevice.
TracedCallback m_linkChanges
Trace source for link up/down changes.
Address GetBroadcast() const override
Ptr< Channel > GetChannel() const override
Mac48Address BuildPseudoMacAddress(uint16_t panId, Mac16Address shortAddr) const
Builds a "pseudo 48-bit address" from the PanId and Short Address The form is PanId : 0x0 : 0x0 : Sho...
Ptr< LrWpanCsmaCa > GetCsmaCa() const
Get the CSMA/CA implementation used by this NetDevice.
void SetPhy(Ptr< LrWpanPhy > phy)
Set the PHY to be used by the MAC and this NetDevice.
void DoDispose() override
Destructor implementation.
bool IsPointToPoint() const override
Return true if the net device is on a point-to-point link.
void SetChannel(Ptr< SpectrumChannel > channel)
Set the channel to which the NetDevice, and therefore the PHY, should be attached to.
Ptr< LrWpanPhy > GetPhy() const
Get the PHY used by this NetDevice.
bool m_linkUp
Is the link/device currently up and running?
bool IsBridge() const override
Return true if the net device is acting as a bridge.
void SetNode(Ptr< Node > node) override
bool IsMulticast() const override
static TypeId GetTypeId()
Get the type ID.
void McpsDataIndication(McpsDataIndicationParams params, Ptr< Packet > pkt)
The callback used by the MAC to hand over incoming packets to the NetDevice.
void SetReceiveCallback(NetDevice::ReceiveCallback cb) override
void DoInitialize() override
Initialize() implementation.
void SetMac(Ptr< LrWpanMac > mac)
Set the MAC to be used by this NetDevice.
Ptr< Node > m_node
The node associated with this NetDevice.
Ptr< Node > GetNode() const override
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:81
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:259
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#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_NOARGS()
Output the name of the function.
#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
@ TX_OPTION_ACK
TX_OPTION_ACK.
Definition: lr-wpan-mac.h:64
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
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:706
Ptr< const AttributeChecker > MakeEnumChecker(T v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:189
MCPS-DATA.indication params.
AddressMode m_dstAddrMode
Destination address mode.
Mac16Address m_dstAddr
Destination address.
uint16_t m_dstPanId
Destination PAN identifier.
AddressMode m_srcAddrMode
Source address mode.
uint8_t m_txOptions
Tx Options (bitfield)