A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
lr-wpan-mac.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 * Authors:
18 * Gary Pei <guangyu.pei@boeing.com>
19 * kwong yin <kwong-sang.yin@boeing.com>
20 * Tom Henderson <thomas.r.henderson@boeing.com>
21 * Sascha Alexander Jopen <jopen@cs.uni-bonn.de>
22 * Erwan Livolant <erwan.livolant@inria.fr>
23 * Alberto Gallegos Ramonet <ramonet@fc.ritsumei.ac.jp>
24 */
25#include "lr-wpan-mac.h"
26
27#include "lr-wpan-constants.h"
28#include "lr-wpan-csmaca.h"
29#include "lr-wpan-mac-header.h"
31#include "lr-wpan-mac-trailer.h"
32
33#include <ns3/double.h>
34#include <ns3/log.h>
35#include <ns3/node.h>
36#include <ns3/packet.h>
37#include <ns3/random-variable-stream.h>
38#include <ns3/simulator.h>
39#include <ns3/uinteger.h>
40
41#undef NS_LOG_APPEND_CONTEXT
42#define NS_LOG_APPEND_CONTEXT \
43 std::clog << "[address " << m_shortAddress << " | " << m_selfExt << "] ";
44
45namespace ns3
46{
47
48NS_LOG_COMPONENT_DEFINE("LrWpanMac");
50
51TypeId
53{
54 static TypeId tid =
55 TypeId("ns3::LrWpanMac")
57 .SetGroupName("LrWpan")
58 .AddConstructor<LrWpanMac>()
59 .AddAttribute("PanId",
60 "16-bit identifier of the associated PAN",
63 MakeUintegerChecker<uint16_t>())
64 .AddTraceSource("MacTxEnqueue",
65 "Trace source indicating a packet has been "
66 "enqueued in the transaction queue",
68 "ns3::Packet::TracedCallback")
69 .AddTraceSource("MacTxDequeue",
70 "Trace source indicating a packet has was "
71 "dequeued from the transaction queue",
73 "ns3::Packet::TracedCallback")
74 .AddTraceSource("MacIndTxEnqueue",
75 "Trace source indicating a packet has been "
76 "enqueued in the indirect transaction queue",
78 "ns3::Packet::TracedCallback")
79 .AddTraceSource("MacIndTxDequeue",
80 "Trace source indicating a packet has was "
81 "dequeued from the indirect transaction queue",
83 "ns3::Packet::TracedCallback")
84 .AddTraceSource("MacTx",
85 "Trace source indicating a packet has "
86 "arrived for transmission by this device",
88 "ns3::Packet::TracedCallback")
89 .AddTraceSource("MacTxOk",
90 "Trace source indicating a packet has been "
91 "successfully sent",
93 "ns3::Packet::TracedCallback")
94 .AddTraceSource("MacTxDrop",
95 "Trace source indicating a packet has been "
96 "dropped during transmission",
98 "ns3::Packet::TracedCallback")
99 .AddTraceSource("MacIndTxDrop",
100 "Trace source indicating a packet has been "
101 "dropped from the indirect transaction queue"
102 "(The pending transaction list)",
104 "ns3::Packet::TracedCallback")
105 .AddTraceSource("MacPromiscRx",
106 "A packet has been received by this device, "
107 "has been passed up from the physical layer "
108 "and is being forwarded up the local protocol stack. "
109 "This is a promiscuous trace,",
111 "ns3::Packet::TracedCallback")
112 .AddTraceSource("MacRx",
113 "A packet has been received by this device, "
114 "has been passed up from the physical layer "
115 "and is being forwarded up the local protocol stack. "
116 "This is a non-promiscuous trace,",
118 "ns3::Packet::TracedCallback")
119 .AddTraceSource("MacRxDrop",
120 "Trace source indicating a packet was received, "
121 "but dropped before being forwarded up the stack",
123 "ns3::Packet::TracedCallback")
124 .AddTraceSource("Sniffer",
125 "Trace source simulating a non-promiscuous "
126 "packet sniffer attached to the device",
128 "ns3::Packet::TracedCallback")
129 .AddTraceSource("PromiscSniffer",
130 "Trace source simulating a promiscuous "
131 "packet sniffer attached to the device",
133 "ns3::Packet::TracedCallback")
134 .AddTraceSource("MacStateValue",
135 "The state of LrWpan Mac",
137 "ns3::TracedValueCallback::LrWpanMacState")
138 .AddTraceSource("MacIncSuperframeStatus",
139 "The period status of the incoming superframe",
141 "ns3::TracedValueCallback::SuperframeState")
142 .AddTraceSource("MacOutSuperframeStatus",
143 "The period status of the outgoing superframe",
145 "ns3::TracedValueCallback::SuperframeState")
146 .AddTraceSource("MacState",
147 "The state of LrWpan Mac",
149 "ns3::LrWpanMac::StateTracedCallback")
150 .AddTraceSource("MacSentPkt",
151 "Trace source reporting some information about "
152 "the sent packet",
154 "ns3::LrWpanMac::SentTracedCallback")
155 .AddTraceSource("IfsEnd",
156 "Trace source reporting the end of an "
157 "Interframe space (IFS)",
159 "ns3::Packet::TracedCallback");
160 return tid;
161}
162
164{
165 // First set the state to a known value, call ChangeMacState to fire trace source.
167
169
172
173 m_macRxOnWhenIdle = true;
174 m_macPanId = 0xffff;
176 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
180 m_macPromiscuousMode = false;
184 m_txPkt = nullptr;
185 m_rxPkt = nullptr;
186 m_ifs = 0;
187
188 m_macLIFSPeriod = 40;
189 m_macSIFSPeriod = 12;
190
191 m_panCoor = false;
192 m_coor = false;
193 m_macBeaconOrder = 15;
195 m_macTransactionPersistenceTime = 500; // 0x01F5
197 m_macAutoRequest = true;
198
201 m_beaconTrackingOn = false;
203
207
210
211 m_maxTxQueueSize = m_txQueue.max_size();
213
214 Ptr<UniformRandomVariable> uniformVar = CreateObject<UniformRandomVariable>();
215 uniformVar->SetAttribute("Min", DoubleValue(0.0));
216 uniformVar->SetAttribute("Max", DoubleValue(255.0));
217 m_macDsn = SequenceNumber8(uniformVar->GetValue());
218 m_macBsn = SequenceNumber8(uniformVar->GetValue());
219 m_macBeaconPayload = nullptr;
221 m_shortAddress = Mac16Address("FF:FF"); // FF:FF = The address is not assigned.
222}
223
225{
226}
227
228void
230{
232 {
233 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
234 }
235 else
236 {
237 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
238 }
239
241}
242
243void
245{
246 if (m_csmaCa)
247 {
248 m_csmaCa->Dispose();
249 m_csmaCa = nullptr;
250 }
251 m_txPkt = nullptr;
252
253 for (uint32_t i = 0; i < m_txQueue.size(); i++)
254 {
255 m_txQueue[i]->txQPkt = nullptr;
256 m_txQueue[i]->txQMsduHandle = 0;
257 }
258 m_txQueue.clear();
259
260 for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
261 {
262 m_indTxQueue[i]->txQPkt = nullptr;
263 m_indTxQueue[i]->seqNum = 0;
264 m_indTxQueue[i]->dstExtAddress = nullptr;
265 m_indTxQueue[i]->dstShortAddress = nullptr;
266 }
267 m_indTxQueue.clear();
268
269 m_phy = nullptr;
270 m_mcpsDataConfirmCallback = MakeNullCallback<void, McpsDataConfirmParams>();
271 m_mcpsDataIndicationCallback = MakeNullCallback<void, McpsDataIndicationParams, Ptr<Packet>>();
272 m_mlmeStartConfirmCallback = MakeNullCallback<void, MlmeStartConfirmParams>();
274 MakeNullCallback<void, MlmeBeaconNotifyIndicationParams>();
275 m_mlmeSyncLossIndicationCallback = MakeNullCallback<void, MlmeSyncLossIndicationParams>();
276 m_mlmePollConfirmCallback = MakeNullCallback<void, MlmePollConfirmParams>();
277 m_mlmeScanConfirmCallback = MakeNullCallback<void, MlmeScanConfirmParams>();
278 m_mlmeAssociateConfirmCallback = MakeNullCallback<void, MlmeAssociateConfirmParams>();
279 m_mlmeAssociateIndicationCallback = MakeNullCallback<void, MlmeAssociateIndicationParams>();
280 m_mlmeCommStatusIndicationCallback = MakeNullCallback<void, MlmeCommStatusIndicationParams>();
281 m_mlmeOrphanIndicationCallback = MakeNullCallback<void, MlmeOrphanIndicationParams>();
282
283 m_panDescriptorList.clear();
284 m_energyDetectList.clear();
285 m_unscannedChannels.clear();
286
291
293}
294
295bool
297{
298 return m_macRxOnWhenIdle;
299}
300
301void
303{
304 NS_LOG_FUNCTION(this << rxOnWhenIdle);
305 m_macRxOnWhenIdle = rxOnWhenIdle;
306
308 {
310 {
311 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
312 }
313 else
314 {
315 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
316 }
317 }
318}
319
320void
322{
323 NS_LOG_FUNCTION(this << address);
324 m_shortAddress = address;
325}
326
327void
329{
330 NS_LOG_FUNCTION(this << address);
331 m_selfExt = address;
332}
333
336{
337 NS_LOG_FUNCTION(this);
338 return m_shortAddress;
339}
340
343{
344 NS_LOG_FUNCTION(this);
345 return m_selfExt;
346}
347
348void
350{
351 NS_LOG_FUNCTION(this << p);
352
353 McpsDataConfirmParams confirmParams;
354 confirmParams.m_msduHandle = params.m_msduHandle;
355
356 // TODO: We need a drop trace for the case that the packet is too large or the request
357 // parameters are maleformed.
358 // The current tx drop trace is not suitable, because packets dropped using this trace
359 // carry the mac header and footer, while packets being dropped here do not have them.
360
362 m_macDsn++;
363
365 {
366 // Note, this is just testing maximum theoretical frame size per the spec
367 // The frame could still be too large once headers are put on
368 // in which case the phy will reject it instead
369 NS_LOG_ERROR(this << " packet too big: " << p->GetSize());
372 {
373 m_mcpsDataConfirmCallback(confirmParams);
374 }
375 return;
376 }
377
378 if ((params.m_srcAddrMode == NO_PANID_ADDR) && (params.m_dstAddrMode == NO_PANID_ADDR))
379 {
380 NS_LOG_ERROR(this << " Can not send packet with no Address field");
383 {
384 m_mcpsDataConfirmCallback(confirmParams);
385 }
386 return;
387 }
388 switch (params.m_srcAddrMode)
389 {
390 case NO_PANID_ADDR:
391 macHdr.SetSrcAddrMode(params.m_srcAddrMode);
392 macHdr.SetNoPanIdComp();
393 break;
395 NS_ABORT_MSG("Can not set source address type to ADDR_MODE_RESERVED. Aborting.");
396 break;
397 case SHORT_ADDR:
398 macHdr.SetSrcAddrMode(params.m_srcAddrMode);
400 break;
401 case EXT_ADDR:
402 macHdr.SetSrcAddrMode(params.m_srcAddrMode);
404 break;
405 default:
406 NS_LOG_ERROR(this << " Can not send packet with incorrect Source Address mode = "
407 << params.m_srcAddrMode);
410 {
411 m_mcpsDataConfirmCallback(confirmParams);
412 }
413 return;
414 }
415 switch (params.m_dstAddrMode)
416 {
417 case NO_PANID_ADDR:
418 macHdr.SetDstAddrMode(params.m_dstAddrMode);
419 macHdr.SetNoPanIdComp();
420 break;
422 NS_ABORT_MSG("Can not set destination address type to ADDR_MODE_RESERVED. Aborting.");
423 break;
424 case SHORT_ADDR:
425 macHdr.SetDstAddrMode(params.m_dstAddrMode);
426 macHdr.SetDstAddrFields(params.m_dstPanId, params.m_dstAddr);
427 break;
428 case EXT_ADDR:
429 macHdr.SetDstAddrMode(params.m_dstAddrMode);
430 macHdr.SetDstAddrFields(params.m_dstPanId, params.m_dstExtAddr);
431 break;
432 default:
433 NS_LOG_ERROR(this << " Can not send packet with incorrect Destination Address mode = "
434 << params.m_dstAddrMode);
437 {
438 m_mcpsDataConfirmCallback(confirmParams);
439 }
440 return;
441 }
442
443 // IEEE 802.15.4-2006 (7.5.6.1)
444 // Src & Dst PANs are identical, PAN compression is ON
445 // only the dst PAN is serialized making the MAC header 2 bytes smaller
446 if ((params.m_dstAddrMode != NO_PANID_ADDR && params.m_srcAddrMode != NO_PANID_ADDR) &&
447 (macHdr.GetDstPanId() == macHdr.GetSrcPanId()))
448 {
449 macHdr.SetPanIdComp();
450 }
451
452 macHdr.SetSecDisable();
453 // extract the first 3 bits in TxOptions
454 int b0 = params.m_txOptions & TX_OPTION_ACK;
455 int b1 = params.m_txOptions & TX_OPTION_GTS;
456 int b2 = params.m_txOptions & TX_OPTION_INDIRECT;
457
458 if (b0 == TX_OPTION_ACK)
459 {
460 // Set AckReq bit only if the destination is not the broadcast address.
461 if (macHdr.GetDstAddrMode() == SHORT_ADDR)
462 {
463 // short address and ACK requested.
464 Mac16Address shortAddr = macHdr.GetShortDstAddr();
465 if (shortAddr.IsBroadcast() || shortAddr.IsMulticast())
466 {
467 NS_LOG_LOGIC("LrWpanMac::McpsDataRequest: requested an ACK on broadcast or "
468 "multicast destination ("
469 << shortAddr << ") - forcefully removing it.");
470 macHdr.SetNoAckReq();
471 params.m_txOptions &= ~uint8_t(TX_OPTION_ACK);
472 }
473 else
474 {
475 macHdr.SetAckReq();
476 }
477 }
478 else
479 {
480 // other address (not short) and ACK requested
481 macHdr.SetAckReq();
482 }
483 }
484 else
485 {
486 macHdr.SetNoAckReq();
487 }
488
489 if (b1 == TX_OPTION_GTS)
490 {
491 // TODO:GTS Transmission
492 }
493 else if (b2 == TX_OPTION_INDIRECT)
494 {
495 // Indirect Tx
496 // A COORDINATOR will save the packet in the pending queue and await for data
497 // requests from its associated devices. The devices are aware of pending data,
498 // from the pending bit information extracted from the received beacon.
499 // A DEVICE must be tracking beacons (MLME-SYNC.request is running) before attempting
500 // request data from the coordinator.
501
502 // Indirect Transmission can only be done by PAN coordinator or coordinators.
504 p->AddHeader(macHdr);
505
506 LrWpanMacTrailer macTrailer;
507 // Calculate FCS if the global attribute ChecksumEnabled is set.
509 {
510 macTrailer.EnableFcs(true);
511 macTrailer.SetFcs(p);
512 }
513 p->AddTrailer(macTrailer);
514
515 NS_LOG_ERROR(this << " Indirect transmissions not currently supported");
516 // Note: The current Pending transaction list should work for indirect transmissions.
517 // However, this is not tested yet. For now, we block the use of indirect transmissions.
518 // TODO: Save packet in the Pending Transaction list.
519 // EnqueueInd (p);
520 }
521 else
522 {
523 // Direct Tx
524 // From this point the packet will be pushed to a Tx queue and immediately
525 // use a slotted (beacon-enabled) or unslotted (nonbeacon-enabled) version of CSMA/CA
526 // before sending the packet, depending on whether it has previously
527 // received a valid beacon or not.
528
529 p->AddHeader(macHdr);
530
531 LrWpanMacTrailer macTrailer;
532 // Calculate FCS if the global attribute ChecksumEnabled is set.
534 {
535 macTrailer.EnableFcs(true);
536 macTrailer.SetFcs(p);
537 }
538 p->AddTrailer(macTrailer);
539
540 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
541 txQElement->txQMsduHandle = params.m_msduHandle;
542 txQElement->txQPkt = p;
543 EnqueueTxQElement(txQElement);
544 CheckQueue();
545 }
546}
547
548void
550{
551 NS_LOG_FUNCTION(this);
553
554 MlmeStartConfirmParams confirmParams;
555
556 if (GetShortAddress() == Mac16Address("ff:ff"))
557 {
558 NS_LOG_ERROR(this << " Invalid MAC short address");
559 confirmParams.m_status = MLMESTART_NO_SHORT_ADDRESS;
561 {
562 m_mlmeStartConfirmCallback(confirmParams);
563 }
564 return;
565 }
566
567 if ((params.m_bcnOrd > 15) || (params.m_sfrmOrd > params.m_bcnOrd))
568 {
571 {
572 m_mlmeStartConfirmCallback(confirmParams);
573 }
574 NS_LOG_ERROR(this << "Incorrect superframe order or beacon order.");
575 return;
576 }
577
578 // Mark primitive as pending and save the start params while the new page and channel is set.
580 m_startParams = params;
581
582 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
583 pibAttr->phyCurrentPage = m_startParams.m_logChPage;
584 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, pibAttr);
585}
586
587void
589{
590 NS_LOG_FUNCTION(this);
591
592 MlmeScanConfirmParams confirmParams;
593 confirmParams.m_scanType = params.m_scanType;
594 confirmParams.m_chPage = params.m_chPage;
595
597 {
599 {
600 confirmParams.m_status = MLMESCAN_SCAN_IN_PROGRESS;
601 m_mlmeScanConfirmCallback(confirmParams);
602 }
603 NS_LOG_ERROR(this << " A channel scan is already in progress");
604 return;
605 }
606
607 if (params.m_scanDuration > 14 || params.m_scanType > MLMESCAN_ORPHAN)
608 {
610 {
611 confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
612 m_mlmeScanConfirmCallback(confirmParams);
613 }
614 NS_LOG_ERROR(this << "Invalid scan duration or unsupported scan type");
615 return;
616 }
617 // Temporary store macPanId and set macPanId to 0xFFFF to accept all beacons.
619 m_macPanId = 0xFFFF;
620
621 m_panDescriptorList.clear();
622 m_energyDetectList.clear();
623 m_unscannedChannels.clear();
624
625 // TODO: stop beacon transmission
626
627 // Cancel any ongoing CSMA/CA operations and set to unslotted mode for scan
628 m_csmaCa->Cancel();
634 m_csmaCa->SetUnSlottedCsmaCa();
635
637
638 // Mark primitive as pending and save the scan params while the new page and/or channel is set.
639 m_scanParams = params;
641
642 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
643 pibAttr->phyCurrentPage = params.m_chPage;
644 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, pibAttr);
645}
646
647void
649{
650 NS_LOG_FUNCTION(this);
651
652 // Association is typically preceded by beacon reception and a MLME-SCAN.request, therefore,
653 // the values of the Associate.request params usually come from the information
654 // obtained from those operations.
656 m_associateParams = params;
657 bool invalidRequest = false;
658
659 if (params.m_coordPanId == 0xffff)
660 {
661 invalidRequest = true;
662 }
663
664 if (!invalidRequest && params.m_coordAddrMode == SHORT_ADDR)
665 {
666 if (params.m_coordShortAddr == Mac16Address("ff:ff") ||
667 params.m_coordShortAddr == Mac16Address("ff:fe"))
668 {
669 invalidRequest = true;
670 }
671 }
672 else if (!invalidRequest && params.m_coordAddrMode == EXT_ADDR)
673 {
674 if (params.m_coordExtAddr == Mac64Address("ff:ff:ff:ff:ff:ff:ff:ff") ||
675 params.m_coordExtAddr == Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed"))
676 {
677 invalidRequest = true;
678 }
679 }
680
681 if (invalidRequest)
682 {
685 NS_LOG_ERROR(this << " Invalid PAN id in Association request");
687 {
688 MlmeAssociateConfirmParams confirmParams;
689 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
691 m_mlmeAssociateConfirmCallback(confirmParams);
692 }
693 }
694 else
695 {
696 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
697 pibAttr->phyCurrentPage = params.m_chPage;
698 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, pibAttr);
699 }
700}
701
702void
704{
705 // the primitive is no longer pending (channel & page are set)
707 // As described in IEEE 802.15.4-2011 (Section 5.1.3.1)
710 {
712 }
713 else
714 {
717 }
718
720}
721
722void
724{
725 // Associate Short Address (m_assocShortAddr)
726 // FF:FF = Association Request failed
727 // FF:FE = The association request is accepted, but the device should use its extended address
728 // Other = The assigned short address by the coordinator
729
730 NS_LOG_FUNCTION(this);
731
733 m_macDsn++;
734 LrWpanMacTrailer macTrailer;
735 Ptr<Packet> commandPacket = Create<Packet>();
736
737 // Mac header Assoc. Response Comm. See 802.15.4-2011 (Section 5.3.2.1)
740 macHdr.SetPanIdComp();
741 macHdr.SetDstAddrFields(m_macPanId, params.m_extDevAddr);
742 macHdr.SetSrcAddrFields(0xffff, GetExtendedAddress());
743
745 macPayload.SetShortAddr(params.m_assocShortAddr);
746 switch (params.m_status)
747 {
750 break;
753 break;
756 break;
758 NS_LOG_ERROR("Error, Associated without address");
759 break;
761 NS_LOG_ERROR("Error, device not associated");
762 break;
763 }
764
765 macHdr.SetSecDisable();
766 macHdr.SetAckReq();
767
768 commandPacket->AddHeader(macPayload);
769 commandPacket->AddHeader(macHdr);
770
771 // Calculate FCS if the global attribute ChecksumEnabled is set.
773 {
774 macTrailer.EnableFcs(true);
775 macTrailer.SetFcs(commandPacket);
776 }
777
778 commandPacket->AddTrailer(macTrailer);
779
780 // Save packet in the Pending Transaction list.
781 EnqueueInd(commandPacket);
782}
783
784void
786{
787 NS_LOG_FUNCTION(this);
788 // Mac header Coordinator realigment Command
789 // See 802.15.4-2011 (Section 6.2.7.2)
791 m_macDsn++;
792 LrWpanMacTrailer macTrailer;
793 Ptr<Packet> commandPacket = Create<Packet>();
794 macHdr.SetPanIdComp();
796 macHdr.SetDstAddrFields(0xffff, params.m_orphanAddr);
797
800 macHdr.SetSrcAddrFields(m_macPanId, Mac16Address("FF:FF"));
801
802 macHdr.SetFrameVer(0x01);
803 macHdr.SetSecDisable();
804 macHdr.SetAckReq();
805
807 macPayload.SetPanId(m_macPanId);
809 macPayload.SetChannel(m_phy->GetCurrentChannelNum());
810 macPayload.SetPage(m_phy->GetCurrentPage());
811
812 if (params.m_assocMember)
813 {
814 // The orphan device was associated with the coordinator
815
816 // Either FF:FE for extended address mode
817 // or the short address assigned by the coord.
818 macPayload.SetShortAddr(params.m_shortAddr);
819 }
820 else
821 {
822 // The orphan device was NOT associated with the coordinator
823 macPayload.SetShortAddr(Mac16Address("FF:FF"));
824 }
825
826 commandPacket->AddHeader(macPayload);
827 commandPacket->AddHeader(macHdr);
828
829 // Calculate FCS if the global attribute ChecksumEnabled is set.
831 {
832 macTrailer.EnableFcs(true);
833 macTrailer.SetFcs(commandPacket);
834 }
835
836 commandPacket->AddTrailer(macTrailer);
837
838 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
839 txQElement->txQPkt = commandPacket;
840 EnqueueTxQElement(txQElement);
841 CheckQueue();
842}
843
844void
846{
847 NS_LOG_FUNCTION(this);
848 NS_ASSERT(params.m_logCh <= 26 && m_macPanId != 0xffff);
849
850 uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
851 // change phy current logical channel
852 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
853 pibAttr->phyCurrentChannel = params.m_logCh;
854 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, pibAttr);
855
856 // Enable Phy receiver
857 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
858
859 uint64_t searchSymbols;
860 Time searchBeaconTime;
861
863 {
865 }
866
867 if (params.m_trackBcn)
868 {
870 // search for a beacon for a time = incomingSuperframe symbols + 960 symbols
871 searchSymbols =
873 searchBeaconTime = Seconds((double)searchSymbols / symbolRate);
874 m_beaconTrackingOn = true;
876 Simulator::Schedule(searchBeaconTime, &LrWpanMac::BeaconSearchTimeout, this);
877 }
878 else
879 {
880 m_beaconTrackingOn = false;
881 }
882}
883
884void
886{
887 NS_LOG_FUNCTION(this);
888
890 m_macBsn++;
891
893
894 Ptr<Packet> beaconPacket = Create<Packet>();
895 // TODO: complete poll request (part of indirect transmissions)
896 NS_FATAL_ERROR(this << " Poll request currently not supported");
897}
898
899void
901{
902 MlmeSetConfirmParams confirmParams;
903 confirmParams.m_status = MLMESET_SUCCESS;
904
905 switch (id)
906 {
907 case macBeaconPayload:
908 if (attribute->macBeaconPayload->GetSize() > lrwpan::aMaxBeaconPayloadLength)
909 {
910 confirmParams.m_status = MLMESET_INVALID_PARAMETER;
911 }
912 else
913 {
914 m_macBeaconPayload = attribute->macBeaconPayload;
915 m_macBeaconPayloadLength = attribute->macBeaconPayload->GetSize();
916 }
917 break;
919 confirmParams.m_status = MLMESET_INVALID_PARAMETER;
920 break;
921 case macShortAddress:
922 m_shortAddress = attribute->macShortAddress;
923 break;
925 confirmParams.m_status = MLMESET_READ_ONLY;
926 break;
927 case macPanId:
929 break;
930 default:
931 // TODO: Add support for setting other attributes
933 break;
934 }
935
937 {
938 confirmParams.id = id;
939 m_mlmeSetConfirmCallback(confirmParams);
940 }
941}
942
943void
945{
947 Ptr<LrWpanMacPibAttributes> attributes = Create<LrWpanMacPibAttributes>();
948
949 switch (id)
950 {
951 case macBeaconPayload:
952 attributes->macBeaconPayload = m_macBeaconPayload;
953 break;
955 attributes->macBeaconPayloadLength = m_macBeaconPayloadLength;
956 break;
957 case macShortAddress:
958 attributes->macShortAddress = m_shortAddress;
959 break;
961 attributes->macExtendedAddress = m_selfExt;
962 break;
963 case macPanId:
964 attributes->macPanId = m_macPanId;
965 break;
966 default:
968 break;
969 }
970
972 {
973 m_mlmeGetConfirmCallback(status, id, attributes);
974 }
975}
976
977void
979{
980 NS_LOG_FUNCTION(this);
982
984 m_macBsn++;
985 BeaconPayloadHeader macPayload;
986 Ptr<Packet> beaconPacket;
987 LrWpanMacTrailer macTrailer;
988
989 if (m_macBeaconPayload == nullptr)
990 {
991 beaconPacket = Create<Packet>();
992 }
993 else
994 {
995 beaconPacket = m_macBeaconPayload;
996 }
997
999 macHdr.SetDstAddrFields(GetPanId(), Mac16Address("ff:ff"));
1000
1001 // see IEEE 802.15.4-2011 Section 5.1.2.4
1002 if (GetShortAddress() == Mac16Address("ff:fe"))
1003 {
1006 }
1007 else
1008 {
1011 }
1012
1013 macHdr.SetSecDisable();
1014 macHdr.SetNoAckReq();
1015
1017 macPayload.SetGtsFields(GetGtsFields());
1019
1020 beaconPacket->AddHeader(macPayload);
1021 beaconPacket->AddHeader(macHdr);
1022
1023 // Calculate FCS if the global attribute ChecksumEnabled is set.
1025 {
1026 macTrailer.EnableFcs(true);
1027 macTrailer.SetFcs(beaconPacket);
1028 }
1029
1030 beaconPacket->AddTrailer(macTrailer);
1031
1032 // Set the Beacon packet to be transmitted
1033 m_txPkt = beaconPacket;
1034
1035 if (m_csmaCa->IsSlottedCsmaCa())
1036 {
1038 NS_LOG_DEBUG("Outgoing superframe Active Portion (Beacon + CAP + CFP): "
1039 << m_superframeDuration << " symbols");
1040 }
1041
1043 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
1044}
1045
1046void
1048{
1049 NS_LOG_FUNCTION(this);
1050
1052 m_macDsn++;
1053 LrWpanMacTrailer macTrailer;
1054 Ptr<Packet> commandPacket = Create<Packet>();
1055
1056 // Beacon Request Command Mac header values See IEEE 802.15.4-2011 (Section 5.3.7)
1057 macHdr.SetNoPanIdComp();
1060
1061 // Not associated PAN, broadcast dst address
1062 macHdr.SetDstAddrFields(0xFFFF, Mac16Address("FF:FF"));
1063
1064 macHdr.SetSecDisable();
1065 macHdr.SetNoAckReq();
1066
1067 CommandPayloadHeader macPayload;
1069
1070 commandPacket->AddHeader(macPayload);
1071 commandPacket->AddHeader(macHdr);
1072
1073 // Calculate FCS if the global attribute ChecksumEnabled is set.
1075 {
1076 macTrailer.EnableFcs(true);
1077 macTrailer.SetFcs(commandPacket);
1078 }
1079
1080 commandPacket->AddTrailer(macTrailer);
1081
1082 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1083 txQElement->txQPkt = commandPacket;
1084 EnqueueTxQElement(txQElement);
1085 CheckQueue();
1086}
1087
1088void
1090{
1092 m_macDsn++;
1093 LrWpanMacTrailer macTrailer;
1094 Ptr<Packet> commandPacket = Create<Packet>();
1095
1096 // See IEEE 802.15.4-2011 (5.3.6)
1097 macHdr.SetPanIdComp();
1098
1100 macHdr.SetSrcAddrFields(0xFFFF, GetExtendedAddress());
1101
1103 macHdr.SetDstAddrFields(0xFFFF, Mac16Address("FF:FF"));
1104
1105 macHdr.SetSecDisable();
1106 macHdr.SetNoAckReq();
1107
1108 CommandPayloadHeader macPayload;
1110
1111 commandPacket->AddHeader(macPayload);
1112 commandPacket->AddHeader(macHdr);
1113
1114 // Calculate FCS if the global attribute ChecksumEnabled is set.
1116 {
1117 macTrailer.EnableFcs(true);
1118 macTrailer.SetFcs(commandPacket);
1119 }
1120
1121 commandPacket->AddTrailer(macTrailer);
1122
1123 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1124 txQElement->txQPkt = commandPacket;
1125 EnqueueTxQElement(txQElement);
1126 CheckQueue();
1127}
1128
1129void
1131{
1132 NS_LOG_FUNCTION(this);
1133
1135 m_macDsn++;
1136 LrWpanMacTrailer macTrailer;
1137 Ptr<Packet> commandPacket = Create<Packet>();
1138
1139 // Assoc. Req. Comm. Mac header values See IEEE 802.15.4-2011 (Section 5.3.1.1)
1141 macHdr.SetSrcAddrFields(0xffff, GetExtendedAddress());
1142
1144 {
1147 }
1148 else
1149 {
1152 }
1153
1154 macHdr.SetSecDisable();
1155 macHdr.SetAckReq();
1156
1159
1160 commandPacket->AddHeader(macPayload);
1161 commandPacket->AddHeader(macHdr);
1162
1163 // Calculate FCS if the global attribute ChecksumEnabled is set.
1165 {
1166 macTrailer.EnableFcs(true);
1167 macTrailer.SetFcs(commandPacket);
1168 }
1169
1170 commandPacket->AddTrailer(macTrailer);
1171
1172 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1173 txQElement->txQPkt = commandPacket;
1174 EnqueueTxQElement(txQElement);
1175 CheckQueue();
1176}
1177
1178void
1180{
1181 // See IEEE 802.15.4-2011 (Section 5.3.5)
1182 // This command can be sent for 3 different situations:
1183 // a) In response to a beacon indicating that there is data for the device.
1184 // b) Triggered by MLME-POLL.request.
1185 // c) To follow an ACK of an Association Request command and continue the associate process.
1186
1187 // TODO: Implementation of a) and b) will be done when Indirect transmissions are fully
1188 // supported.
1189 // for now, only case c) is considered.
1190
1191 NS_LOG_FUNCTION(this);
1192
1194 m_macDsn++;
1195 LrWpanMacTrailer macTrailer;
1196 Ptr<Packet> commandPacket = Create<Packet>();
1197
1198 // Mac Header values (Section 5.3.5)
1200 macHdr.SetSrcAddrFields(0xffff, m_selfExt);
1201
1202 if (m_macCoordShortAddress == Mac16Address("ff:fe"))
1203 {
1206 }
1207 else
1208 {
1211 }
1212
1213 macHdr.SetSecDisable();
1214 macHdr.SetAckReq();
1215
1217
1218 commandPacket->AddHeader(macPayload);
1219 commandPacket->AddHeader(macHdr);
1220
1221 // Calculate FCS if the global attribute ChecksumEnabled is set.
1223 {
1224 macTrailer.EnableFcs(true);
1225 macTrailer.SetFcs(commandPacket);
1226 }
1227
1228 commandPacket->AddTrailer(macTrailer);
1229
1230 // Set the Command packet to be transmitted
1231 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1232 txQElement->txQPkt = commandPacket;
1233 EnqueueTxQElement(txQElement);
1234 CheckQueue();
1235}
1236
1237void
1239{
1240 LrWpanMacHeader receivedMacHdr;
1241 rxDataReqPkt->RemoveHeader(receivedMacHdr);
1242 CommandPayloadHeader receivedMacPayload;
1243 rxDataReqPkt->RemoveHeader(receivedMacPayload);
1244
1246
1247 Ptr<IndTxQueueElement> indTxQElement = Create<IndTxQueueElement>();
1248 bool elementFound;
1249 elementFound = DequeueInd(receivedMacHdr.GetExtSrcAddr(), indTxQElement);
1250 if (elementFound)
1251 {
1252 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1253 txQElement->txQPkt = indTxQElement->txQPkt;
1254 m_txQueue.emplace_back(txQElement);
1255 }
1256 else
1257 {
1258 NS_LOG_DEBUG("Requested element not found in pending list");
1259 }
1260}
1261
1262void
1264{
1265 // Association response command was not received, return to default values.
1266 m_macPanId = 0xffff;
1268 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
1269
1271 {
1272 MlmeAssociateConfirmParams confirmParams;
1273 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
1274 confirmParams.m_status = MLMEASSOC_NO_DATA;
1275 m_mlmeAssociateConfirmCallback(confirmParams);
1276 }
1277}
1278
1279void
1281{
1282 NS_LOG_FUNCTION(this);
1283 // The primitive is no longer pending (Channel & Page have been set)
1285
1286 if (m_startParams.m_coorRealgn) // Coordinator Realignment
1287 {
1288 // TODO: Send realignment request command frame in CSMA/CA
1289 NS_LOG_ERROR(this << " Coordinator realignment request not supported");
1290 return;
1291 }
1292 else
1293 {
1295 {
1296 m_panCoor = true;
1297 }
1298
1299 m_coor = true;
1301
1302 NS_ASSERT(m_startParams.m_PanId != 0xffff);
1303
1305 if (m_macBeaconOrder == 15)
1306 {
1307 // Non-beacon enabled PAN
1308 // Cancel any ongoing events and CSMA-CA process
1310 m_fnlCapSlot = 15;
1311 m_beaconInterval = 0;
1312
1313 m_csmaCa->Cancel();
1322
1323 m_csmaCa->SetUnSlottedCsmaCa();
1324
1326 {
1327 MlmeStartConfirmParams confirmParams;
1328 confirmParams.m_status = MLMESTART_SUCCESS;
1329 m_mlmeStartConfirmCallback(confirmParams);
1330 }
1331
1332 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
1333 }
1334 else
1335 {
1337 m_csmaCa->SetBatteryLifeExtension(m_startParams.m_battLifeExt);
1338
1339 m_csmaCa->SetSlottedCsmaCa();
1340
1341 // TODO: Calculate the real Final CAP slot (requires GTS implementation)
1342 // FinalCapSlot = Superframe duration slots - CFP slots.
1343 // In the current implementation the value of the final cap slot is equal to
1344 // the total number of possible slots in the superframe (15).
1345 m_fnlCapSlot = 15;
1346
1349 m_superframeDuration = (static_cast<uint32_t>(1 << m_macSuperframeOrder)) *
1351
1352 // TODO: change the beacon sending according to the startTime parameter (if not PAN
1353 // coordinator)
1354
1356 }
1357 }
1358}
1359
1360void
1362{
1363 NS_LOG_FUNCTION(this);
1364
1366
1367 bool channelFound = false;
1368
1369 for (int i = m_channelScanIndex; i <= 26; i++)
1370 {
1372 {
1373 channelFound = true;
1374 break;
1375 }
1377 }
1378
1379 if (channelFound)
1380 {
1381 // Switch to the next channel in the list and restart scan
1382 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
1383 pibAttr->phyCurrentChannel = m_channelScanIndex;
1384 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, pibAttr);
1385 }
1386 else
1387 {
1388 // All channels in the list scan completed.
1389 // Return variables to the values before the scan and return the status to the next layer.
1391 m_macPanIdScan = 0;
1392
1393 // TODO: restart beacon transmissions that were active before the beginning of the scan
1394 // (i.e when a coordinator perform a scan and it was already transmitting beacons)
1395 MlmeScanConfirmParams confirmParams;
1396 confirmParams.m_chPage = m_scanParams.m_chPage;
1397 confirmParams.m_scanType = m_scanParams.m_scanType;
1398 confirmParams.m_energyDetList = {};
1399 confirmParams.m_unscannedCh = m_unscannedChannels;
1400 confirmParams.m_resultListSize = m_panDescriptorList.size();
1401
1402 // See IEEE 802.15.4-2011, Table 31 (panDescriptorList value on macAutoRequest)
1403 // and Section 6.2.10.2
1404 switch (confirmParams.m_scanType)
1405 {
1406 case MLMESCAN_PASSIVE:
1407 if (m_macAutoRequest)
1408 {
1409 confirmParams.m_panDescList = m_panDescriptorList;
1410 }
1411 confirmParams.m_status = MLMESCAN_SUCCESS;
1412 break;
1413 case MLMESCAN_ACTIVE:
1414 if (m_panDescriptorList.empty())
1415 {
1416 confirmParams.m_status = MLMESCAN_NO_BEACON;
1417 }
1418 else
1419 {
1420 if (m_macAutoRequest)
1421 {
1422 confirmParams.m_panDescList = m_panDescriptorList;
1423 }
1424 confirmParams.m_status = MLMESCAN_SUCCESS;
1425 }
1426 break;
1427 case MLMESCAN_ORPHAN:
1428 confirmParams.m_panDescList = {};
1429 confirmParams.m_status = MLMESCAN_NO_BEACON;
1430 confirmParams.m_resultListSize = 0;
1431 // The device lost track of the coordinator and was unable
1432 // to locate it, disassociate from the network.
1433 m_macPanId = 0xffff;
1434 m_shortAddress = Mac16Address("FF:FF");
1436 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
1437 break;
1438 default:
1439 NS_LOG_ERROR(this << " Invalid scan type");
1440 }
1441
1444 m_scanParams = {};
1445
1447 {
1448 m_mlmeScanConfirmCallback(confirmParams);
1449 }
1450 }
1451}
1452
1453void
1455{
1456 NS_LOG_FUNCTION(this);
1457 // Add the results of channel energy scan to the detectList
1459 m_maxEnergyLevel = 0;
1460
1462
1463 bool channelFound = false;
1464 for (int i = m_channelScanIndex; i <= 26; i++)
1465 {
1467 {
1468 channelFound = true;
1469 break;
1470 }
1472 }
1473
1474 if (channelFound)
1475 {
1476 // switch to the next channel in the list and restart scan
1477 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
1478 pibAttr->phyCurrentChannel = m_channelScanIndex;
1479 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, pibAttr);
1480 }
1481 else
1482 {
1483 // Scan on all channels on the list completed
1484 // Return to the MAC values previous to start of the first scan.
1486 m_macPanIdScan = 0;
1487
1488 // TODO: restart beacon transmissions that were active before the beginning of the scan
1489 // (i.e when a coordinator perform a scan and it was already transmitting beacons)
1490
1491 // All channels scanned, report success
1492 MlmeScanConfirmParams confirmParams;
1493 confirmParams.m_status = MLMESCAN_SUCCESS;
1494 confirmParams.m_chPage = m_phy->GetCurrentPage();
1495 confirmParams.m_scanType = m_scanParams.m_scanType;
1496 confirmParams.m_energyDetList = m_energyDetectList;
1497 confirmParams.m_resultListSize = m_energyDetectList.size();
1498
1501 m_scanParams = {};
1502
1504 {
1505 m_mlmeScanConfirmCallback(confirmParams);
1506 }
1507 }
1508}
1509
1510void
1512{
1513 uint32_t activeSlot;
1514 uint64_t capDuration;
1515 Time endCapTime;
1516 uint64_t symbolRate;
1517
1518 symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1519
1520 if (superframeType == OUTGOING)
1521 {
1523 activeSlot = m_superframeDuration / 16;
1524 capDuration = activeSlot * (m_fnlCapSlot + 1);
1525 endCapTime = Seconds((double)capDuration / symbolRate);
1526 // Obtain the end of the CAP by adjust the time it took to send the beacon
1527 endCapTime -= (Simulator::Now() - m_macBeaconTxTime);
1528
1529 NS_LOG_DEBUG("Outgoing superframe CAP duration " << (endCapTime.GetSeconds() * symbolRate)
1530 << " symbols (" << endCapTime.As(Time::S)
1531 << ")");
1532 NS_LOG_DEBUG("Active Slots duration " << activeSlot << " symbols");
1533
1534 m_capEvent =
1536 }
1537 else
1538 {
1540 activeSlot = m_incomingSuperframeDuration / 16;
1541 capDuration = activeSlot * (m_incomingFnlCapSlot + 1);
1542 endCapTime = Seconds((double)capDuration / symbolRate);
1543 // Obtain the end of the CAP by adjust the time it took to receive the beacon
1544 endCapTime -= (Simulator::Now() - m_macBeaconRxTime);
1545
1546 NS_LOG_DEBUG("Incoming superframe CAP duration " << (endCapTime.GetSeconds() * symbolRate)
1547 << " symbols (" << endCapTime.As(Time::S)
1548 << ")");
1549 NS_LOG_DEBUG("Active Slots duration " << activeSlot << " symbols");
1550
1551 m_capEvent =
1553 }
1554
1555 CheckQueue();
1556}
1557
1558void
1560{
1561 uint32_t activeSlot;
1562 uint64_t cfpDuration;
1563 Time endCfpTime;
1564 uint64_t symbolRate;
1565
1566 symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1567
1568 if (superframeType == INCOMING)
1569 {
1570 activeSlot = m_incomingSuperframeDuration / 16;
1571 cfpDuration = activeSlot * (15 - m_incomingFnlCapSlot);
1572 endCfpTime = Seconds((double)cfpDuration / symbolRate);
1573 if (cfpDuration > 0)
1574 {
1576 }
1577
1578 NS_LOG_DEBUG("Incoming superframe CFP duration " << cfpDuration << " symbols ("
1579 << endCfpTime.As(Time::S) << ")");
1580
1583 this,
1585 }
1586 else
1587 {
1588 activeSlot = m_superframeDuration / 16;
1589 cfpDuration = activeSlot * (15 - m_fnlCapSlot);
1590 endCfpTime = Seconds((double)cfpDuration / symbolRate);
1591
1592 if (cfpDuration > 0)
1593 {
1595 }
1596
1597 NS_LOG_DEBUG("Outgoing superframe CFP duration " << cfpDuration << " symbols ("
1598 << endCfpTime.As(Time::S) << ")");
1599
1600 m_cfpEvent = Simulator::Schedule(endCfpTime,
1602 this,
1604 }
1605 // TODO: Start transmit or receive GTS here.
1606}
1607
1608void
1610{
1611 uint64_t inactiveDuration;
1612 Time endInactiveTime;
1613 uint64_t symbolRate;
1614
1615 symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1616
1617 if (superframeType == INCOMING)
1618 {
1620 endInactiveTime = Seconds((double)inactiveDuration / symbolRate);
1621
1622 if (inactiveDuration > 0)
1623 {
1625 }
1626
1627 NS_LOG_DEBUG("Incoming superframe Inactive Portion duration "
1628 << inactiveDuration << " symbols (" << endInactiveTime.As(Time::S) << ")");
1629 m_beaconEvent = Simulator::Schedule(endInactiveTime, &LrWpanMac::AwaitBeacon, this);
1630 }
1631 else
1632 {
1633 inactiveDuration = m_beaconInterval - m_superframeDuration;
1634 endInactiveTime = Seconds((double)inactiveDuration / symbolRate);
1635
1636 if (inactiveDuration > 0)
1637 {
1639 }
1640
1641 NS_LOG_DEBUG("Outgoing superframe Inactive Portion duration "
1642 << inactiveDuration << " symbols (" << endInactiveTime.As(Time::S) << ")");
1644 }
1645}
1646
1647void
1649{
1651
1652 // TODO: If the device waits more than the expected time to receive the beacon (wait = 46
1653 // symbols for default beacon size)
1654 // it should continue with the start of the incoming CAP even if it did not receive the
1655 // beacon. At the moment, the start of the incoming CAP is only triggered if the beacon is
1656 // received. See MLME-SyncLoss for details.
1657}
1658
1659void
1661{
1662 uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1663
1665 {
1666 MlmeSyncLossIndicationParams syncLossParams;
1667 // syncLossParams.m_logCh =
1668 syncLossParams.m_lossReason = MLMESYNCLOSS_BEACON_LOST;
1669 syncLossParams.m_panId = m_macPanId;
1670 m_mlmeSyncLossIndicationCallback(syncLossParams);
1671
1672 m_beaconTrackingOn = false;
1673 m_numLostBeacons = 0;
1674 }
1675 else
1676 {
1678
1679 // Search for one more beacon
1680 uint64_t searchSymbols;
1681 Time searchBeaconTime;
1682 searchSymbols =
1684 searchBeaconTime = Seconds((double)searchSymbols / symbolRate);
1686 Simulator::Schedule(searchBeaconTime, &LrWpanMac::BeaconSearchTimeout, this);
1687 }
1688}
1689
1690void
1692{
1693 NS_LOG_FUNCTION(this);
1694 // Pull a packet from the queue and start sending if we are not already sending.
1696 {
1697 if (m_csmaCa->IsUnSlottedCsmaCa() || (m_outSuperframeStatus == CAP && m_coor) ||
1699 {
1700 // check MAC is not in a IFS
1701 if (!m_ifsEvent.IsRunning())
1702 {
1703 Ptr<TxQueueElement> txQElement = m_txQueue.front();
1704 m_txPkt = txQElement->txQPkt;
1705
1708 }
1709 }
1710 }
1711}
1712
1715{
1716 SuperframeField sfrmSpec;
1717
1720 sfrmSpec.SetFinalCapSlot(m_fnlCapSlot);
1721
1722 if (m_csmaCa->GetBatteryLifeExtension())
1723 {
1724 sfrmSpec.SetBattLifeExt(true);
1725 }
1726
1727 if (m_panCoor)
1728 {
1729 sfrmSpec.SetPanCoor(true);
1730 }
1731
1732 // used to associate devices via Beacons
1734 {
1735 sfrmSpec.SetAssocPermit(true);
1736 }
1737
1738 return sfrmSpec;
1739}
1740
1743{
1744 GtsFields gtsFields;
1745
1746 // TODO: Logic to populate the GTS Fields from local information here
1747
1748 return gtsFields;
1749}
1750
1753{
1754 PendingAddrFields pndAddrFields;
1755
1756 // TODO: Logic to populate the Pending Address Fields from local information here
1757 return pndAddrFields;
1758}
1759
1760void
1762{
1763 m_csmaCa = csmaCa;
1764}
1765
1766void
1768{
1769 m_phy = phy;
1770}
1771
1774{
1775 return m_phy;
1776}
1777
1778void
1780{
1782}
1783
1784void
1786{
1788}
1789
1790void
1792{
1794}
1795
1796void
1798{
1800}
1801
1802void
1804{
1806}
1807
1808void
1810{
1812}
1813
1814void
1816{
1818}
1819
1820void
1822{
1824}
1825
1826void
1828{
1830}
1831
1832void
1834{
1836}
1837
1838void
1840{
1842}
1843
1844void
1846{
1848}
1849
1850void
1852{
1854}
1855
1856void
1858{
1861 NS_LOG_FUNCTION(this << psduLength << p << (uint16_t)lqi);
1862
1863 bool acceptFrame;
1864
1865 // from sec 7.5.6.2 Reception and rejection, Std802.15.4-2006
1866 // level 1 filtering, test FCS field and reject if frame fails
1867 // level 2 filtering if promiscuous mode pass frame to higher layer otherwise perform level 3
1868 // filtering level 3 filtering accept frame if Frame type and version is not reserved, and if
1869 // there is a dstPanId then dstPanId=m_macPanId or broadcastPanId, and if there is a
1870 // shortDstAddr then shortDstAddr =shortMacAddr or broadcastAddr, and if beacon frame then
1871 // srcPanId = m_macPanId if only srcAddr field in Data or Command frame,accept frame if
1872 // srcPanId=m_macPanId
1873
1874 Ptr<Packet> originalPkt = p->Copy(); // because we will strip headers
1875 uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1876 m_promiscSnifferTrace(originalPkt);
1877
1878 m_macPromiscRxTrace(originalPkt);
1879 // XXX no rejection tracing (to macRxDropTrace) being performed below
1880
1881 LrWpanMacTrailer receivedMacTrailer;
1882 p->RemoveTrailer(receivedMacTrailer);
1884 {
1885 receivedMacTrailer.EnableFcs(true);
1886 }
1887
1888 // level 1 filtering
1889 if (!receivedMacTrailer.CheckFcs(p))
1890 {
1891 m_macRxDropTrace(originalPkt);
1892 }
1893 else
1894 {
1895 LrWpanMacHeader receivedMacHdr;
1896 p->RemoveHeader(receivedMacHdr);
1897
1899 params.m_dsn = receivedMacHdr.GetSeqNum();
1900 params.m_mpduLinkQuality = lqi;
1901 params.m_srcPanId = receivedMacHdr.GetSrcPanId();
1902 params.m_srcAddrMode = receivedMacHdr.GetSrcAddrMode();
1903 switch (params.m_srcAddrMode)
1904 {
1905 case SHORT_ADDR:
1906 params.m_srcAddr = receivedMacHdr.GetShortSrcAddr();
1907 break;
1908 case EXT_ADDR:
1909 params.m_srcExtAddr = receivedMacHdr.GetExtSrcAddr();
1910 break;
1911 default:
1912 break;
1913 }
1914 params.m_dstPanId = receivedMacHdr.GetDstPanId();
1915 params.m_dstAddrMode = receivedMacHdr.GetDstAddrMode();
1916 switch (params.m_dstAddrMode)
1917 {
1918 case SHORT_ADDR:
1919 params.m_dstAddr = receivedMacHdr.GetShortDstAddr();
1920 break;
1921 case EXT_ADDR:
1922 params.m_dstExtAddr = receivedMacHdr.GetExtDstAddr();
1923 break;
1924 default:
1925 break;
1926 }
1927
1929 {
1930 // level 2 filtering
1931 if (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR)
1932 {
1933 NS_LOG_DEBUG("Packet from " << params.m_srcAddr);
1934 NS_LOG_DEBUG("Packet to " << params.m_dstAddr);
1935 }
1936 else if (receivedMacHdr.GetDstAddrMode() == EXT_ADDR)
1937 {
1938 NS_LOG_DEBUG("Packet from " << params.m_srcExtAddr);
1939 NS_LOG_DEBUG("Packet to " << params.m_dstExtAddr);
1940 }
1941
1942 // TODO: Fix here, this should trigger different Indication Callbacks
1943 // depending the type of frame received (data,command, beacon)
1945 {
1946 NS_LOG_DEBUG("promiscuous mode, forwarding up");
1948 }
1949 else
1950 {
1951 NS_LOG_ERROR(this << " Data Indication Callback not initialized");
1952 }
1953 }
1954 else
1955 {
1956 // level 3 frame filtering
1957 acceptFrame = (receivedMacHdr.GetType() != LrWpanMacHeader::LRWPAN_MAC_RESERVED);
1958
1959 if (acceptFrame)
1960 {
1961 acceptFrame = (receivedMacHdr.GetFrameVer() <= 1);
1962 }
1963
1964 if (acceptFrame && (receivedMacHdr.GetDstAddrMode() > 1))
1965 {
1966 // Accept frame if one of the following is true:
1967
1968 // 1) Have the same macPanId
1969 // 2) Is Message to all PANs
1970 // 3) Is a beacon or command frame and the macPanId is not present (bootstrap)
1971 acceptFrame = ((receivedMacHdr.GetDstPanId() == m_macPanId ||
1972 receivedMacHdr.GetDstPanId() == 0xffff) ||
1973 (m_macPanId == 0xffff && receivedMacHdr.IsBeacon())) ||
1974 (m_macPanId == 0xffff && receivedMacHdr.IsCommand());
1975 }
1976
1977 if (acceptFrame && (receivedMacHdr.GetShortDstAddr() == Mac16Address("FF:FF")))
1978 {
1979 // TODO: shouldn't this be filtered by the PHY?
1980 // A broadcast message (e.g. beacons, orphan notifications) should not be received
1981 // by the device who issues it.
1982 if (receivedMacHdr.GetSrcAddrMode() == EXT_ADDR)
1983 {
1984 acceptFrame = (receivedMacHdr.GetExtSrcAddr() != GetExtendedAddress());
1985 }
1986 else
1987 {
1988 acceptFrame = (receivedMacHdr.GetShortSrcAddr() != GetShortAddress());
1989 }
1990 }
1991
1992 if (acceptFrame && (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR))
1993 {
1994 if (receivedMacHdr.GetShortDstAddr() == m_shortAddress)
1995 {
1996 // unicast, for me
1997 acceptFrame = true;
1998 }
1999 else if (receivedMacHdr.GetShortDstAddr().IsBroadcast() ||
2000 receivedMacHdr.GetShortDstAddr().IsMulticast())
2001 {
2002 // Broadcast or multicast.
2003 // Discard broadcast/multicast with the ACK bit set.
2004 acceptFrame = !receivedMacHdr.IsAckReq();
2005 }
2006 else
2007 {
2008 acceptFrame = false;
2009 }
2010 }
2011
2012 if (acceptFrame && (receivedMacHdr.GetDstAddrMode() == EXT_ADDR))
2013 {
2014 acceptFrame = (receivedMacHdr.GetExtDstAddr() == m_selfExt);
2015 }
2016
2017 if (acceptFrame && m_scanEvent.IsRunning())
2018 {
2019 if (!receivedMacHdr.IsBeacon())
2020 {
2021 acceptFrame = false;
2022 }
2023 }
2024 else if (acceptFrame && m_scanOrphanEvent.IsRunning())
2025 {
2026 if (!receivedMacHdr.IsCommand())
2027 {
2028 acceptFrame = false;
2029 }
2030 }
2031 else if (m_scanEnergyEvent.IsRunning())
2032 {
2033 // Reject any frames if energy scan is running
2034 acceptFrame = false;
2035 }
2036
2037 // Check device is panCoor with association permit when receiving Association Request
2038 // Commands.
2039 // TODO:: Simple coordinators should also be able to receive it (currently only Pan
2040 // Coordinators are checked)
2041 if (acceptFrame && (receivedMacHdr.IsCommand() && receivedMacHdr.IsAckReq()))
2042 {
2043 CommandPayloadHeader receivedMacPayload;
2044 p->PeekHeader(receivedMacPayload);
2045
2046 if (receivedMacPayload.GetCommandFrameType() ==
2049 {
2050 acceptFrame = false;
2051 }
2052
2053 // Although ACKs do not use CSMA to to be transmitted, we need to make sure
2054 // that the transmitted ACK will not collide with the transmission of a beacon
2055 // when beacon-enabled mode is running in the coordinator.
2056 if (acceptFrame && (m_csmaCa->IsSlottedCsmaCa() && m_capEvent.IsRunning()))
2057 {
2058 Time timeLeftInCap = Simulator::GetDelayLeft(m_capEvent);
2059 uint64_t ackSymbols = lrwpan::aTurnaroundTime + m_phy->GetPhySHRDuration() +
2060 ceil(6 * m_phy->GetPhySymbolsPerOctet());
2061 Time ackTime = Seconds((double)ackSymbols / symbolRate);
2062
2063 if (ackTime >= timeLeftInCap)
2064 {
2065 NS_LOG_DEBUG("Command frame received but not enough time to transmit ACK "
2066 "before the end of CAP ");
2067 acceptFrame = false;
2068 }
2069 }
2070 }
2071
2072 if (acceptFrame)
2073 {
2074 m_macRxTrace(originalPkt);
2075 // \todo: What should we do if we receive a frame while waiting for an ACK?
2076 // Especially if this frame has the ACK request bit set, should we reply with
2077 // an ACK, possibly missing the pending ACK?
2078
2079 // If the received frame is a frame with the ACK request bit set, we immediately
2080 // send back an ACK. If we are currently waiting for a pending ACK, we assume the
2081 // ACK was lost and trigger a retransmission after sending the ACK.
2082 if ((receivedMacHdr.IsData() || receivedMacHdr.IsCommand()) &&
2083 receivedMacHdr.IsAckReq() &&
2084 !(receivedMacHdr.GetDstAddrMode() == SHORT_ADDR &&
2085 (receivedMacHdr.GetShortDstAddr().IsBroadcast() ||
2086 receivedMacHdr.GetShortDstAddr().IsMulticast())))
2087 {
2088 // If this is a data or mac command frame, which is not a broadcast or
2089 // multicast, with ack req set, generate and send an ack frame. If there is a
2090 // CSMA medium access in progress we cancel the medium access for sending the
2091 // ACK frame. A new transmission attempt will be started after the ACK was send.
2093 {
2096 }
2097 else if (m_lrWpanMacState == MAC_CSMA)
2098 {
2099 // \todo: If we receive a packet while doing CSMA/CA, should we drop the
2100 // packet because of channel busy,
2101 // or should we restart CSMA/CA for the packet after sending the ACK?
2102 // Currently we simply restart CSMA/CA after sending the ACK.
2103 NS_LOG_DEBUG("Received a packet with ACK required while in CSMA. Cancel "
2104 "current CSMA-CA");
2105 m_csmaCa->Cancel();
2106 }
2107 // Cancel any pending MAC state change, ACKs have higher priority.
2110
2111 // save received packet to process the appropriate indication/response after
2112 // sending ACK (PD-DATA.confirm)
2113 m_rxPkt = originalPkt->Copy();
2114
2115 // LOG Commands with ACK required.
2116 CommandPayloadHeader receivedMacPayload;
2117 p->PeekHeader(receivedMacPayload);
2118 switch (receivedMacPayload.GetCommandFrameType())
2119 {
2121 NS_LOG_DEBUG("Data Request Command Received; processing ACK");
2122 break;
2124 NS_LOG_DEBUG("Association Request Command Received; processing ACK");
2125 break;
2127 m_assocResCmdWaitTimeout.Cancel(); // cancel event to a lost assoc resp cmd.
2128 NS_LOG_DEBUG("Association Response Command Received; processing ACK");
2129 break;
2130 default:
2131 break;
2132 }
2133
2135 this,
2136 receivedMacHdr.GetSeqNum());
2137 }
2138
2139 if (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2140 {
2141 NS_LOG_DEBUG("Packet from " << params.m_srcAddr);
2142 NS_LOG_DEBUG("Packet to " << params.m_dstAddr);
2143 }
2144 else if (receivedMacHdr.GetDstAddrMode() == EXT_ADDR)
2145 {
2146 NS_LOG_DEBUG("Packet from " << params.m_srcExtAddr);
2147 NS_LOG_DEBUG("Packet to " << params.m_dstExtAddr);
2148 }
2149
2150 if (receivedMacHdr.IsBeacon())
2151 {
2152 // The received beacon size in symbols
2153 // Beacon = 5 bytes Sync Header (SHR) + 1 byte PHY header (PHR) + PSDU (default
2154 // 17 bytes)
2155 m_rxBeaconSymbols = m_phy->GetPhySHRDuration() +
2156 1 * m_phy->GetPhySymbolsPerOctet() +
2157 (originalPkt->GetSize() * m_phy->GetPhySymbolsPerOctet());
2158
2159 // The start of Rx beacon time and start of the Incoming superframe Active
2160 // Period
2162 Simulator::Now() - Seconds(double(m_rxBeaconSymbols) / symbolRate);
2163
2164 NS_LOG_DEBUG("Beacon Received; forwarding up (m_macBeaconRxTime: "
2165 << m_macBeaconRxTime.As(Time::S) << ")");
2166
2167 BeaconPayloadHeader receivedMacPayload;
2168 p->RemoveHeader(receivedMacPayload);
2169
2170 // Fill the PAN descriptor
2171 PanDescriptor panDescriptor;
2172
2173 if (receivedMacHdr.GetSrcAddrMode() == SHORT_ADDR)
2174 {
2175 panDescriptor.m_coorAddrMode = SHORT_ADDR;
2176 panDescriptor.m_coorShortAddr = receivedMacHdr.GetShortSrcAddr();
2177 }
2178 else
2179 {
2180 panDescriptor.m_coorAddrMode = EXT_ADDR;
2181 panDescriptor.m_coorExtAddr = receivedMacHdr.GetExtSrcAddr();
2182 }
2183
2184 panDescriptor.m_coorPanId = receivedMacHdr.GetSrcPanId();
2185 panDescriptor.m_gtsPermit = receivedMacPayload.GetGtsFields().GetGtsPermit();
2186 panDescriptor.m_linkQuality = lqi;
2187 panDescriptor.m_logChPage = m_phy->GetCurrentPage();
2188 panDescriptor.m_logCh = m_phy->GetCurrentChannelNum();
2189 panDescriptor.m_superframeSpec = receivedMacPayload.GetSuperframeSpecField();
2190 panDescriptor.m_timeStamp = m_macBeaconRxTime;
2191
2192 // Process beacon when device belongs to a PAN (associated device)
2193 if (!m_scanEvent.IsRunning() && m_macPanId == receivedMacHdr.GetDstPanId())
2194 {
2195 // We need to make sure to cancel any possible ongoing unslotted CSMA/CA
2196 // operations when receiving a beacon (e.g. Those taking place at the
2197 // beginning of an Association).
2198 m_csmaCa->Cancel();
2199
2200 SuperframeField incomingSuperframe;
2201 incomingSuperframe = receivedMacPayload.GetSuperframeSpecField();
2202
2203 m_incomingBeaconOrder = incomingSuperframe.GetBeaconOrder();
2204 m_incomingSuperframeOrder = incomingSuperframe.GetFrameOrder();
2205 m_incomingFnlCapSlot = incomingSuperframe.GetFinalCapSlot();
2206
2208 (static_cast<uint32_t>(1 << m_incomingBeaconOrder)) *
2212 (static_cast<uint32_t>(1 << m_incomingSuperframeOrder));
2213
2214 if (incomingSuperframe.IsBattLifeExt())
2215 {
2216 m_csmaCa->SetBatteryLifeExtension(true);
2217 }
2218 else
2219 {
2220 m_csmaCa->SetBatteryLifeExtension(false);
2221 }
2222
2223 if (m_incomingBeaconOrder < 15 && !m_csmaCa->IsSlottedCsmaCa())
2224 {
2225 m_csmaCa->SetSlottedCsmaCa();
2226 }
2227
2228 // TODO: get Incoming frame GTS Fields here
2229
2230 // Begin CAP on the current device using info from the Incoming superframe
2231 NS_LOG_DEBUG("Incoming superframe Active Portion (Beacon + CAP + CFP): "
2232 << m_incomingSuperframeDuration << " symbols");
2234 this,
2238 }
2239 else if (!m_scanEvent.IsRunning() && m_macPanId == 0xFFFF)
2240 {
2241 NS_LOG_DEBUG(this << " Device not associated, cannot process beacon");
2242 }
2243
2244 if (m_macAutoRequest)
2245 {
2246 if (p->GetSize() > 0)
2247 {
2249 {
2250 // The beacon contains payload, send the beacon notification.
2252 beaconParams.m_bsn = receivedMacHdr.GetSeqNum();
2253 beaconParams.m_panDescriptor = panDescriptor;
2254 beaconParams.m_sduLength = p->GetSize();
2255 beaconParams.m_sdu = p;
2257 }
2258 }
2259
2260 if (m_scanEvent.IsRunning())
2261 {
2262 // Channel scanning is taking place, save only unique PAN descriptors
2263 bool descriptorExists = false;
2264
2265 for (const auto& descriptor : m_panDescriptorList)
2266 {
2267 if (descriptor.m_coorAddrMode == SHORT_ADDR)
2268 {
2269 // Found a coordinator in PAN descriptor list with the same
2270 // registered short address
2271 descriptorExists =
2272 (descriptor.m_coorShortAddr ==
2273 panDescriptor.m_coorShortAddr &&
2274 descriptor.m_coorPanId == panDescriptor.m_coorPanId);
2275 }
2276 else
2277 {
2278 // Found a coordinator in PAN descriptor list with the same
2279 // registered extended address
2280 descriptorExists =
2281 (descriptor.m_coorExtAddr == panDescriptor.m_coorExtAddr &&
2282 descriptor.m_coorPanId == panDescriptor.m_coorPanId);
2283 }
2284
2285 if (descriptorExists)
2286 {
2287 break;
2288 }
2289 }
2290
2291 if (!descriptorExists)
2292 {
2293 m_panDescriptorList.emplace_back(panDescriptor);
2294 }
2295 return;
2296 }
2297 else if (m_trackingEvent.IsRunning())
2298 {
2299 // check if MLME-SYNC.request was previously issued and running
2300 // Sync. is necessary to handle pending messages (indirect
2301 // transmissions)
2303 m_numLostBeacons = 0;
2304
2306 {
2307 // if tracking option is on keep tracking the next beacon
2308 uint64_t searchSymbols;
2309 Time searchBeaconTime;
2310
2311 searchSymbols =
2312 (static_cast<uint64_t>(1 << m_incomingBeaconOrder)) +
2314 searchBeaconTime =
2315 Seconds(static_cast<double>(searchSymbols / symbolRate));
2317 Simulator::Schedule(searchBeaconTime,
2319 this);
2320 }
2321
2322 PendingAddrFields pndAddrFields;
2323 pndAddrFields = receivedMacPayload.GetPndAddrFields();
2324
2325 // TODO: Ignore pending data, and do not send data command request if
2326 // the address is in the GTS list.
2327 // If the address is not in the GTS list, then check if the
2328 // address is in the short address pending list or in the extended
2329 // address pending list and send a data command request.
2330 }
2331 }
2332 else
2333 {
2334 // m_macAutoRequest is FALSE
2335 // Data command request are not send, only the beacon notification.
2336 // see IEEE 802.15.4-2011 Section 6.2.4.1
2338 {
2340 beaconParams.m_bsn = receivedMacHdr.GetSeqNum();
2341 beaconParams.m_panDescriptor = panDescriptor;
2342 beaconParams.m_sduLength = p->GetSize();
2343 beaconParams.m_sdu = p;
2345 }
2346 }
2347 }
2348 else if (receivedMacHdr.IsCommand())
2349 {
2350 // Handle the reception of frame commands that do not require ACK
2351 // (i.e. Beacon Request, Orphan notification, Coordinator Realigment)
2352 CommandPayloadHeader receivedMacPayload;
2353 p->PeekHeader(receivedMacPayload);
2354
2355 switch (receivedMacPayload.GetCommandFrameType())
2356 {
2358 if (m_csmaCa->IsUnSlottedCsmaCa() && m_coor)
2359 {
2360 SendOneBeacon();
2361 }
2362 else
2363 {
2364 m_macRxDropTrace(originalPkt);
2365 }
2366 break;
2369 {
2370 if (m_coor)
2371 {
2372 MlmeOrphanIndicationParams orphanParams;
2373 orphanParams.m_orphanAddr = receivedMacHdr.GetExtSrcAddr();
2374 m_mlmeOrphanIndicationCallback(orphanParams);
2375 }
2376 }
2377 break;
2380 {
2381 // Coordinator located, no need to keep scanning other channels
2383
2384 m_macPanIdScan = 0;
2387
2388 // Update the device information with the received information
2389 // from the Coordinator Realigment command.
2390 m_macPanId = receivedMacPayload.GetPanId();
2391 m_shortAddress = receivedMacPayload.GetShortAddr();
2392 m_macCoordExtendedAddress = receivedMacHdr.GetExtSrcAddr();
2393 m_macCoordShortAddress = receivedMacPayload.GetCoordShortAddr();
2394
2396 {
2397 MlmeScanConfirmParams confirmParams;
2398 confirmParams.m_scanType = m_scanParams.m_scanType;
2399 confirmParams.m_chPage = m_scanParams.m_chPage;
2400 confirmParams.m_status = MLMESCAN_SUCCESS;
2401 m_mlmeScanConfirmCallback(confirmParams);
2402 }
2403 m_scanParams = {};
2404 }
2405 // TODO: handle Coordinator realignment when not
2406 // used during an orphan scan.
2407 break;
2408 default:
2409 m_macRxDropTrace(originalPkt);
2410 break;
2411 }
2412 }
2413 else if (receivedMacHdr.IsData() && !m_mcpsDataIndicationCallback.IsNull())
2414 {
2415 // If it is a data frame, push it up the stack.
2416 NS_LOG_DEBUG("Data Packet is for me; forwarding up");
2418 }
2419 else if (receivedMacHdr.IsAcknowledgment() && m_txPkt &&
2421 {
2422 LrWpanMacHeader peekedMacHdr;
2423 m_txPkt->PeekHeader(peekedMacHdr);
2424 // If it is an ACK with the expected sequence number, finish the transmission
2425 if (receivedMacHdr.GetSeqNum() == peekedMacHdr.GetSeqNum())
2426 {
2429
2430 // TODO: check if the IFS is the correct size after ACK.
2431 Time ifsWaitTime = Seconds((double)GetIfsSize() / symbolRate);
2432
2433 // We received an ACK to a command
2434 if (peekedMacHdr.IsCommand())
2435 {
2436 // check the original sent command frame which belongs to this received
2437 // ACK
2438 Ptr<Packet> pkt = m_txPkt->Copy();
2439 LrWpanMacHeader macHdr;
2440 CommandPayloadHeader cmdPayload;
2441 pkt->RemoveHeader(macHdr);
2442 pkt->RemoveHeader(cmdPayload);
2443
2444 switch (cmdPayload.GetCommandFrameType())
2445 {
2447 double symbolRate = m_phy->GetDataOrSymbolRate(false);
2448 Time waitTime = Seconds(static_cast<double>(m_macResponseWaitTime) /
2449 symbolRate);
2450 if (!m_beaconTrackingOn)
2451 {
2453 Simulator::Schedule(waitTime,
2455 this);
2456 }
2457 else
2458 {
2459 // TODO: The data must be extracted by the coordinator within
2460 // macResponseWaitTime on timeout, MLME-ASSOCIATE.confirm is set
2461 // with status NO_DATA, and this should trigger the cancellation
2462 // of the beacon tracking (MLME-SYNC.request trackBeacon
2463 // =FALSE)
2464 }
2465 break;
2466 }
2467
2469 // MLME-comm-status.Indication generated as a result of an
2470 // association response command, therefore src and dst address use
2471 // extended mode (see 5.3.2.1)
2473 {
2474 MlmeCommStatusIndicationParams commStatusParams;
2475 commStatusParams.m_panId = m_macPanId;
2476 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2477 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2478 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2479 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2480 commStatusParams.m_status =
2482 m_mlmeCommStatusIndicationCallback(commStatusParams);
2483 }
2484 // Remove element from Pending Transaction List
2486 break;
2487 }
2488
2490 // Schedule an event in case the Association Response Command never
2491 // reached this device during an association process.
2492 double symbolRate = m_phy->GetDataOrSymbolRate(false);
2493 Time waitTime = Seconds(
2494 static_cast<double>(m_assocRespCmdWaitTime) / symbolRate);
2496 Simulator::Schedule(waitTime,
2498 this);
2499
2501 {
2502 MlmePollConfirmParams pollConfirmParams;
2503 pollConfirmParams.m_status =
2505 m_mlmePollConfirmCallback(pollConfirmParams);
2506 }
2507 break;
2508 }
2509
2511 // ACK of coordinator realigment commands is not specified in the
2512 // standard, in here, we assume they are required as in other
2513 // commands.
2515 {
2516 MlmeCommStatusIndicationParams commStatusParams;
2517 commStatusParams.m_panId = m_macPanId;
2518 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2519 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2520 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2521 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2522 commStatusParams.m_status =
2524 m_mlmeCommStatusIndicationCallback(commStatusParams);
2525 }
2526 }
2527
2528 default: {
2529 // TODO: add response to other request commands (e.g. Orphan)
2530 break;
2531 }
2532 }
2533 }
2534 else
2535 {
2537 {
2538 Ptr<TxQueueElement> txQElement = m_txQueue.front();
2539 McpsDataConfirmParams confirmParams;
2540 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2541 confirmParams.m_status = IEEE_802_15_4_SUCCESS;
2542 m_mcpsDataConfirmCallback(confirmParams);
2543 }
2544 }
2545
2546 // Ack was successfully received, wait for the Interframe Space (IFS) and
2547 // then proceed
2552 m_ifsEvent = Simulator::Schedule(ifsWaitTime,
2554 this,
2555 ifsWaitTime);
2556 }
2557 else
2558 {
2559 // If it is an ACK with an unexpected sequence number, mark the current
2560 // transmission as failed and start a retransmit. (cf 7.5.6.4.3)
2562 if (!PrepareRetransmission())
2563 {
2566 this,
2567 MAC_IDLE);
2568 }
2569 else
2570 {
2573 this,
2574 MAC_CSMA);
2575 }
2576 }
2577 }
2578 }
2579 else
2580 {
2581 m_macRxDropTrace(originalPkt);
2582 }
2583 }
2584 }
2585}
2586
2587void
2589{
2590 NS_LOG_FUNCTION(this << static_cast<uint32_t>(seqno));
2591
2593
2594 // Generate a corresponding ACK Frame.
2596 LrWpanMacTrailer macTrailer;
2597 Ptr<Packet> ackPacket = Create<Packet>(0);
2598 ackPacket->AddHeader(macHdr);
2599 // Calculate FCS if the global attribute ChecksumEnabled is set.
2601 {
2602 macTrailer.EnableFcs(true);
2603 macTrailer.SetFcs(ackPacket);
2604 }
2605 ackPacket->AddTrailer(macTrailer);
2606
2607 // Enqueue the ACK packet for further processing
2608 // when the transmitter is activated.
2609 m_txPkt = ackPacket;
2610
2611 // Switch transceiver to TX mode. Proceed sending the Ack on confirm.
2613 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
2614}
2615
2616void
2618{
2619 if (m_txQueue.size() < m_maxTxQueueSize)
2620 {
2621 m_txQueue.emplace_back(txQElement);
2622 m_macTxEnqueueTrace(txQElement->txQPkt);
2623 }
2624 else
2625 {
2627 {
2628 McpsDataConfirmParams confirmParams;
2629 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2631 m_mcpsDataConfirmCallback(confirmParams);
2632 }
2633 NS_LOG_DEBUG("TX Queue with size " << m_txQueue.size() << " is full, dropping packet");
2634 m_macTxDropTrace(txQElement->txQPkt);
2635 }
2636}
2637
2638void
2640{
2641 Ptr<TxQueueElement> txQElement = m_txQueue.front();
2642 Ptr<const Packet> p = txQElement->txQPkt;
2643 m_numCsmacaRetry += m_csmaCa->GetNB() + 1;
2644
2645 Ptr<Packet> pkt = p->Copy();
2646 LrWpanMacHeader hdr;
2647 pkt->RemoveHeader(hdr);
2648 if (!hdr.GetShortDstAddr().IsBroadcast() && !hdr.GetShortDstAddr().IsMulticast())
2649 {
2651 }
2652
2653 txQElement->txQPkt = nullptr;
2654 txQElement = nullptr;
2655 m_txQueue.pop_front();
2656 m_txPkt = nullptr;
2657 m_retransmission = 0;
2658 m_numCsmacaRetry = 0;
2660}
2661
2662void
2664{
2665 NS_LOG_FUNCTION(this);
2666
2667 // TODO: If we are a PAN coordinator and this was an indirect transmission,
2668 // we will not initiate a retransmission. Instead we wait for the data
2669 // being extracted after a new data request command.
2670 if (!PrepareRetransmission())
2671 {
2673 }
2674 else
2675 {
2677 }
2678}
2679
2680void
2682{
2683 uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false);
2684 Time lifsTime = Seconds((double)m_macLIFSPeriod / symbolRate);
2685 Time sifsTime = Seconds((double)m_macSIFSPeriod / symbolRate);
2686
2687 if (ifsTime == lifsTime)
2688 {
2689 NS_LOG_DEBUG("LIFS of " << m_macLIFSPeriod << " symbols (" << ifsTime.As(Time::S)
2690 << ") completed ");
2691 }
2692 else if (ifsTime == sifsTime)
2693 {
2694 NS_LOG_DEBUG("SIFS of " << m_macSIFSPeriod << " symbols (" << ifsTime.As(Time::S)
2695 << ") completed ");
2696 }
2697 else
2698 {
2699 NS_LOG_DEBUG("Unknown IFS size (" << ifsTime.As(Time::S) << ") completed ");
2700 }
2701
2702 m_macIfsEndTrace(ifsTime);
2703 CheckQueue();
2704}
2705
2706bool
2708{
2709 NS_LOG_FUNCTION(this);
2710
2711 // Max retransmissions reached without receiving ACK,
2712 // send the proper indication/confirmation
2713 // according to the frame type and call drop trace.
2715 {
2716 LrWpanMacHeader peekedMacHdr;
2717 m_txPkt->PeekHeader(peekedMacHdr);
2718
2719 if (peekedMacHdr.IsCommand())
2720 {
2722
2723 Ptr<Packet> pkt = m_txPkt->Copy();
2724 LrWpanMacHeader macHdr;
2725 CommandPayloadHeader cmdPayload;
2726 pkt->RemoveHeader(macHdr);
2727 pkt->RemoveHeader(cmdPayload);
2728
2729 switch (cmdPayload.GetCommandFrameType())
2730 {
2732 m_macPanId = 0xffff;
2734 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2737 m_csmaCa->SetUnSlottedCsmaCa();
2740
2742 {
2743 MlmeAssociateConfirmParams confirmParams;
2744 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
2745 confirmParams.m_status = MLMEASSOC_NO_ACK;
2746 m_mlmeAssociateConfirmCallback(confirmParams);
2747 }
2748 break;
2749 }
2751 // IEEE 802.15.4-2006 (Section 7.1.3.3.3 and 7.1.8.2.3)
2753 {
2754 MlmeCommStatusIndicationParams commStatusParams;
2755 commStatusParams.m_panId = m_macPanId;
2756 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2757 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2758 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2759 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2761 m_mlmeCommStatusIndicationCallback(commStatusParams);
2762 }
2764 break;
2765 }
2767 // IEEE 802.15.4-2006 (Section 7.1.16.1.3)
2768 m_macPanId = 0xffff;
2770 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2773 m_csmaCa->SetUnSlottedCsmaCa();
2776
2778 {
2779 MlmePollConfirmParams pollConfirmParams;
2781 m_mlmePollConfirmCallback(pollConfirmParams);
2782 }
2783 break;
2784 }
2785 default: {
2786 // TODO: Specify other indications according to other commands
2787 break;
2788 }
2789 }
2790 }
2791 else
2792 {
2793 // Maximum number of retransmissions has been reached.
2794 // remove the copy of the DATA packet that was just sent
2795 Ptr<TxQueueElement> txQElement = m_txQueue.front();
2796 m_macTxDropTrace(txQElement->txQPkt);
2798 {
2799 McpsDataConfirmParams confirmParams;
2800 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2801 confirmParams.m_status = IEEE_802_15_4_NO_ACK;
2802 m_mcpsDataConfirmCallback(confirmParams);
2803 }
2804 }
2805
2807 return false;
2808 }
2809 else
2810 {
2812 m_numCsmacaRetry += m_csmaCa->GetNB() + 1;
2813 // Start next CCA process for this packet.
2814 return true;
2815 }
2816}
2817
2818void
2820{
2821 Ptr<IndTxQueueElement> indTxQElement = Create<IndTxQueueElement>();
2822 LrWpanMacHeader peekedMacHdr;
2823 p->PeekHeader(peekedMacHdr);
2824
2825 PurgeInd();
2826
2827 NS_ASSERT(peekedMacHdr.GetDstAddrMode() == SHORT_ADDR ||
2828 peekedMacHdr.GetDstAddrMode() == EXT_ADDR);
2829
2830 if (peekedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2831 {
2832 indTxQElement->dstShortAddress = peekedMacHdr.GetShortDstAddr();
2833 }
2834 else
2835 {
2836 indTxQElement->dstExtAddress = peekedMacHdr.GetExtDstAddr();
2837 }
2838
2839 indTxQElement->seqNum = peekedMacHdr.GetSeqNum();
2840
2841 // See IEEE 802.15.4-2006, Table 86
2842 uint32_t unit = 0; // The persistence time in symbols
2843 if (m_macBeaconOrder == 15)
2844 {
2845 // Non-beacon enabled mode
2847 }
2848 else
2849 {
2850 // Beacon-enabled mode
2851 unit = ((static_cast<uint32_t>(1) << m_macBeaconOrder) * lrwpan::aBaseSuperframeDuration) *
2853 }
2854
2855 if (m_indTxQueue.size() < m_maxIndTxQueueSize)
2856 {
2857 double symbolRate = m_phy->GetDataOrSymbolRate(false);
2858 Time expireTime = Seconds(unit / symbolRate);
2859 expireTime += Simulator::Now();
2860 indTxQElement->expireTime = expireTime;
2861 indTxQElement->txQPkt = p;
2862 m_indTxQueue.emplace_back(indTxQElement);
2864 }
2865 else
2866 {
2868 {
2869 LrWpanMacHeader peekedMacHdr;
2870 indTxQElement->txQPkt->PeekHeader(peekedMacHdr);
2871 MlmeCommStatusIndicationParams commStatusParams;
2872 commStatusParams.m_panId = m_macPanId;
2873 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2874 commStatusParams.m_srcExtAddr = peekedMacHdr.GetExtSrcAddr();
2875 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2876 commStatusParams.m_dstExtAddr = peekedMacHdr.GetExtDstAddr();
2878 m_mlmeCommStatusIndicationCallback(commStatusParams);
2879 }
2881 }
2882}
2883
2884bool
2886{
2887 PurgeInd();
2888
2889 for (auto iter = m_indTxQueue.begin(); iter != m_indTxQueue.end(); iter++)
2890 {
2891 if ((*iter)->dstExtAddress == dst)
2892 {
2893 *entry = **iter;
2894 m_macIndTxDequeueTrace((*iter)->txQPkt->Copy());
2895 m_indTxQueue.erase(iter);
2896 return true;
2897 }
2898 }
2899 return false;
2900}
2901
2902void
2904{
2905 for (uint32_t i = 0; i < m_indTxQueue.size();)
2906 {
2907 if (Simulator::Now() > m_indTxQueue[i]->expireTime)
2908 {
2909 // Transaction expired, remove and send proper confirmation/indication to a higher layer
2910 LrWpanMacHeader peekedMacHdr;
2911 m_indTxQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2912
2913 if (peekedMacHdr.IsCommand())
2914 {
2915 // IEEE 802.15.4-2006 (Section 7.1.3.3.3)
2917 {
2918 MlmeCommStatusIndicationParams commStatusParams;
2919 commStatusParams.m_panId = m_macPanId;
2920 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2921 commStatusParams.m_srcExtAddr = peekedMacHdr.GetExtSrcAddr();
2922 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2923 commStatusParams.m_dstExtAddr = peekedMacHdr.GetExtDstAddr();
2924 commStatusParams.m_status =
2926 m_mlmeCommStatusIndicationCallback(commStatusParams);
2927 }
2928 }
2929 else if (peekedMacHdr.IsData())
2930 {
2931 // IEEE 802.15.4-2006 (Section 7.1.1.1.3)
2933 {
2934 McpsDataConfirmParams confParams;
2936 m_mcpsDataConfirmCallback(confParams);
2937 }
2938 }
2939 m_macIndTxDropTrace(m_indTxQueue[i]->txQPkt->Copy());
2940 m_indTxQueue.erase(m_indTxQueue.begin() + i);
2941 }
2942 else
2943 {
2944 i++;
2945 }
2946 }
2947}
2948
2949void
2950LrWpanMac::PrintPendTxQ(std::ostream& os) const
2951{
2952 LrWpanMacHeader peekedMacHdr;
2953
2954 os << "Pending Transaction List [" << GetShortAddress() << " | " << GetExtendedAddress()
2955 << "] | CurrentTime: " << Simulator::Now().As(Time::S) << "\n"
2956 << " Destination | Sequence Number | Frame type | Expire time\n";
2957
2958 for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
2959 {
2960 m_indTxQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2961 os << m_indTxQueue[i]->dstExtAddress << " "
2962 << static_cast<uint32_t>(m_indTxQueue[i]->seqNum) << " ";
2963
2964 if (peekedMacHdr.IsCommand())
2965 {
2966 os << "Cmd Frame ";
2967 }
2968 else if (peekedMacHdr.IsData())
2969 {
2970 os << "Data Frame ";
2971 }
2972 else
2973 {
2974 os << "Unk Frame ";
2975 }
2976
2977 os << m_indTxQueue[i]->expireTime.As(Time::S) << "\n";
2978 }
2979}
2980
2981void
2982LrWpanMac::PrintTxQueue(std::ostream& os) const
2983{
2984 LrWpanMacHeader peekedMacHdr;
2985
2986 os << "\nTx Queue [" << GetShortAddress() << " | " << GetExtendedAddress()
2987 << "] | CurrentTime: " << Simulator::Now().As(Time::S) << "\n"
2988 << " Destination | Sequence Number | Dst PAN id | Frame type |\n";
2989
2990 for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
2991 {
2992 m_txQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2993
2994 os << "[" << peekedMacHdr.GetShortDstAddr() << "]"
2995 << ", [" << peekedMacHdr.GetExtDstAddr() << "] "
2996 << static_cast<uint32_t>(peekedMacHdr.GetSeqNum()) << " "
2997 << peekedMacHdr.GetDstPanId() << " ";
2998
2999 if (peekedMacHdr.IsCommand())
3000 {
3001 os << "Cmd Frame ";
3002 }
3003 else if (peekedMacHdr.IsData())
3004 {
3005 os << "Data Frame ";
3006 }
3007 else
3008 {
3009 os << "Unk Frame ";
3010 }
3011
3012 os << "\n";
3013 }
3014 os << "\n";
3015}
3016
3017void
3019{
3020 LrWpanMacHeader peekedMacHdr;
3021 p->PeekHeader(peekedMacHdr);
3022
3023 for (auto it = m_indTxQueue.begin(); it != m_indTxQueue.end(); it++)
3024 {
3025 if (peekedMacHdr.GetDstAddrMode() == EXT_ADDR)
3026 {
3027 if (((*it)->dstExtAddress == peekedMacHdr.GetExtDstAddr()) &&
3028 ((*it)->seqNum == peekedMacHdr.GetSeqNum()))
3029 {
3031 m_indTxQueue.erase(it);
3032 break;
3033 }
3034 }
3035 else if (peekedMacHdr.GetDstAddrMode() == SHORT_ADDR)
3036 {
3037 if (((*it)->dstShortAddress == peekedMacHdr.GetShortDstAddr()) &&
3038 ((*it)->seqNum == peekedMacHdr.GetSeqNum()))
3039 {
3041 m_indTxQueue.erase(it);
3042 break;
3043 }
3044 }
3045 }
3046
3047 p = nullptr;
3048}
3049
3050void
3052{
3054 NS_LOG_FUNCTION(this << status << m_txQueue.size());
3055
3056 LrWpanMacHeader macHdr;
3057 Time ifsWaitTime;
3058 double symbolRate;
3059
3060 symbolRate = m_phy->GetDataOrSymbolRate(false); // symbols per second
3061
3062 m_txPkt->PeekHeader(macHdr);
3063
3064 if (status == IEEE_802_15_4_PHY_SUCCESS)
3065 {
3066 if (!macHdr.IsAcknowledgment())
3067 {
3068 if (macHdr.IsBeacon())
3069 {
3070 // Start CAP only if we are in beacon mode (i.e. if slotted csma-ca is running)
3071 if (m_csmaCa->IsSlottedCsmaCa())
3072 {
3073 // The Tx Beacon in symbols
3074 // Beacon = 5 bytes Sync Header (SHR) + 1 byte PHY header (PHR) + PSDU (default
3075 // 17 bytes)
3076 uint64_t beaconSymbols = m_phy->GetPhySHRDuration() +
3077 1 * m_phy->GetPhySymbolsPerOctet() +
3078 (m_txPkt->GetSize() * m_phy->GetPhySymbolsPerOctet());
3079
3080 // The beacon Tx time and start of the Outgoing superframe Active Period
3082 Simulator::Now() - Seconds(static_cast<double>(beaconSymbols) / symbolRate);
3083
3085 this,
3087 NS_LOG_DEBUG("Beacon Sent (m_macBeaconTxTime: " << m_macBeaconTxTime.As(Time::S)
3088 << ")");
3089
3091 {
3092 MlmeStartConfirmParams mlmeConfirmParams;
3093 mlmeConfirmParams.m_status = MLMESTART_SUCCESS;
3094 m_mlmeStartConfirmCallback(mlmeConfirmParams);
3095 }
3096 }
3097
3098 ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
3099 m_txPkt = nullptr;
3100 }
3101 else if (macHdr.IsAckReq()) // We have sent a regular data packet, check if we have to
3102 // wait for an ACK.
3103 {
3104 // we sent a regular data frame or command frame (e.g. AssocReq command) that
3105 // require ACK wait for the ack or the next retransmission timeout start
3106 // retransmission timer
3107 Time waitTime = Seconds(static_cast<double>(GetMacAckWaitDuration()) / symbolRate);
3113 return;
3114 }
3115 else if (macHdr.IsCommand())
3116 {
3117 // We handle commands that do not require ACK
3118 // (e.g. Coordinator realigment command in an orphan response)
3119 // Other command with ACK required are handle by the previous if statement.
3120
3121 // Check the transmitted packet command type and issue the appropriate indication.
3122 Ptr<Packet> txOriginalPkt = m_txPkt->Copy();
3123 LrWpanMacHeader txMacHdr;
3124 txOriginalPkt->RemoveHeader(txMacHdr);
3125 CommandPayloadHeader txMacPayload;
3126 txOriginalPkt->RemoveHeader(txMacPayload);
3127
3129 {
3131 {
3132 MlmeCommStatusIndicationParams commStatusParams;
3133 commStatusParams.m_panId = m_macPanId;
3134
3135 commStatusParams.m_srcAddrMode = macHdr.GetSrcAddrMode();
3136 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
3137 commStatusParams.m_srcShortAddr = macHdr.GetShortSrcAddr();
3138
3139 commStatusParams.m_dstAddrMode = macHdr.GetDstAddrMode();
3140 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
3141 commStatusParams.m_dstShortAddr = macHdr.GetShortDstAddr();
3142
3144 m_mlmeCommStatusIndicationCallback(commStatusParams);
3145 }
3146 }
3147
3148 ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
3150 }
3151 else
3152 {
3154 // remove the copy of the packet that was just sent
3156 {
3157 McpsDataConfirmParams confirmParams;
3158 NS_ASSERT_MSG(!m_txQueue.empty(), "TxQsize = 0");
3159 Ptr<TxQueueElement> txQElement = m_txQueue.front();
3160 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
3161 confirmParams.m_status = IEEE_802_15_4_SUCCESS;
3162 m_mcpsDataConfirmCallback(confirmParams);
3163 }
3164 ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
3166 }
3167 }
3168 else
3169 {
3170 // The packet sent was a successful ACK
3171
3172 // Check the received frame before the transmission of the ACK,
3173 // and send the appropriate Indication or Confirmation
3174 Ptr<Packet> recvOriginalPkt = m_rxPkt->Copy();
3175 LrWpanMacHeader receivedMacHdr;
3176 recvOriginalPkt->RemoveHeader(receivedMacHdr);
3177
3178 if (receivedMacHdr.IsCommand())
3179 {
3180 CommandPayloadHeader receivedMacPayload;
3181 recvOriginalPkt->RemoveHeader(receivedMacPayload);
3182
3183 if (receivedMacPayload.GetCommandFrameType() ==
3185 {
3187 {
3188 MlmeAssociateIndicationParams associateParams;
3189 associateParams.capabilityInfo = receivedMacPayload.GetCapabilityField();
3190 associateParams.m_extDevAddr = receivedMacHdr.GetExtSrcAddr();
3191 m_mlmeAssociateIndicationCallback(associateParams);
3192 }
3193
3194 // Clear the packet buffer for the packet request received.
3195 m_rxPkt = nullptr;
3196 }
3197 else if (receivedMacPayload.GetCommandFrameType() ==
3199 {
3200 MlmeAssociateConfirmParams confirmParams;
3201
3202 switch (receivedMacPayload.GetAssociationStatus())
3203 {
3205 confirmParams.m_status =
3207 // The original short address used in the association
3208 // used in the association request
3209 confirmParams.m_assocShortAddr = GetShortAddress();
3210
3211 // The assigned short address by the coordinator
3212 SetShortAddress(receivedMacPayload.GetShortAddr());
3213 m_macPanId = receivedMacHdr.GetSrcPanId();
3214 break;
3216 confirmParams.m_status =
3218 m_macPanId = 0xffff;
3220 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3223 m_csmaCa->SetUnSlottedCsmaCa();
3226 break;
3228 confirmParams.m_status =
3230 m_macPanId = 0xffff;
3232 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3235 m_csmaCa->SetUnSlottedCsmaCa();
3238 break;
3239 }
3240
3242 {
3243 m_mlmeAssociateConfirmCallback(confirmParams);
3244 }
3245 }
3246 else if (receivedMacPayload.GetCommandFrameType() == CommandPayloadHeader::DATA_REQ)
3247 {
3248 // We enqueue the the Assoc Response command frame in the Tx queue
3249 // and the packet is transmitted as soon as the PHY is free and the IFS have
3250 // taken place.
3252 }
3253 }
3254
3255 // Clear the packet buffer for the ACK packet sent.
3256 m_txPkt = nullptr;
3257 }
3258 }
3259 else if (status == IEEE_802_15_4_PHY_UNSPECIFIED)
3260 {
3261 if (!macHdr.IsAcknowledgment())
3262 {
3263 NS_ASSERT_MSG(!m_txQueue.empty(), "TxQsize = 0");
3264 Ptr<TxQueueElement> txQElement = m_txQueue.front();
3265 m_macTxDropTrace(txQElement->txQPkt);
3267 {
3268 McpsDataConfirmParams confirmParams;
3269 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
3270 confirmParams.m_status = IEEE_802_15_4_FRAME_TOO_LONG;
3271 m_mcpsDataConfirmCallback(confirmParams);
3272 }
3274 }
3275 else
3276 {
3277 NS_LOG_ERROR("Unable to send ACK");
3278 }
3279 }
3280 else
3281 {
3282 // Something went really wrong. The PHY is not in the correct state for
3283 // data transmission.
3284 NS_FATAL_ERROR("Transmission attempt failed with PHY status " << status);
3285 }
3286
3287 if (!ifsWaitTime.IsZero())
3288 {
3289 m_ifsEvent =
3290 Simulator::Schedule(ifsWaitTime, &LrWpanMac::IfsWaitTimeout, this, ifsWaitTime);
3291 }
3292
3295}
3296
3297void
3299{
3300 NS_LOG_FUNCTION(this << status);
3301 // Direct this call through the csmaCa object
3302 m_csmaCa->PlmeCcaConfirm(status);
3303}
3304
3305void
3307{
3308 NS_LOG_FUNCTION(this << status << energyLevel);
3309
3310 if (energyLevel > m_maxEnergyLevel)
3311 {
3312 m_maxEnergyLevel = energyLevel;
3313 }
3314
3316 Seconds(8.0 / m_phy->GetDataOrSymbolRate(false)))
3317 {
3318 m_phy->PlmeEdRequest();
3319 }
3320}
3321
3322void
3326{
3327 NS_LOG_FUNCTION(this << status << id << attribute);
3328}
3329
3330void
3332{
3333 NS_LOG_FUNCTION(this << status);
3334
3336 (status == IEEE_802_15_4_PHY_TX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
3337 {
3339
3340 // Start sending if we are in state SENDING and the PHY transmitter was enabled.
3344 m_phy->PdDataRequest(m_txPkt->GetSize(), m_txPkt);
3345 }
3346 else if (m_lrWpanMacState == MAC_CSMA &&
3347 (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
3348 {
3349 // Start the CSMA algorithm as soon as the receiver is enabled.
3350 m_csmaCa->Start();
3351 }
3352 else if (m_lrWpanMacState == MAC_IDLE)
3353 {
3355 status == IEEE_802_15_4_PHY_TRX_OFF);
3356
3358 {
3359 // Kick start Energy Detection Scan
3360 m_phy->PlmeEdRequest();
3361 }
3362 else if (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS)
3363 {
3364 // Check if there is not messages to transmit when going idle
3365 CheckQueue();
3366 }
3367 }
3369 {
3371 }
3372 else
3373 {
3374 // TODO: What to do when we receive an error?
3375 // If we want to transmit a packet, but switching the transceiver on results
3376 // in an error, we have to recover somehow (and start sending again).
3377 NS_FATAL_ERROR("Error changing transceiver state");
3378 }
3379}
3380
3381void
3383{
3384 NS_LOG_FUNCTION(this << status << id);
3386 {
3388 {
3389 // get the first channel to scan from scan channel list
3390 bool channelFound = false;
3391 for (int i = m_channelScanIndex; i <= 26; i++)
3392 {
3394 {
3395 channelFound = true;
3396 break;
3397 }
3399 }
3400
3401 if (channelFound)
3402 {
3403 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
3404 pibAttr->phyCurrentChannel = m_channelScanIndex;
3406 pibAttr);
3407 }
3408 }
3409 else
3410 {
3412 {
3413 MlmeScanConfirmParams confirmParams;
3414 confirmParams.m_scanType = m_scanParams.m_scanType;
3415 confirmParams.m_chPage = m_scanParams.m_chPage;
3416 confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3417 m_mlmeScanConfirmCallback(confirmParams);
3418 }
3419 NS_LOG_ERROR(this << "Channel Scan: Invalid channel page");
3420 }
3421 }
3424 {
3426 {
3427 uint64_t symbolRate = static_cast<uint64_t>(m_phy->GetDataOrSymbolRate(false));
3428 Time nextScanTime;
3429
3431 {
3432 nextScanTime = Seconds(static_cast<double>(m_macResponseWaitTime) / symbolRate);
3433 }
3434 else
3435 {
3436 uint64_t scanDurationSym =
3438
3439 nextScanTime = Seconds(static_cast<double>(scanDurationSym) / symbolRate);
3440 }
3441
3442 switch (m_scanParams.m_scanType)
3443 {
3444 case MLMESCAN_ED:
3445 m_maxEnergyLevel = 0;
3448 // set phy to RX_ON and kick start the first PLME-ED.request
3449 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3450 break;
3451 case MLMESCAN_ACTIVE:
3454 break;
3455 case MLMESCAN_PASSIVE:
3457 // turn back the phy to RX_ON after setting Page/channel
3458 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3459 break;
3460 case MLMESCAN_ORPHAN:
3462 Simulator::Schedule(nextScanTime, &LrWpanMac::EndChannelScan, this);
3464 break;
3465
3466 default:
3467 MlmeScanConfirmParams confirmParams;
3468 confirmParams.m_scanType = m_scanParams.m_scanType;
3469 confirmParams.m_chPage = m_scanParams.m_chPage;
3470 confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3472 {
3473 m_mlmeScanConfirmCallback(confirmParams);
3474 }
3475 NS_LOG_ERROR("Scan Type currently not supported");
3476 return;
3477 }
3478 }
3479 else
3480 {
3482 {
3483 MlmeScanConfirmParams confirmParams;
3484 confirmParams.m_scanType = m_scanParams.m_scanType;
3485 confirmParams.m_chPage = m_scanParams.m_chPage;
3486 confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3487 m_mlmeScanConfirmCallback(confirmParams);
3488 }
3489 NS_LOG_ERROR("Channel " << m_channelScanIndex
3490 << " could not be set in the current page");
3491 }
3492 }
3495 {
3497 {
3498 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
3499 pibAttr->phyCurrentChannel = m_startParams.m_logCh;
3501 pibAttr);
3502 }
3503 else
3504 {
3506 {
3507 MlmeStartConfirmParams confirmParams;
3508 confirmParams.m_status = MLMESTART_INVALID_PARAMETER;
3509 m_mlmeStartConfirmCallback(confirmParams);
3510 }
3511 NS_LOG_ERROR("Invalid page parameter in MLME-start");
3512 }
3513 }
3516 {
3518 {
3520 }
3521 else
3522 {
3524 {
3525 MlmeStartConfirmParams confirmParams;
3526 confirmParams.m_status = MLMESTART_INVALID_PARAMETER;
3527 m_mlmeStartConfirmCallback(confirmParams);
3528 }
3529 NS_LOG_ERROR("Invalid channel parameter in MLME-start");
3530 }
3531 }
3534 {
3536 {
3537 Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
3538 pibAttr->phyCurrentChannel = m_associateParams.m_chNum;
3540 pibAttr);
3541 }
3542 else
3543 {
3544 m_macPanId = 0xffff;
3546 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3549 m_csmaCa->SetUnSlottedCsmaCa();
3552
3554 {
3555 MlmeAssociateConfirmParams confirmParams;
3556 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3557 confirmParams.m_status = MLMEASSOC_INVALID_PARAMETER;
3558 m_mlmeAssociateConfirmCallback(confirmParams);
3559 }
3560 NS_LOG_ERROR("Invalid page parameter in MLME-associate");
3561 }
3562 }
3565 {
3567 {
3569 }
3570 else
3571 {
3572 m_macPanId = 0xffff;
3574 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3577 m_csmaCa->SetUnSlottedCsmaCa();
3580
3582 {
3583 MlmeAssociateConfirmParams confirmParams;
3584 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3585 confirmParams.m_status = MLMEASSOC_INVALID_PARAMETER;
3586 m_mlmeAssociateConfirmCallback(confirmParams);
3587 }
3588 NS_LOG_ERROR("Invalid channel parameter in MLME-associate");
3589 }
3590 }
3591}
3592
3593void
3595{
3596 NS_LOG_FUNCTION(this << "mac state = " << macState);
3597
3598 if (macState == MAC_IDLE)
3599 {
3602 {
3603 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3604 }
3605 else
3606 {
3607 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
3608 }
3609 }
3610 else if (macState == MAC_ACK_PENDING)
3611 {
3613 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3614 }
3615 else if (macState == MAC_CSMA)
3616 {
3619 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3620 }
3621 else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_IDLE)
3622 {
3623 // Channel is idle, set transmitter to TX_ON
3625 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
3626 }
3627 else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_ACCESS_FAILURE)
3628 {
3630
3631 // Cannot find a clear channel, drop the current packet
3632 // and send the proper confirm/indication according to the packet type
3633 NS_LOG_DEBUG(this << " cannot find clear channel");
3634
3636
3637 Ptr<Packet> pkt = m_txPkt->Copy();
3638 LrWpanMacHeader macHdr;
3639 pkt->RemoveHeader(macHdr);
3640
3641 if (macHdr.IsCommand())
3642 {
3643 CommandPayloadHeader cmdPayload;
3644 pkt->RemoveHeader(cmdPayload);
3645
3646 switch (cmdPayload.GetCommandFrameType())
3647 {
3649 m_macPanId = 0xffff;
3651 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3654 m_csmaCa->SetUnSlottedCsmaCa();
3657
3659 {
3660 MlmeAssociateConfirmParams confirmParams;
3661 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3663 m_mlmeAssociateConfirmCallback(confirmParams);
3664 }
3665 break;
3666 }
3669 {
3670 MlmeCommStatusIndicationParams commStatusParams;
3671 commStatusParams.m_panId = m_macPanId;
3672 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
3673 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
3674 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
3675 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
3676 commStatusParams.m_status =
3678 m_mlmeCommStatusIndicationCallback(commStatusParams);
3679 }
3681 break;
3682 }
3684 m_macPanId = 0xffff;
3686 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3689 m_csmaCa->SetUnSlottedCsmaCa();
3692
3694 {
3695 MlmePollConfirmParams pollConfirmParams;
3696 pollConfirmParams.m_status =
3698 m_mlmePollConfirmCallback(pollConfirmParams);
3699 }
3700 break;
3701 }
3704 {
3705 MlmeCommStatusIndicationParams commStatusParams;
3706 commStatusParams.m_panId = m_macPanId;
3707 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
3708 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
3709 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
3710 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
3711 commStatusParams.m_status =
3713 m_mlmeCommStatusIndicationCallback(commStatusParams);
3714 }
3715 break;
3716 }
3719 {
3720 m_unscannedChannels.emplace_back(m_phy->GetCurrentChannelNum());
3721 }
3722 // TODO: Handle orphan notification command during a
3723 // channel access failure when not is not scanning.
3724 break;
3725 }
3727 if (m_scanEvent.IsRunning())
3728 {
3729 m_unscannedChannels.emplace_back(m_phy->GetCurrentChannelNum());
3730 }
3731 // TODO: Handle beacon request command during a
3732 // channel access failure when not scanning.
3733 break;
3734 }
3735 default: {
3736 // TODO: Other commands(e.g. Disassociation notification, etc)
3737 break;
3738 }
3739 }
3741 }
3742 else if (macHdr.IsData())
3743 {
3745 {
3746 McpsDataConfirmParams confirmParams;
3747 confirmParams.m_msduHandle = m_txQueue.front()->txQMsduHandle;
3749 m_mcpsDataConfirmCallback(confirmParams);
3750 }
3751 // remove the copy of the packet that was just sent
3753 }
3754 else
3755 {
3756 // TODO:: specify behavior for other packets
3757 m_txPkt = nullptr;
3758 m_retransmission = 0;
3759 m_numCsmacaRetry = 0;
3760 }
3761
3764 {
3765 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3766 }
3767 else
3768 {
3769 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
3770 }
3771 }
3772 else if (m_lrWpanMacState == MAC_CSMA && macState == MAC_CSMA_DEFERRED)
3773 {
3775 m_txPkt = nullptr;
3776 // The MAC is running on beacon mode and the current packet could not be sent in the
3777 // current CAP. The packet will be send on the next CAP after receiving the beacon.
3778 // The PHY state does not change from its current form. The PHY change (RX_ON) will be
3779 // triggered by the scheduled beacon event.
3780
3781 NS_LOG_DEBUG("****** PACKET DEFERRED to the next superframe *****");
3782 }
3783}
3784
3787{
3788 return m_associationStatus;
3789}
3790
3791void
3793{
3794 m_associationStatus = status;
3795}
3796
3797void
3799{
3800 m_maxTxQueueSize = queueSize;
3801}
3802
3803void
3805{
3806 m_maxIndTxQueueSize = queueSize;
3807}
3808
3809uint16_t
3811{
3812 return m_macPanId;
3813}
3814
3817{
3819}
3820
3823{
3825}
3826
3827void
3828LrWpanMac::SetPanId(uint16_t panId)
3829{
3830 m_macPanId = panId;
3831}
3832
3833void
3835{
3836 NS_LOG_LOGIC(this << " change lrwpan mac state from " << m_lrWpanMacState << " to "
3837 << newState);
3839 m_lrWpanMacState = newState;
3840}
3841
3842uint64_t
3844{
3845 return lrwpan::aUnitBackoffPeriod + lrwpan::aTurnaroundTime + m_phy->GetPhySHRDuration() +
3846 ceil(6 * m_phy->GetPhySymbolsPerOctet());
3847}
3848
3849uint8_t
3851{
3852 return m_macMaxFrameRetries;
3853}
3854
3855void
3857{
3858 NS_LOG_DEBUG("Transmit Queue Size: " << m_txQueue.size());
3859}
3860
3861void
3863{
3864 m_macMaxFrameRetries = retries;
3865}
3866
3867bool
3869{
3871 LrWpanMacHeader macHdr;
3872 m_txPkt->PeekHeader(macHdr);
3873
3874 if (m_coor)
3875 {
3876 // The device is its coordinator and the packet is not to itself
3877 return false;
3878 }
3879 else if (m_macCoordShortAddress == macHdr.GetShortDstAddr() ||
3881 {
3882 return true;
3883 }
3884 else
3885 {
3886 NS_LOG_DEBUG("ERROR: Packet not for the coordinator!");
3887 return false;
3888 }
3889}
3890
3893{
3895
3897 {
3898 return m_macSIFSPeriod;
3899 }
3900 else
3901 {
3902 return m_macLIFSPeriod;
3903 }
3904}
3905
3906void
3908{
3910}
3911
3912void
3914{
3916}
3917
3918uint64_t
3920{
3922 // Sync Header (SHR) + 8 bits PHY header (PHR) + PSDU
3923 return (m_phy->GetPhySHRDuration() + 1 * m_phy->GetPhySymbolsPerOctet() +
3924 (m_txPkt->GetSize() * m_phy->GetPhySymbolsPerOctet()));
3925}
3926
3927bool
3929{
3931 LrWpanMacHeader macHdr;
3932 m_txPkt->PeekHeader(macHdr);
3933
3934 return macHdr.IsAckReq();
3935}
3936
3937} // namespace ns3
Implements the header for the MAC payload beacon frame according to the IEEE 802.15....
GtsFields GetGtsFields() const
Get the Guaranteed Time Slots (GTS) fields from the beacon payload header.
PendingAddrFields GetPndAddrFields() const
Get the pending address fields from the beacon payload header.
void SetSuperframeSpecField(SuperframeField sfrmField)
Set the superframe specification field to the beacon payload header.
void SetGtsFields(GtsFields gtsFields)
Set the superframe Guaranteed Time Slot (GTS) fields to the beacon payload header.
SuperframeField GetSuperframeSpecField() const
Get the superframe specification field from the beacon payload header.
void SetPndAddrFields(PendingAddrFields pndAddrFields)
Set the superframe Pending Address fields to the beacon payload header.
bool IsNull() const
Check for null implementation.
Definition: callback.h:567
Implements the header for the MAC payload command frame according to the IEEE 802....
void SetPage(uint8_t page)
Set the logical channel page number.
@ SUCCESSFUL
Association successful.
CapabilityField GetCapabilityField() const
Get the Capability Information Field from the command payload header.
void SetPanId(uint16_t id)
Get the PAN identifier.
Mac16Address GetShortAddr() const
Get the Short address assigned by the coordinator (Association Response and Coordinator Realigment co...
void SetCapabilityField(CapabilityField cap)
Set the Capability Information Field to the command payload header (Association Request Command).
AssocStatus GetAssociationStatus() const
Get the status resulting from an association request (Association Response Command).
void SetAssociationStatus(AssocStatus status)
Set status resulting from the association attempt (Association Response Command).
MacCommand GetCommandFrameType() const
Get the command frame type ID.
@ ASSOCIATION_RESP
Association response (RFD true: Rx)
@ BEACON_REQ
Beacon Request (RFD true: none )
@ DATA_REQ
Data Request (RFD true: Tx)
@ ORPHAN_NOTIF
Orphan Notification (RFD true: Tx)
@ ASSOCIATION_REQ
Association request (RFD true: Tx)
@ COOR_REALIGN
Coordinator Realignment (RFD true: Rx)
Mac16Address GetCoordShortAddr() const
Get the coordinator short address.
uint16_t GetPanId() const
Get the PAN identifier.
void SetCommandFrameType(MacCommand macCmd)
Set the command frame type.
void SetCoordShortAddr(Mac16Address addr)
Set the coordinator short address (16 bit address).
void SetShortAddr(Mac16Address shortAddr)
Set the Short Address Assigned by the coordinator (Association Response and Coordinator Realigment Co...
void SetChannel(uint8_t channel)
Set the logical channel number.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
Represent the GTS information fields.
bool GetGtsPermit() const
Get the GTS Specification Permit.
Represent the Mac Header with the Frame Control and Sequence Number fields.
Mac16Address GetShortSrcAddr() const
Get the Source Short address.
@ LRWPAN_MAC_BEACON
LRWPAN_MAC_BEACON.
@ LRWPAN_MAC_COMMAND
LRWPAN_MAC_COMMAND.
@ LRWPAN_MAC_DATA
LRWPAN_MAC_DATA.
@ LRWPAN_MAC_ACKNOWLEDGMENT
LRWPAN_MAC_ACKNOWLEDGMENT.
@ LRWPAN_MAC_RESERVED
LRWPAN_MAC_RESERVED.
bool IsCommand() const
Returns true if the header is a command.
bool IsBeacon() const
Returns true if the header is a beacon.
Mac64Address GetExtSrcAddr() const
Get the Source Extended address.
void SetNoPanIdComp()
Set the Frame Control field "PAN ID Compression" bit to false.
uint8_t GetSrcAddrMode() const
Get the Source Addressing Mode of Frame control field.
void SetPanIdComp()
Set the Frame Control field "PAN ID Compression" bit to true.
void SetSrcAddrMode(uint8_t addrMode)
Set the Source address mode.
uint8_t GetDstAddrMode() const
Get the Dest.
void SetSecDisable()
Set the Frame Control field "Security Enabled" bit to false.
void SetSrcAddrFields(uint16_t panId, Mac16Address addr)
Set Source address fields.
bool IsAcknowledgment() const
Returns true if the header is an ack.
bool IsData() const
Returns true if the header is a data.
void SetDstAddrFields(uint16_t panId, Mac16Address addr)
Set Destination address fields.
uint8_t GetSeqNum() const
Get the frame Sequence number.
void SetDstAddrMode(uint8_t addrMode)
Set the Destination address mode.
void SetNoAckReq()
Set the Frame Control field "Ack. Request" bit to false.
Mac64Address GetExtDstAddr() const
Get the Destination Extended address.
LrWpanMacType GetType() const
Get the header type.
uint16_t GetDstPanId() const
Get the Destination PAN ID.
uint8_t GetFrameVer() const
Get the Frame Version of Frame control field.
void SetFrameVer(uint8_t ver)
Set the Frame version.
uint16_t GetSrcPanId() const
Get the Source PAN ID.
bool IsAckReq() const
Check if Ack.
Mac16Address GetShortDstAddr() const
Get the Destination Short address.
void SetAckReq()
Set the Frame Control field "Ack. Request" bit to true.
Class that implements the LR-WPAN MAC state machine.
Definition: lr-wpan-mac.h:838
uint32_t m_incomingBeaconInterval
Indication of the interval a node should receive a superframe expressed in symbols.
Definition: lr-wpan-mac.h:1492
uint32_t GetIfsSize()
Get the size of the Interframe Space according to MPDU size (m_txPkt).
Ptr< LrWpanCsmaCa > m_csmaCa
The CSMA/CA implementation used by this MAC.
Definition: lr-wpan-mac.h:2014
uint64_t m_assocRespCmdWaitTime
The maximum wait time for an association response command after the reception of data request command...
Definition: lr-wpan-mac.h:1288
McpsDataConfirmCallback m_mcpsDataConfirmCallback
This callback is used to report data transmission request status to the upper layers.
Definition: lr-wpan-mac.h:2099
uint64_t GetMacAckWaitDuration() const
Get the macAckWaitDuration attribute value.
Time m_macBeaconRxTime
The time that the device received its last bit of the beacon frame.
Definition: lr-wpan-mac.h:1273
void PlmeCcaConfirm(LrWpanPhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.2.2 PLME-CCA.confirm status.
~LrWpanMac() override
Definition: lr-wpan-mac.cc:224
bool m_macRxOnWhenIdle
Indication of whether the MAC sublayer is to enable its receiver during idle periods.
Definition: lr-wpan-mac.h:1426
bool m_macAssociationPermit
Indication of whether a coordinator is currently allowing association.
Definition: lr-wpan-mac.h:1445
TracedCallback< Ptr< const Packet > > m_macTxOkTrace
The trace source fired when packets where successfully transmitted, that is an acknowledgment was rec...
Definition: lr-wpan-mac.h:1911
void SetMlmeBeaconNotifyIndicationCallback(MlmeBeaconNotifyIndicationCallback c)
Set the callback for the indication of an incoming beacon packet.
uint64_t m_rxBeaconSymbols
The total size of the received beacon in symbols.
Definition: lr-wpan-mac.h:1343
void SetRxOnWhenIdle(bool rxOnWhenIdle)
Set if the receiver should be enabled when the MAC is idle.
Definition: lr-wpan-mac.cc:302
uint64_t GetTxPacketSymbols()
Obtain the number of symbols in the packet which is currently being sent by the MAC layer.
void MlmeGetRequest(LrWpanMacPibAttributeIdentifier id)
IEEE 802.15.4-2011, section 6.2.5.1 MLME-GET.request Request information about a given PIB attribute.
Definition: lr-wpan-mac.cc:944
bool m_panCoor
Indication of whether the current device is the PAN coordinator.
Definition: lr-wpan-mac.h:1469
void SetMlmeAssociateIndicationCallback(MlmeAssociateIndicationCallback c)
Set the callback for the indication of an incoming associate request command.
void PlmeSetTRXStateConfirm(LrWpanPhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.2.8 PLME-SET-TRX-STATE.confirm Set PHY state.
uint8_t m_numCsmacaRetry
The number of CSMA/CA retries used for sending the current packet.
Definition: lr-wpan-mac.h:2219
void MlmeSyncRequest(MlmeSyncRequestParams params)
IEEE 802.15.4-2011, section 6.2.13.1 MLME-SYNC.request Request to synchronize with the coordinator by...
Definition: lr-wpan-mac.cc:845
static TypeId GetTypeId()
Get the type ID.
Definition: lr-wpan-mac.cc:52
MlmeStartConfirmCallback m_mlmeStartConfirmCallback
This callback is used to report the start of a new PAN or the begin of a new superframe configuration...
Definition: lr-wpan-mac.h:2068
uint8_t m_deviceCapability
Indication of current device capability (FFD or RFD)
Definition: lr-wpan-mac.h:1503
void AwaitBeacon()
Called after the end of an INCOMING superframe to start the moment a device waits for a new incoming ...
bool m_coor
Indicates if the current device is a coordinator type.
Definition: lr-wpan-mac.h:1474
void LostAssocRespCommand()
Called after m_assocRespCmdWaitTime timeout while waiting for an association response command.
bool isCoordDest()
Check if the packet destination is its coordinator.
EventId m_trackingEvent
Scheduler event to track the incoming beacons.
Definition: lr-wpan-mac.h:2275
void SetMlmeScanConfirmCallback(MlmeScanConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
uint32_t m_maxIndTxQueueSize
The maximum size of the indirect transmit queue (The pending transaction list).
Definition: lr-wpan-mac.h:2163
EventId m_assocResCmdWaitTimeout
Scheduler event for the lost of a association response command frame.
Definition: lr-wpan-mac.h:2235
void PurgeInd()
Purge expired transactions from the pending transactions list.
void SetMlmePollConfirmCallback(MlmePollConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
void RemoveFirstTxQElement()
Remove the tip of the transmission queue, including clean up related to the last packet transmission.
void PlmeEdConfirm(LrWpanPhyEnumeration status, uint8_t energyLevel)
IEEE 802.15.4-2006 section 6.2.2.4 PLME-ED.confirm status and energy level.
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
Definition: lr-wpan-mac.h:1945
TracedCallback< Ptr< const Packet > > m_promiscSnifferTrace
A trace source that emulates a promiscuous mode protocol sniffer connected to the device.
Definition: lr-wpan-mac.h:1994
void SetExtendedAddress(Mac64Address address)
Set the extended address of this MAC.
Definition: lr-wpan-mac.cc:328
void MlmeStartRequest(MlmeStartRequestParams params)
IEEE 802.15.4-2006, section 7.1.14.1 MLME-START.request Request to allow a PAN coordinator to initiat...
Definition: lr-wpan-mac.cc:549
uint32_t m_macLIFSPeriod
The minimum time forming a Long InterFrame Spacing (LIFS) period.
Definition: lr-wpan-mac.h:1432
void StartInactivePeriod(SuperframeType superframeType)
Start the Inactive Period in a beacon-enabled mode.
TracedCallback< Ptr< const Packet > > m_macTxDropTrace
The trace source fired when packets are dropped due to missing ACKs or because of transmission failur...
Definition: lr-wpan-mac.h:1919
void SetMcpsDataIndicationCallback(McpsDataIndicationCallback c)
Set the callback for the indication of an incoming data packet.
TracedCallback< Ptr< const Packet > > m_macIndTxDequeueTrace
The trace source fired when packets are dequeued from the L3/l2 indirect transmission queue (Pending ...
Definition: lr-wpan-mac.h:1895
TracedCallback< Ptr< const Packet > > m_macIndTxDropTrace
The trace source fired when packets are dropped due to indirect Tx queue overflows or expiration.
Definition: lr-wpan-mac.h:1927
void SetMlmeAssociateConfirmCallback(MlmeAssociateConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
MlmeScanConfirmCallback m_mlmeScanConfirmCallback
This callback is used to report the result of a scan on a group of channels for the selected channel ...
Definition: lr-wpan-mac.h:2047
Mac16Address GetShortAddress() const
Get the short address of this MAC.
Definition: lr-wpan-mac.cc:335
void SendDataRequestCommand()
Used to send a data request command (i.e.
void SetMlmeStartConfirmCallback(MlmeStartConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
SuperframeField GetSuperframeField()
Constructs a Superframe specification field from the local information, the superframe Specification ...
EventId m_cfpEvent
Scheduler event for the end of the outgoing superframe CFP.
Definition: lr-wpan-mac.h:2260
void PlmeGetAttributeConfirm(LrWpanPhyEnumeration status, LrWpanPibAttributeIdentifier id, Ptr< LrWpanPhyPibAttributes > attribute)
IEEE 802.15.4-2006 section 6.2.2.6 PLME-GET.confirm Get attributes per definition from Table 23 in se...
uint8_t m_macMaxFrameRetries
The maximum number of retries allowed after a transmission failure.
Definition: lr-wpan-mac.h:1419
Mac64Address m_macCoordExtendedAddress
The extended address of the coordinator through which the device is associated.
Definition: lr-wpan-mac.h:1304
MlmeSyncLossIndicationCallback m_mlmeSyncLossIndicationCallback
This callback is used to indicate the loss of synchronization with a coordinator.
Definition: lr-wpan-mac.h:2040
PendingPrimitiveStatus m_pendPrimitive
Indicates the pending primitive when PLME.SET operation (page or channel switch) is called from withi...
Definition: lr-wpan-mac.h:2208
MlmePollConfirmCallback m_mlmePollConfirmCallback
This callback is used to report the status after a device send data command request to the coordinato...
Definition: lr-wpan-mac.h:2061
uint8_t GetMacMaxFrameRetries() const
Get the macMaxFrameRetries attribute value.
uint16_t m_channelScanIndex
The channel list index used to obtain the current scanned channel.
Definition: lr-wpan-mac.h:2202
uint16_t GetPanId() const
Get the PAN id used by this MAC.
PendingAddrFields GetPendingAddrFields()
Constructs Pending Address Fields from the local information, the Pending Address Fields are part of ...
std::vector< PanDescriptor > m_panDescriptorList
The list of PAN descriptors accumulated during channel scans, used to select a PAN to associate.
Definition: lr-wpan-mac.h:2169
void SendBeaconRequestCommand()
Called to send a beacon request command.
EventId m_respWaitTimeout
Scheduler event for a response to a request command frame.
Definition: lr-wpan-mac.h:2230
uint32_t m_maxTxQueueSize
The maximum size of the transmit queue.
Definition: lr-wpan-mac.h:2158
Ptr< Packet > m_macBeaconPayload
The contents of the beacon payload.
Definition: lr-wpan-mac.h:1407
std::deque< Ptr< TxQueueElement > > m_txQueue
The transmit queue used by the MAC.
Definition: lr-wpan-mac.h:2147
SequenceNumber8 m_macBsn
Sequence number added to transmitted beacon frame, 00-ff.
Definition: lr-wpan-mac.h:1400
LrWpanAssociationStatus m_associationStatus
The current association status of the MAC layer.
Definition: lr-wpan-mac.h:2119
Ptr< Packet > m_rxPkt
The command request packet received.
Definition: lr-wpan-mac.h:2130
TracedCallback< Ptr< const Packet > > m_macIndTxEnqueueTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition,...
Definition: lr-wpan-mac.h:1887
void SetLrWpanMacState(LrWpanMacState macState)
CSMA-CA algorithm calls back the MAC after executing channel assessment.
Mac16Address m_shortAddress
The short address (16 bit address) used by this MAC.
Definition: lr-wpan-mac.h:2137
uint8_t m_macSuperframeOrder
Used by a PAN coordinator or coordinator.
Definition: lr-wpan-mac.h:1326
void SetCsmaCa(Ptr< LrWpanCsmaCa > csmaCa)
Set the CSMA/CA implementation to be used by the MAC.
void BeaconSearchTimeout()
Called if the device is unable to locate a beacon in the time set by MLME-SYNC.request.
bool isTxAckReq()
Check if the packet to transmit requires acknowledgment.
std::vector< uint8_t > m_energyDetectList
The list of energy measurements, one for each channel searched during an ED scan.
Definition: lr-wpan-mac.h:2174
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 SendOneBeacon()
Called to send a single beacon frame.
Definition: lr-wpan-mac.cc:978
Time m_macBeaconTxTime
The time that the device transmitted its last beacon frame.
Definition: lr-wpan-mac.h:1265
MlmeBeaconNotifyIndicationCallback m_mlmeBeaconNotifyIndicationCallback
This callback is used to notify incoming beacon packets to the upper layers.
Definition: lr-wpan-mac.h:2034
void EndStartRequest()
Called to end a MLME-START.request after changing the page and channel number.
TracedCallback< LrWpanMacState, LrWpanMacState > m_macStateLogger
A trace source that fires when the LrWpanMac changes states.
Definition: lr-wpan-mac.h:2004
Mac64Address GetExtendedAddress() const
Get the extended address of this MAC.
Definition: lr-wpan-mac.cc:342
EventId m_setMacState
Scheduler event for a deferred MAC state change.
Definition: lr-wpan-mac.h:2240
uint64_t m_macResponseWaitTime
The maximum time, in multiples of aBaseSuperframeDuration, a device shall wait for a response command...
Definition: lr-wpan-mac.h:1280
void EnqueueInd(Ptr< Packet > p)
Adds a packet to the pending transactions list (Indirect transmissions).
void SendAssocResponseCommand(Ptr< Packet > rxDataReqPkt)
Called to send an associate response command.
void SetMlmeSetConfirmCallback(MlmeSetConfirmCallback c)
Set the callback for the confirmation of an attempt to write an attribute.
void StartCFP(SuperframeType superframeType)
Called to begin the Contention Free Period (CFP) in a beacon-enabled mode.
EventId m_scanEnergyEvent
Scheduler event for the end of a ED channel scan.
Definition: lr-wpan-mac.h:2290
void SetMcpsDataConfirmCallback(McpsDataConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
bool PrepareRetransmission()
Check for remaining retransmissions for the packet currently being sent.
void SetAssociationStatus(LrWpanAssociationStatus status)
Set the current association status.
void MlmeAssociateRequest(MlmeAssociateRequestParams params)
IEEE 802.15.4-2011, section 6.2.2.1 MLME-ASSOCIATE.request Request primitive used by a device to requ...
Definition: lr-wpan-mac.cc:648
void EnqueueTxQElement(Ptr< TxQueueElement > txQElement)
Add an element to the transmission queue.
void SetPanId(uint16_t panId)
Set the PAN id used by this MAC.
EventId m_scanEvent
Scheduler event for the end of an ACTIVE or PASSIVE channel scan.
Definition: lr-wpan-mac.h:2280
TracedCallback< Ptr< const Packet > > m_snifferTrace
A trace source that emulates a non-promiscuous protocol sniffer connected to the device.
Definition: lr-wpan-mac.h:1974
uint8_t m_incomingBeaconOrder
The beaconOrder value of the INCOMING frame.
Definition: lr-wpan-mac.h:1355
SequenceNumber8 m_macDsn
Sequence number added to transmitted data or MAC command frame, 00-ff.
Definition: lr-wpan-mac.h:1394
void SetMlmeSyncLossIndicationCallback(MlmeSyncLossIndicationCallback c)
Set the callback for the loss of synchronization with a coordinator.
void SendOrphanNotificationCommand()
Called to send a orphan notification command.
uint32_t m_ifs
The value of the necessary InterFrame Space after the transmission of a packet.
Definition: lr-wpan-mac.h:1464
uint16_t m_macTransactionPersistenceTime
The maximum time (in UNIT periods) that a transaction is stored by a coordinator and indicated in its...
Definition: lr-wpan-mac.h:1337
Mac16Address GetCoordShortAddress() const
Get the coordinator short address currently associated to this device.
void ChangeMacState(LrWpanMacState newState)
Change the current MAC state to the given new state.
MlmeStartRequestParams m_startParams
The parameters used during a MLME-START.request.
Definition: lr-wpan-mac.h:2191
void AckWaitTimeout()
Handle an ACK timeout with a packet retransmission, if there are retransmission left,...
void MlmeScanRequest(MlmeScanRequestParams params)
IEEE 802.15.4-2011, section 6.2.10.1 MLME-SCAN.request Request primitive used to initiate a channel s...
Definition: lr-wpan-mac.cc:588
LrWpanAssociationStatus GetAssociationStatus() const
Get the current association status.
std::vector< uint8_t > m_unscannedChannels
The list of unscanned channels during a scan operation.
Definition: lr-wpan-mac.h:2179
Mac64Address GetCoordExtAddress() const
Get the coordinator extended address currently associated to this device.
uint8_t m_macBeaconOrder
Used by a PAN coordinator or coordinator.
Definition: lr-wpan-mac.h:1318
TracedCallback< Time > m_macIfsEndTrace
The trace source is fired at the end of any Interframe Space (IFS).
Definition: lr-wpan-mac.h:1851
void SetMlmeGetConfirmCallback(MlmeGetConfirmCallback c)
Set the callback for the confirmation of an attempt to read an attribute.
TracedValue< SuperframeStatus > m_outSuperframeStatus
The current period of the outgoing superframe.
Definition: lr-wpan-mac.h:2114
void PlmeSetAttributeConfirm(LrWpanPhyEnumeration status, LrWpanPibAttributeIdentifier id)
IEEE 802.15.4-2006 section 6.2.2.10 PLME-SET.confirm Set attributes per definition from Table 23 in s...
MlmeOrphanIndicationCallback m_mlmeOrphanIndicationCallback
This callback is used to indicate the reception of a orphan notification command.
Definition: lr-wpan-mac.h:2092
void SetMlmeCommStatusIndicationCallback(MlmeCommStatusIndicationCallback c)
Set the callback for the indication to a response primitive.
bool DequeueInd(Mac64Address dst, Ptr< IndTxQueueElement > entry)
Extracts a packet from pending transactions list (Indirect transmissions).
MlmeAssociateRequestParams m_associateParams
The parameters used during a MLME-ASSOCIATE.request.
Definition: lr-wpan-mac.h:2197
LrWpanMac()
Default constructor.
Definition: lr-wpan-mac.cc:163
void CheckQueue()
Check the transmission queue.
EventId m_ackWaitTimeout
Scheduler event for the ACK timeout of the currently transmitted data packet.
Definition: lr-wpan-mac.h:2225
MlmeAssociateConfirmCallback m_mlmeAssociateConfirmCallback
This callback is used to report the status after a device request an association with a coordinator.
Definition: lr-wpan-mac.h:2054
bool m_macPromiscuousMode
Indicates if MAC sublayer is in receive all mode.
Definition: lr-wpan-mac.h:1375
uint8_t m_fnlCapSlot
Indication of the Slot where the CAP portion of the OUTGOING Superframe ends.
Definition: lr-wpan-mac.h:1348
uint32_t m_macSIFSPeriod
The minimum time forming a Short InterFrame Spacing (SIFS) period.
Definition: lr-wpan-mac.h:1438
void IfsWaitTimeout(Time ifsTime)
After a successful transmission of a frame (beacon, data) or an ack frame reception,...
std::deque< Ptr< IndTxQueueElement > > m_indTxQueue
The indirect transmit queue used by the MAC pending messages (The pending transaction list).
Definition: lr-wpan-mac.h:2153
uint32_t m_beaconInterval
Indication of the Interval used by the coordinator to transmit beacon frames expressed in symbols.
Definition: lr-wpan-mac.h:1480
TracedValue< LrWpanMacState > m_lrWpanMacState
The current state of the MAC layer.
Definition: lr-wpan-mac.h:2104
TracedCallback< Ptr< const Packet > > m_macTxEnqueueTrace
The trace source fired when packets come into the "top" of the device at the L3/L2 transition,...
Definition: lr-wpan-mac.h:1871
EventId m_capEvent
Scheduler event for the end of the outgoing superframe CAP.
Definition: lr-wpan-mac.h:2255
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets are being sent down to L1.
Definition: lr-wpan-mac.h:1902
uint16_t m_macPanId
16 bits id of PAN on which this device is operating.
Definition: lr-wpan-mac.h:1382
void EndChannelScan()
Called at the end of the current channel scan (Active or Passive) for a given duration.
void DoInitialize() override
Initialize() implementation.
Definition: lr-wpan-mac.cc:229
void MlmeAssociateResponse(MlmeAssociateResponseParams params)
IEEE 802.15.4-2011, section 6.2.2.3 MLME-ASSOCIATE.response Primitive used to initiate a response to ...
Definition: lr-wpan-mac.cc:723
void PrintTxQueue(std::ostream &os) const
Print the Transmit Queue.
TracedCallback< Ptr< const Packet > > m_macRxDropTrace
The trace source fired for packets successfully received by the device but dropped before being forwa...
Definition: lr-wpan-mac.h:1954
bool m_macAutoRequest
Indication of whether a device automatically sends data request command if its address is listed in t...
Definition: lr-wpan-mac.h:1454
uint8_t m_incomingSuperframeOrder
Used by all devices that have a parent.
Definition: lr-wpan-mac.h:1363
uint16_t m_macPanIdScan
Temporally stores the value of the current m_macPanId when a MLME-SCAN.request is performed.
Definition: lr-wpan-mac.h:1388
uint32_t m_macBeaconPayloadLength
The length, in octets, of the beacon payload.
Definition: lr-wpan-mac.h:1413
TracedCallback< Ptr< const Packet > > m_macTxDequeueTrace
The trace source fired when packets are dequeued from the L3/l2 transmission queue.
Definition: lr-wpan-mac.h:1879
void PdDataConfirm(LrWpanPhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.1.2 Confirm the end of transmission of an MPDU to MAC.
uint8_t m_numLostBeacons
The number of consecutive loss beacons in a beacon tracking operation.
Definition: lr-wpan-mac.h:1513
Ptr< Packet > m_txPkt
The packet which is currently being sent by the MAC layer.
Definition: lr-wpan-mac.h:2124
void McpsDataRequest(McpsDataRequestParams params, Ptr< Packet > p)
IEEE 802.15.4-2006, section 7.1.1.1 MCPS-DATA.request Request to transfer a MSDU.
Definition: lr-wpan-mac.cc:349
void SendAssocRequestCommand()
Called to send an associate request command.
uint8_t m_maxEnergyLevel
The maximum energy level detected during ED scan on the current channel.
Definition: lr-wpan-mac.h:1459
void DoDispose() override
Destructor implementation.
Definition: lr-wpan-mac.cc:244
MlmeScanRequestParams m_scanParams
The parameters used during a MLME-SCAN.request.
Definition: lr-wpan-mac.h:2185
MlmeAssociateIndicationCallback m_mlmeAssociateIndicationCallback
This callback is used to indicate the reception of an association request command.
Definition: lr-wpan-mac.h:2080
void SetPhy(Ptr< LrWpanPhy > phy)
Set the underlying PHY for the MAC.
Ptr< LrWpanPhy > GetPhy()
Get the underlying PHY of the MAC.
EventId m_scanOrphanEvent
Scheduler event for the end of an ORPHAN channel scan.
Definition: lr-wpan-mac.h:2285
void EndAssociateRequest()
Called to end an MLME-ASSOCIATE.request after changing the page and channel number.
Definition: lr-wpan-mac.cc:703
MlmeSetConfirmCallback m_mlmeSetConfirmCallback
This callback is used to report the result of an attribute writing request to the upper layers.
Definition: lr-wpan-mac.h:2021
Mac64Address m_selfExt
The extended 64 address (IEEE EUI-64) used by this MAC.
Definition: lr-wpan-mac.h:2142
MlmeGetConfirmCallback m_mlmeGetConfirmCallback
This callback is used to report the result of an attribute read request to the upper layers.
Definition: lr-wpan-mac.h:2028
EventId m_incCapEvent
Scheduler event for the end of the incoming superframe CAP.
Definition: lr-wpan-mac.h:2265
void SetTxQMaxSize(uint32_t queueSize)
Set the max size of the transmit queue.
void SetIndTxQMaxSize(uint32_t queueSize)
Set the max size of the indirect transmit queue (Pending Transaction list)
McpsDataIndicationCallback m_mcpsDataIndicationCallback
This callback is used to notify incoming packets to the upper layers.
Definition: lr-wpan-mac.h:2074
bool m_beaconTrackingOn
Indication of whether the current device is tracking incoming beacons.
Definition: lr-wpan-mac.h:1508
uint32_t m_superframeDuration
Indication of the superframe duration in symbols.
Definition: lr-wpan-mac.h:1486
bool GetRxOnWhenIdle() const
Check if the receiver will be enabled when the MAC is idle.
Definition: lr-wpan-mac.cc:296
Mac16Address m_macCoordShortAddress
The short address of the coordinator through which the device is associated.
Definition: lr-wpan-mac.h:1297
GtsFields GetGtsFields()
Constructs the Guaranteed Time Slots (GTS) Fields from local information.
void MlmeOrphanResponse(MlmeOrphanResponseParams params)
IEEE 802.15.4-2011, section 6.2.7.2 MLME-ORPHAN.response Primitive used to initiatte a response to an...
Definition: lr-wpan-mac.cc:785
Ptr< LrWpanPhy > m_phy
The PHY associated with this MAC.
Definition: lr-wpan-mac.h:2009
void EndChannelEnergyScan()
Called at the end of one ED channel scan.
void PrintTransmitQueueSize()
Print the number of elements in the packet transmit queue.
void PrintPendTxQ(std::ostream &os) const
Print the Pending transaction list.
void MlmeSetRequest(LrWpanMacPibAttributeIdentifier id, Ptr< LrWpanMacPibAttributes > attribute)
IEEE 802.15.4-2011, section 6.2.11.1 MLME-SET.request Attempts to write the given value to the indica...
Definition: lr-wpan-mac.cc:900
void StartCAP(SuperframeType superframeType)
Called to begin the Contention Access Period (CAP) in a beacon-enabled mode.
TracedCallback< Ptr< const Packet > > m_macPromiscRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
Definition: lr-wpan-mac.h:1936
void MlmePollRequest(MlmePollRequestParams params)
IEEE 802.15.4-2011, section 6.2.14.2 MLME-POLL.request Prompts the device to request data from the co...
Definition: lr-wpan-mac.cc:885
EventId m_ifsEvent
Scheduler event for Interframe spacing wait time.
Definition: lr-wpan-mac.h:2245
EventId m_beaconEvent
Scheduler event for generation of one beacon.
Definition: lr-wpan-mac.h:2250
uint32_t m_incomingSuperframeDuration
Indication of the superframe duration in symbols (e.g.
Definition: lr-wpan-mac.h:1498
TracedCallback< Ptr< const Packet >, uint8_t, uint8_t > m_sentPktTrace
The trace source fired when packets are considered as successfully sent or the transmission has been ...
Definition: lr-wpan-mac.h:1863
void RemovePendTxQElement(Ptr< Packet > p)
Remove an element from the pending transaction list.
void SetMlmeOrphanIndicationCallback(MlmeOrphanIndicationCallback c)
Set the callback for the indication to the reception of an orphan notification.
void SetShortAddress(Mac16Address address)
Set the short address of this MAC.
Definition: lr-wpan-mac.cc:321
void SetMacMaxFrameRetries(uint8_t retries)
Set the macMaxFrameRetries attribute value.
uint8_t m_retransmission
The number of already used retransmission for the currently transmitted packet.
Definition: lr-wpan-mac.h:2214
EventId m_incCfpEvent
Scheduler event for the end of the incoming superframe CFP.
Definition: lr-wpan-mac.h:2270
void SendAck(uint8_t seqno)
Send an acknowledgment packet for the given sequence number.
uint8_t m_incomingFnlCapSlot
Indication of the Slot where the CAP portion of the INCOMING Superframe ends.
Definition: lr-wpan-mac.h:1368
MlmeCommStatusIndicationCallback m_mlmeCommStatusIndicationCallback
This callback is instigated through a response primitive.
Definition: lr-wpan-mac.h:2086
TracedValue< SuperframeStatus > m_incSuperframeStatus
The current period of the incoming superframe.
Definition: lr-wpan-mac.h:2109
void SetAssociatedCoor(Mac16Address mac)
Check if the packet destination is its coordinator.
Represent the Mac Trailer with the Frame Check Sequence field.
void SetFcs(Ptr< const Packet > p)
Calculate and set the FCS value based on the given packet.
bool CheckFcs(Ptr< const Packet > p)
Check the FCS of a given packet against the FCS value stored in the trailer.
void EnableFcs(bool enable)
Enable or disable FCS calculation for this trailer.
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
bool IsMulticast() const
Checks if the address is a multicast address according to RFC 4944 Section 9 (i.e....
bool IsBroadcast() const
Checks if the address is a broadcast address according to 802.15.4 scheme (i.e., 0xFFFF).
an EUI-64 address
Definition: mac64-address.h:46
static Mac64Address Allocate()
Allocate a new Mac64Address.
static bool ChecksumEnabled()
Definition: node.cc:290
A base class which provides memory management and object aggregation.
Definition: object.h:89
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:360
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
Represent the Pending Address Specification field.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
NUMERIC_TYPE GetValue() const
Extracts the numeric value of the sequence number.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:208
Represent the Superframe Specification information field.
uint8_t GetFinalCapSlot() const
Get the the Final CAP Slot.
void SetAssocPermit(bool assocPermit)
Set the Superframe Specification Association Permit field.
void SetBattLifeExt(bool battLifeExt)
Set the Superframe Specification Battery Life Extension (BLE).
uint8_t GetBeaconOrder() const
Get the Superframe Specification Beacon Order field.
bool IsBattLifeExt() const
Check if the Battery Life Extension bit is enabled.
void SetFinalCapSlot(uint8_t capSlot)
Set the superframe specification Final CAP slot field.
void SetSuperframeOrder(uint8_t frmOrder)
Set the superframe specification Superframe Order field.
void SetPanCoor(bool panCoor)
Set the Superframe Specification PAN coordinator field.
void SetBeaconOrder(uint8_t bcnOrder)
Set the superframe specification Beacon Order field.
uint8_t GetFrameOrder() const
Get the Superframe Specification Frame Order field.
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:417
@ S
second
Definition: nstime.h:116
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:314
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:936
Hold an unsigned integer type.
Definition: uinteger.h:45
constexpr uint32_t aMaxSIFSFrameSize
The maximum size of an MPDU, in octets, that can be followed by a Short InterFrame Spacing (SIFS) per...
constexpr uint32_t aMaxLostBeacons
The number of consecutive lost beacons that will cause the MAC sublayer of a receiving device to decl...
constexpr uint32_t aMaxBeaconPayloadLength
The maximum size, in octets, of a beacon payload.
constexpr uint32_t aMaxPhyPacketSize
The maximum packet size accepted by the PHY.
Definition: