A Discrete-Event Network Simulator
API
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-csmaca.h"
28#include "lr-wpan-mac-header.h"
30#include "lr-wpan-mac-trailer.h"
31
32#include <ns3/double.h>
33#include <ns3/log.h>
34#include <ns3/node.h>
35#include <ns3/packet.h>
36#include <ns3/random-variable-stream.h>
37#include <ns3/simulator.h>
38#include <ns3/uinteger.h>
39
40#undef NS_LOG_APPEND_CONTEXT
41#define NS_LOG_APPEND_CONTEXT std::clog << "[address " << m_shortAddress << "] ";
42
43namespace ns3
44{
45
46NS_LOG_COMPONENT_DEFINE("LrWpanMac");
48
49TypeId
51{
52 static TypeId tid =
53 TypeId("ns3::LrWpanMac")
55 .SetGroupName("LrWpan")
56 .AddConstructor<LrWpanMac>()
57 .AddAttribute("PanId",
58 "16-bit identifier of the associated PAN",
61 MakeUintegerChecker<uint16_t>())
62 .AddTraceSource("MacTxEnqueue",
63 "Trace source indicating a packet has been "
64 "enqueued in the transaction queue",
66 "ns3::Packet::TracedCallback")
67 .AddTraceSource("MacTxDequeue",
68 "Trace source indicating a packet has was "
69 "dequeued from the transaction queue",
71 "ns3::Packet::TracedCallback")
72 .AddTraceSource("MacIndTxEnqueue",
73 "Trace source indicating a packet has been "
74 "enqueued in the indirect transaction queue",
76 "ns3::Packet::TracedCallback")
77 .AddTraceSource("MacIndTxDequeue",
78 "Trace source indicating a packet has was "
79 "dequeued from the indirect transaction queue",
81 "ns3::Packet::TracedCallback")
82 .AddTraceSource("MacTx",
83 "Trace source indicating a packet has "
84 "arrived for transmission by this device",
86 "ns3::Packet::TracedCallback")
87 .AddTraceSource("MacTxOk",
88 "Trace source indicating a packet has been "
89 "successfully sent",
91 "ns3::Packet::TracedCallback")
92 .AddTraceSource("MacTxDrop",
93 "Trace source indicating a packet has been "
94 "dropped during transmission",
96 "ns3::Packet::TracedCallback")
97 .AddTraceSource("MacIndTxDrop",
98 "Trace source indicating a packet has been "
99 "dropped from the indirect transaction queue"
100 "(The pending transaction list)",
102 "ns3::Packet::TracedCallback")
103 .AddTraceSource("MacPromiscRx",
104 "A packet has been received by this device, "
105 "has been passed up from the physical layer "
106 "and is being forwarded up the local protocol stack. "
107 "This is a promiscuous trace,",
109 "ns3::Packet::TracedCallback")
110 .AddTraceSource("MacRx",
111 "A packet has been received by this device, "
112 "has been passed up from the physical layer "
113 "and is being forwarded up the local protocol stack. "
114 "This is a non-promiscuous trace,",
116 "ns3::Packet::TracedCallback")
117 .AddTraceSource("MacRxDrop",
118 "Trace source indicating a packet was received, "
119 "but dropped before being forwarded up the stack",
121 "ns3::Packet::TracedCallback")
122 .AddTraceSource("Sniffer",
123 "Trace source simulating a non-promiscuous "
124 "packet sniffer attached to the device",
126 "ns3::Packet::TracedCallback")
127 .AddTraceSource("PromiscSniffer",
128 "Trace source simulating a promiscuous "
129 "packet sniffer attached to the device",
131 "ns3::Packet::TracedCallback")
132 .AddTraceSource("MacStateValue",
133 "The state of LrWpan Mac",
135 "ns3::TracedValueCallback::LrWpanMacState")
136 .AddTraceSource("MacIncSuperframeStatus",
137 "The period status of the incoming superframe",
139 "ns3::TracedValueCallback::SuperframeState")
140 .AddTraceSource("MacOutSuperframeStatus",
141 "The period status of the outgoing superframe",
143 "ns3::TracedValueCallback::SuperframeState")
144 .AddTraceSource("MacState",
145 "The state of LrWpan Mac",
147 "ns3::LrWpanMac::StateTracedCallback")
148 .AddTraceSource("MacSentPkt",
149 "Trace source reporting some information about "
150 "the sent packet",
152 "ns3::LrWpanMac::SentTracedCallback")
153 .AddTraceSource("IfsEnd",
154 "Trace source reporting the end of an "
155 "Interframe space (IFS)",
157 "ns3::Packet::TracedCallback");
158 return tid;
159}
160
162{
163 // First set the state to a known value, call ChangeMacState to fire trace source.
165
167
170
171 m_macRxOnWhenIdle = true;
172 m_macPanId = 0xffff;
174 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
178 m_macPromiscuousMode = false;
182 m_txPkt = nullptr;
183 m_rxPkt = nullptr;
184 m_ifs = 0;
185
186 m_macLIFSPeriod = 40;
187 m_macSIFSPeriod = 12;
188
189 m_panCoor = false;
190 m_macBeaconOrder = 15;
192 m_macTransactionPersistenceTime = 500; // 0x01F5
194 m_macAutoRequest = true;
195
198 m_beaconTrackingOn = false;
200
204
207
208 m_maxTxQueueSize = m_txQueue.max_size();
210
211 Ptr<UniformRandomVariable> uniformVar = CreateObject<UniformRandomVariable>();
212 uniformVar->SetAttribute("Min", DoubleValue(0.0));
213 uniformVar->SetAttribute("Max", DoubleValue(255.0));
214 m_macDsn = SequenceNumber8(uniformVar->GetValue());
215 m_macBsn = SequenceNumber8(uniformVar->GetValue());
216 m_shortAddress = Mac16Address("00:00");
217}
218
220{
221}
222
223void
225{
227 {
228 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
229 }
230 else
231 {
232 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
233 }
234
236}
237
238void
240{
241 if (m_csmaCa)
242 {
243 m_csmaCa->Dispose();
244 m_csmaCa = nullptr;
245 }
246 m_txPkt = nullptr;
247
248 for (uint32_t i = 0; i < m_txQueue.size(); i++)
249 {
250 m_txQueue[i]->txQPkt = nullptr;
251 m_txQueue[i]->txQMsduHandle = 0;
252 }
253 m_txQueue.clear();
254
255 for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
256 {
257 m_indTxQueue[i]->txQPkt = nullptr;
258 m_indTxQueue[i]->seqNum = 0;
259 m_indTxQueue[i]->dstExtAddress = nullptr;
260 m_indTxQueue[i]->dstShortAddress = nullptr;
261 }
262 m_indTxQueue.clear();
263
264 m_phy = nullptr;
265 m_mcpsDataConfirmCallback = MakeNullCallback<void, McpsDataConfirmParams>();
266 m_mcpsDataIndicationCallback = MakeNullCallback<void, McpsDataIndicationParams, Ptr<Packet>>();
267 m_mlmeStartConfirmCallback = MakeNullCallback<void, MlmeStartConfirmParams>();
269 MakeNullCallback<void, MlmeBeaconNotifyIndicationParams, Ptr<Packet>>();
270 m_mlmeSyncLossIndicationCallback = MakeNullCallback<void, MlmeSyncLossIndicationParams>();
271 m_mlmePollConfirmCallback = MakeNullCallback<void, MlmePollConfirmParams>();
272 m_mlmeScanConfirmCallback = MakeNullCallback<void, MlmeScanConfirmParams>();
273 m_mlmeAssociateConfirmCallback = MakeNullCallback<void, MlmeAssociateConfirmParams>();
274 m_mlmeAssociateIndicationCallback = MakeNullCallback<void, MlmeAssociateIndicationParams>();
275 m_mlmeCommStatusIndicationCallback = MakeNullCallback<void, MlmeCommStatusIndicationParams>();
276
278
280}
281
282bool
284{
285 return m_macRxOnWhenIdle;
286}
287
288void
290{
291 NS_LOG_FUNCTION(this << rxOnWhenIdle);
292 m_macRxOnWhenIdle = rxOnWhenIdle;
293
295 {
297 {
298 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
299 }
300 else
301 {
302 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
303 }
304 }
305}
306
307void
309{
310 NS_LOG_FUNCTION(this << address);
312}
313
314void
316{
317 NS_LOG_FUNCTION(this << address);
319}
320
323{
324 NS_LOG_FUNCTION(this);
325 return m_shortAddress;
326}
327
330{
331 NS_LOG_FUNCTION(this);
332 return m_selfExt;
333}
334
335void
337{
338 NS_LOG_FUNCTION(this << p);
339
340 McpsDataConfirmParams confirmParams;
341 confirmParams.m_msduHandle = params.m_msduHandle;
342
343 // TODO: We need a drop trace for the case that the packet is too large or the request
344 // parameters are maleformed.
345 // The current tx drop trace is not suitable, because packets dropped using this trace
346 // carry the mac header and footer, while packets being dropped here do not have them.
347
349 m_macDsn++;
350
352 {
353 // Note, this is just testing maximum theoretical frame size per the spec
354 // The frame could still be too large once headers are put on
355 // in which case the phy will reject it instead
356 NS_LOG_ERROR(this << " packet too big: " << p->GetSize());
359 {
360 m_mcpsDataConfirmCallback(confirmParams);
361 }
362 return;
363 }
364
365 if ((params.m_srcAddrMode == NO_PANID_ADDR) && (params.m_dstAddrMode == NO_PANID_ADDR))
366 {
367 NS_LOG_ERROR(this << " Can not send packet with no Address field");
370 {
371 m_mcpsDataConfirmCallback(confirmParams);
372 }
373 return;
374 }
375 switch (params.m_srcAddrMode)
376 {
377 case NO_PANID_ADDR:
378 macHdr.SetSrcAddrMode(params.m_srcAddrMode);
379 macHdr.SetNoPanIdComp();
380 break;
382 NS_ABORT_MSG("Can not set source address type to ADDR_MODE_RESERVED. Aborting.");
383 break;
384 case SHORT_ADDR:
385 macHdr.SetSrcAddrMode(params.m_srcAddrMode);
387 break;
388 case EXT_ADDR:
389 macHdr.SetSrcAddrMode(params.m_srcAddrMode);
391 break;
392 default:
393 NS_LOG_ERROR(this << " Can not send packet with incorrect Source Address mode = "
394 << params.m_srcAddrMode);
397 {
398 m_mcpsDataConfirmCallback(confirmParams);
399 }
400 return;
401 }
402 switch (params.m_dstAddrMode)
403 {
404 case NO_PANID_ADDR:
405 macHdr.SetDstAddrMode(params.m_dstAddrMode);
406 macHdr.SetNoPanIdComp();
407 break;
409 NS_ABORT_MSG("Can not set destination address type to ADDR_MODE_RESERVED. Aborting.");
410 break;
411 case SHORT_ADDR:
412 macHdr.SetDstAddrMode(params.m_dstAddrMode);
413 macHdr.SetDstAddrFields(params.m_dstPanId, params.m_dstAddr);
414 break;
415 case EXT_ADDR:
416 macHdr.SetDstAddrMode(params.m_dstAddrMode);
417 macHdr.SetDstAddrFields(params.m_dstPanId, params.m_dstExtAddr);
418 break;
419 default:
420 NS_LOG_ERROR(this << " Can not send packet with incorrect Destination Address mode = "
421 << params.m_dstAddrMode);
424 {
425 m_mcpsDataConfirmCallback(confirmParams);
426 }
427 return;
428 }
429
430 // IEEE 802.15.4-2006 (7.5.6.1)
431 // Src & Dst PANs are identical, PAN compression is ON
432 // only the dst PAN is serialized making the MAC header 2 bytes smaller
433 if ((params.m_dstAddrMode != NO_PANID_ADDR && params.m_srcAddrMode != NO_PANID_ADDR) &&
434 (macHdr.GetDstPanId() == macHdr.GetSrcPanId()))
435 {
436 macHdr.SetPanIdComp();
437 }
438
439 macHdr.SetSecDisable();
440 // extract the first 3 bits in TxOptions
441 int b0 = params.m_txOptions & TX_OPTION_ACK;
442 int b1 = params.m_txOptions & TX_OPTION_GTS;
443 int b2 = params.m_txOptions & TX_OPTION_INDIRECT;
444
445 if (b0 == TX_OPTION_ACK)
446 {
447 // Set AckReq bit only if the destination is not the broadcast address.
448 if (macHdr.GetDstAddrMode() == SHORT_ADDR)
449 {
450 // short address and ACK requested.
451 Mac16Address shortAddr = macHdr.GetShortDstAddr();
452 if (shortAddr.IsBroadcast() || shortAddr.IsMulticast())
453 {
454 NS_LOG_LOGIC("LrWpanMac::McpsDataRequest: requested an ACK on broadcast or "
455 "multicast destination ("
456 << shortAddr << ") - forcefully removing it.");
457 macHdr.SetNoAckReq();
458 params.m_txOptions &= ~uint8_t(TX_OPTION_ACK);
459 }
460 else
461 {
462 macHdr.SetAckReq();
463 }
464 }
465 else
466 {
467 // other address (not short) and ACK requested
468 macHdr.SetAckReq();
469 }
470 }
471 else
472 {
473 macHdr.SetNoAckReq();
474 }
475
476 if (b1 == TX_OPTION_GTS)
477 {
478 // TODO:GTS Transmission
479 }
480 else if (b2 == TX_OPTION_INDIRECT)
481 {
482 // Indirect Tx
483 // A COORDINATOR will save the packet in the pending queue and await for data
484 // requests from its associated devices. The devices are aware of pending data,
485 // from the pending bit information extracted from the received beacon.
486 // A DEVICE must be tracking beacons (MLME-SYNC.request is running) before attempting
487 // request data from the coordinator.
488
489 // TODO: Check if the current device is coordinator (not just pan coordinator)
490 // Indirect Transmission can only be done by PAN coordinator or coordinators.
492 p->AddHeader(macHdr);
493
494 LrWpanMacTrailer macTrailer;
495 // Calculate FCS if the global attribute ChecksumEnable is set.
497 {
498 macTrailer.EnableFcs(true);
499 macTrailer.SetFcs(p);
500 }
501 p->AddTrailer(macTrailer);
502
503 NS_LOG_ERROR(this << " Indirect transmissions not currently supported");
504 // Note: The current Pending transaction list should work for indirect transmissions.
505 // However, this is not tested yet. For now, we block the use of indirect transmissions.
506 // TODO: Save packet in the Pending Transaction list.
507 // EnqueueInd (p);
508 }
509 else
510 {
511 // Direct Tx
512 // From this point the packet will be pushed to a Tx queue and immediately
513 // use a slotted (beacon-enabled) or unslotted (nonbeacon-enabled) version of CSMA/CA
514 // before sending the packet, depending on whether it has previously
515 // received a valid beacon or not.
516
517 p->AddHeader(macHdr);
518
519 LrWpanMacTrailer macTrailer;
520 // Calculate FCS if the global attribute ChecksumEnable is set.
522 {
523 macTrailer.EnableFcs(true);
524 macTrailer.SetFcs(p);
525 }
526 p->AddTrailer(macTrailer);
527
528 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
529 txQElement->txQMsduHandle = params.m_msduHandle;
530 txQElement->txQPkt = p;
531 EnqueueTxQElement(txQElement);
532 CheckQueue();
533 }
534}
535
536void
538{
539 NS_LOG_FUNCTION(this);
541
542 MlmeStartConfirmParams confirmParams;
543
544 if (GetShortAddress() == Mac16Address("ff:ff"))
545 {
546 NS_LOG_ERROR(this << " Invalid MAC short address");
547 confirmParams.m_status = MLMESTART_NO_SHORT_ADDRESS;
549 {
550 m_mlmeStartConfirmCallback(confirmParams);
551 }
552 return;
553 }
554
555 if ((params.m_bcnOrd > 15) || (params.m_sfrmOrd > params.m_bcnOrd))
556 {
559 {
560 m_mlmeStartConfirmCallback(confirmParams);
561 }
562 NS_LOG_ERROR(this << "Incorrect superframe order or beacon order.");
563 return;
564 }
565
566 // Mark primitive as pending and save the start params while the new page and channel is set.
568 m_startParams = params;
569
572 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, &pibAttr);
573}
574
575void
577{
578 NS_LOG_FUNCTION(this);
579
580 MlmeScanConfirmParams confirmParams;
581 confirmParams.m_scanType = params.m_scanType;
582 confirmParams.m_chPage = params.m_chPage;
583
585 {
587 {
588 confirmParams.m_status = MLMESCAN_SCAN_IN_PROGRESS;
589 m_mlmeScanConfirmCallback(confirmParams);
590 }
591 NS_LOG_ERROR(this << " A channel scan is already in progress");
592 return;
593 }
594
595 if (params.m_scanDuration > 14 || params.m_scanType > MLMESCAN_PASSIVE)
596 {
598 {
599 confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
600 m_mlmeScanConfirmCallback(confirmParams);
601 }
602 NS_LOG_ERROR(this << "Invalid scan duration or unsupported scan type");
603 return;
604 }
605 // Temporary store macPanId and set macPanId to 0xFFFF to accept all beacons.
607 m_macPanId = 0xFFFF;
608
609 m_panDescriptorList.clear();
610 m_energyDetectList.clear();
611
612 // TODO: stop beacon transmission
613
614 // Cancel any ongoing CSMA/CA operations and set to unslotted mode for scan
615 m_csmaCa->Cancel();
621 m_csmaCa->SetUnSlottedCsmaCa();
622
624
625 // Mark primitive as pending and save the scan params while the new page and/or channel is set.
626 m_scanParams = params;
628
630 pibAttr.phyCurrentPage = params.m_chPage;
631 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, &pibAttr);
632}
633
634void
636{
637 NS_LOG_FUNCTION(this);
638
639 // Association is typically preceded by beacon reception and a MLME-SCAN.request, therefore,
640 // the values of the Associate.request params usually come from the information
641 // obtained from those operations.
643 m_associateParams = params;
644 bool invalidRequest = false;
645
646 if (params.m_coordPanId == 0xffff)
647 {
648 invalidRequest = true;
649 }
650
651 if (!invalidRequest && params.m_coordAddrMode == SHORT_ADDR)
652 {
653 if (params.m_coordShortAddr == Mac16Address("ff:ff") ||
654 params.m_coordShortAddr == Mac16Address("ff:fe"))
655 {
656 invalidRequest = true;
657 }
658 }
659 else if (!invalidRequest && params.m_coordAddrMode == EXT_ADDR)
660 {
661 if (params.m_coordExtAddr == Mac64Address("ff:ff:ff:ff:ff:ff:ff:ff") ||
662 params.m_coordExtAddr == Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed"))
663 {
664 invalidRequest = true;
665 }
666 }
667
668 if (invalidRequest)
669 {
672 NS_LOG_ERROR(this << " Invalid PAN id in Association request");
674 {
675 MlmeAssociateConfirmParams confirmParams;
676 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
678 m_mlmeAssociateConfirmCallback(confirmParams);
679 }
680 }
681 else
682 {
684 pibAttr.phyCurrentPage = params.m_chPage;
685 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, &pibAttr);
686 }
687}
688
689void
691{
692 // the primitive is no longer pending (channel & page are set)
694 // As described in IEEE 802.15.4-2011 (Section 5.1.3.1)
697 {
699 }
700 else
701 {
704 }
705
707}
708
709void
711{
712 // Associate Short Address (m_assocShortAddr)
713 // FF:FF = Association Request failed
714 // FF:FE = The association request is accepted, but the device should use its extended address
715 // Other = The assigned short address by the coordinator
716
717 NS_LOG_FUNCTION(this);
718
720 m_macDsn++;
721 LrWpanMacTrailer macTrailer;
722 Ptr<Packet> commandPacket = Create<Packet>();
723
724 // Mac header Assoc. Response Comm. See 802.15.4-2011 (Section 5.3.2.1)
727 macHdr.SetPanIdComp();
729 macHdr.SetSrcAddrFields(0xffff, GetExtendedAddress());
730
732 macPayload.SetShortAddr(params.m_assocShortAddr);
733 switch (params.m_status)
734 {
737 break;
740 break;
743 break;
745 NS_LOG_ERROR("Error, Associated without address");
746 break;
748 NS_LOG_ERROR("Error, device not associated");
749 break;
750 }
751
752 macHdr.SetSecDisable();
753 macHdr.SetAckReq();
754
755 commandPacket->AddHeader(macPayload);
756 commandPacket->AddHeader(macHdr);
757
758 // Calculate FCS if the global attribute ChecksumEnable is set.
760 {
761 macTrailer.EnableFcs(true);
762 macTrailer.SetFcs(commandPacket);
763 }
764
765 commandPacket->AddTrailer(macTrailer);
766
767 // Save packet in the Pending Transaction list.
768 EnqueueInd(commandPacket);
769}
770
771void
773{
774 NS_LOG_FUNCTION(this);
775 NS_ASSERT(params.m_logCh <= 26 && m_macPanId != 0xffff);
776
777 uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
778 // change phy current logical channel
780 pibAttr.phyCurrentChannel = params.m_logCh;
781 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, &pibAttr);
782
783 // Enable Phy receiver
784 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
785
786 uint64_t searchSymbols;
787 Time searchBeaconTime;
788
790 {
792 }
793
794 if (params.m_trackBcn)
795 {
797 // search for a beacon for a time = incomingSuperframe symbols + 960 symbols
798 searchSymbols = ((uint64_t)1 << m_incomingBeaconOrder) + 1 * aBaseSuperframeDuration;
799 searchBeaconTime = Seconds((double)searchSymbols / symbolRate);
800 m_beaconTrackingOn = true;
802 Simulator::Schedule(searchBeaconTime, &LrWpanMac::BeaconSearchTimeout, this);
803 }
804 else
805 {
806 m_beaconTrackingOn = false;
807 }
808}
809
810void
812{
813 NS_LOG_FUNCTION(this);
814
816 m_macBsn++;
817
819
820 Ptr<Packet> beaconPacket = Create<Packet>();
821 // TODO: complete poll request (part of indirect transmissions)
822 NS_FATAL_ERROR(this << " Poll request currently not supported");
823}
824
825void
827{
828 NS_LOG_FUNCTION(this);
830
832 m_macBsn++;
833 BeaconPayloadHeader macPayload;
834 Ptr<Packet> beaconPacket = Create<Packet>();
835 LrWpanMacTrailer macTrailer;
836
838 macHdr.SetDstAddrFields(GetPanId(), Mac16Address("ff:ff"));
839
840 // see IEEE 802.15.4-2011 Section 5.1.2.4
841 if (GetShortAddress() == Mac16Address("ff:fe"))
842 {
845 }
846 else
847 {
850 }
851
852 macHdr.SetSecDisable();
853 macHdr.SetNoAckReq();
854
856 macPayload.SetGtsFields(GetGtsFields());
858
859 beaconPacket->AddHeader(macPayload);
860 beaconPacket->AddHeader(macHdr);
861
862 // Calculate FCS if the global attribute ChecksumEnable is set.
864 {
865 macTrailer.EnableFcs(true);
866 macTrailer.SetFcs(beaconPacket);
867 }
868
869 beaconPacket->AddTrailer(macTrailer);
870
871 // Set the Beacon packet to be transmitted
872 m_txPkt = beaconPacket;
873
874 if (m_csmaCa->IsSlottedCsmaCa())
875 {
877 NS_LOG_DEBUG("Outgoing superframe Active Portion (Beacon + CAP + CFP): "
878 << m_superframeDuration << " symbols");
879 }
880
882 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
883}
884
885void
887{
888 NS_LOG_FUNCTION(this);
889
891 m_macDsn++;
892 LrWpanMacTrailer macTrailer;
893 Ptr<Packet> commandPacket = Create<Packet>();
894
895 // Beacon Request Command Mac header values See IEEE 802.15.4-2011 (Section 5.3.7)
896 macHdr.SetNoPanIdComp();
899
900 macHdr.SetDstAddrFields(0xFFFF,
901 Mac16Address("FF:FF")); // Not associated PAN, broadcast dst address
902
903 macHdr.SetSecDisable();
904 macHdr.SetNoAckReq();
905
906 CommandPayloadHeader macPayload;
908
909 commandPacket->AddHeader(macPayload);
910 commandPacket->AddHeader(macHdr);
911
912 // Calculate FCS if the global attribute ChecksumEnable is set.
914 {
915 macTrailer.EnableFcs(true);
916 macTrailer.SetFcs(commandPacket);
917 }
918
919 commandPacket->AddTrailer(macTrailer);
920
921 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
922 txQElement->txQPkt = commandPacket;
923 EnqueueTxQElement(txQElement);
924 CheckQueue();
925}
926
927void
929{
930 NS_LOG_FUNCTION(this);
931
933 m_macDsn++;
934 LrWpanMacTrailer macTrailer;
935 Ptr<Packet> commandPacket = Create<Packet>();
936
937 // Assoc. Req. Comm. Mac header values See IEEE 802.15.4-2011 (Section 5.3.1.1)
939 macHdr.SetSrcAddrFields(0xffff, GetExtendedAddress());
940
942 {
945 }
946 else
947 {
950 }
951
952 macHdr.SetSecDisable();
953 macHdr.SetAckReq();
954
957
958 commandPacket->AddHeader(macPayload);
959 commandPacket->AddHeader(macHdr);
960
961 // Calculate FCS if the global attribute ChecksumEnable is set.
963 {
964 macTrailer.EnableFcs(true);
965 macTrailer.SetFcs(commandPacket);
966 }
967
968 commandPacket->AddTrailer(macTrailer);
969
970 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
971 txQElement->txQPkt = commandPacket;
972 EnqueueTxQElement(txQElement);
973 CheckQueue();
974}
975
976void
978{
979 // See IEEE 802.15.4-2011 (Section 5.3.5)
980 // This command can be sent for 3 different situations:
981 // a) In response to a beacon indicating that there is data for the device.
982 // b) Triggered by MLME-POLL.request.
983 // c) To follow an ACK of an Association Request command and continue the associate process.
984
985 // TODO: Implementation of a) and b) will be done when Indirect transmissions are fully
986 // supported.
987 // for now, only case c) is considered.
988
989 NS_LOG_FUNCTION(this);
990
992 m_macDsn++;
993 LrWpanMacTrailer macTrailer;
994 Ptr<Packet> commandPacket = Create<Packet>();
995
996 // Mac Header values (Section 5.3.5)
998 macHdr.SetSrcAddrFields(0xffff, m_selfExt);
999
1000 if (m_macCoordShortAddress == Mac16Address("ff:fe"))
1001 {
1004 }
1005 else
1006 {
1009 }
1010
1011 macHdr.SetSecDisable();
1012 macHdr.SetAckReq();
1013
1015
1016 commandPacket->AddHeader(macPayload);
1017 commandPacket->AddHeader(macHdr);
1018
1019 // Calculate FCS if the global attribute ChecksumEnable is set.
1021 {
1022 macTrailer.EnableFcs(true);
1023 macTrailer.SetFcs(commandPacket);
1024 }
1025
1026 commandPacket->AddTrailer(macTrailer);
1027
1028 // Set the Command packet to be transmitted
1029 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1030 txQElement->txQPkt = commandPacket;
1031 EnqueueTxQElement(txQElement);
1032 CheckQueue();
1033}
1034
1035void
1037{
1038 LrWpanMacHeader receivedMacHdr;
1039 rxDataReqPkt->RemoveHeader(receivedMacHdr);
1040 CommandPayloadHeader receivedMacPayload;
1041 rxDataReqPkt->RemoveHeader(receivedMacPayload);
1042
1044
1045 Ptr<IndTxQueueElement> indTxQElement = Create<IndTxQueueElement>();
1046 bool elementFound;
1047 elementFound = DequeueInd(receivedMacHdr.GetExtSrcAddr(), indTxQElement);
1048 if (elementFound)
1049 {
1050 Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1051 txQElement->txQPkt = indTxQElement->txQPkt;
1052 m_txQueue.emplace_back(txQElement);
1053 }
1054 else
1055 {
1056 NS_LOG_DEBUG("Requested element not found in pending list");
1057 }
1058}
1059
1060void
1062{
1063 // Association response command was not received, return to default values.
1064 m_macPanId = 0xffff;
1066 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
1067
1069 {
1070 MlmeAssociateConfirmParams confirmParams;
1071 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
1072 confirmParams.m_status = MLMEASSOC_NO_DATA;
1073 m_mlmeAssociateConfirmCallback(confirmParams);
1074 }
1075}
1076
1077void
1079{
1080 NS_LOG_FUNCTION(this);
1081 // The primitive is no longer pending (Channel & Page have been set)
1083
1084 if (m_startParams.m_coorRealgn) // Coordinator Realignment
1085 {
1086 // TODO: Send realignment request command frame in CSMA/CA
1087 NS_LOG_ERROR(this << " Coordinator realignment request not supported");
1088 return;
1089 }
1090 else
1091 {
1093 {
1094 m_panCoor = true;
1096 }
1097
1098 NS_ASSERT(m_startParams.m_PanId != 0xffff);
1099
1101 if (m_macBeaconOrder == 15)
1102 {
1103 // Non-beacon enabled PAN
1104 // Cancel any ongoing events and CSMA-CA process
1106 m_fnlCapSlot = 15;
1107 m_beaconInterval = 0;
1108
1109 m_csmaCa->Cancel();
1117
1118 m_csmaCa->SetUnSlottedCsmaCa();
1119
1121 {
1122 MlmeStartConfirmParams confirmParams;
1123 confirmParams.m_status = MLMESTART_SUCCESS;
1124 m_mlmeStartConfirmCallback(confirmParams);
1125 }
1126
1127 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
1128 }
1129 else
1130 {
1132 m_csmaCa->SetBatteryLifeExtension(m_startParams.m_battLifeExt);
1133
1134 m_csmaCa->SetSlottedCsmaCa();
1135
1136 // TODO: Calculate the real Final CAP slot (requires GTS implementation)
1137 // FinalCapSlot = Superframe duration slots - CFP slots.
1138 // In the current implementation the value of the final cap slot is equal to
1139 // the total number of possible slots in the superframe (15).
1140 m_fnlCapSlot = 15;
1141
1143 (static_cast<uint32_t>(1 << m_macBeaconOrder)) * aBaseSuperframeDuration;
1146
1147 // TODO: change the beacon sending according to the startTime parameter (if not PAN
1148 // coordinator)
1149
1151 }
1152 }
1153}
1154
1155void
1157{
1158 NS_LOG_FUNCTION(this);
1159
1161
1162 bool channelFound = false;
1163
1164 for (int i = m_channelScanIndex; i <= 26; i++)
1165 {
1167 {
1168 channelFound = true;
1169 break;
1170 }
1172 }
1173
1174 if (channelFound)
1175 {
1176 // Switch to the next channel in the list and restart scan
1177 LrWpanPhyPibAttributes pibAttr;
1179 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, &pibAttr);
1180 }
1181 else
1182 {
1183 // All scans on the channel list completed
1184 // Return to the MAC values previous to start of the first scan.
1186 m_macPanIdScan = 0;
1187
1188 // TODO: restart beacon transmissions that were active before the beginning of the scan
1189 // (i.e when a coordinator perform a scan and it was already transmitting beacons)
1190
1191 // All channels scanned, report success
1192 MlmeScanConfirmParams confirmParams;
1193 confirmParams.m_status = MLMESCAN_SUCCESS;
1194 confirmParams.m_chPage = m_scanParams.m_chPage;
1195 confirmParams.m_scanType = m_scanParams.m_scanType;
1196 confirmParams.m_energyDetList = {};
1197 confirmParams.m_panDescList = m_panDescriptorList;
1198
1200 {
1201 m_mlmeScanConfirmCallback(confirmParams);
1202 }
1203
1206 m_scanParams = {};
1207 }
1208}
1209
1210void
1212{
1213 NS_LOG_FUNCTION(this);
1214 // Add the results of channel energy scan to the detectList
1216 m_maxEnergyLevel = 0;
1217
1219
1220 bool channelFound = false;
1221 for (int i = m_channelScanIndex; i <= 26; i++)
1222 {
1224 {
1225 channelFound = true;
1226 break;
1227 }
1229 }
1230
1231 if (channelFound)
1232 {
1233 // switch to the next channel in the list and restart scan
1234 LrWpanPhyPibAttributes pibAttr;
1236 m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, &pibAttr);
1237 }
1238 else
1239 {
1240 // Scan on all channels on the list completed
1241 // Return to the MAC values previous to start of the first scan.
1243 m_macPanIdScan = 0;
1244
1245 // TODO: restart beacon transmissions that were active before the beginning of the scan
1246 // (i.e when a coordinator perform a scan and it was already transmitting beacons)
1247
1248 // All channels scanned, report success
1250 {
1251 MlmeScanConfirmParams confirmParams;
1252 confirmParams.m_status = MLMESCAN_SUCCESS;
1253 confirmParams.m_chPage = m_phy->GetCurrentPage();
1254 confirmParams.m_scanType = m_scanParams.m_scanType;
1255 confirmParams.m_energyDetList = m_energyDetectList;
1256 m_mlmeScanConfirmCallback(confirmParams);
1257 }
1260 m_scanParams = {};
1261 }
1262}
1263
1264void
1266{
1267 uint32_t activeSlot;
1268 uint64_t capDuration;
1269 Time endCapTime;
1270 uint64_t symbolRate;
1271
1272 symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1273
1274 if (superframeType == OUTGOING)
1275 {
1277 activeSlot = m_superframeDuration / 16;
1278 capDuration = activeSlot * (m_fnlCapSlot + 1);
1279 endCapTime = Seconds((double)capDuration / symbolRate);
1280 // Obtain the end of the CAP by adjust the time it took to send the beacon
1281 endCapTime -= (Simulator::Now() - m_macBeaconTxTime);
1282
1283 NS_LOG_DEBUG("Outgoing superframe CAP duration " << (endCapTime.GetSeconds() * symbolRate)
1284 << " symbols (" << endCapTime.As(Time::S)
1285 << ")");
1286 NS_LOG_DEBUG("Active Slots duration " << activeSlot << " symbols");
1287
1288 m_capEvent =
1290 }
1291 else
1292 {
1294 activeSlot = m_incomingSuperframeDuration / 16;
1295 capDuration = activeSlot * (m_incomingFnlCapSlot + 1);
1296 endCapTime = Seconds((double)capDuration / symbolRate);
1297 // Obtain the end of the CAP by adjust the time it took to receive the beacon
1298 endCapTime -= (Simulator::Now() - m_macBeaconRxTime);
1299
1300 NS_LOG_DEBUG("Incoming superframe CAP duration " << (endCapTime.GetSeconds() * symbolRate)
1301 << " symbols (" << endCapTime.As(Time::S)
1302 << ")");
1303 NS_LOG_DEBUG("Active Slots duration " << activeSlot << " symbols");
1304
1305 m_capEvent =
1307 }
1308
1309 CheckQueue();
1310}
1311
1312void
1314{
1315 uint32_t activeSlot;
1316 uint64_t cfpDuration;
1317 Time endCfpTime;
1318 uint64_t symbolRate;
1319
1320 symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1321
1322 if (superframeType == INCOMING)
1323 {
1324 activeSlot = m_incomingSuperframeDuration / 16;
1325 cfpDuration = activeSlot * (15 - m_incomingFnlCapSlot);
1326 endCfpTime = Seconds((double)cfpDuration / symbolRate);
1327 if (cfpDuration > 0)
1328 {
1330 }
1331
1332 NS_LOG_DEBUG("Incoming superframe CFP duration " << cfpDuration << " symbols ("
1333 << endCfpTime.As(Time::S) << ")");
1334
1337 this,
1339 }
1340 else
1341 {
1342 activeSlot = m_superframeDuration / 16;
1343 cfpDuration = activeSlot * (15 - m_fnlCapSlot);
1344 endCfpTime = Seconds((double)cfpDuration / symbolRate);
1345
1346 if (cfpDuration > 0)
1347 {
1349 }
1350
1351 NS_LOG_DEBUG("Outgoing superframe CFP duration " << cfpDuration << " symbols ("
1352 << endCfpTime.As(Time::S) << ")");
1353
1354 m_cfpEvent = Simulator::Schedule(endCfpTime,
1356 this,
1358 }
1359 // TODO: Start transmit or receive GTS here.
1360}
1361
1362void
1364{
1365 uint64_t inactiveDuration;
1366 Time endInactiveTime;
1367 uint64_t symbolRate;
1368
1369 symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1370
1371 if (superframeType == INCOMING)
1372 {
1374 endInactiveTime = Seconds((double)inactiveDuration / symbolRate);
1375
1376 if (inactiveDuration > 0)
1377 {
1379 }
1380
1381 NS_LOG_DEBUG("Incoming superframe Inactive Portion duration "
1382 << inactiveDuration << " symbols (" << endInactiveTime.As(Time::S) << ")");
1383 m_beaconEvent = Simulator::Schedule(endInactiveTime, &LrWpanMac::AwaitBeacon, this);
1384 }
1385 else
1386 {
1387 inactiveDuration = m_beaconInterval - m_superframeDuration;
1388 endInactiveTime = Seconds((double)inactiveDuration / symbolRate);
1389
1390 if (inactiveDuration > 0)
1391 {
1393 }
1394
1395 NS_LOG_DEBUG("Outgoing superframe Inactive Portion duration "
1396 << inactiveDuration << " symbols (" << endInactiveTime.As(Time::S) << ")");
1398 }
1399}
1400
1401void
1403{
1405
1406 // TODO: If the device waits more than the expected time to receive the beacon (wait = 46
1407 // symbols for default beacon size)
1408 // it should continue with the start of the incoming CAP even if it did not receive the
1409 // beacon. At the moment, the start of the incoming CAP is only triggered if the beacon is
1410 // received. See MLME-SyncLoss for details.
1411}
1412
1413void
1415{
1416 uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1417
1419 {
1420 MlmeSyncLossIndicationParams syncLossParams;
1421 // syncLossParams.m_logCh =
1422 syncLossParams.m_lossReason = MLMESYNCLOSS_BEACON_LOST;
1423 syncLossParams.m_panId = m_macPanId;
1424 m_mlmeSyncLossIndicationCallback(syncLossParams);
1425
1426 m_beaconTrackingOn = false;
1427 m_numLostBeacons = 0;
1428 }
1429 else
1430 {
1432
1433 // Search for one more beacon
1434 uint64_t searchSymbols;
1435 Time searchBeaconTime;
1436 searchSymbols = ((uint64_t)1 << m_incomingBeaconOrder) + 1 * aBaseSuperframeDuration;
1437 searchBeaconTime = Seconds((double)searchSymbols / symbolRate);
1439 Simulator::Schedule(searchBeaconTime, &LrWpanMac::BeaconSearchTimeout, this);
1440 }
1441}
1442
1443void
1445{
1446 NS_LOG_FUNCTION(this);
1447 // Pull a packet from the queue and start sending if we are not already sending.
1449 {
1450 // TODO: this should check if the node is a coordinator and using the outcoming superframe
1451 // not just the PAN coordinator
1452 if (m_csmaCa->IsUnSlottedCsmaCa() || (m_outSuperframeStatus == CAP && m_panCoor) ||
1454 {
1455 // check MAC is not in a IFS
1456 if (!m_ifsEvent.IsRunning())
1457 {
1458 Ptr<TxQueueElement> txQElement = m_txQueue.front();
1459 m_txPkt = txQElement->txQPkt;
1460
1463 }
1464 }
1465 }
1466}
1467
1470{
1471 SuperframeField sfrmSpec;
1472
1475 sfrmSpec.SetFinalCapSlot(m_fnlCapSlot);
1476
1477 if (m_csmaCa->GetBatteryLifeExtension())
1478 {
1479 sfrmSpec.SetBattLifeExt(true);
1480 }
1481
1482 if (m_panCoor)
1483 {
1484 sfrmSpec.SetPanCoor(true);
1485 }
1486
1487 // used to associate devices via Beacons
1489 {
1490 sfrmSpec.SetAssocPermit(true);
1491 }
1492
1493 return sfrmSpec;
1494}
1495
1498{
1499 GtsFields gtsFields;
1500
1501 // TODO: Logic to populate the GTS Fields from local information here
1502
1503 return gtsFields;
1504}
1505
1508{
1509 PendingAddrFields pndAddrFields;
1510
1511 // TODO: Logic to populate the Pending Address Fields from local information here
1512 return pndAddrFields;
1513}
1514
1515void
1517{
1518 m_csmaCa = csmaCa;
1519}
1520
1521void
1523{
1524 m_phy = phy;
1525}
1526
1529{
1530 return m_phy;
1531}
1532
1533void
1535{
1537}
1538
1539void
1541{
1543}
1544
1545void
1547{
1549}
1550
1551void
1553{
1555}
1556
1557void
1559{
1561}
1562
1563void
1565{
1567}
1568
1569void
1571{
1573}
1574
1575void
1577{
1579}
1580
1581void
1583{
1585}
1586
1587void
1589{
1591}
1592
1593void
1595{
1598 NS_LOG_FUNCTION(this << psduLength << p << (uint16_t)lqi);
1599
1600 bool acceptFrame;
1601
1602 // from sec 7.5.6.2 Reception and rejection, Std802.15.4-2006
1603 // level 1 filtering, test FCS field and reject if frame fails
1604 // level 2 filtering if promiscuous mode pass frame to higher layer otherwise perform level 3
1605 // filtering level 3 filtering accept frame if Frame type and version is not reserved, and if
1606 // there is a dstPanId then dstPanId=m_macPanId or broadcastPanId, and if there is a
1607 // shortDstAddr then shortDstAddr =shortMacAddr or broadcastAddr, and if beacon frame then
1608 // srcPanId = m_macPanId if only srcAddr field in Data or Command frame,accept frame if
1609 // srcPanId=m_macPanId
1610
1611 Ptr<Packet> originalPkt = p->Copy(); // because we will strip headers
1612 uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1613 m_promiscSnifferTrace(originalPkt);
1614
1615 m_macPromiscRxTrace(originalPkt);
1616 // XXX no rejection tracing (to macRxDropTrace) being performed below
1617
1618 LrWpanMacTrailer receivedMacTrailer;
1619 p->RemoveTrailer(receivedMacTrailer);
1621 {
1622 receivedMacTrailer.EnableFcs(true);
1623 }
1624
1625 // level 1 filtering
1626 if (!receivedMacTrailer.CheckFcs(p))
1627 {
1628 m_macRxDropTrace(originalPkt);
1629 }
1630 else
1631 {
1632 LrWpanMacHeader receivedMacHdr;
1633 p->RemoveHeader(receivedMacHdr);
1634
1636 params.m_dsn = receivedMacHdr.GetSeqNum();
1637 params.m_mpduLinkQuality = lqi;
1638 params.m_srcPanId = receivedMacHdr.GetSrcPanId();
1639 params.m_srcAddrMode = receivedMacHdr.GetSrcAddrMode();
1640 switch (params.m_srcAddrMode)
1641 {
1642 case SHORT_ADDR:
1643 params.m_srcAddr = receivedMacHdr.GetShortSrcAddr();
1644 break;
1645 case EXT_ADDR:
1646 params.m_srcExtAddr = receivedMacHdr.GetExtSrcAddr();
1647 break;
1648 default:
1649 break;
1650 }
1651 params.m_dstPanId = receivedMacHdr.GetDstPanId();
1652 params.m_dstAddrMode = receivedMacHdr.GetDstAddrMode();
1653 switch (params.m_dstAddrMode)
1654 {
1655 case SHORT_ADDR:
1656 params.m_dstAddr = receivedMacHdr.GetShortDstAddr();
1657 break;
1658 case EXT_ADDR:
1659 params.m_dstExtAddr = receivedMacHdr.GetExtDstAddr();
1660 break;
1661 default:
1662 break;
1663 }
1664
1666 {
1667 // level 2 filtering
1668 if (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR)
1669 {
1670 NS_LOG_DEBUG("Packet from " << params.m_srcAddr);
1671 NS_LOG_DEBUG("Packet to " << params.m_dstAddr);
1672 }
1673 else if (receivedMacHdr.GetDstAddrMode() == EXT_ADDR)
1674 {
1675 NS_LOG_DEBUG("Packet from " << params.m_srcExtAddr);
1676 NS_LOG_DEBUG("Packet to " << params.m_dstExtAddr);
1677 }
1678
1679 // TODO: Fix here, this should trigger different Indication Callbacks
1680 // depending the type of frame received (data,command, beacon)
1682 {
1683 NS_LOG_DEBUG("promiscuous mode, forwarding up");
1685 }
1686 else
1687 {
1688 NS_LOG_ERROR(this << " Data Indication Callback not initialized");
1689 }
1690 }
1691 else
1692 {
1693 // level 3 frame filtering
1694 acceptFrame = (receivedMacHdr.GetType() != LrWpanMacHeader::LRWPAN_MAC_RESERVED);
1695
1696 if (acceptFrame)
1697 {
1698 acceptFrame = (receivedMacHdr.GetFrameVer() <= 1);
1699 }
1700
1701 if (acceptFrame && (receivedMacHdr.GetDstAddrMode() > 1))
1702 {
1703 // Accept frame if:
1704
1705 // 1) Have the same macPanId
1706 // 2) Or is Message to all PANs
1707 // 3) Or Is a beacon and the macPanId is not present (bootstrap)
1708 acceptFrame = ((receivedMacHdr.GetDstPanId() == m_macPanId ||
1709 receivedMacHdr.GetDstPanId() == 0xffff) ||
1710 (m_macPanId == 0xffff && receivedMacHdr.IsBeacon())) ||
1711 (m_macPanId == 0xffff && receivedMacHdr.IsCommand());
1712 }
1713
1714 if (acceptFrame && (receivedMacHdr.GetShortDstAddr() == Mac16Address("FF:FF")))
1715 {
1716 // A broadcast message (e.g. beacons) should not be received by the device who
1717 // issues it.
1718 acceptFrame = (receivedMacHdr.GetShortSrcAddr() != GetShortAddress());
1719 // TODO: shouldn't this be filtered by the PHY?
1720 }
1721
1722 if (acceptFrame && (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR))
1723 {
1724 if (receivedMacHdr.GetShortDstAddr() == m_shortAddress)
1725 {
1726 // unicast, for me
1727 acceptFrame = true;
1728 }
1729 else if (receivedMacHdr.GetShortDstAddr().IsBroadcast() ||
1730 receivedMacHdr.GetShortDstAddr().IsMulticast())
1731 {
1732 // broadcast or multicast
1733 if (receivedMacHdr.IsAckReq())
1734 {
1735 // discard broadcast/multicast with the ACK bit set
1736 acceptFrame = false;
1737 }
1738 else
1739 {
1740 acceptFrame = true;
1741 }
1742 }
1743 else
1744 {
1745 acceptFrame = false;
1746 }
1747 }
1748
1749 if (acceptFrame && (receivedMacHdr.GetDstAddrMode() == EXT_ADDR))
1750 {
1751 acceptFrame = (receivedMacHdr.GetExtDstAddr() == m_selfExt);
1752 }
1753
1754 // When PASSIVE or ACTIVE scan is running, reject any frames other than BEACON frames
1755 if (acceptFrame && (!receivedMacHdr.IsBeacon() && m_scanEvent.IsRunning()))
1756 {
1757 acceptFrame = false;
1758 }
1759
1760 // Energy Scan is running, reject any frames
1762 {
1763 acceptFrame = false;
1764 }
1765
1766 // Check device is panCoor with association permit when receiving Association Request
1767 // Commands.
1768 // TODO:: Simple coordinators should also be able to receive it (currently only Pan
1769 // Coordinators are checked)
1770 if (acceptFrame && (receivedMacHdr.IsCommand() && receivedMacHdr.IsAckReq()))
1771 {
1772 CommandPayloadHeader receivedMacPayload;
1773 p->PeekHeader(receivedMacPayload);
1774
1775 if (receivedMacPayload.GetCommandFrameType() ==
1777 !(m_macAssociationPermit == true && m_panCoor == true))
1778 {
1779 acceptFrame = false;
1780 }
1781
1782 // Although ACKs do not use CSMA to to be transmitted, we need to make sure
1783 // that the transmitted ACK will not collide with the transmission of a beacon
1784 // when beacon-enabled mode is running in the coordinator.
1785 if (acceptFrame && (m_csmaCa->IsSlottedCsmaCa() && m_capEvent.IsRunning()))
1786 {
1787 Time timeLeftInCap = Simulator::GetDelayLeft(m_capEvent);
1788 uint64_t ackSymbols = m_phy->aTurnaroundTime + m_phy->GetPhySHRDuration() +
1789 ceil(6 * m_phy->GetPhySymbolsPerOctet());
1790 Time ackTime = Seconds((double)ackSymbols / symbolRate);
1791
1792 if (ackTime >= timeLeftInCap)
1793 {
1794 NS_LOG_DEBUG("Command frame received but not enough time to transmit ACK "
1795 "before the end of CAP ");
1796 acceptFrame = false;
1797 }
1798 }
1799 }
1800
1801 if (acceptFrame)
1802 {
1803 m_macRxTrace(originalPkt);
1804 // \todo: What should we do if we receive a frame while waiting for an ACK?
1805 // Especially if this frame has the ACK request bit set, should we reply with
1806 // an ACK, possibly missing the pending ACK?
1807
1808 // If the received frame is a frame with the ACK request bit set, we immediately
1809 // send back an ACK. If we are currently waiting for a pending ACK, we assume the
1810 // ACK was lost and trigger a retransmission after sending the ACK.
1811 if ((receivedMacHdr.IsData() || receivedMacHdr.IsCommand()) &&
1812 receivedMacHdr.IsAckReq() &&
1813 !(receivedMacHdr.GetDstAddrMode() == SHORT_ADDR &&
1814 (receivedMacHdr.GetShortDstAddr().IsBroadcast() ||
1815 receivedMacHdr.GetShortDstAddr().IsMulticast())))
1816 {
1817 // If this is a data or mac command frame, which is not a broadcast or
1818 // multicast, with ack req set, generate and send an ack frame. If there is a
1819 // CSMA medium access in progress we cancel the medium access for sending the
1820 // ACK frame. A new transmission attempt will be started after the ACK was send.
1822 {
1825 }
1826 else if (m_lrWpanMacState == MAC_CSMA)
1827 {
1828 // \todo: If we receive a packet while doing CSMA/CA, should we drop the
1829 // packet because of channel busy,
1830 // or should we restart CSMA/CA for the packet after sending the ACK?
1831 // Currently we simply restart CSMA/CA after sending the ACK.
1832 NS_LOG_DEBUG("Received a packet with ACK required while in CSMA. Cancel "
1833 "current CSMA-CA");
1834 m_csmaCa->Cancel();
1835 }
1836 // Cancel any pending MAC state change, ACKs have higher priority.
1839
1840 // save received packet to process the appropriate indication/response after
1841 // sending ACK (PD-DATA.confirm)
1842 m_rxPkt = originalPkt->Copy();
1843
1844 // LOG Commands with ACK required.
1845 CommandPayloadHeader receivedMacPayload;
1846 p->PeekHeader(receivedMacPayload);
1847 switch (receivedMacPayload.GetCommandFrameType())
1848 {
1850 NS_LOG_DEBUG("Data Request Command Received; processing ACK");
1851 break;
1853 NS_LOG_DEBUG("Association Request Command Received; processing ACK");
1854 break;
1856 m_assocResCmdWaitTimeout.Cancel(); // cancel event to a lost assoc resp cmd.
1857 NS_LOG_DEBUG("Association Response Command Received; processing ACK");
1858 break;
1859 default:
1860 break;
1861 }
1862
1864 this,
1865 receivedMacHdr.GetSeqNum());
1866 }
1867
1868 if (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR)
1869 {
1870 NS_LOG_DEBUG("Packet from " << params.m_srcAddr);
1871 NS_LOG_DEBUG("Packet to " << params.m_dstAddr);
1872 }
1873 else if (receivedMacHdr.GetDstAddrMode() == EXT_ADDR)
1874 {
1875 NS_LOG_DEBUG("Packet from " << params.m_srcExtAddr);
1876 NS_LOG_DEBUG("Packet to " << params.m_dstExtAddr);
1877 }
1878
1879 if (receivedMacHdr.IsBeacon())
1880 {
1881 // The received beacon size in symbols
1882 // Beacon = 5 bytes Sync Header (SHR) + 1 byte PHY header (PHR) + PSDU (default
1883 // 17 bytes)
1884 m_rxBeaconSymbols = m_phy->GetPhySHRDuration() +
1885 1 * m_phy->GetPhySymbolsPerOctet() +
1886 (originalPkt->GetSize() * m_phy->GetPhySymbolsPerOctet());
1887
1888 // The start of Rx beacon time and start of the Incoming superframe Active
1889 // Period
1891 Simulator::Now() - Seconds(double(m_rxBeaconSymbols) / symbolRate);
1892
1893 NS_LOG_DEBUG("Beacon Received; forwarding up (m_macBeaconRxTime: "
1894 << m_macBeaconRxTime.As(Time::S) << ")");
1895
1896 BeaconPayloadHeader receivedMacPayload;
1897 p->RemoveHeader(receivedMacPayload);
1898
1899 // Fill the PAN descriptor
1900 PanDescriptor panDescriptor;
1901
1902 if (receivedMacHdr.GetSrcAddrMode() == SHORT_ADDR)
1903 {
1904 panDescriptor.m_coorAddrMode = SHORT_ADDR;
1905 panDescriptor.m_coorShortAddr = receivedMacHdr.GetShortSrcAddr();
1906 }
1907 else
1908 {
1909 panDescriptor.m_coorAddrMode = EXT_ADDR;
1910 panDescriptor.m_coorExtAddr = receivedMacHdr.GetExtSrcAddr();
1911 }
1912
1913 panDescriptor.m_coorPanId = receivedMacHdr.GetSrcPanId();
1914 panDescriptor.m_gtsPermit = receivedMacPayload.GetGtsFields().GetGtsPermit();
1915 panDescriptor.m_linkQuality = lqi;
1916 panDescriptor.m_logChPage = m_phy->GetCurrentPage();
1917 panDescriptor.m_logCh = m_phy->GetCurrentChannelNum();
1918 panDescriptor.m_superframeSpec = receivedMacPayload.GetSuperframeSpecField();
1919 panDescriptor.m_timeStamp = m_macBeaconRxTime;
1920
1921 // Process beacon when device belongs to a PAN (associated device)
1922 if (!m_scanEvent.IsRunning() && m_macPanId == receivedMacHdr.GetDstPanId())
1923 {
1924 // We need to make sure to cancel any possible ongoing unslotted CSMA/CA
1925 // operations when receiving a beacon (e.g. Those taking place at the
1926 // beginning of an Association).
1927 m_csmaCa->Cancel();
1928
1929 SuperframeField incomingSuperframe;
1930 incomingSuperframe = receivedMacPayload.GetSuperframeSpecField();
1931
1932 m_incomingBeaconOrder = incomingSuperframe.GetBeaconOrder();
1933 m_incomingSuperframeOrder = incomingSuperframe.GetFrameOrder();
1934 m_incomingFnlCapSlot = incomingSuperframe.GetFinalCapSlot();
1935
1937 (static_cast<uint32_t>(1 << m_incomingBeaconOrder)) *
1941 (static_cast<uint32_t>(1 << m_incomingSuperframeOrder));
1942
1943 if (incomingSuperframe.IsBattLifeExt())
1944 {
1945 m_csmaCa->SetBatteryLifeExtension(true);
1946 }
1947 else
1948 {
1949 m_csmaCa->SetBatteryLifeExtension(false);
1950 }
1951
1952 if (m_incomingBeaconOrder < 15 && !m_csmaCa->IsSlottedCsmaCa())
1953 {
1954 m_csmaCa->SetSlottedCsmaCa();
1955 }
1956
1957 // TODO: get Incoming frame GTS Fields here
1958
1959 // Begin CAP on the current device using info from the Incoming superframe
1960 NS_LOG_DEBUG("Incoming superframe Active Portion (Beacon + CAP + CFP): "
1961 << m_incomingSuperframeDuration << " symbols");
1963 this,
1967 }
1968 else if (!m_scanEvent.IsRunning() && m_macPanId == 0xFFFF)
1969 {
1970 NS_LOG_DEBUG(this << " Device not associated, cannot process beacon");
1971 }
1972
1973 if (m_macAutoRequest)
1974 {
1975 if (p->GetSize() > 0)
1976 {
1978 {
1979 // The beacon contains payload, send the beacon notification.
1981 beaconParams.m_bsn = receivedMacHdr.GetSeqNum();
1982 beaconParams.m_panDescriptor = panDescriptor;
1983 beaconParams.m_sduLength = p->GetSize();
1984 beaconParams.m_sdu = p;
1985 m_mlmeBeaconNotifyIndicationCallback(beaconParams, originalPkt);
1986 }
1987 }
1988
1989 if (m_scanEvent.IsRunning())
1990 {
1991 // Channel scanning is taking place, save only unique PAN descriptors
1992 bool descriptorExists = false;
1993
1994 for (const auto& descriptor : m_panDescriptorList)
1995 {
1996 if (descriptor.m_coorAddrMode == SHORT_ADDR)
1997 {
1998 // Found a coordinator in PAN descriptor list with the same
1999 // registered short address
2000 descriptorExists =
2001 (descriptor.m_coorShortAddr ==
2002 panDescriptor.m_coorShortAddr &&
2003 descriptor.m_coorPanId == panDescriptor.m_coorPanId);
2004 }
2005 else
2006 {
2007 // Found a coordinator in PAN descriptor list with the same
2008 // registered extended address
2009 descriptorExists =
2010 (descriptor.m_coorExtAddr == panDescriptor.m_coorExtAddr &&
2011 descriptor.m_coorPanId == panDescriptor.m_coorPanId);
2012 }
2013
2014 if (descriptorExists)
2015 {
2016 break;
2017 }
2018 }
2019
2020 if (!descriptorExists)
2021 {
2022 m_panDescriptorList.push_back(panDescriptor);
2023 }
2024 return;
2025 }
2026 else if (m_trackingEvent.IsRunning())
2027 {
2028 // check if MLME-SYNC.request was previously issued and running
2029 // Sync. is necessary to handle pending messages (indirect
2030 // transmissions)
2032 m_numLostBeacons = 0;
2033
2035 {
2036 // if tracking option is on keep tracking the next beacon
2037 uint64_t searchSymbols;
2038 Time searchBeaconTime;
2039
2040 searchSymbols =
2041 (static_cast<uint64_t>(1 << m_incomingBeaconOrder)) +
2043 searchBeaconTime =
2044 Seconds(static_cast<double>(searchSymbols / symbolRate));
2046 Simulator::Schedule(searchBeaconTime,
2048 this);
2049 }
2050
2051 PendingAddrFields pndAddrFields;
2052 pndAddrFields = receivedMacPayload.GetPndAddrFields();
2053
2054 // TODO: Ignore pending data, and do not send data command request if
2055 // the address is in the GTS list.
2056 // If the address is not in the GTS list, then check if the
2057 // address is in the short address pending list or in the extended
2058 // address pending list and send a data command request.
2059 }
2060 }
2061 else
2062 {
2063 // m_macAutoRequest is FALSE
2064 // Data command request are not send, only the beacon notification.
2065 // see IEEE 802.15.4-2011 Section 6.2.4.1
2067 {
2069 beaconParams.m_bsn = receivedMacHdr.GetSeqNum();
2070 beaconParams.m_panDescriptor = panDescriptor;
2071 m_mlmeBeaconNotifyIndicationCallback(beaconParams, originalPkt);
2072 }
2073 }
2074 }
2075 else if (receivedMacHdr.IsCommand())
2076 {
2077 // Handle the reception of frame commands that do not require ACK (i.e. Beacon
2078 // Request Command)
2079 CommandPayloadHeader receivedMacPayload;
2080 p->PeekHeader(receivedMacPayload);
2081 if (receivedMacPayload.GetCommandFrameType() ==
2083 {
2084 // TODO: check that node is any coordinator not just pan coordinator
2085 if (m_csmaCa->IsUnSlottedCsmaCa() && m_panCoor)
2086 {
2087 SendOneBeacon();
2088 }
2089 else
2090 {
2091 m_macRxDropTrace(originalPkt);
2092 }
2093 }
2094 }
2095 else if (receivedMacHdr.IsData() && !m_mcpsDataIndicationCallback.IsNull())
2096 {
2097 // If it is a data frame, push it up the stack.
2098 NS_LOG_DEBUG("Data Packet is for me; forwarding up");
2100 }
2101 else if (receivedMacHdr.IsAcknowledgment() && m_txPkt &&
2103 {
2104 LrWpanMacHeader peekedMacHdr;
2105 m_txPkt->PeekHeader(peekedMacHdr);
2106 // If it is an ACK with the expected sequence number, finish the transmission
2107 if (receivedMacHdr.GetSeqNum() == peekedMacHdr.GetSeqNum())
2108 {
2111
2112 // TODO: check if the IFS is the correct size after ACK.
2113 Time ifsWaitTime = Seconds((double)GetIfsSize() / symbolRate);
2114
2115 // We received an ACK to a command
2116 if (peekedMacHdr.IsCommand())
2117 {
2118 // check the original sent command frame which belongs to this received
2119 // ACK
2120 Ptr<Packet> pkt = m_txPkt->Copy();
2121 LrWpanMacHeader macHdr;
2122 CommandPayloadHeader cmdPayload;
2123 pkt->RemoveHeader(macHdr);
2124 pkt->RemoveHeader(cmdPayload);
2125
2126 switch (cmdPayload.GetCommandFrameType())
2127 {
2129 double symbolRate = m_phy->GetDataOrSymbolRate(false);
2130 Time waitTime = Seconds(static_cast<double>(m_macResponseWaitTime) /
2131 symbolRate);
2132 if (!m_beaconTrackingOn)
2133 {
2135 Simulator::Schedule(waitTime,
2137 this);
2138 }
2139 else
2140 {
2141 // TODO: The data must be extracted by the coordinator within
2142 // macResponseWaitTime on timeout, MLME-ASSOCIATE.confirm is set
2143 // with status NO_DATA, and this should trigger the cancellation
2144 // of the beacon tracking (MLME-SYNC.request trackBeacon
2145 // =FALSE)
2146 }
2147 break;
2148 }
2149
2151 // MLME-comm-status.Indication generated as a result of an
2152 // association response command, therefore src and dst address use
2153 // extended mode (see 5.3.2.1)
2155 {
2156 MlmeCommStatusIndicationParams commStatusParams;
2157 commStatusParams.m_panId = m_macPanId;
2158 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2159 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2160 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2161 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2162 commStatusParams.m_status =
2164 m_mlmeCommStatusIndicationCallback(commStatusParams);
2165 }
2166 // Remove element from Pending Transaction List
2168 break;
2169 }
2170
2172 // Schedule an event in case the Association Response Command never
2173 // reached this device during an association process.
2174 double symbolRate = m_phy->GetDataOrSymbolRate(false);
2175 Time waitTime = Seconds(
2176 static_cast<double>(m_assocRespCmdWaitTime) / symbolRate);
2178 Simulator::Schedule(waitTime,
2180 this);
2181
2183 {
2184 MlmePollConfirmParams pollConfirmParams;
2185 pollConfirmParams.m_status =
2187 m_mlmePollConfirmCallback(pollConfirmParams);
2188 }
2189 break;
2190 }
2191
2192 default: {
2193 // TODO: add response to other request commands (e.g. Orphan)
2194 break;
2195 }
2196 }
2197 }
2198 else
2199 {
2201 {
2202 Ptr<TxQueueElement> txQElement = m_txQueue.front();
2203 McpsDataConfirmParams confirmParams;
2204 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2205 confirmParams.m_status = IEEE_802_15_4_SUCCESS;
2206 m_mcpsDataConfirmCallback(confirmParams);
2207 }
2208 }
2209
2210 // Ack was successfully received, wait for the Interframe Space (IFS) and
2211 // then proceed
2216 m_ifsEvent = Simulator::Schedule(ifsWaitTime,
2218 this,
2219 ifsWaitTime);
2220 }
2221 else
2222 {
2223 // If it is an ACK with an unexpected sequence number, mark the current
2224 // transmission as failed and start a retransmit. (cf 7.5.6.4.3)
2226 if (!PrepareRetransmission())
2227 {
2230 this,
2231 MAC_IDLE);
2232 }
2233 else
2234 {
2237 this,
2238 MAC_CSMA);
2239 }
2240 }
2241 }
2242 }
2243 else
2244 {
2245 m_macRxDropTrace(originalPkt);
2246 }
2247 }
2248 }
2249}
2250
2251void
2253{
2254 NS_LOG_FUNCTION(this << static_cast<uint32_t>(seqno));
2255
2257
2258 // Generate a corresponding ACK Frame.
2260 LrWpanMacTrailer macTrailer;
2261 Ptr<Packet> ackPacket = Create<Packet>(0);
2262 ackPacket->AddHeader(macHdr);
2263 // Calculate FCS if the global attribute ChecksumEnable is set.
2265 {
2266 macTrailer.EnableFcs(true);
2267 macTrailer.SetFcs(ackPacket);
2268 }
2269 ackPacket->AddTrailer(macTrailer);
2270
2271 // Enqueue the ACK packet for further processing
2272 // when the transmitter is activated.
2273 m_txPkt = ackPacket;
2274
2275 // Switch transceiver to TX mode. Proceed sending the Ack on confirm.
2277 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
2278}
2279
2280void
2282{
2283 if (m_txQueue.size() < m_maxTxQueueSize)
2284 {
2285 m_txQueue.emplace_back(txQElement);
2286 m_macTxEnqueueTrace(txQElement->txQPkt);
2287 }
2288 else
2289 {
2291 {
2292 McpsDataConfirmParams confirmParams;
2293 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2295 m_mcpsDataConfirmCallback(confirmParams);
2296 }
2297 NS_LOG_DEBUG("TX Queue with size " << m_txQueue.size() << " is full, dropping packet");
2298 m_macTxDropTrace(txQElement->txQPkt);
2299 }
2300}
2301
2302void
2304{
2305 Ptr<TxQueueElement> txQElement = m_txQueue.front();
2306 Ptr<const Packet> p = txQElement->txQPkt;
2307 m_numCsmacaRetry += m_csmaCa->GetNB() + 1;
2308
2309 Ptr<Packet> pkt = p->Copy();
2310 LrWpanMacHeader hdr;
2311 pkt->RemoveHeader(hdr);
2312 if (!hdr.GetShortDstAddr().IsBroadcast() && !hdr.GetShortDstAddr().IsMulticast())
2313 {
2315 }
2316
2317 txQElement->txQPkt = nullptr;
2318 txQElement = nullptr;
2319 m_txQueue.pop_front();
2320 m_txPkt = nullptr;
2321 m_retransmission = 0;
2322 m_numCsmacaRetry = 0;
2324}
2325
2326void
2328{
2329 NS_LOG_FUNCTION(this);
2330
2331 // TODO: If we are a PAN coordinator and this was an indirect transmission,
2332 // we will not initiate a retransmission. Instead we wait for the data
2333 // being extracted after a new data request command.
2334 if (!PrepareRetransmission())
2335 {
2337 }
2338 else
2339 {
2341 }
2342}
2343
2344void
2346{
2347 uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false);
2348 Time lifsTime = Seconds((double)m_macLIFSPeriod / symbolRate);
2349 Time sifsTime = Seconds((double)m_macSIFSPeriod / symbolRate);
2350
2351 if (ifsTime == lifsTime)
2352 {
2353 NS_LOG_DEBUG("LIFS of " << m_macLIFSPeriod << " symbols (" << ifsTime.As(Time::S)
2354 << ") completed ");
2355 }
2356 else if (ifsTime == sifsTime)
2357 {
2358 NS_LOG_DEBUG("SIFS of " << m_macSIFSPeriod << " symbols (" << ifsTime.As(Time::S)
2359 << ") completed ");
2360 }
2361 else
2362 {
2363 NS_LOG_DEBUG("Unknown IFS size (" << ifsTime.As(Time::S) << ") completed ");
2364 }
2365
2366 m_macIfsEndTrace(ifsTime);
2367 CheckQueue();
2368}
2369
2370bool
2372{
2373 NS_LOG_FUNCTION(this);
2374
2375 // Max retransmissions reached without receiving ACK,
2376 // send the proper indication/confirmation
2377 // according to the frame type and call drop trace.
2379 {
2380 LrWpanMacHeader peekedMacHdr;
2381 m_txPkt->PeekHeader(peekedMacHdr);
2382
2383 if (peekedMacHdr.IsCommand())
2384 {
2386
2387 Ptr<Packet> pkt = m_txPkt->Copy();
2388 LrWpanMacHeader macHdr;
2389 CommandPayloadHeader cmdPayload;
2390 pkt->RemoveHeader(macHdr);
2391 pkt->RemoveHeader(cmdPayload);
2392
2393 switch (cmdPayload.GetCommandFrameType())
2394 {
2396 m_macPanId = 0xffff;
2398 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2401 m_csmaCa->SetUnSlottedCsmaCa();
2404
2406 {
2407 MlmeAssociateConfirmParams confirmParams;
2408 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
2409 confirmParams.m_status = MLMEASSOC_NO_ACK;
2410 m_mlmeAssociateConfirmCallback(confirmParams);
2411 }
2412 break;
2413 }
2415 // IEEE 802.15.4-2006 (Section 7.1.3.3.3 and 7.1.8.2.3)
2417 {
2418 MlmeCommStatusIndicationParams commStatusParams;
2419 commStatusParams.m_panId = m_macPanId;
2420 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2421 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2422 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2423 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2425 m_mlmeCommStatusIndicationCallback(commStatusParams);
2426 }
2428 break;
2429 }
2431 // IEEE 802.15.4-2006 (Section 7.1.16.1.3)
2432 m_macPanId = 0xffff;
2434 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2437 m_csmaCa->SetUnSlottedCsmaCa();
2440
2442 {
2443 MlmePollConfirmParams pollConfirmParams;
2445 m_mlmePollConfirmCallback(pollConfirmParams);
2446 }
2447 break;
2448 }
2449 default: {
2450 // TODO: Specify other indications according to other commands
2451 break;
2452 }
2453 }
2454 }
2455 else
2456 {
2457 // Maximum number of retransmissions has been reached.
2458 // remove the copy of the DATA packet that was just sent
2459 Ptr<TxQueueElement> txQElement = m_txQueue.front();
2460 m_macTxDropTrace(txQElement->txQPkt);
2462 {
2463 McpsDataConfirmParams confirmParams;
2464 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2465 confirmParams.m_status = IEEE_802_15_4_NO_ACK;
2466 m_mcpsDataConfirmCallback(confirmParams);
2467 }
2468 }
2469
2471 return false;
2472 }
2473 else
2474 {
2476 m_numCsmacaRetry += m_csmaCa->GetNB() + 1;
2477 // Start next CCA process for this packet.
2478 return true;
2479 }
2480}
2481
2482void
2484{
2485 Ptr<IndTxQueueElement> indTxQElement = Create<IndTxQueueElement>();
2486 LrWpanMacHeader peekedMacHdr;
2487 p->PeekHeader(peekedMacHdr);
2488
2489 PurgeInd();
2490
2491 NS_ASSERT(peekedMacHdr.GetDstAddrMode() == SHORT_ADDR ||
2492 peekedMacHdr.GetDstAddrMode() == EXT_ADDR);
2493
2494 if (peekedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2495 {
2496 indTxQElement->dstShortAddress = peekedMacHdr.GetShortDstAddr();
2497 }
2498 else
2499 {
2500 indTxQElement->dstExtAddress = peekedMacHdr.GetExtDstAddr();
2501 }
2502
2503 indTxQElement->seqNum = peekedMacHdr.GetSeqNum();
2504
2505 // See IEEE 802.15.4-2006, Table 86
2506 uint32_t unit = 0; // The persistence time in symbols
2507 if (m_macBeaconOrder == 15)
2508 {
2509 // Non-beacon enabled mode
2511 }
2512 else
2513 {
2514 // Beacon-enabled mode
2515 unit = ((static_cast<uint32_t>(1) << m_macBeaconOrder) * aBaseSuperframeDuration) *
2517 }
2518
2519 if (m_indTxQueue.size() < m_maxIndTxQueueSize)
2520 {
2521 double symbolRate = m_phy->GetDataOrSymbolRate(false);
2522 Time expireTime = Seconds(unit / symbolRate);
2523 expireTime += Simulator::Now();
2524 indTxQElement->expireTime = expireTime;
2525 indTxQElement->txQPkt = p;
2526 m_indTxQueue.emplace_back(indTxQElement);
2528 }
2529 else
2530 {
2532 {
2533 LrWpanMacHeader peekedMacHdr;
2534 indTxQElement->txQPkt->PeekHeader(peekedMacHdr);
2535 MlmeCommStatusIndicationParams commStatusParams;
2536 commStatusParams.m_panId = m_macPanId;
2537 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2538 commStatusParams.m_srcExtAddr = peekedMacHdr.GetExtSrcAddr();
2539 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2540 commStatusParams.m_dstExtAddr = peekedMacHdr.GetExtDstAddr();
2542 m_mlmeCommStatusIndicationCallback(commStatusParams);
2543 }
2545 }
2546}
2547
2548bool
2550{
2551 PurgeInd();
2552
2553 for (auto iter = m_indTxQueue.begin(); iter != m_indTxQueue.end(); iter++)
2554 {
2555 if ((*iter)->dstExtAddress == dst)
2556 {
2557 *entry = **iter;
2558 m_macIndTxDequeueTrace((*iter)->txQPkt->Copy());
2559 m_indTxQueue.erase(iter);
2560 return true;
2561 }
2562 }
2563 return false;
2564}
2565
2566void
2568{
2569 for (uint32_t i = 0; i < m_indTxQueue.size();)
2570 {
2571 if (Simulator::Now() > m_indTxQueue[i]->expireTime)
2572 {
2573 // Transaction expired, remove and send proper confirmation/indication to a higher layer
2574 LrWpanMacHeader peekedMacHdr;
2575 m_indTxQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2576
2577 if (peekedMacHdr.IsCommand())
2578 {
2579 // IEEE 802.15.4-2006 (Section 7.1.3.3.3)
2581 {
2582 MlmeCommStatusIndicationParams commStatusParams;
2583 commStatusParams.m_panId = m_macPanId;
2584 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2585 commStatusParams.m_srcExtAddr = peekedMacHdr.GetExtSrcAddr();
2586 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2587 commStatusParams.m_dstExtAddr = peekedMacHdr.GetExtDstAddr();
2588 commStatusParams.m_status =
2590 m_mlmeCommStatusIndicationCallback(commStatusParams);
2591 }
2592 }
2593 else if (peekedMacHdr.IsData())
2594 {
2595 // IEEE 802.15.4-2006 (Section 7.1.1.1.3)
2597 {
2598 McpsDataConfirmParams confParams;
2600 m_mcpsDataConfirmCallback(confParams);
2601 }
2602 }
2603 m_macIndTxDropTrace(m_indTxQueue[i]->txQPkt->Copy());
2604 m_indTxQueue.erase(m_indTxQueue.begin() + i);
2605 }
2606 else
2607 {
2608 i++;
2609 }
2610 }
2611}
2612
2613void
2614LrWpanMac::PrintPendTxQ(std::ostream& os) const
2615{
2616 LrWpanMacHeader peekedMacHdr;
2617
2618 os << "Pending Transaction List [" << GetShortAddress() << " | " << GetExtendedAddress()
2619 << "] | CurrentTime: " << Simulator::Now().As(Time::S) << "\n"
2620 << " Destination | Sequence Number | Frame type | Expire time\n";
2621
2622 for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
2623 {
2624 m_indTxQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2625 os << m_indTxQueue[i]->dstExtAddress << " "
2626 << static_cast<uint32_t>(m_indTxQueue[i]->seqNum) << " ";
2627
2628 if (peekedMacHdr.IsCommand())
2629 {
2630 os << "Cmd Frame ";
2631 }
2632 else if (peekedMacHdr.IsData())
2633 {
2634 os << "Data Frame ";
2635 }
2636 else
2637 {
2638 os << "Unk Frame ";
2639 }
2640
2641 os << m_indTxQueue[i]->expireTime.As(Time::S) << "\n";
2642 }
2643}
2644
2645void
2646LrWpanMac::PrintTxQueue(std::ostream& os) const
2647{
2648 LrWpanMacHeader peekedMacHdr;
2649
2650 os << "\nTx Queue [" << GetShortAddress() << " | " << GetExtendedAddress()
2651 << "] | CurrentTime: " << Simulator::Now().As(Time::S) << "\n"
2652 << " Destination | Sequence Number | Dst PAN id | Frame type |\n";
2653
2654 for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
2655 {
2656 m_txQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2657
2658 os << "[" << peekedMacHdr.GetShortDstAddr() << "]"
2659 << ", [" << peekedMacHdr.GetExtDstAddr() << "] "
2660 << static_cast<uint32_t>(peekedMacHdr.GetSeqNum()) << " "
2661 << peekedMacHdr.GetDstPanId() << " ";
2662
2663 if (peekedMacHdr.IsCommand())
2664 {
2665 os << "Cmd Frame ";
2666 }
2667 else if (peekedMacHdr.IsData())
2668 {
2669 os << "Data Frame ";
2670 }
2671 else
2672 {
2673 os << "Unk Frame ";
2674 }
2675
2676 os << "\n";
2677 }
2678 os << "\n";
2679}
2680
2681void
2683{
2684 LrWpanMacHeader peekedMacHdr;
2685 p->PeekHeader(peekedMacHdr);
2686
2687 for (auto it = m_indTxQueue.begin(); it != m_indTxQueue.end(); it++)
2688 {
2689 if (peekedMacHdr.GetDstAddrMode() == EXT_ADDR)
2690 {
2691 if (((*it)->dstExtAddress == peekedMacHdr.GetExtDstAddr()) &&
2692 ((*it)->seqNum == peekedMacHdr.GetSeqNum()))
2693 {
2695 m_indTxQueue.erase(it);
2696 break;
2697 }
2698 }
2699 else if (peekedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2700 {
2701 if (((*it)->dstShortAddress == peekedMacHdr.GetShortDstAddr()) &&
2702 ((*it)->seqNum == peekedMacHdr.GetSeqNum()))
2703 {
2705 m_indTxQueue.erase(it);
2706 break;
2707 }
2708 }
2709 }
2710
2711 p = nullptr;
2712}
2713
2714void
2716{
2718 NS_LOG_FUNCTION(this << status << m_txQueue.size());
2719
2720 LrWpanMacHeader macHdr;
2721 Time ifsWaitTime;
2722 double symbolRate;
2723
2724 symbolRate = m_phy->GetDataOrSymbolRate(false); // symbols per second
2725
2726 m_txPkt->PeekHeader(macHdr);
2727
2728 if (status == IEEE_802_15_4_PHY_SUCCESS)
2729 {
2730 if (!macHdr.IsAcknowledgment())
2731 {
2732 if (macHdr.IsBeacon())
2733 {
2734 // Start CAP only if we are in beacon mode (i.e. if slotted csma-ca is running)
2735 if (m_csmaCa->IsSlottedCsmaCa())
2736 {
2737 // The Tx Beacon in symbols
2738 // Beacon = 5 bytes Sync Header (SHR) + 1 byte PHY header (PHR) + PSDU (default
2739 // 17 bytes)
2740 uint64_t beaconSymbols = m_phy->GetPhySHRDuration() +
2741 1 * m_phy->GetPhySymbolsPerOctet() +
2742 (m_txPkt->GetSize() * m_phy->GetPhySymbolsPerOctet());
2743
2744 // The beacon Tx time and start of the Outgoing superframe Active Period
2746 Simulator::Now() - Seconds(static_cast<double>(beaconSymbols) / symbolRate);
2747
2749 this,
2751 NS_LOG_DEBUG("Beacon Sent (m_macBeaconTxTime: " << m_macBeaconTxTime.As(Time::S)
2752 << ")");
2753
2755 {
2756 MlmeStartConfirmParams mlmeConfirmParams;
2757 mlmeConfirmParams.m_status = MLMESTART_SUCCESS;
2758 m_mlmeStartConfirmCallback(mlmeConfirmParams);
2759 }
2760 }
2761
2762 ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
2763 m_txPkt = nullptr;
2764 }
2765 else if (macHdr.IsAckReq()) // We have sent a regular data packet, check if we have to
2766 // wait for an ACK.
2767 {
2768 // we sent a regular data frame or command frame (e.g. AssocReq command) that
2769 // require ACK wait for the ack or the next retransmission timeout start
2770 // retransmission timer
2771 Time waitTime = Seconds(static_cast<double>(GetMacAckWaitDuration()) / symbolRate);
2777 return;
2778 }
2779 else if (macHdr.IsCommand())
2780 {
2781 // We handle commands that do not require ACK (e.g. BeaconReq command)
2782 // other command are handle by the previous if statement.
2784 }
2785 else
2786 {
2788 // remove the copy of the packet that was just sent
2790 {
2791 McpsDataConfirmParams confirmParams;
2792 NS_ASSERT_MSG(m_txQueue.size() > 0, "TxQsize = 0");
2793 Ptr<TxQueueElement> txQElement = m_txQueue.front();
2794 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2795 confirmParams.m_status = IEEE_802_15_4_SUCCESS;
2796 m_mcpsDataConfirmCallback(confirmParams);
2797 }
2798 ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
2800 }
2801 }
2802 else
2803 {
2804 // The packet sent was a successful ACK
2805
2806 // Check the received frame before the transmission of the ACK,
2807 // and send the appropriate Indication or Confirmation
2808 Ptr<Packet> recvOriginalPkt = m_rxPkt->Copy();
2809 LrWpanMacHeader receivedMacHdr;
2810 recvOriginalPkt->RemoveHeader(receivedMacHdr);
2811
2812 if (receivedMacHdr.IsCommand())
2813 {
2814 CommandPayloadHeader receivedMacPayload;
2815 recvOriginalPkt->RemoveHeader(receivedMacPayload);
2816
2817 if (receivedMacPayload.GetCommandFrameType() ==
2819 {
2821 {
2822 MlmeAssociateIndicationParams associateParams;
2823 associateParams.capabilityInfo = receivedMacPayload.GetCapabilityField();
2824 associateParams.m_extDevAddr = receivedMacHdr.GetExtSrcAddr();
2825 m_mlmeAssociateIndicationCallback(associateParams);
2826 }
2827
2828 // Clear the packet buffer for the packet request received.
2829 m_rxPkt = nullptr;
2830 }
2831 else if (receivedMacPayload.GetCommandFrameType() ==
2833 {
2834 MlmeAssociateConfirmParams confirmParams;
2835
2836 switch (receivedMacPayload.GetAssociationStatus())
2837 {
2839 confirmParams.m_status =
2841 confirmParams.m_assocShortAddr =
2842 GetShortAddress(); // the original short address used in the association
2843 // request
2845 receivedMacPayload
2846 .GetShortAddr()); // the assigned short address by the coordinator
2847 m_macPanId = receivedMacHdr.GetSrcPanId();
2848 break;
2850 confirmParams.m_status =
2852 m_macPanId = 0xffff;
2854 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2857 m_csmaCa->SetUnSlottedCsmaCa();
2860 break;
2862 confirmParams.m_status =
2864 m_macPanId = 0xffff;
2866 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2869 m_csmaCa->SetUnSlottedCsmaCa();
2872 break;
2873 }
2874
2876 {
2877 m_mlmeAssociateConfirmCallback(confirmParams);
2878 }
2879 }
2880 else if (receivedMacPayload.GetCommandFrameType() == CommandPayloadHeader::DATA_REQ)
2881 {
2882 // We enqueue the the Assoc Response command frame in the Tx queue
2883 // and the packet is transmitted as soon as the PHY is free and the IFS have
2884 // taken place.
2886 }
2887 }
2888
2889 // Clear the packet buffer for the ACK packet sent.
2890 m_txPkt = nullptr;
2891 }
2892 }
2893 else if (status == IEEE_802_15_4_PHY_UNSPECIFIED)
2894 {
2895 if (!macHdr.IsAcknowledgment())
2896 {
2897 NS_ASSERT_MSG(m_txQueue.size() > 0, "TxQsize = 0");
2898 Ptr<TxQueueElement> txQElement = m_txQueue.front();
2899 m_macTxDropTrace(txQElement->txQPkt);
2901 {
2902 McpsDataConfirmParams confirmParams;
2903 confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2904 confirmParams.m_status = IEEE_802_15_4_FRAME_TOO_LONG;
2905 m_mcpsDataConfirmCallback(confirmParams);
2906 }
2908 }
2909 else
2910 {
2911 NS_LOG_ERROR("Unable to send ACK");
2912 }
2913 }
2914 else
2915 {
2916 // Something went really wrong. The PHY is not in the correct state for
2917 // data transmission.
2918 NS_FATAL_ERROR("Transmission attempt failed with PHY status " << status);
2919 }
2920
2921 if (!ifsWaitTime.IsZero())
2922 {
2923 m_ifsEvent =
2924 Simulator::Schedule(ifsWaitTime, &LrWpanMac::IfsWaitTimeout, this, ifsWaitTime);
2925 }
2926
2929}
2930
2931void
2933{
2934 NS_LOG_FUNCTION(this << status);
2935 // Direct this call through the csmaCa object
2936 m_csmaCa->PlmeCcaConfirm(status);
2937}
2938
2939void
2941{
2942 NS_LOG_FUNCTION(this << status << energyLevel);
2943
2944 if (energyLevel > m_maxEnergyLevel)
2945 {
2946 m_maxEnergyLevel = energyLevel;
2947 }
2948
2950 Seconds(8.0 / m_phy->GetDataOrSymbolRate(false)))
2951 {
2952 m_phy->PlmeEdRequest();
2953 }
2954}
2955
2956void
2959 LrWpanPhyPibAttributes* attribute)
2960{
2961 NS_LOG_FUNCTION(this << status << id << attribute);
2962}
2963
2964void
2966{
2967 NS_LOG_FUNCTION(this << status);
2968
2970 (status == IEEE_802_15_4_PHY_TX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
2971 {
2973
2974 // Start sending if we are in state SENDING and the PHY transmitter was enabled.
2978 m_phy->PdDataRequest(m_txPkt->GetSize(), m_txPkt);
2979 }
2980 else if (m_lrWpanMacState == MAC_CSMA &&
2981 (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
2982 {
2983 // Start the CSMA algorithm as soon as the receiver is enabled.
2984 m_csmaCa->Start();
2985 }
2986 else if (m_lrWpanMacState == MAC_IDLE)
2987 {
2989 status == IEEE_802_15_4_PHY_TRX_OFF);
2990
2992 {
2993 // Kick start Energy Detection Scan
2994 m_phy->PlmeEdRequest();
2995 }
2996 else if (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS)
2997 {
2998 // Check if there is not messages to transmit when going idle
2999 CheckQueue();
3000 }
3001 }
3003 {
3005 }
3006 else
3007 {
3008 // TODO: What to do when we receive an error?
3009 // If we want to transmit a packet, but switching the transceiver on results
3010 // in an error, we have to recover somehow (and start sending again).
3011 NS_FATAL_ERROR("Error changing transceiver state");
3012 }
3013}
3014
3015void
3017{
3018 NS_LOG_FUNCTION(this << status << id);
3020 {
3022 {
3023 // get the first channel to scan from scan channel list
3024 bool channelFound = false;
3025 for (int i = m_channelScanIndex; i <= 26; i++)
3026 {
3028 {
3029 channelFound = true;
3030 break;
3031 }
3033 }
3034
3035 if (channelFound)
3036 {
3037 LrWpanPhyPibAttributes pibAttr;
3040 &pibAttr);
3041 }
3042 }
3043 else
3044 {
3046 {
3047 MlmeScanConfirmParams confirmParams;
3048 confirmParams.m_scanType = m_scanParams.m_scanType;
3049 confirmParams.m_chPage = m_scanParams.m_chPage;
3050 confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3051 m_mlmeScanConfirmCallback(confirmParams);
3052 }
3053 NS_LOG_ERROR(this << "Channel Scan: Invalid channel page");
3054 }
3055 }
3058 {
3060 {
3061 uint64_t symbolRate = static_cast<uint64_t>(m_phy->GetDataOrSymbolRate(false));
3062 uint64_t scanDuration = aBaseSuperframeDuration *
3063 ((static_cast<uint32_t>(1 << m_scanParams.m_scanDuration)) + 1);
3064 Time nextScanTime = Seconds(static_cast<double>(scanDuration / symbolRate));
3065
3066 switch (m_scanParams.m_scanType)
3067 {
3068 case MLMESCAN_ED:
3069 m_maxEnergyLevel = 0;
3072 // set phy to RX_ON and kick start the first PLME-ED.request
3073 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3074 break;
3075 case MLMESCAN_ACTIVE:
3078 break;
3079 case MLMESCAN_PASSIVE:
3081 // turn back the phy to RX_ON after setting Page/channel
3082 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3083 break;
3084 case MLMESCAN_ORPHAN:
3085 // TODO: add orphan scan support
3086 NS_LOG_ERROR("Scan Type currently not supported");
3087 break;
3088
3089 default:
3090 MlmeScanConfirmParams confirmParams;
3091 confirmParams.m_scanType = m_scanParams.m_scanType;
3092 confirmParams.m_chPage = m_scanParams.m_chPage;
3093 confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3095 {
3096 m_mlmeScanConfirmCallback(confirmParams);
3097 }
3098 NS_LOG_ERROR("Scan Type currently not supported");
3099 return;
3100 }
3101 }
3102 else
3103 {
3105 {
3106 MlmeScanConfirmParams confirmParams;
3107 confirmParams.m_scanType = m_scanParams.m_scanType;
3108 confirmParams.m_chPage = m_scanParams.m_chPage;
3109 confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3110 m_mlmeScanConfirmCallback(confirmParams);
3111 }
3112 NS_LOG_ERROR("Channel " << m_channelScanIndex
3113 << " could not be set in the current page");
3114 }
3115 }
3118 {
3120 {
3121 LrWpanPhyPibAttributes pibAttr;
3124 &pibAttr);
3125 }
3126 else
3127 {
3129 {
3130 MlmeStartConfirmParams confirmParams;
3131 confirmParams.m_status = MLMESTART_INVALID_PARAMETER;
3132 m_mlmeStartConfirmCallback(confirmParams);
3133 }
3134 NS_LOG_ERROR("Invalid page parameter in MLME-start");
3135 }
3136 }
3139 {
3141 {
3143 }
3144 else
3145 {
3147 {
3148 MlmeStartConfirmParams confirmParams;
3149 confirmParams.m_status = MLMESTART_INVALID_PARAMETER;
3150 m_mlmeStartConfirmCallback(confirmParams);
3151 }
3152 NS_LOG_ERROR("Invalid channel parameter in MLME-start");
3153 }
3154 }
3157 {
3159 {
3160 LrWpanPhyPibAttributes pibAttr;
3163 &pibAttr);
3164 }
3165 else
3166 {
3167 m_macPanId = 0xffff;
3169 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3172 m_csmaCa->SetUnSlottedCsmaCa();
3175
3177 {
3178 MlmeAssociateConfirmParams confirmParams;
3179 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3180 confirmParams.m_status = MLMEASSOC_INVALID_PARAMETER;
3181 m_mlmeAssociateConfirmCallback(confirmParams);
3182 }
3183 NS_LOG_ERROR("Invalid page parameter in MLME-associate");
3184 }
3185 }
3188 {
3190 {
3192 }
3193 else
3194 {
3195 m_macPanId = 0xffff;
3197 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3200 m_csmaCa->SetUnSlottedCsmaCa();
3203
3205 {
3206 MlmeAssociateConfirmParams confirmParams;
3207 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3208 confirmParams.m_status = MLMEASSOC_INVALID_PARAMETER;
3209 m_mlmeAssociateConfirmCallback(confirmParams);
3210 }
3211 NS_LOG_ERROR("Invalid channel parameter in MLME-associate");
3212 }
3213 }
3214}
3215
3216void
3218{
3219 NS_LOG_FUNCTION(this << "mac state = " << macState);
3220
3221 if (macState == MAC_IDLE)
3222 {
3225 {
3226 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3227 }
3228 else
3229 {
3230 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
3231 }
3232 }
3233 else if (macState == MAC_ACK_PENDING)
3234 {
3236 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3237 }
3238 else if (macState == MAC_CSMA)
3239 {
3242 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3243 }
3244 else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_IDLE)
3245 {
3246 // Channel is idle, set transmitter to TX_ON
3248 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
3249 }
3250 else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_ACCESS_FAILURE)
3251 {
3253
3254 // Cannot find a clear channel, drop the current packet
3255 // and send the proper confirm/indication according to the packet type
3256 NS_LOG_DEBUG(this << " cannot find clear channel");
3257
3259
3260 Ptr<Packet> pkt = m_txPkt->Copy();
3261 LrWpanMacHeader macHdr;
3262 pkt->RemoveHeader(macHdr);
3263
3264 if (macHdr.IsCommand())
3265 {
3266 CommandPayloadHeader cmdPayload;
3267 pkt->RemoveHeader(cmdPayload);
3268
3269 switch (cmdPayload.GetCommandFrameType())
3270 {
3272 m_macPanId = 0xffff;
3274 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3277 m_csmaCa->SetUnSlottedCsmaCa();
3280
3282 {
3283 MlmeAssociateConfirmParams confirmParams;
3284 confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3286 m_mlmeAssociateConfirmCallback(confirmParams);
3287 }
3288 break;
3289 }
3292 {
3293 MlmeCommStatusIndicationParams commStatusParams;
3294 commStatusParams.m_panId = m_macPanId;
3295 commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
3296 commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
3297 commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
3298 commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
3299 commStatusParams.m_status =
3301 m_mlmeCommStatusIndicationCallback(commStatusParams);
3302 }
3304 break;
3305 }
3307 m_macPanId = 0xffff;
3309 m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3312 m_csmaCa->SetUnSlottedCsmaCa();
3315
3317 {
3318 MlmePollConfirmParams pollConfirmParams;
3319 pollConfirmParams.m_status =
3321 m_mlmePollConfirmCallback(pollConfirmParams);
3322 }
3323 break;
3324 }
3325 default: {
3326 // TODO: Other commands(e.g. Orphan Request)
3327 break;
3328 }
3329 }
3331 }
3332 else if (macHdr.IsData())
3333 {
3335 {
3336 McpsDataConfirmParams confirmParams;
3337 confirmParams.m_msduHandle = m_txQueue.front()->txQMsduHandle;
3339 m_mcpsDataConfirmCallback(confirmParams);
3340 }
3341 // remove the copy of the packet that was just sent
3343 }
3344 else
3345 {
3346 // TODO:: specify behavior for other packets
3347 m_txPkt = nullptr;
3348 m_retransmission = 0;
3349 m_numCsmacaRetry = 0;
3350 }
3351
3354 {
3355 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3356 }
3357 else
3358 {
3359 m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
3360 }
3361 }
3362 else if (m_lrWpanMacState == MAC_CSMA && macState == MAC_CSMA_DEFERRED)
3363 {
3365 m_txPkt = nullptr;
3366 // The MAC is running on beacon mode and the current packet could not be sent in the
3367 // current CAP. The packet will be send on the next CAP after receiving the beacon.
3368 // The PHY state does not change from its current form. The PHY change (RX_ON) will be
3369 // triggered by the scheduled beacon event.
3370
3371 NS_LOG_DEBUG("****** PACKET DEFERRED to the next superframe *****");
3372 }
3373}
3374
3377{
3378 return m_associationStatus;
3379}
3380
3381void
3383{
3384 m_associationStatus = status;
3385}
3386
3387void
3389{
3390 m_maxTxQueueSize = queueSize;
3391}
3392
3393void
3395{
3396 m_maxIndTxQueueSize = queueSize;
3397}
3398
3399uint16_t
3401{
3402 return m_macPanId;
3403}
3404
3407{
3409}
3410
3413{
3415}
3416
3417void
3418LrWpanMac::SetPanId(uint16_t panId)
3419{
3420 m_macPanId = panId;
3421}
3422
3423void
3425{
3426 NS_LOG_LOGIC(this << " change lrwpan mac state from " << m_lrWpanMacState << " to "
3427 << newState);
3429 m_lrWpanMacState = newState;
3430}
3431
3432uint64_t
3434{
3435 return m_csmaCa->GetUnitBackoffPeriod() + m_phy->aTurnaroundTime + m_phy->GetPhySHRDuration() +
3436 ceil(6 * m_phy->GetPhySymbolsPerOctet());
3437}
3438
3439uint8_t
3441{
3442 return m_macMaxFrameRetries;
3443}
3444
3445void
3447{
3448 NS_LOG_DEBUG("Transmit Queue Size: " << m_txQueue.size());
3449}
3450
3451void
3453{
3454 m_macMaxFrameRetries = retries;
3455}
3456
3457bool
3459{
3461 LrWpanMacHeader macHdr;
3462 m_txPkt->PeekHeader(macHdr);
3463
3464 if (m_panCoor)
3465 {
3466 // The device is the PAN coordinator and the packet is not to itself
3467 return false;
3468 }
3469 else if (m_macCoordShortAddress == macHdr.GetShortDstAddr() ||
3471 {
3472 return true;
3473 }
3474 else
3475 {
3476 NS_LOG_DEBUG("ERROR: Packet not for the coordinator!");
3477 return false;
3478 }
3479}
3480
3483{
3485
3487 {
3488 return m_macSIFSPeriod;
3489 }
3490 else
3491 {
3492 return m_macLIFSPeriod;
3493 }
3494}
3495
3496void
3498{
3500}
3501
3502void
3504{
3506}
3507
3508uint64_t
3510{
3512 // Sync Header (SHR) + 8 bits PHY header (PHR) + PSDU
3513 return (m_phy->GetPhySHRDuration() + 1 * m_phy->GetPhySymbolsPerOctet() +
3514 (m_txPkt->GetSize() * m_phy->GetPhySymbolsPerOctet()));
3515}
3516
3517bool
3519{
3521 LrWpanMacHeader macHdr;
3522 m_txPkt->PeekHeader(macHdr);
3523
3524 return macHdr.IsAckReq();
3525}
3526
3527} // 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:556
Implements the header for the MAC payload command frame according to the IEEE 802....
@ SUCCESSFUL
Association successful.
CapabilityField GetCapabilityField() const
Get the Capability Information Field from the command payload header.
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)
@ ASSOCIATION_REQ
Association request (RFD true: Tx)
void SetCommandFrameType(MacCommand macCmd)
Set the command frame type.
void SetShortAddr(Mac16Address shortAddr)
Set the Short Address Assigned by the coordinator (Association Response Command).
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.
enum LrWpanMacType GetType() const
Get the header type.
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.
uint16_t GetDstPanId() const
Get the Destination PAN ID.
uint8_t GetFrameVer() const
Get the Frame Version of Frame control field.
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:709
uint32_t m_incomingBeaconInterval
Indication of the interval a node should receive a superframe expressed in symbols.
Definition: lr-wpan-mac.h:1329
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:1844
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:1143
McpsDataConfirmCallback m_mcpsDataConfirmCallback
This callback is used to report data transmission request status to the upper layers.
Definition: lr-wpan-mac.h:1909
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:1128
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:219
bool m_macRxOnWhenIdle
Indication of whether the MAC sublayer is to enable its receiver during idle periods.
Definition: lr-wpan-mac.h:1268
bool m_macAssociationPermit
Indication of whether a coordinator is currently allowing association.
Definition: lr-wpan-mac.h:1287
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:1741
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:1198
void SetRxOnWhenIdle(bool rxOnWhenIdle)
Set if the receiver should be enabled when the MAC is idle.
Definition: lr-wpan-mac.cc:289
uint64_t GetTxPacketSymbols()
Obtain the number of symbols in the packet which is currently being sent by the MAC layer.
bool m_panCoor
Indication of whether the current device is the PAN coordinator.
Definition: lr-wpan-mac.h:1311
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:2025
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:772
static TypeId GetTypeId()
Get the type ID.
Definition: lr-wpan-mac.cc:50
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:1884
uint8_t m_deviceCapability
Indication of current device capability (FFD or RFD)
Definition: lr-wpan-mac.h:1340
void AwaitBeacon()
Called after the end of an INCOMING superframe to start the moment a device waits for a new incoming ...
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:2081
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:1974
EventId m_assocResCmdWaitTimeout
Scheduler event for the lost of a association response command frame.
Definition: lr-wpan-mac.h:2041
void PurgeInd()
Purge expired transactions from the pending transactions list.
bool GetRxOnWhenIdle()
Check if the receiver will be enabled when the MAC is idle.
Definition: lr-wpan-mac.cc:283
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:1775
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:1824
void SetExtendedAddress(Mac64Address address)
Set the extended address of this MAC.
Definition: lr-wpan-mac.cc:315
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:537
uint32_t m_macLIFSPeriod
The minimum time forming a Long InterFrame Spacing (LIFS) period.
Definition: lr-wpan-mac.h:1274
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:1749
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:1725
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:1757
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:1863
Mac16Address GetShortAddress() const
Get the short address of this MAC.
Definition: lr-wpan-mac.cc:322
void SendDataRequestCommand()
Used to send a data request command (i.e.
Definition: lr-wpan-mac.cc:977
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:2066
static constexpr uint32_t aBaseSuperframeDuration
Length of a superframe in symbols.
Definition: lr-wpan-mac.h:742
uint8_t m_macMaxFrameRetries
The maximum number of retries allowed after a transmission failure.
Definition: lr-wpan-mac.h:1261
Mac64Address m_macCoordExtendedAddress
The extended address of the coordinator through which the device is associated.
Definition: lr-wpan-mac.h:1159
MlmeSyncLossIndicationCallback m_mlmeSyncLossIndicationCallback
This callback is used to indicate the loss of synchronization with a coordinator.
Definition: lr-wpan-mac.h:1856
PendingPrimitiveStatus m_pendPrimitive
Indicates the pending primitive when PLME.SET operation (page or channel switch) is called from withi...
Definition: lr-wpan-mac.h:2014
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:1877
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:2008
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:1980
void SendBeaconRequestCommand()
Called to send a beacon request command.
Definition: lr-wpan-mac.cc:886
EventId m_respWaitTimeout
Scheduler event for a response to a request command frame.
Definition: lr-wpan-mac.h:2036
uint32_t m_maxTxQueueSize
The maximum size of the transmit queue.
Definition: lr-wpan-mac.h:1969
std::deque< Ptr< TxQueueElement > > m_txQueue
The transmit queue used by the MAC.
Definition: lr-wpan-mac.h:1958
SequenceNumber8 m_macBsn
Sequence number added to transmitted beacon frame, 00-ff.
Definition: lr-wpan-mac.h:1255
LrWpanAssociationStatus m_associationStatus
The current association status of the MAC layer.
Definition: lr-wpan-mac.h:1929
Ptr< Packet > m_rxPkt
The command request packet received.
Definition: lr-wpan-mac.h:1940
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:1717
void SetLrWpanMacState(LrWpanMacState macState)
CSMA-CA algorithm calls back the MAC after executing channel assessment.
Mac16Address m_shortAddress
The short address used by this MAC.
Definition: lr-wpan-mac.h:1947
uint8_t m_macSuperframeOrder
Used by a PAN coordinator or coordinator.
Definition: lr-wpan-mac.h:1181
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:1985
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:826
Time m_macBeaconTxTime
The time that the device transmitted its last beacon frame.
Definition: lr-wpan-mac.h:1120
MlmeBeaconNotifyIndicationCallback m_mlmeBeaconNotifyIndicationCallback
This callback is used to notify incoming beacon packets to the upper layers.
Definition: lr-wpan-mac.h:1850
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:1834
Mac64Address GetExtendedAddress() const
Get the extended address of this MAC.
Definition: lr-wpan-mac.cc:329
EventId m_setMacState
Scheduler event for a deferred MAC state change.
Definition: lr-wpan-mac.h:2046
uint64_t m_macResponseWaitTime
The maximum time, in multiples of aBaseSuperframeDuration, a device shall wait for a response command...
Definition: lr-wpan-mac.h:1135
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 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:2091
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.
static constexpr uint32_t aMaxSIFSFrameSize
The maximum size of an MPDU, in octets, that can be followed by a Short InterFrame Spacing (SIFS) per...
Definition: lr-wpan-mac.h:757
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:635
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 a channel scan.
Definition: lr-wpan-mac.h:2086
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:1804
uint8_t m_incomingBeaconOrder
The beaconOrder value of the INCOMING frame.
Definition: lr-wpan-mac.h:1210
SequenceNumber8 m_macDsn
Sequence number added to transmitted data or MAC command frame, 00-ff.
Definition: lr-wpan-mac.h:1249
void SetMlmeSyncLossIndicationCallback(MlmeSyncLossIndicationCallback c)
Set the callback for the loss of synchronization with a coordinator.
uint32_t m_ifs
The value of the necessary InterFrame Space after the transmission of a packet.
Definition: lr-wpan-mac.h:1306
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:1192
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.
void PlmeGetAttributeConfirm(LrWpanPhyEnumeration status, LrWpanPibAttributeIdentifier id, LrWpanPhyPibAttributes *attribute)
IEEE 802.15.4-2006 section 6.2.2.6 PLME-GET.confirm Get attributes per definition from Table 23 in se...
MlmeStartRequestParams m_startParams
The parameters used during a MLME-START.request.
Definition: lr-wpan-mac.h:1997
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:576
LrWpanAssociationStatus GetAssociationStatus() const
Get the current association status.
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:1173
TracedCallback< Time > m_macIfsEndTrace
The trace source is fired at the end of any Interframe Space (IFS).
Definition: lr-wpan-mac.h:1681
TracedValue< SuperframeStatus > m_outSuperframeStatus
The current period of the outgoing superframe.
Definition: lr-wpan-mac.h:1924
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...
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:2003
LrWpanMac()
Default constructor.
Definition: lr-wpan-mac.cc:161
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:2031
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:1870
bool m_macPromiscuousMode
Indicates if MAC sublayer is in receive all mode.
Definition: lr-wpan-mac.h:1230
uint8_t m_fnlCapSlot
Indication of the Slot where the CAP portion of the OUTGOING Superframe ends.
Definition: lr-wpan-mac.h:1203
uint32_t m_macSIFSPeriod
The minimum time forming a Short InterFrame Spacing (SIFS) period.
Definition: lr-wpan-mac.h:1280
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:1964
uint32_t m_beaconInterval
Indication of the Interval used by the coordinator to transmit beacon frames expressed in symbols.
Definition: lr-wpan-mac.h:1317
static constexpr uint32_t aMaxLostBeacons
The number of consecutive lost beacons that will cause the MAC sublayer of a receiving device to decl...
Definition: lr-wpan-mac.h:750
TracedValue< LrWpanMacState > m_lrWpanMacState
The current state of the MAC layer.
Definition: lr-wpan-mac.h:1914
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:1701
EventId m_capEvent
Scheduler event for the end of the outgoing superframe CAP.
Definition: lr-wpan-mac.h:2061
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets are being sent down to L1.
Definition: lr-wpan-mac.h:1732
uint16_t m_macPanId
16 bits id of PAN on which this device is operating.
Definition: lr-wpan-mac.h:1237
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:224
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:710
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:1784
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:1296
uint8_t m_incomingSuperframeOrder
Used by all devices that have a parent.
Definition: lr-wpan-mac.h:1218
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:1243
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:1709
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:1350
Ptr< Packet > m_txPkt
The packet which is currently being sent by the MAC layer.
Definition: lr-wpan-mac.h:1934
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:336
void SendAssocRequestCommand()
Called to send an associate request command.
Definition: lr-wpan-mac.cc:928
uint8_t m_maxEnergyLevel
The maximum energy level detected during ED scan on the current channel.
Definition: lr-wpan-mac.h:1301
void DoDispose() override
Destructor implementation.
Definition: lr-wpan-mac.cc:239
MlmeScanRequestParams m_scanParams
The parameters used during a MLME-SCAN.request.
Definition: lr-wpan-mac.h:1991
MlmeAssociateIndicationCallback m_mlmeAssociateIndicationCallback
This callback is used to indicate the reception of an association request command.
Definition: lr-wpan-mac.h:1896
static constexpr uint32_t aMinMPDUOverhead
The minimum number of octets added by the MAC sublayer to the PSDU.
Definition: lr-wpan-mac.h:722
void SetPhy(Ptr< LrWpanPhy > phy)
Set the underlying PHY for the MAC.
Ptr< LrWpanPhy > GetPhy()
Get the underlying PHY of the MAC.
void EndAssociateRequest()
Called to end an MLME-ASSOCIATE.request after changing the page and channel number.
Definition: lr-wpan-mac.cc:690
Mac64Address m_selfExt
The extended address used by this MAC.
Definition: lr-wpan-mac.h:1953
EventId m_incCapEvent
Scheduler event for the end of the incoming superframe CAP.
Definition: lr-wpan-mac.h:2071
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:1890
bool m_beaconTrackingOn
Indication of whether the current device is tracking incoming beacons.
Definition: lr-wpan-mac.h:1345
uint32_t m_superframeDuration
Indication of the superframe duration in symbols.
Definition: lr-wpan-mac.h:1323
Mac16Address m_macCoordShortAddress
The short address of the coordinator through which the device is associated.
Definition: lr-wpan-mac.h:1152
GtsFields GetGtsFields()
Constructs the Guaranteed Time Slots (GTS) Fields from local information.
Ptr< LrWpanPhy > m_phy
The PHY associated with this MAC.
Definition: lr-wpan-mac.h:1839
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 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:1766
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:811
EventId m_ifsEvent
Scheduler event for Interframe spacing wait time.
Definition: lr-wpan-mac.h:2051
EventId m_beaconEvent
Scheduler event for generation of one beacon.
Definition: lr-wpan-mac.h:2056
uint32_t m_incomingSuperframeDuration
Indication of the superframe duration in symbols (e.g.
Definition: lr-wpan-mac.h:1335
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:1693
void RemovePendTxQElement(Ptr< Packet > p)
Remove an element from the pending transaction list.
void SetShortAddress(Mac16Address address)
Set the short address of this MAC.
Definition: lr-wpan-mac.cc:308
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:2020
EventId m_incCfpEvent
Scheduler event for the end of the incoming superframe CFP.
Definition: lr-wpan-mac.h:2076
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:1223
MlmeCommStatusIndicationCallback m_mlmeCommStatusIndicationCallback
This callback is instigated through a response primitive.
Definition: lr-wpan-mac.h:1902
TracedValue< SuperframeStatus > m_incSuperframeStatus
The current period of the incoming superframe.
Definition: lr-wpan-mac.h:1919
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.
static const uint32_t aMaxPhyPacketSize
The maximum packet size accepted by the PHY.
Definition: lr-wpan-phy.h:264
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
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:258
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 RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:336
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
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
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:324
Represent the Pending Address Specification field.
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
@ S
second
Definition: nstime.h:116
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:314
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
LrWpanMacState
MAC states.
Definition: lr-wpan-mac.h:73
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:109
LrWpanAssociationStatus
table 83 of 802.15.4
Definition: lr-wpan-mac.h:166
SuperframeType
Superframe type.
Definition: lr-wpan-mac.h:105
LrWpanPibAttributeIdentifier
IEEE802.15.4-2006 PHY PIB Attribute Identifiers Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:143
@ MLMEPOLL_SUCCESS
Definition: lr-wpan-mac.h:301
@ MLMEPOLL_NO_ACK
Definition: lr-wpan-mac.h:303
@ MLMEPOLL_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:302
@ CHANNEL_ACCESS_FAILURE
CHANNEL_ACCESS_FAILURE.
Definition: lr-wpan-mac.h:78
@ MAC_IDLE
MAC_IDLE.
Definition: lr-wpan-mac.h:74
@ MAC_CSMA_DEFERRED
MAC_CSMA_DEFERRED.
Definition: lr-wpan-mac.h:83
@ MAC_CSMA
MAC_CSMA.
Definition: lr-wpan-mac.h:75
@ CHANNEL_IDLE
CHANNEL_IDLE.
Definition: lr-wpan-mac.h:79
@ MAC_SENDING
MAC_SENDING.
Definition: lr-wpan-mac.h:76
@ MAC_ACK_PENDING
MAC_ACK_PENDING.
Definition: lr-wpan-mac.h:77
@ FFD
Full Functional Device (FFD)
@ MLMESCAN_ED
Definition: lr-wpan-mac.h:181
@ MLMESCAN_PASSIVE
Definition: lr-wpan-mac.h:183
@ MLMESCAN_ORPHAN
Definition: lr-wpan-mac.h:184
@ MLMESCAN_ACTIVE
Definition: lr-wpan-mac.h:182
@ IEEE_802_15_4_TRANSACTION_OVERFLOW
Definition: lr-wpan-mac.h:195
@ IEEE_802_15_4_NO_ACK
Definition: lr-wpan-mac.h:200
@ IEEE_802_15_4_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:197
@ IEEE_802_15_4_INVALID_ADDRESS
Definition: lr-wpan-mac.h:198
@ IEEE_802_15_4_SUCCESS
Definition: lr-wpan-mac.h:194
@ IEEE_802_15_4_FRAME_TOO_LONG
Definition: lr-wpan-mac.h:202
@ IEEE_802_15_4_TRANSACTION_EXPIRED
Definition: lr-wpan-mac.h:196
@ MLMESCAN_SUCCESS
Definition: lr-wpan-mac.h:234
@ MLMESCAN_SCAN_IN_PROGRESS
Definition: lr-wpan-mac.h:237
@ MLMESCAN_INVALID_PARAMETER
Definition: lr-wpan-mac.h:242
@ CFP
Contention Free Period.
Definition: lr-wpan-mac.h:95
@ INACTIVE
Inactive Period or unslotted CSMA-CA.
Definition: lr-wpan-mac.h:96
@ CAP
Contention Access Period.
Definition: lr-wpan-mac.h:94
@ BEACON
The Beacon transmission or reception Period.
Definition: lr-wpan-mac.h:93
@ IEEE_802_15_4_PHY_SUCCESS
Definition: lr-wpan-phy.h:117
@ IEEE_802_15_4_PHY_UNSPECIFIED
Definition: lr-wpan-phy.h:122
@ IEEE_802_15_4_PHY_TRX_OFF
Definition: lr-wpan-phy.h:118
@ IEEE_802_15_4_PHY_RX_ON
Definition: lr-wpan-phy.h:116
@ IEEE_802_15_4_PHY_TX_ON
Definition: lr-wpan-phy.h:119
@ TX_OPTION_ACK
TX_OPTION_ACK.
Definition: lr-wpan-mac.h:62
@ TX_OPTION_INDIRECT
TX_OPTION_INDIRECT.
Definition: lr-wpan-mac.h:64
@ TX_OPTION_GTS
TX_OPTION_GTS.
Definition: lr-wpan-mac.h:63
@ ASSOCIATED
Definition: lr-wpan-mac.h:167
@ PAN_ACCESS_DENIED
Definition: lr-wpan-mac.h:169
@ ASSOCIATED_WITHOUT_ADDRESS
Definition: lr-wpan-mac.h:170
@ PAN_AT_CAPACITY
Definition: lr-wpan-mac.h:168
@ DISASSOCIATED
Definition: lr-wpan-mac.h:171
@ MLMESTART_INVALID_PARAMETER
Definition: lr-wpan-mac.h:219
@ MLMESTART_SUCCESS
Definition: lr-wpan-mac.h:215
@ MLMESTART_NO_SHORT_ADDRESS
Definition: lr-wpan-mac.h:216
@ MLME_SCAN_REQ
Pending MLME-SCAN.request primitive.
Definition: lr-wpan-mac.h:119
@ MLME_ASSOC_REQ
Pending MLME-ASSOCIATION.request primitive.
Definition: lr-wpan-mac.h:120
@ MLME_START_REQ
Pending MLME-START.request primitive.
Definition: lr-wpan-mac.h:118
@ MLME_NONE
No pending primitive.
Definition: lr-wpan-mac.h:117
@ SHORT_ADDR
Definition: lr-wpan-mac.h:156
@ NO_PANID_ADDR
Definition: lr-wpan-mac.h:154
@ EXT_ADDR
Definition: lr-wpan-mac.h:157
@ ADDR_MODE_RESERVED
Definition: lr-wpan-mac.h:155
@ MLMEASSOC_NO_DATA
Definition: lr-wpan-mac.h:257
@ MLMEASSOC_ACCESS_DENIED
Definition: lr-wpan-mac.h:254
@ MLMEASSOC_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:255
@ MLMEASSOC_SUCCESS
Definition: lr-wpan-mac.h:252
@ MLMEASSOC_INVALID_PARAMETER
Definition: lr-wpan-mac.h:261
@ MLMEASSOC_NO_ACK
Definition: lr-wpan-mac.h:256
@ MLMEASSOC_FULL_CAPACITY
Definition: lr-wpan-mac.h:253
@ INCOMING
Incoming Superframe.
Definition: lr-wpan-mac.h:107
@ OUTGOING
Outgoing Superframe.
Definition: lr-wpan-mac.h:106
@ MLMECOMMSTATUS_SUCCESS
Definition: lr-wpan-mac.h:284
@ MLMECOMMSTATUS_TRANSACTION_OVERFLOW
Definition: lr-wpan-mac.h:285
@ MLMECOMMSTATUS_TRANSACTION_EXPIRED
Definition: lr-wpan-mac.h:286
@ MLMECOMMSTATUS_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:287
@ MLMECOMMSTATUS_NO_ACK
Definition: lr-wpan-mac.h:288
@ phyCurrentChannel
Definition: lr-wpan-phy.h:144
@ phyCurrentPage
Definition: lr-wpan-phy.h:148
@ MLMESYNCLOSS_BEACON_LOST
Definition: lr-wpan-mac.h:273
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
SequenceNumber< uint8_t, int8_t > SequenceNumber8
8 bit Sequence number.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
mac
Definition: third.py:85
phy
Definition: third.py:82
IEEE802.15.4-2006 PHY PIB Attributes Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:160
uint8_t phyCurrentPage
Current channel page.
Definition: lr-wpan-phy.h:167
uint8_t phyCurrentChannel
The RF channel to use.
Definition: lr-wpan-phy.h:161
MCPS-DATA.confirm params.
Definition: lr-wpan-mac.h:361
LrWpanMcpsDataConfirmStatus m_status
The status of the last MSDU transmission.
Definition: lr-wpan-mac.h:363
uint8_t m_msduHandle
MSDU handle.
Definition: lr-wpan-mac.h:362
MCPS-DATA.indication params.
Definition: lr-wpan-mac.h:373
Mac16Address m_dstAddr
Destination address.
Definition: lr-wpan-mac.h:380
uint8_t m_dstAddrMode
Destination address mode.
Definition: lr-wpan-mac.h:378
uint16_t m_dstPanId
Destination PAN identifier.
Definition: lr-wpan-mac.h:379
uint8_t m_dsn
The DSN of the received data frame.
Definition: lr-wpan-mac.h:383
uint8_t m_mpduLinkQuality
LQI value measured during reception of the MPDU.
Definition: lr-wpan-mac.h:382
uint16_t m_srcPanId
Source PAN identifier.
Definition: lr-wpan-mac.h:375
Mac64Address m_dstExtAddr
Destination extended address.
Definition: lr-wpan-mac.h:381
uint8_t m_srcAddrMode
Source address mode.
Definition: lr-wpan-mac.h:374
Mac64Address m_srcExtAddr
Source extended address.
Definition: lr-wpan-mac.h:377
Mac16Address m_srcAddr
Source address.
Definition: lr-wpan-mac.h:376
MCPS-DATA.request params.
Definition: lr-wpan-mac.h:345
LrWpanAddressMode m_srcAddrMode
Source address mode.
Definition: lr-wpan-mac.h:346
Mac64Address m_dstExtAddr
Destination extended address.
Definition: lr-wpan-mac.h:350
LrWpanAddressMode m_dstAddrMode
Destination address mode.
Definition: lr-wpan-mac.h:347
uint16_t m_dstPanId
Destination PAN identifier.
Definition: lr-wpan-mac.h:348
Mac16Address m_dstAddr
Destination address.
Definition: lr-wpan-mac.h:349
uint8_t m_msduHandle
MSDU handle.
Definition: lr-wpan-mac.h:351
uint8_t m_txOptions
Tx Options (bitfield)
Definition: lr-wpan-mac.h:352
MLME-ASSOCIATE.confirm params.
Definition: lr-wpan-mac.h:524
LrWpanMlmeAssociateConfirmStatus m_status
The status of a MLME-associate.request.
Definition: lr-wpan-mac.h:526
Mac16Address m_assocShortAddr
The short address used in the association request.
Definition: lr-wpan-mac.h:525
MLME-ASSOCIATE.indication params.
Definition: lr-wpan-mac.h:392
Mac64Address m_extDevAddr
The extended address of the device requesting association.
Definition: lr-wpan-mac.h:393
CapabilityField capabilityInfo
The operational capabilities of the device requesting association.
Definition: lr-wpan-mac.h:395
MLME-ASSOCIATE.request params.
Definition: lr-wpan-mac.h:504
uint8_t m_chNum
The channel number on which to attempt association.
Definition: lr-wpan-mac.h:505
CapabilityField m_capabilityInfo
Specifies the operational capabilities of the associating device.
Definition: lr-wpan-mac.h:515
uint8_t m_coordAddrMode
The coordinator addressing mode for this primitive and subsequent MPDU.
Definition: lr-wpan-mac.h:507
uint32_t m_chPage
The channel page on which to attempt association.
Definition: lr-wpan-mac.h:506
Mac64Address m_coordExtAddr
The extended address of the coordinator with which to associate.
Definition: lr-wpan-mac.h:513
Mac16Address m_coordShortAddr
The short address of the coordinator with which to associate.
Definition: lr-wpan-mac.h:511
uint16_t m_coordPanId
The identifier of the PAN with which to associate.
Definition: lr-wpan-mac.h:509
MLME-ASSOCIATE.response params.
Definition: lr-wpan-mac.h:404
LrWpanAssociationStatus m_status
The status of the association attempt (As defined on Table 83 IEEE 802.15.4-2006)
Definition: lr-wpan-mac.h:408
Mac16Address m_assocShortAddr
The short address allocated by the coordinator on successful assoc.
Definition: lr-wpan-mac.h:406
Mac64Address m_extDevAddr
The extended address of the device requesting association.
Definition: lr-wpan-mac.h:405
MLME-BEACON-NOTIFY.indication params.
Definition: lr-wpan-mac.h:547
uint32_t m_sduLength
The number of octets contained in the beacon payload.
Definition: lr-wpan-mac.h:550
uint8_t m_bsn
The beacon sequence number.
Definition: lr-wpan-mac.h:548
Ptr< Packet > m_sdu
The set of octets comprising the beacon payload.
Definition: lr-wpan-mac.h:551
PanDescriptor m_panDescriptor
The PAN descriptor for the received beacon.
Definition: lr-wpan-mac.h:549
MLME-COMM-STATUS.indication params.
Definition: lr-wpan-mac.h:575
LrWpanMlmeCommStatus m_status
The communication status.
Definition: lr-wpan-mac.h:588
Mac64Address m_dstExtAddr
The extended address of the device for which the frame was intended.
Definition: lr-wpan-mac.h:587
uint16_t m_panId
The PAN identifier of the device from which the frame was received or to which the frame was being se...
Definition: lr-wpan-mac.h:576
Mac64Address m_srcExtAddr
The extended address of the entity from which the frame causing the error originated.
Definition: lr-wpan-mac.h:581
uint8_t m_dstAddrMode
The destination addressing mode for this primitive.
Definition: lr-wpan-mac.h:583
uint8_t m_srcAddrMode
The source addressing mode for this primitive.
Definition: lr-wpan-mac.h:578
MLME-START.confirm params.
Definition: lr-wpan-mac.h:597
LrWpanMlmePollConfirmStatus m_status
The confirmation status resulting from a MLME-poll.request.
Definition: lr-wpan-mac.h:598
MLME-POLL.request params.
Definition: lr-wpan-mac.h:454
MLME-SCAN.confirm params.
Definition: lr-wpan-mac.h:483
std::vector< PanDescriptor > m_panDescList
A list of PAN descriptor, one for each beacon found (Not valid for ED and Orphan scans).
Definition: lr-wpan-mac.h:494
LrWpanMlmeScanType m_scanType
Indicates the type of scan performed (ED,ACTIVE,PASSIVE,ORPHAN).
Definition: lr-wpan-mac.h:486
uint32_t m_chPage
The channel page on which the scan was performed.
Definition: lr-wpan-mac.h:488
LrWpanMlmeScanConfirmStatus m_status
The status of the scan request.
Definition: lr-wpan-mac.h:484
std::vector< uint8_t > m_energyDetList
A list of energy measurements, one for each channel searched during ED scan (Not valid for Active,...
Definition: lr-wpan-mac.h:492
MLME-SCAN.request params.
Definition: lr-wpan-mac.h:468
uint32_t m_scanChannels
The channel numbers to be scanned.
Definition: lr-wpan-mac.h:471
uint32_t m_chPage
The channel page on which to perform scan.
Definition: lr-wpan-mac.h:474
uint8_t m_scanDuration
A value used to calculate the length of time to spend scanning [aBaseSuperframeDuration * (2^m_scanDu...
Definition: lr-wpan-mac.h:472
LrWpanMlmeScanType m_scanType
Indicates the type of scan performed as described in IEEE 802.15.4-2011 (5.1.2.1).
Definition: lr-wpan-mac.h:469
MLME-START.confirm params.
Definition: lr-wpan-mac.h:536
LrWpanMlmeStartConfirmStatus m_status
The status of a MLME-start.request.
Definition: lr-wpan-mac.h:537
MLME-START.request params.
Definition: lr-wpan-mac.h:418
uint32_t m_logChPage
Logical channel page on which to start using the new superframe configuration.
Definition: lr-wpan-mac.h:422
uint8_t m_logCh
Logical channel on which to start using the new superframe configuration.
Definition: lr-wpan-mac.h:420
bool m_panCoor
On true this device will become coordinator.
Definition: lr-wpan-mac.h:429
bool m_coorRealgn
True if a realignment request command is to be transmitted prior changing the superframe.
Definition: lr-wpan-mac.h:432
uint8_t m_bcnOrd
Beacon Order, Used to calculate the beacon interval, a value of 15 indicates no periodic beacons will...
Definition: lr-wpan-mac.h:426
uint16_t m_PanId
Pan Identifier used by the device.
Definition: lr-wpan-mac.h:419
uint8_t m_sfrmOrd
Superframe Order, indicates the length of the CAP in time slots.
Definition: lr-wpan-mac.h:428
bool m_battLifeExt
Flag indicating whether or not the Battery life extension (BLE) features are used.
Definition: lr-wpan-mac.h:430
MLME-SYNC-LOSS.indication params.
Definition: lr-wpan-mac.h:560
uint16_t m_panId
The PAN identifier with which the device lost synchronization or to which it was realigned.
Definition: lr-wpan-mac.h:563
LrWpanSyncLossReason m_lossReason
The reason for the lost of synchronization.
Definition: lr-wpan-mac.h:561
MLME-SYNC.request params.
Definition: lr-wpan-mac.h:442
bool m_trackBcn
True if the mlme sync with the next beacon and attempts to track future beacons.
Definition: lr-wpan-mac.h:444
uint8_t m_logCh
The channel number on which to attempt coordinator synchronization.
Definition: lr-wpan-mac.h:443
PAN Descriptor, Table 17 IEEE 802.15.4-2011.
Definition: lr-wpan-mac.h:318
LrWpanAddressMode m_coorAddrMode
The coordinator addressing mode corresponding to the received beacon frame.
Definition: lr-wpan-mac.h:319
Mac64Address m_coorExtAddr
The coordinator extended address as specified in the coordinator address mode.
Definition: lr-wpan-mac.h:325
Mac16Address m_coorShortAddr
The coordinator short address as specified in the coordinator address mode.
Definition: lr-wpan-mac.h:323
uint8_t m_logChPage
The current channel page occupied by the network.
Definition: lr-wpan-mac.h:328
uint16_t m_coorPanId
The PAN ID of the coordinator as specified in the received beacon frame.
Definition: lr-wpan-mac.h:321
bool m_gtsPermit
TRUE if the beacon is from the PAN coordinator that is accepting GTS requests.
Definition: lr-wpan-mac.h:331
SuperframeField m_superframeSpec
The superframe specification as specified in the received beacon frame.
Definition: lr-wpan-mac.h:329
uint8_t m_linkQuality
The LQI at which the network beacon was received.
Definition: lr-wpan-mac.h:333
Time m_timeStamp
Beacon frame reception time.
Definition: lr-wpan-mac.h:335
uint8_t m_logCh
The current channel number occupied by the network.
Definition: lr-wpan-mac.h:327