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-constants.h"
28 #include "lr-wpan-csmaca.h"
29 #include "lr-wpan-mac-header.h"
30 #include "lr-wpan-mac-pl-headers.h"
31 #include "lr-wpan-mac-trailer.h"
32 
33 #include <ns3/double.h>
34 #include <ns3/log.h>
35 #include <ns3/node.h>
36 #include <ns3/packet.h>
37 #include <ns3/random-variable-stream.h>
38 #include <ns3/simulator.h>
39 #include <ns3/uinteger.h>
40 
41 #undef NS_LOG_APPEND_CONTEXT
42 #define NS_LOG_APPEND_CONTEXT \
43  std::clog << "[address " << m_shortAddress << " | " << m_selfExt << "] ";
44 
45 namespace ns3
46 {
47 
48 NS_LOG_COMPONENT_DEFINE("LrWpanMac");
50 
51 std::ostream&
52 operator<<(std::ostream& os, const LrWpanMacState& state)
53 {
54  switch (state)
55  {
57  os << "MAC IDLE";
58  break;
60  os << "CSMA";
61  break;
63  os << "SENDING";
64  break;
66  os << "ACK PENDING";
67  break;
69  os << "CHANNEL_ACCESS_FAILURE";
70  break;
72  os << "CHANNEL IDLE";
73  break;
75  os << "SET PHY to TX ON";
76  break;
78  os << "MAC GTS PERIOD";
79  break;
81  os << "SUPERFRAME INACTIVE PERIOD";
82  break;
84  os << "CSMA DEFERRED TO NEXT PERIOD";
85  break;
86  }
87  return os;
88 };
89 
90 TypeId
92 {
93  static TypeId tid =
94  TypeId("ns3::LrWpanMac")
96  .SetGroupName("LrWpan")
97  .AddConstructor<LrWpanMac>()
98  .AddAttribute("PanId",
99  "16-bit identifier of the associated PAN",
100  UintegerValue(),
102  MakeUintegerChecker<uint16_t>())
103  .AddTraceSource("MacTxEnqueue",
104  "Trace source indicating a packet has been "
105  "enqueued in the transaction queue",
107  "ns3::Packet::TracedCallback")
108  .AddTraceSource("MacTxDequeue",
109  "Trace source indicating a packet has was "
110  "dequeued from the transaction queue",
112  "ns3::Packet::TracedCallback")
113  .AddTraceSource("MacIndTxEnqueue",
114  "Trace source indicating a packet has been "
115  "enqueued in the indirect transaction queue",
117  "ns3::Packet::TracedCallback")
118  .AddTraceSource("MacIndTxDequeue",
119  "Trace source indicating a packet has was "
120  "dequeued from the indirect transaction queue",
122  "ns3::Packet::TracedCallback")
123  .AddTraceSource("MacTx",
124  "Trace source indicating a packet has "
125  "arrived for transmission by this device",
127  "ns3::Packet::TracedCallback")
128  .AddTraceSource("MacTxOk",
129  "Trace source indicating a packet has been "
130  "successfully sent",
132  "ns3::Packet::TracedCallback")
133  .AddTraceSource("MacTxDrop",
134  "Trace source indicating a packet has been "
135  "dropped during transmission",
137  "ns3::Packet::TracedCallback")
138  .AddTraceSource("MacIndTxDrop",
139  "Trace source indicating a packet has been "
140  "dropped from the indirect transaction queue"
141  "(The pending transaction list)",
143  "ns3::Packet::TracedCallback")
144  .AddTraceSource("MacPromiscRx",
145  "A packet has been received by this device, "
146  "has been passed up from the physical layer "
147  "and is being forwarded up the local protocol stack. "
148  "This is a promiscuous trace,",
150  "ns3::Packet::TracedCallback")
151  .AddTraceSource("MacRx",
152  "A packet has been received by this device, "
153  "has been passed up from the physical layer "
154  "and is being forwarded up the local protocol stack. "
155  "This is a non-promiscuous trace,",
157  "ns3::Packet::TracedCallback")
158  .AddTraceSource("MacRxDrop",
159  "Trace source indicating a packet was received, "
160  "but dropped before being forwarded up the stack",
162  "ns3::Packet::TracedCallback")
163  .AddTraceSource("Sniffer",
164  "Trace source simulating a non-promiscuous "
165  "packet sniffer attached to the device",
167  "ns3::Packet::TracedCallback")
168  .AddTraceSource("PromiscSniffer",
169  "Trace source simulating a promiscuous "
170  "packet sniffer attached to the device",
172  "ns3::Packet::TracedCallback")
173  .AddTraceSource("MacStateValue",
174  "The state of LrWpan Mac",
176  "ns3::TracedValueCallback::LrWpanMacState")
177  .AddTraceSource("MacIncSuperframeStatus",
178  "The period status of the incoming superframe",
180  "ns3::TracedValueCallback::SuperframeState")
181  .AddTraceSource("MacOutSuperframeStatus",
182  "The period status of the outgoing superframe",
184  "ns3::TracedValueCallback::SuperframeState")
185  .AddTraceSource("MacState",
186  "The state of LrWpan Mac",
188  "ns3::LrWpanMac::StateTracedCallback")
189  .AddTraceSource("MacSentPkt",
190  "Trace source reporting some information about "
191  "the sent packet",
193  "ns3::LrWpanMac::SentTracedCallback")
194  .AddTraceSource("IfsEnd",
195  "Trace source reporting the end of an "
196  "Interframe space (IFS)",
198  "ns3::Packet::TracedCallback");
199  return tid;
200 }
201 
203 {
204  // First set the state to a known value, call ChangeMacState to fire trace source.
206 
208 
211 
212  m_macRxOnWhenIdle = true;
213  m_macPanId = 0xffff;
215  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
218  m_macPromiscuousMode = false;
220  m_retransmission = 0;
221  m_numCsmacaRetry = 0;
222  m_txPkt = nullptr;
223  m_rxPkt = nullptr;
224  m_lastRxFrameLqi = 0;
225  m_ifs = 0;
226 
227  m_macLIFSPeriod = 40;
228  m_macSIFSPeriod = 12;
229 
230  m_panCoor = false;
231  m_coor = false;
232  m_macBeaconOrder = 15;
234  m_macTransactionPersistenceTime = 500; // 0x01F5
235  m_macAssociationPermit = true;
236  m_macAutoRequest = true;
237 
240  m_beaconTrackingOn = false;
241  m_numLostBeacons = 0;
242 
244  m_channelScanIndex = 0;
245  m_maxEnergyLevel = 0;
246 
249 
250  m_maxTxQueueSize = m_txQueue.max_size();
251  m_maxIndTxQueueSize = m_indTxQueue.max_size();
252 
253  Ptr<UniformRandomVariable> uniformVar = CreateObject<UniformRandomVariable>();
254  uniformVar->SetAttribute("Min", DoubleValue(0.0));
255  uniformVar->SetAttribute("Max", DoubleValue(255.0));
256  m_macDsn = SequenceNumber8(uniformVar->GetValue());
257  m_macBsn = SequenceNumber8(uniformVar->GetValue());
258  m_macBeaconPayload = nullptr;
260  m_shortAddress = Mac16Address("FF:FF"); // FF:FF = The address is not assigned.
261 }
262 
264 {
265 }
266 
267 void
269 {
270  if (m_macRxOnWhenIdle)
271  {
272  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
273  }
274  else
275  {
276  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
277  }
278 
280 }
281 
282 void
284 {
285  if (m_csmaCa)
286  {
287  m_csmaCa->Dispose();
288  m_csmaCa = nullptr;
289  }
290  m_txPkt = nullptr;
291 
292  for (uint32_t i = 0; i < m_txQueue.size(); i++)
293  {
294  m_txQueue[i]->txQPkt = nullptr;
295  }
296  m_txQueue.clear();
297 
298  for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
299  {
300  m_indTxQueue[i]->txQPkt = nullptr;
301  }
302  m_indTxQueue.clear();
303 
304  m_phy = nullptr;
305  m_mcpsDataConfirmCallback = MakeNullCallback<void, McpsDataConfirmParams>();
306  m_mcpsDataIndicationCallback = MakeNullCallback<void, McpsDataIndicationParams, Ptr<Packet>>();
307  m_mlmeStartConfirmCallback = MakeNullCallback<void, MlmeStartConfirmParams>();
309  MakeNullCallback<void, MlmeBeaconNotifyIndicationParams>();
310  m_mlmeSyncLossIndicationCallback = MakeNullCallback<void, MlmeSyncLossIndicationParams>();
311  m_mlmePollConfirmCallback = MakeNullCallback<void, MlmePollConfirmParams>();
312  m_mlmeScanConfirmCallback = MakeNullCallback<void, MlmeScanConfirmParams>();
313  m_mlmeAssociateConfirmCallback = MakeNullCallback<void, MlmeAssociateConfirmParams>();
314  m_mlmeAssociateIndicationCallback = MakeNullCallback<void, MlmeAssociateIndicationParams>();
315  m_mlmeCommStatusIndicationCallback = MakeNullCallback<void, MlmeCommStatusIndicationParams>();
316  m_mlmeOrphanIndicationCallback = MakeNullCallback<void, MlmeOrphanIndicationParams>();
317 
318  m_panDescriptorList.clear();
319  m_energyDetectList.clear();
320  m_unscannedChannels.clear();
321 
326 
328 }
329 
330 bool
332 {
333  return m_macRxOnWhenIdle;
334 }
335 
336 void
337 LrWpanMac::SetRxOnWhenIdle(bool rxOnWhenIdle)
338 {
339  NS_LOG_FUNCTION(this << rxOnWhenIdle);
340  m_macRxOnWhenIdle = rxOnWhenIdle;
341 
342  if (m_lrWpanMacState == MAC_IDLE)
343  {
344  if (m_macRxOnWhenIdle)
345  {
346  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
347  }
348  else
349  {
350  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
351  }
352  }
353 }
354 
355 void
357 {
358  NS_LOG_FUNCTION(this << address);
360 }
361 
362 void
364 {
365  NS_LOG_FUNCTION(this << address);
366  m_selfExt = address;
367 }
368 
371 {
372  NS_LOG_FUNCTION(this);
373  return m_shortAddress;
374 }
375 
378 {
379  NS_LOG_FUNCTION(this);
380  return m_selfExt;
381 }
382 
383 void
385 {
386  NS_LOG_FUNCTION(this << p);
387 
388  McpsDataConfirmParams confirmParams;
389  confirmParams.m_msduHandle = params.m_msduHandle;
390 
391  // TODO: We need a drop trace for the case that the packet is too large or the request
392  // parameters are maleformed.
393  // The current tx drop trace is not suitable, because packets dropped using this trace
394  // carry the mac header and footer, while packets being dropped here do not have them.
395 
397  m_macDsn++;
398 
400  {
401  // Note, this is just testing maximum theoretical frame size per the spec
402  // The frame could still be too large once headers are put on
403  // in which case the phy will reject it instead
404  NS_LOG_ERROR(this << " packet too big: " << p->GetSize());
407  {
408  m_mcpsDataConfirmCallback(confirmParams);
409  }
410  return;
411  }
412 
413  if ((params.m_srcAddrMode == NO_PANID_ADDR) && (params.m_dstAddrMode == NO_PANID_ADDR))
414  {
415  NS_LOG_ERROR(this << " Can not send packet with no Address field");
418  {
419  m_mcpsDataConfirmCallback(confirmParams);
420  }
421  return;
422  }
423  switch (params.m_srcAddrMode)
424  {
425  case NO_PANID_ADDR:
426  macHdr.SetSrcAddrMode(params.m_srcAddrMode);
427  macHdr.SetNoPanIdComp();
428  break;
429  case ADDR_MODE_RESERVED:
430  NS_ABORT_MSG("Can not set source address type to ADDR_MODE_RESERVED. Aborting.");
431  break;
432  case SHORT_ADDR:
433  macHdr.SetSrcAddrMode(params.m_srcAddrMode);
435  break;
436  case EXT_ADDR:
437  macHdr.SetSrcAddrMode(params.m_srcAddrMode);
439  break;
440  default:
441  NS_LOG_ERROR(this << " Can not send packet with incorrect Source Address mode = "
442  << params.m_srcAddrMode);
445  {
446  m_mcpsDataConfirmCallback(confirmParams);
447  }
448  return;
449  }
450  switch (params.m_dstAddrMode)
451  {
452  case NO_PANID_ADDR:
453  macHdr.SetDstAddrMode(params.m_dstAddrMode);
454  macHdr.SetNoPanIdComp();
455  break;
456  case ADDR_MODE_RESERVED:
457  NS_ABORT_MSG("Can not set destination address type to ADDR_MODE_RESERVED. Aborting.");
458  break;
459  case SHORT_ADDR:
460  macHdr.SetDstAddrMode(params.m_dstAddrMode);
461  macHdr.SetDstAddrFields(params.m_dstPanId, params.m_dstAddr);
462  break;
463  case EXT_ADDR:
464  macHdr.SetDstAddrMode(params.m_dstAddrMode);
465  macHdr.SetDstAddrFields(params.m_dstPanId, params.m_dstExtAddr);
466  break;
467  default:
468  NS_LOG_ERROR(this << " Can not send packet with incorrect Destination Address mode = "
469  << params.m_dstAddrMode);
472  {
473  m_mcpsDataConfirmCallback(confirmParams);
474  }
475  return;
476  }
477 
478  // IEEE 802.15.4-2006 (7.5.6.1)
479  // Src & Dst PANs are identical, PAN compression is ON
480  // only the dst PAN is serialized making the MAC header 2 bytes smaller
481  if ((params.m_dstAddrMode != NO_PANID_ADDR && params.m_srcAddrMode != NO_PANID_ADDR) &&
482  (macHdr.GetDstPanId() == macHdr.GetSrcPanId()))
483  {
484  macHdr.SetPanIdComp();
485  }
486 
487  macHdr.SetSecDisable();
488  // extract the first 3 bits in TxOptions
489  int b0 = params.m_txOptions & TX_OPTION_ACK;
490  int b1 = params.m_txOptions & TX_OPTION_GTS;
491  int b2 = params.m_txOptions & TX_OPTION_INDIRECT;
492 
493  if (b0 == TX_OPTION_ACK)
494  {
495  // Set AckReq bit only if the destination is not the broadcast address.
496  if (macHdr.GetDstAddrMode() == SHORT_ADDR)
497  {
498  // short address and ACK requested.
499  Mac16Address shortAddr = macHdr.GetShortDstAddr();
500  if (shortAddr.IsBroadcast() || shortAddr.IsMulticast())
501  {
502  NS_LOG_LOGIC("LrWpanMac::McpsDataRequest: requested an ACK on broadcast or "
503  "multicast destination ("
504  << shortAddr << ") - forcefully removing it.");
505  macHdr.SetNoAckReq();
506  params.m_txOptions &= ~uint8_t(TX_OPTION_ACK);
507  }
508  else
509  {
510  macHdr.SetAckReq();
511  }
512  }
513  else
514  {
515  // other address (not short) and ACK requested
516  macHdr.SetAckReq();
517  }
518  }
519  else
520  {
521  macHdr.SetNoAckReq();
522  }
523 
524  if (b1 == TX_OPTION_GTS)
525  {
526  // TODO:GTS Transmission
527  }
528  else if (b2 == TX_OPTION_INDIRECT)
529  {
530  // Indirect Tx
531  // A COORDINATOR will save the packet in the pending queue and await for data
532  // requests from its associated devices. The devices are aware of pending data,
533  // from the pending bit information extracted from the received beacon.
534  // A DEVICE must be tracking beacons (MLME-SYNC.request is running) before attempting
535  // request data from the coordinator.
536 
537  // Indirect Transmission can only be done by PAN coordinator or coordinators.
538  NS_ASSERT(m_coor);
539  p->AddHeader(macHdr);
540 
541  LrWpanMacTrailer macTrailer;
542  // Calculate FCS if the global attribute ChecksumEnabled is set.
543  if (Node::ChecksumEnabled())
544  {
545  macTrailer.EnableFcs(true);
546  macTrailer.SetFcs(p);
547  }
548  p->AddTrailer(macTrailer);
549 
550  NS_LOG_ERROR(this << " Indirect transmissions not currently supported");
551  // Note: The current Pending transaction list should work for indirect transmissions.
552  // However, this is not tested yet. For now, we block the use of indirect transmissions.
553  // TODO: Save packet in the Pending Transaction list.
554  // EnqueueInd (p);
555  }
556  else
557  {
558  // Direct Tx
559  // From this point the packet will be pushed to a Tx queue and immediately
560  // use a slotted (beacon-enabled) or unslotted (nonbeacon-enabled) version of CSMA/CA
561  // before sending the packet, depending on whether it has previously
562  // received a valid beacon or not.
563 
564  p->AddHeader(macHdr);
565 
566  LrWpanMacTrailer macTrailer;
567  // Calculate FCS if the global attribute ChecksumEnabled is set.
568  if (Node::ChecksumEnabled())
569  {
570  macTrailer.EnableFcs(true);
571  macTrailer.SetFcs(p);
572  }
573  p->AddTrailer(macTrailer);
574 
575  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
576  txQElement->txQMsduHandle = params.m_msduHandle;
577  txQElement->txQPkt = p;
578  EnqueueTxQElement(txQElement);
579  CheckQueue();
580  }
581 }
582 
583 void
585 {
586  NS_LOG_FUNCTION(this);
588 
589  MlmeStartConfirmParams confirmParams;
590 
591  if (GetShortAddress() == Mac16Address("ff:ff"))
592  {
593  NS_LOG_ERROR(this << " Invalid MAC short address");
596  {
597  m_mlmeStartConfirmCallback(confirmParams);
598  }
599  return;
600  }
601 
602  if ((params.m_bcnOrd > 15) || (params.m_sfrmOrd > params.m_bcnOrd))
603  {
606  {
607  m_mlmeStartConfirmCallback(confirmParams);
608  }
609  NS_LOG_ERROR(this << "Incorrect superframe order or beacon order.");
610  return;
611  }
612 
613  // Mark primitive as pending and save the start params while the new page and channel is set.
616 
617  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
618  pibAttr->phyCurrentPage = m_startParams.m_logChPage;
619  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, pibAttr);
620 }
621 
622 void
624 {
625  NS_LOG_FUNCTION(this);
626 
627  MlmeScanConfirmParams confirmParams;
628  confirmParams.m_scanType = params.m_scanType;
629  confirmParams.m_chPage = params.m_chPage;
630 
632  {
634  {
636  m_mlmeScanConfirmCallback(confirmParams);
637  }
638  NS_LOG_ERROR(this << " A channel scan is already in progress");
639  return;
640  }
641 
642  if (params.m_scanDuration > 14 || params.m_scanType > MLMESCAN_ORPHAN)
643  {
645  {
647  m_mlmeScanConfirmCallback(confirmParams);
648  }
649  NS_LOG_ERROR(this << "Invalid scan duration or unsupported scan type");
650  return;
651  }
652  // Temporary store macPanId and set macPanId to 0xFFFF to accept all beacons.
654  m_macPanId = 0xFFFF;
655 
656  m_panDescriptorList.clear();
657  m_energyDetectList.clear();
658  m_unscannedChannels.clear();
659 
660  // TODO: stop beacon transmission
661 
662  // Cancel any ongoing CSMA/CA operations and set to unslotted mode for scan
663  m_csmaCa->Cancel();
664  m_capEvent.Cancel();
665  m_cfpEvent.Cancel();
669  m_csmaCa->SetUnSlottedCsmaCa();
670 
671  m_channelScanIndex = 0;
672 
673  // Mark primitive as pending and save the scan params while the new page and/or channel is set.
676 
677  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
678  pibAttr->phyCurrentPage = params.m_chPage;
679  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, pibAttr);
680 }
681 
682 void
684 {
685  NS_LOG_FUNCTION(this);
686 
687  // Association is typically preceded by beacon reception and a MLME-SCAN.request, therefore,
688  // the values of the Associate.request params usually come from the information
689  // obtained from those operations.
692  bool invalidRequest = false;
693 
694  if (params.m_coordPanId == 0xffff)
695  {
696  invalidRequest = true;
697  }
698 
699  if (!invalidRequest && params.m_coordAddrMode == SHORT_ADDR)
700  {
701  if (params.m_coordShortAddr == Mac16Address("ff:ff") ||
702  params.m_coordShortAddr == Mac16Address("ff:fe"))
703  {
704  invalidRequest = true;
705  }
706  }
707  else if (!invalidRequest && params.m_coordAddrMode == EXT_ADDR)
708  {
709  if (params.m_coordExtAddr == Mac64Address("ff:ff:ff:ff:ff:ff:ff:ff") ||
710  params.m_coordExtAddr == Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed"))
711  {
712  invalidRequest = true;
713  }
714  }
715 
716  if (invalidRequest)
717  {
720  NS_LOG_ERROR(this << " Invalid PAN id in Association request");
722  {
723  MlmeAssociateConfirmParams confirmParams;
724  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
726  m_mlmeAssociateConfirmCallback(confirmParams);
727  }
728  }
729  else
730  {
731  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
732  pibAttr->phyCurrentPage = params.m_chPage;
733  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, pibAttr);
734  }
735 }
736 
737 void
739 {
740  // the primitive is no longer pending (channel & page are set)
742  // As described in IEEE 802.15.4-2011 (Section 5.1.3.1)
745  {
747  }
748  else
749  {
752  }
753 
755 }
756 
757 void
759 {
760  // Associate Short Address (m_assocShortAddr)
761  // FF:FF = Association Request failed
762  // FF:FE = The association request is accepted, but the device should use its extended address
763  // Other = The assigned short address by the coordinator
764 
765  NS_LOG_FUNCTION(this);
766 
768  m_macDsn++;
769  LrWpanMacTrailer macTrailer;
770  Ptr<Packet> commandPacket = Create<Packet>();
771 
772  // Mac header Assoc. Response Comm. See 802.15.4-2011 (Section 5.3.2.1)
775  macHdr.SetPanIdComp();
776  macHdr.SetDstAddrFields(m_macPanId, params.m_extDevAddr);
777  macHdr.SetSrcAddrFields(0xffff, GetExtendedAddress());
778 
780  macPayload.SetShortAddr(params.m_assocShortAddr);
781  macPayload.SetAssociationStatus(static_cast<uint8_t>(params.m_status));
782 
783  macHdr.SetSecDisable();
784  macHdr.SetAckReq();
785 
786  commandPacket->AddHeader(macPayload);
787  commandPacket->AddHeader(macHdr);
788 
789  // Calculate FCS if the global attribute ChecksumEnabled is set.
790  if (Node::ChecksumEnabled())
791  {
792  macTrailer.EnableFcs(true);
793  macTrailer.SetFcs(commandPacket);
794  }
795 
796  commandPacket->AddTrailer(macTrailer);
797 
798  // Save packet in the Pending Transaction list.
799  EnqueueInd(commandPacket);
800 }
801 
802 void
804 {
805  NS_LOG_FUNCTION(this);
806  // Mac header Coordinator realigment Command
807  // See 802.15.4-2011 (Section 6.2.7.2)
809  m_macDsn++;
810  LrWpanMacTrailer macTrailer;
811  Ptr<Packet> commandPacket = Create<Packet>();
812  macHdr.SetPanIdComp();
814  macHdr.SetDstAddrFields(0xffff, params.m_orphanAddr);
815 
818  macHdr.SetSrcAddrFields(m_macPanId, Mac16Address("FF:FF"));
819 
820  macHdr.SetFrameVer(0x01);
821  macHdr.SetSecDisable();
822  macHdr.SetAckReq();
823 
825  macPayload.SetPanId(m_macPanId);
826  macPayload.SetCoordShortAddr(GetShortAddress());
827  macPayload.SetChannel(m_phy->GetCurrentChannelNum());
828  macPayload.SetPage(m_phy->GetCurrentPage());
829 
830  if (params.m_assocMember)
831  {
832  // The orphan device was associated with the coordinator
833 
834  // Either FF:FE for extended address mode
835  // or the short address assigned by the coord.
836  macPayload.SetShortAddr(params.m_shortAddr);
837  }
838  else
839  {
840  // The orphan device was NOT associated with the coordinator
841  macPayload.SetShortAddr(Mac16Address("FF:FF"));
842  }
843 
844  commandPacket->AddHeader(macPayload);
845  commandPacket->AddHeader(macHdr);
846 
847  // Calculate FCS if the global attribute ChecksumEnabled is set.
848  if (Node::ChecksumEnabled())
849  {
850  macTrailer.EnableFcs(true);
851  macTrailer.SetFcs(commandPacket);
852  }
853 
854  commandPacket->AddTrailer(macTrailer);
855 
856  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
857  txQElement->txQPkt = commandPacket;
858  EnqueueTxQElement(txQElement);
859  CheckQueue();
860 }
861 
862 void
864 {
865  NS_LOG_FUNCTION(this);
866  NS_ASSERT(params.m_logCh <= 26 && m_macPanId != 0xffff);
867 
868  auto symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
869  // change phy current logical channel
870  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
871  pibAttr->phyCurrentChannel = params.m_logCh;
872  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, pibAttr);
873 
874  // Enable Phy receiver
875  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
876 
877  uint64_t searchSymbols;
878  Time searchBeaconTime;
879 
881  {
883  }
884 
885  if (params.m_trackBcn)
886  {
887  m_numLostBeacons = 0;
888  // search for a beacon for a time = incomingSuperframe symbols + 960 symbols
889  searchSymbols =
891  searchBeaconTime = Seconds((double)searchSymbols / symbolRate);
892  m_beaconTrackingOn = true;
894  Simulator::Schedule(searchBeaconTime, &LrWpanMac::BeaconSearchTimeout, this);
895  }
896  else
897  {
898  m_beaconTrackingOn = false;
899  }
900 }
901 
902 void
904 {
905  NS_LOG_FUNCTION(this);
906 
908  m_macBsn++;
909 
911 
912  Ptr<Packet> beaconPacket = Create<Packet>();
913  // TODO: complete poll request (part of indirect transmissions)
914  NS_FATAL_ERROR(this << " Poll request currently not supported");
915 }
916 
917 void
919 {
920  MlmeSetConfirmParams confirmParams;
921  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
922 
923  switch (id)
924  {
925  case macBeaconPayload:
926  if (attribute->macBeaconPayload->GetSize() > lrwpan::aMaxBeaconPayloadLength)
927  {
929  }
930  else
931  {
932  m_macBeaconPayload = attribute->macBeaconPayload;
933  m_macBeaconPayloadLength = attribute->macBeaconPayload->GetSize();
934  }
935  break;
938  break;
939  case macShortAddress:
940  m_shortAddress = attribute->macShortAddress;
941  break;
942  case macExtendedAddress:
943  confirmParams.m_status = LrWpanMacStatus::READ_ONLY;
944  break;
945  case macPanId:
947  break;
948  default:
949  // TODO: Add support for setting other attributes
951  break;
952  }
953 
955  {
956  confirmParams.id = id;
957  m_mlmeSetConfirmCallback(confirmParams);
958  }
959 }
960 
961 void
963 {
965  Ptr<LrWpanMacPibAttributes> attributes = Create<LrWpanMacPibAttributes>();
966 
967  switch (id)
968  {
969  case macBeaconPayload:
970  attributes->macBeaconPayload = m_macBeaconPayload;
971  break;
973  attributes->macBeaconPayloadLength = m_macBeaconPayloadLength;
974  break;
975  case macShortAddress:
976  attributes->macShortAddress = m_shortAddress;
977  break;
978  case macExtendedAddress:
979  attributes->macExtendedAddress = m_selfExt;
980  break;
981  case macPanId:
982  attributes->macPanId = m_macPanId;
983  break;
984  case pCurrentChannel:
985  attributes->pCurrentChannel = m_phy->GetCurrentChannelNum();
986  break;
987  case pCurrentPage:
988  attributes->pCurrentPage = m_phy->GetCurrentPage();
989  break;
990  default:
992  break;
993  }
994 
996  {
997  m_mlmeGetConfirmCallback(status, id, attributes);
998  }
999 }
1000 
1001 void
1003 {
1004  NS_LOG_FUNCTION(this);
1006 
1008  m_macBsn++;
1009  BeaconPayloadHeader macPayload;
1010  Ptr<Packet> beaconPacket;
1011  LrWpanMacTrailer macTrailer;
1012 
1013  if (m_macBeaconPayload == nullptr)
1014  {
1015  beaconPacket = Create<Packet>();
1016  }
1017  else
1018  {
1019  beaconPacket = m_macBeaconPayload;
1020  }
1021 
1023  macHdr.SetDstAddrFields(GetPanId(), Mac16Address("ff:ff"));
1024 
1025  // see IEEE 802.15.4-2011 Section 5.1.2.4
1026  if (GetShortAddress() == Mac16Address("ff:fe"))
1027  {
1030  }
1031  else
1032  {
1035  }
1036 
1037  macHdr.SetSecDisable();
1038  macHdr.SetNoAckReq();
1039 
1041  macPayload.SetGtsFields(GetGtsFields());
1042  macPayload.SetPndAddrFields(GetPendingAddrFields());
1043 
1044  beaconPacket->AddHeader(macPayload);
1045  beaconPacket->AddHeader(macHdr);
1046 
1047  // Calculate FCS if the global attribute ChecksumEnabled is set.
1048  if (Node::ChecksumEnabled())
1049  {
1050  macTrailer.EnableFcs(true);
1051  macTrailer.SetFcs(beaconPacket);
1052  }
1053 
1054  beaconPacket->AddTrailer(macTrailer);
1055 
1056  // Set the Beacon packet to be transmitted
1057  m_txPkt = beaconPacket;
1058 
1059  if (m_csmaCa->IsSlottedCsmaCa())
1060  {
1062  NS_LOG_DEBUG("Outgoing superframe Active Portion (Beacon + CAP + CFP): "
1063  << m_superframeDuration << " symbols");
1064  }
1065 
1067  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
1068 }
1069 
1070 void
1072 {
1073  NS_LOG_FUNCTION(this);
1074 
1076  m_macDsn++;
1077  LrWpanMacTrailer macTrailer;
1078  Ptr<Packet> commandPacket = Create<Packet>();
1079 
1080  // Beacon Request Command Mac header values See IEEE 802.15.4-2011 (Section 5.3.7)
1081  macHdr.SetNoPanIdComp();
1084 
1085  // Not associated PAN, broadcast dst address
1086  macHdr.SetDstAddrFields(0xFFFF, Mac16Address("FF:FF"));
1087 
1088  macHdr.SetSecDisable();
1089  macHdr.SetNoAckReq();
1090 
1091  CommandPayloadHeader macPayload;
1093 
1094  commandPacket->AddHeader(macPayload);
1095  commandPacket->AddHeader(macHdr);
1096 
1097  // Calculate FCS if the global attribute ChecksumEnabled is set.
1098  if (Node::ChecksumEnabled())
1099  {
1100  macTrailer.EnableFcs(true);
1101  macTrailer.SetFcs(commandPacket);
1102  }
1103 
1104  commandPacket->AddTrailer(macTrailer);
1105 
1106  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1107  txQElement->txQPkt = commandPacket;
1108  EnqueueTxQElement(txQElement);
1109  CheckQueue();
1110 }
1111 
1112 void
1114 {
1116  m_macDsn++;
1117  LrWpanMacTrailer macTrailer;
1118  Ptr<Packet> commandPacket = Create<Packet>();
1119 
1120  // See IEEE 802.15.4-2011 (5.3.6)
1121  macHdr.SetPanIdComp();
1122 
1124  macHdr.SetSrcAddrFields(0xFFFF, GetExtendedAddress());
1125 
1127  macHdr.SetDstAddrFields(0xFFFF, Mac16Address("FF:FF"));
1128 
1129  macHdr.SetSecDisable();
1130  macHdr.SetNoAckReq();
1131 
1132  CommandPayloadHeader macPayload;
1134 
1135  commandPacket->AddHeader(macPayload);
1136  commandPacket->AddHeader(macHdr);
1137 
1138  // Calculate FCS if the global attribute ChecksumEnabled is set.
1139  if (Node::ChecksumEnabled())
1140  {
1141  macTrailer.EnableFcs(true);
1142  macTrailer.SetFcs(commandPacket);
1143  }
1144 
1145  commandPacket->AddTrailer(macTrailer);
1146 
1147  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1148  txQElement->txQPkt = commandPacket;
1149  EnqueueTxQElement(txQElement);
1150  CheckQueue();
1151 }
1152 
1153 void
1155 {
1156  NS_LOG_FUNCTION(this);
1157 
1159  m_macDsn++;
1160  LrWpanMacTrailer macTrailer;
1161  Ptr<Packet> commandPacket = Create<Packet>();
1162 
1163  // Assoc. Req. Comm. Mac header values See IEEE 802.15.4-2011 (Section 5.3.1.1)
1165  macHdr.SetSrcAddrFields(0xffff, GetExtendedAddress());
1166 
1168  {
1171  }
1172  else
1173  {
1176  }
1177 
1178  macHdr.SetSecDisable();
1179  macHdr.SetAckReq();
1180 
1183 
1184  commandPacket->AddHeader(macPayload);
1185  commandPacket->AddHeader(macHdr);
1186 
1187  // Calculate FCS if the global attribute ChecksumEnabled is set.
1188  if (Node::ChecksumEnabled())
1189  {
1190  macTrailer.EnableFcs(true);
1191  macTrailer.SetFcs(commandPacket);
1192  }
1193 
1194  commandPacket->AddTrailer(macTrailer);
1195 
1196  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1197  txQElement->txQPkt = commandPacket;
1198  EnqueueTxQElement(txQElement);
1199  CheckQueue();
1200 }
1201 
1202 void
1204 {
1205  // See IEEE 802.15.4-2011 (Section 5.3.5)
1206  // This command can be sent for 3 different situations:
1207  // a) In response to a beacon indicating that there is data for the device.
1208  // b) Triggered by MLME-POLL.request.
1209  // c) To follow an ACK of an Association Request command and continue the associate process.
1210 
1211  // TODO: Implementation of a) and b) will be done when Indirect transmissions are fully
1212  // supported.
1213  // for now, only case c) is considered.
1214 
1215  NS_LOG_FUNCTION(this);
1216 
1218  m_macDsn++;
1219  LrWpanMacTrailer macTrailer;
1220  Ptr<Packet> commandPacket = Create<Packet>();
1221 
1222  // Mac Header values (Section 5.3.5)
1224  macHdr.SetSrcAddrFields(0xffff, m_selfExt);
1225 
1226  if (m_macCoordShortAddress == Mac16Address("ff:fe"))
1227  {
1230  }
1231  else
1232  {
1235  }
1236 
1237  macHdr.SetSecDisable();
1238  macHdr.SetAckReq();
1239 
1241 
1242  commandPacket->AddHeader(macPayload);
1243  commandPacket->AddHeader(macHdr);
1244 
1245  // Calculate FCS if the global attribute ChecksumEnabled is set.
1246  if (Node::ChecksumEnabled())
1247  {
1248  macTrailer.EnableFcs(true);
1249  macTrailer.SetFcs(commandPacket);
1250  }
1251 
1252  commandPacket->AddTrailer(macTrailer);
1253 
1254  // Set the Command packet to be transmitted
1255  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1256  txQElement->txQPkt = commandPacket;
1257  EnqueueTxQElement(txQElement);
1258  CheckQueue();
1259 }
1260 
1261 void
1263 {
1264  LrWpanMacHeader receivedMacHdr;
1265  rxDataReqPkt->RemoveHeader(receivedMacHdr);
1266  CommandPayloadHeader receivedMacPayload;
1267  rxDataReqPkt->RemoveHeader(receivedMacPayload);
1268 
1270 
1271  Ptr<IndTxQueueElement> indTxQElement = Create<IndTxQueueElement>();
1272  bool elementFound;
1273  elementFound = DequeueInd(receivedMacHdr.GetExtSrcAddr(), indTxQElement);
1274  if (elementFound)
1275  {
1276  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1277  txQElement->txQPkt = indTxQElement->txQPkt;
1278  m_txQueue.emplace_back(txQElement);
1279  }
1280  else
1281  {
1282  NS_LOG_DEBUG("Requested element not found in pending list");
1283  }
1284 }
1285 
1286 void
1288 {
1289  // Association response command was not received, return to default values.
1290  m_macPanId = 0xffff;
1292  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
1293 
1295  {
1296  MlmeAssociateConfirmParams confirmParams;
1297  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
1298  confirmParams.m_status = LrWpanMacStatus::NO_DATA;
1299  m_mlmeAssociateConfirmCallback(confirmParams);
1300  }
1301 }
1302 
1303 void
1305 {
1306  NS_LOG_FUNCTION(this);
1307  // The primitive is no longer pending (Channel & Page have been set)
1309 
1310  if (m_startParams.m_coorRealgn) // Coordinator Realignment
1311  {
1312  // TODO: Send realignment request command frame in CSMA/CA
1313  NS_LOG_ERROR(this << " Coordinator realignment request not supported");
1314  return;
1315  }
1316  else
1317  {
1319  {
1320  m_panCoor = true;
1321  }
1322 
1323  m_coor = true;
1325 
1326  NS_ASSERT(m_startParams.m_PanId != 0xffff);
1327 
1329  if (m_macBeaconOrder == 15)
1330  {
1331  // Non-beacon enabled PAN
1332  // Cancel any ongoing events and CSMA-CA process
1333  m_macSuperframeOrder = 15;
1334  m_fnlCapSlot = 15;
1335  m_beaconInterval = 0;
1336 
1337  m_csmaCa->Cancel();
1338  m_capEvent.Cancel();
1339  m_cfpEvent.Cancel();
1343  m_scanEvent.Cancel();
1346 
1347  m_csmaCa->SetUnSlottedCsmaCa();
1348 
1350  {
1351  MlmeStartConfirmParams confirmParams;
1352  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
1353  m_mlmeStartConfirmCallback(confirmParams);
1354  }
1355 
1356  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
1357  }
1358  else
1359  {
1361  m_csmaCa->SetBatteryLifeExtension(m_startParams.m_battLifeExt);
1362 
1363  m_csmaCa->SetSlottedCsmaCa();
1364 
1365  // TODO: Calculate the real Final CAP slot (requires GTS implementation)
1366  // FinalCapSlot = Superframe duration slots - CFP slots.
1367  // In the current implementation the value of the final cap slot is equal to
1368  // the total number of possible slots in the superframe (15).
1369  m_fnlCapSlot = 15;
1370 
1372  (static_cast<uint32_t>(1 << m_macBeaconOrder)) * lrwpan::aBaseSuperframeDuration;
1373  m_superframeDuration = (static_cast<uint32_t>(1 << m_macSuperframeOrder)) *
1375 
1376  // TODO: change the beacon sending according to the startTime parameter (if not PAN
1377  // coordinator)
1378 
1380  }
1381  }
1382 }
1383 
1384 void
1386 {
1387  NS_LOG_FUNCTION(this);
1388 
1390 
1391  bool channelFound = false;
1392 
1393  for (int i = m_channelScanIndex; i <= 26; i++)
1394  {
1395  if ((m_scanParams.m_scanChannels & (1 << m_channelScanIndex)) != 0)
1396  {
1397  channelFound = true;
1398  break;
1399  }
1401  }
1402 
1403  if (channelFound)
1404  {
1405  // Switch to the next channel in the list and restart scan
1406  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
1407  pibAttr->phyCurrentChannel = m_channelScanIndex;
1408  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, pibAttr);
1409  }
1410  else
1411  {
1412  // All channels in the list scan completed.
1413  // Return variables to the values before the scan and return the status to the next layer.
1415  m_macPanIdScan = 0;
1416 
1417  // TODO: restart beacon transmissions that were active before the beginning of the scan
1418  // (i.e when a coordinator perform a scan and it was already transmitting beacons)
1419  MlmeScanConfirmParams confirmParams;
1420  confirmParams.m_chPage = m_scanParams.m_chPage;
1421  confirmParams.m_scanType = m_scanParams.m_scanType;
1422  confirmParams.m_energyDetList = {};
1423  confirmParams.m_unscannedCh = m_unscannedChannels;
1424  confirmParams.m_resultListSize = m_panDescriptorList.size();
1425 
1426  // See IEEE 802.15.4-2011, Table 31 (panDescriptorList value on macAutoRequest)
1427  // and Section 6.2.10.2
1428  switch (confirmParams.m_scanType)
1429  {
1430  case MLMESCAN_PASSIVE:
1431  if (m_macAutoRequest)
1432  {
1433  confirmParams.m_panDescList = m_panDescriptorList;
1434  }
1435  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
1436  break;
1437  case MLMESCAN_ACTIVE:
1438  if (m_panDescriptorList.empty())
1439  {
1440  confirmParams.m_status = LrWpanMacStatus::NO_BEACON;
1441  }
1442  else
1443  {
1444  if (m_macAutoRequest)
1445  {
1446  confirmParams.m_panDescList = m_panDescriptorList;
1447  }
1448  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
1449  }
1450  break;
1451  case MLMESCAN_ORPHAN:
1452  confirmParams.m_panDescList = {};
1453  confirmParams.m_status = LrWpanMacStatus::NO_BEACON;
1454  confirmParams.m_resultListSize = 0;
1455  // The device lost track of the coordinator and was unable
1456  // to locate it, disassociate from the network.
1457  m_macPanId = 0xffff;
1458  m_shortAddress = Mac16Address("FF:FF");
1460  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
1461  break;
1462  default:
1463  NS_LOG_ERROR(this << " Invalid scan type");
1464  }
1465 
1467  m_channelScanIndex = 0;
1468  m_scanParams = {};
1469 
1471  {
1472  m_mlmeScanConfirmCallback(confirmParams);
1473  }
1474  }
1475 }
1476 
1477 void
1479 {
1480  NS_LOG_FUNCTION(this);
1481  // Add the results of channel energy scan to the detectList
1482  m_energyDetectList.emplace_back(m_maxEnergyLevel);
1483  m_maxEnergyLevel = 0;
1484 
1486 
1487  bool channelFound = false;
1488  for (int i = m_channelScanIndex; i <= 26; i++)
1489  {
1490  if ((m_scanParams.m_scanChannels & (1 << m_channelScanIndex)) != 0)
1491  {
1492  channelFound = true;
1493  break;
1494  }
1496  }
1497 
1498  if (channelFound)
1499  {
1500  // switch to the next channel in the list and restart scan
1501  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
1502  pibAttr->phyCurrentChannel = m_channelScanIndex;
1503  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, pibAttr);
1504  }
1505  else
1506  {
1507  // Scan on all channels on the list completed
1508  // Return to the MAC values previous to start of the first scan.
1510  m_macPanIdScan = 0;
1511 
1512  // TODO: restart beacon transmissions that were active before the beginning of the scan
1513  // (i.e when a coordinator perform a scan and it was already transmitting beacons)
1514 
1515  // All channels scanned, report success
1516  MlmeScanConfirmParams confirmParams;
1517  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
1518  confirmParams.m_chPage = m_phy->GetCurrentPage();
1519  confirmParams.m_scanType = m_scanParams.m_scanType;
1520  confirmParams.m_energyDetList = m_energyDetectList;
1521  confirmParams.m_resultListSize = m_energyDetectList.size();
1522 
1524  m_channelScanIndex = 0;
1525  m_scanParams = {};
1526 
1528  {
1529  m_mlmeScanConfirmCallback(confirmParams);
1530  }
1531  }
1532 }
1533 
1534 void
1536 {
1537  uint32_t activeSlot;
1538  uint64_t capDuration;
1539  Time endCapTime;
1540  uint64_t symbolRate;
1541 
1542  symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1543 
1544  if (superframeType == OUTGOING)
1545  {
1547  activeSlot = m_superframeDuration / 16;
1548  capDuration = activeSlot * (m_fnlCapSlot + 1);
1549  endCapTime = Seconds((double)capDuration / symbolRate);
1550  // Obtain the end of the CAP by adjust the time it took to send the beacon
1551  endCapTime -= (Simulator::Now() - m_macBeaconTxTime);
1552 
1553  NS_LOG_DEBUG("Outgoing superframe CAP duration " << (endCapTime.GetSeconds() * symbolRate)
1554  << " symbols (" << endCapTime.As(Time::S)
1555  << ")");
1556  NS_LOG_DEBUG("Active Slots duration " << activeSlot << " symbols");
1557 
1558  m_capEvent =
1560  }
1561  else
1562  {
1564  activeSlot = m_incomingSuperframeDuration / 16;
1565  capDuration = activeSlot * (m_incomingFnlCapSlot + 1);
1566  endCapTime = Seconds((double)capDuration / symbolRate);
1567  // Obtain the end of the CAP by adjust the time it took to receive the beacon
1568  endCapTime -= (Simulator::Now() - m_macBeaconRxTime);
1569 
1570  NS_LOG_DEBUG("Incoming superframe CAP duration " << (endCapTime.GetSeconds() * symbolRate)
1571  << " symbols (" << endCapTime.As(Time::S)
1572  << ")");
1573  NS_LOG_DEBUG("Active Slots duration " << activeSlot << " symbols");
1574 
1575  m_capEvent =
1577  }
1578 
1579  CheckQueue();
1580 }
1581 
1582 void
1584 {
1585  uint32_t activeSlot;
1586  uint64_t cfpDuration;
1587  Time endCfpTime;
1588  uint64_t symbolRate;
1589 
1590  symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1591 
1592  if (superframeType == INCOMING)
1593  {
1594  activeSlot = m_incomingSuperframeDuration / 16;
1595  cfpDuration = activeSlot * (15 - m_incomingFnlCapSlot);
1596  endCfpTime = Seconds((double)cfpDuration / symbolRate);
1597  if (cfpDuration > 0)
1598  {
1600  }
1601 
1602  NS_LOG_DEBUG("Incoming superframe CFP duration " << cfpDuration << " symbols ("
1603  << endCfpTime.As(Time::S) << ")");
1604 
1605  m_incCfpEvent = Simulator::Schedule(endCfpTime,
1607  this,
1609  }
1610  else
1611  {
1612  activeSlot = m_superframeDuration / 16;
1613  cfpDuration = activeSlot * (15 - m_fnlCapSlot);
1614  endCfpTime = Seconds((double)cfpDuration / symbolRate);
1615 
1616  if (cfpDuration > 0)
1617  {
1619  }
1620 
1621  NS_LOG_DEBUG("Outgoing superframe CFP duration " << cfpDuration << " symbols ("
1622  << endCfpTime.As(Time::S) << ")");
1623 
1624  m_cfpEvent = Simulator::Schedule(endCfpTime,
1626  this,
1628  }
1629  // TODO: Start transmit or receive GTS here.
1630 }
1631 
1632 void
1634 {
1635  uint64_t inactiveDuration;
1636  Time endInactiveTime;
1637  uint64_t symbolRate;
1638 
1639  symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1640 
1641  if (superframeType == INCOMING)
1642  {
1644  endInactiveTime = Seconds((double)inactiveDuration / symbolRate);
1645 
1646  if (inactiveDuration > 0)
1647  {
1649  }
1650 
1651  NS_LOG_DEBUG("Incoming superframe Inactive Portion duration "
1652  << inactiveDuration << " symbols (" << endInactiveTime.As(Time::S) << ")");
1653  m_beaconEvent = Simulator::Schedule(endInactiveTime, &LrWpanMac::AwaitBeacon, this);
1654  }
1655  else
1656  {
1657  inactiveDuration = m_beaconInterval - m_superframeDuration;
1658  endInactiveTime = Seconds((double)inactiveDuration / symbolRate);
1659 
1660  if (inactiveDuration > 0)
1661  {
1663  }
1664 
1665  NS_LOG_DEBUG("Outgoing superframe Inactive Portion duration "
1666  << inactiveDuration << " symbols (" << endInactiveTime.As(Time::S) << ")");
1667  m_beaconEvent = Simulator::Schedule(endInactiveTime, &LrWpanMac::SendOneBeacon, this);
1668  }
1669 }
1670 
1671 void
1673 {
1675 
1676  // TODO: If the device waits more than the expected time to receive the beacon (wait = 46
1677  // symbols for default beacon size)
1678  // it should continue with the start of the incoming CAP even if it did not receive the
1679  // beacon. At the moment, the start of the incoming CAP is only triggered if the beacon is
1680  // received. See MLME-SyncLoss for details.
1681 }
1682 
1683 void
1685 {
1686  auto symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1687 
1689  {
1690  MlmeSyncLossIndicationParams syncLossParams;
1691  // syncLossParams.m_logCh =
1692  syncLossParams.m_lossReason = LrWpanMacStatus::BEACON_LOSS;
1693  syncLossParams.m_panId = m_macPanId;
1694  m_mlmeSyncLossIndicationCallback(syncLossParams);
1695 
1696  m_beaconTrackingOn = false;
1697  m_numLostBeacons = 0;
1698  }
1699  else
1700  {
1701  m_numLostBeacons++;
1702 
1703  // Search for one more beacon
1704  uint64_t searchSymbols;
1705  Time searchBeaconTime;
1706  searchSymbols =
1708  searchBeaconTime = Seconds((double)searchSymbols / symbolRate);
1709  m_trackingEvent =
1710  Simulator::Schedule(searchBeaconTime, &LrWpanMac::BeaconSearchTimeout, this);
1711  }
1712 }
1713 
1714 void
1716 {
1717  NS_LOG_FUNCTION(this);
1718  // Pull a packet from the queue and start sending if we are not already sending.
1719  if (m_lrWpanMacState == MAC_IDLE && !m_txQueue.empty() && !m_setMacState.IsRunning())
1720  {
1721  if (m_csmaCa->IsUnSlottedCsmaCa() || (m_outSuperframeStatus == CAP && m_coor) ||
1723  {
1724  // check MAC is not in a IFS
1725  if (!m_ifsEvent.IsRunning())
1726  {
1727  Ptr<TxQueueElement> txQElement = m_txQueue.front();
1728  m_txPkt = txQElement->txQPkt;
1729 
1730  m_setMacState =
1732  }
1733  }
1734  }
1735 }
1736 
1737 uint16_t
1739 {
1740  SuperframeField sfrmSpec;
1741 
1742  sfrmSpec.SetBeaconOrder(m_macBeaconOrder);
1744  sfrmSpec.SetFinalCapSlot(m_fnlCapSlot);
1745 
1746  if (m_csmaCa->GetBatteryLifeExtension())
1747  {
1748  sfrmSpec.SetBattLifeExt(true);
1749  }
1750 
1751  if (m_panCoor)
1752  {
1753  sfrmSpec.SetPanCoor(true);
1754  }
1755 
1756  // used to associate devices via Beacons
1758  {
1759  sfrmSpec.SetAssocPermit(true);
1760  }
1761 
1762  return sfrmSpec.GetSuperframe();
1763 }
1764 
1765 GtsFields
1767 {
1768  GtsFields gtsFields;
1769 
1770  // TODO: Logic to populate the GTS Fields from local information here
1771 
1772  return gtsFields;
1773 }
1774 
1777 {
1778  PendingAddrFields pndAddrFields;
1779 
1780  // TODO: Logic to populate the Pending Address Fields from local information here
1781  return pndAddrFields;
1782 }
1783 
1784 void
1786 {
1787  m_csmaCa = csmaCa;
1788 }
1789 
1790 void
1792 {
1793  m_phy = phy;
1794 }
1795 
1798 {
1799  return m_phy;
1800 }
1801 
1802 void
1803 LrWpanMac::PdDataIndication(uint32_t psduLength, Ptr<Packet> p, uint8_t lqi)
1804 {
1807  NS_LOG_FUNCTION(this << psduLength << p << (uint16_t)lqi);
1808 
1809  bool acceptFrame;
1810 
1811  // from sec 7.5.6.2 Reception and rejection, Std802.15.4-2006
1812  // level 1 filtering, test FCS field and reject if frame fails
1813  // level 2 filtering if promiscuous mode pass frame to higher layer otherwise perform level 3
1814  // filtering level 3 filtering accept frame if Frame type and version is not reserved, and if
1815  // there is a dstPanId then dstPanId=m_macPanId or broadcastPanId, and if there is a
1816  // shortDstAddr then shortDstAddr =shortMacAddr or broadcastAddr, and if beacon frame then
1817  // srcPanId = m_macPanId if only srcAddr field in Data or Command frame,accept frame if
1818  // srcPanId=m_macPanId
1819 
1820  Ptr<Packet> originalPkt = p->Copy(); // because we will strip headers
1821  auto symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1822  m_promiscSnifferTrace(originalPkt);
1823 
1824  m_macPromiscRxTrace(originalPkt);
1825  // XXX no rejection tracing (to macRxDropTrace) being performed below
1826 
1827  LrWpanMacTrailer receivedMacTrailer;
1828  p->RemoveTrailer(receivedMacTrailer);
1829  if (Node::ChecksumEnabled())
1830  {
1831  receivedMacTrailer.EnableFcs(true);
1832  }
1833 
1834  // level 1 filtering
1835  if (!receivedMacTrailer.CheckFcs(p))
1836  {
1837  m_macRxDropTrace(originalPkt);
1838  }
1839  else
1840  {
1841  LrWpanMacHeader receivedMacHdr;
1842  p->RemoveHeader(receivedMacHdr);
1843 
1845  params.m_dsn = receivedMacHdr.GetSeqNum();
1846  params.m_mpduLinkQuality = lqi;
1847  params.m_srcPanId = receivedMacHdr.GetSrcPanId();
1848  params.m_srcAddrMode = receivedMacHdr.GetSrcAddrMode();
1849  switch (params.m_srcAddrMode)
1850  {
1851  case SHORT_ADDR:
1852  params.m_srcAddr = receivedMacHdr.GetShortSrcAddr();
1853  break;
1854  case EXT_ADDR:
1855  params.m_srcExtAddr = receivedMacHdr.GetExtSrcAddr();
1856  break;
1857  default:
1858  break;
1859  }
1860  params.m_dstPanId = receivedMacHdr.GetDstPanId();
1861  params.m_dstAddrMode = receivedMacHdr.GetDstAddrMode();
1862  switch (params.m_dstAddrMode)
1863  {
1864  case SHORT_ADDR:
1865  params.m_dstAddr = receivedMacHdr.GetShortDstAddr();
1866  break;
1867  case EXT_ADDR:
1868  params.m_dstExtAddr = receivedMacHdr.GetExtDstAddr();
1869  break;
1870  default:
1871  break;
1872  }
1873 
1875  {
1876  // level 2 filtering
1877  if (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR)
1878  {
1879  NS_LOG_DEBUG("Packet from " << params.m_srcAddr);
1880  NS_LOG_DEBUG("Packet to " << params.m_dstAddr);
1881  }
1882  else if (receivedMacHdr.GetDstAddrMode() == EXT_ADDR)
1883  {
1884  NS_LOG_DEBUG("Packet from " << params.m_srcExtAddr);
1885  NS_LOG_DEBUG("Packet to " << params.m_dstExtAddr);
1886  }
1887 
1888  // TODO: Fix here, this should trigger different Indication Callbacks
1889  // depending the type of frame received (data,command, beacon)
1891  {
1892  NS_LOG_DEBUG("promiscuous mode, forwarding up");
1894  }
1895  else
1896  {
1897  NS_LOG_ERROR(this << " Data Indication Callback not initialized");
1898  }
1899  }
1900  else
1901  {
1902  // level 3 frame filtering
1903  acceptFrame = (receivedMacHdr.GetType() != LrWpanMacHeader::LRWPAN_MAC_RESERVED);
1904 
1905  if (acceptFrame)
1906  {
1907  acceptFrame = (receivedMacHdr.GetFrameVer() <= 1);
1908  }
1909 
1910  if (acceptFrame && (receivedMacHdr.GetDstAddrMode() > 1))
1911  {
1912  // Accept frame if one of the following is true:
1913 
1914  // 1) Have the same macPanId
1915  // 2) Is Message to all PANs
1916  // 3) Is a beacon or command frame and the macPanId is not present (bootstrap)
1917  acceptFrame = ((receivedMacHdr.GetDstPanId() == m_macPanId ||
1918  receivedMacHdr.GetDstPanId() == 0xffff) ||
1919  (m_macPanId == 0xffff && receivedMacHdr.IsBeacon())) ||
1920  (m_macPanId == 0xffff && receivedMacHdr.IsCommand());
1921  }
1922 
1923  if (acceptFrame && (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR))
1924  {
1925  if (receivedMacHdr.GetShortDstAddr() == m_shortAddress)
1926  {
1927  // unicast, for me
1928  acceptFrame = true;
1929  }
1930  else if (receivedMacHdr.GetShortDstAddr().IsBroadcast() ||
1931  receivedMacHdr.GetShortDstAddr().IsMulticast())
1932  {
1933  // Broadcast or multicast.
1934  // Discard broadcast/multicast with the ACK bit set.
1935  acceptFrame = !receivedMacHdr.IsAckReq();
1936  }
1937  else
1938  {
1939  acceptFrame = false;
1940  }
1941  }
1942 
1943  if (acceptFrame && (receivedMacHdr.GetDstAddrMode() == EXT_ADDR))
1944  {
1945  acceptFrame = (receivedMacHdr.GetExtDstAddr() == m_selfExt);
1946  }
1947 
1948  if (acceptFrame && m_scanEvent.IsRunning())
1949  {
1950  if (!receivedMacHdr.IsBeacon())
1951  {
1952  acceptFrame = false;
1953  }
1954  }
1955  else if (acceptFrame && m_scanOrphanEvent.IsRunning())
1956  {
1957  if (!receivedMacHdr.IsCommand())
1958  {
1959  acceptFrame = false;
1960  }
1961  }
1962  else if (m_scanEnergyEvent.IsRunning())
1963  {
1964  // Reject any frames if energy scan is running
1965  acceptFrame = false;
1966  }
1967 
1968  // Check device is panCoor with association permit when receiving Association Request
1969  // Commands.
1970  // TODO:: Simple coordinators should also be able to receive it (currently only Pan
1971  // Coordinators are checked)
1972  if (acceptFrame && (receivedMacHdr.IsCommand() && receivedMacHdr.IsAckReq()))
1973  {
1974  CommandPayloadHeader receivedMacPayload;
1975  p->PeekHeader(receivedMacPayload);
1976 
1977  if (receivedMacPayload.GetCommandFrameType() ==
1980  {
1981  acceptFrame = false;
1982  }
1983 
1984  // Although ACKs do not use CSMA to to be transmitted, we need to make sure
1985  // that the transmitted ACK will not collide with the transmission of a beacon
1986  // when beacon-enabled mode is running in the coordinator.
1987  if (acceptFrame && (m_csmaCa->IsSlottedCsmaCa() && m_capEvent.IsRunning()))
1988  {
1989  Time timeLeftInCap = Simulator::GetDelayLeft(m_capEvent);
1990  uint64_t ackSymbols = lrwpan::aTurnaroundTime + m_phy->GetPhySHRDuration() +
1991  ceil(6 * m_phy->GetPhySymbolsPerOctet());
1992  Time ackTime = Seconds((double)ackSymbols / symbolRate);
1993 
1994  if (ackTime >= timeLeftInCap)
1995  {
1996  NS_LOG_DEBUG("Command frame received but not enough time to transmit ACK "
1997  "before the end of CAP ");
1998  acceptFrame = false;
1999  }
2000  }
2001  }
2002 
2003  if (acceptFrame)
2004  {
2005  m_macRxTrace(originalPkt);
2006  // \todo: What should we do if we receive a frame while waiting for an ACK?
2007  // Especially if this frame has the ACK request bit set, should we reply with
2008  // an ACK, possibly missing the pending ACK?
2009 
2010  // If the received frame is a frame with the ACK request bit set, we immediately
2011  // send back an ACK. If we are currently waiting for a pending ACK, we assume the
2012  // ACK was lost and trigger a retransmission after sending the ACK.
2013  if ((receivedMacHdr.IsData() || receivedMacHdr.IsCommand()) &&
2014  receivedMacHdr.IsAckReq() &&
2015  !(receivedMacHdr.GetDstAddrMode() == SHORT_ADDR &&
2016  (receivedMacHdr.GetShortDstAddr().IsBroadcast() ||
2017  receivedMacHdr.GetShortDstAddr().IsMulticast())))
2018  {
2019  // If this is a data or mac command frame, which is not a broadcast or
2020  // multicast, with ack req set, generate and send an ack frame. If there is a
2021  // CSMA medium access in progress we cancel the medium access for sending the
2022  // ACK frame. A new transmission attempt will be started after the ACK was send.
2024  {
2027  }
2028  else if (m_lrWpanMacState == MAC_CSMA)
2029  {
2030  // \todo: If we receive a packet while doing CSMA/CA, should we drop the
2031  // packet because of channel busy,
2032  // or should we restart CSMA/CA for the packet after sending the ACK?
2033  // Currently we simply restart CSMA/CA after sending the ACK.
2034  NS_LOG_DEBUG("Received a packet with ACK required while in CSMA. Cancel "
2035  "current CSMA-CA");
2036  m_csmaCa->Cancel();
2037  }
2038  // Cancel any pending MAC state change, ACKs have higher priority.
2041 
2042  // save received packet and LQI to process the appropriate indication/response
2043  // after sending ACK (PD-DATA.confirm)
2044  m_rxPkt = originalPkt->Copy();
2045  m_lastRxFrameLqi = lqi;
2046 
2047  // LOG Commands with ACK required.
2048  CommandPayloadHeader receivedMacPayload;
2049  p->PeekHeader(receivedMacPayload);
2050  switch (receivedMacPayload.GetCommandFrameType())
2051  {
2053  NS_LOG_DEBUG("Data Request Command Received; processing ACK");
2054  break;
2056  NS_LOG_DEBUG("Association Request Command Received; processing ACK");
2057  break;
2059  m_assocResCmdWaitTimeout.Cancel(); // cancel event to a lost assoc resp cmd.
2060  NS_LOG_DEBUG("Association Response Command Received; processing ACK");
2061  break;
2062  default:
2063  break;
2064  }
2065 
2067  this,
2068  receivedMacHdr.GetSeqNum());
2069  }
2070 
2071  if (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2072  {
2073  NS_LOG_DEBUG("Packet from " << params.m_srcAddr);
2074  NS_LOG_DEBUG("Packet to " << params.m_dstAddr);
2075  }
2076  else if (receivedMacHdr.GetDstAddrMode() == EXT_ADDR)
2077  {
2078  NS_LOG_DEBUG("Packet from " << params.m_srcExtAddr);
2079  NS_LOG_DEBUG("Packet to " << params.m_dstExtAddr);
2080  }
2081 
2082  if (receivedMacHdr.IsBeacon())
2083  {
2084  // The received beacon size in symbols
2085  // Beacon = 5 bytes Sync Header (SHR) + 1 byte PHY header (PHR) + PSDU (default
2086  // 17 bytes)
2087  m_rxBeaconSymbols = m_phy->GetPhySHRDuration() +
2088  1 * m_phy->GetPhySymbolsPerOctet() +
2089  (originalPkt->GetSize() * m_phy->GetPhySymbolsPerOctet());
2090 
2091  // The start of Rx beacon time and start of the Incoming superframe Active
2092  // Period
2094  Simulator::Now() - Seconds(double(m_rxBeaconSymbols) / symbolRate);
2095 
2096  NS_LOG_DEBUG("Beacon Received; forwarding up (m_macBeaconRxTime: "
2097  << m_macBeaconRxTime.As(Time::S) << ")");
2098 
2099  BeaconPayloadHeader receivedMacPayload;
2100  p->RemoveHeader(receivedMacPayload);
2101 
2102  // Fill the PAN descriptor
2103  PanDescriptor panDescriptor;
2104 
2105  if (receivedMacHdr.GetSrcAddrMode() == SHORT_ADDR)
2106  {
2107  panDescriptor.m_coorAddrMode = SHORT_ADDR;
2108  panDescriptor.m_coorShortAddr = receivedMacHdr.GetShortSrcAddr();
2109  }
2110  else
2111  {
2112  panDescriptor.m_coorAddrMode = EXT_ADDR;
2113  panDescriptor.m_coorExtAddr = receivedMacHdr.GetExtSrcAddr();
2114  }
2115 
2116  panDescriptor.m_coorPanId = receivedMacHdr.GetSrcPanId();
2117  panDescriptor.m_gtsPermit = receivedMacPayload.GetGtsFields().GetGtsPermit();
2118  panDescriptor.m_linkQuality = lqi;
2119  panDescriptor.m_logChPage = m_phy->GetCurrentPage();
2120  panDescriptor.m_logCh = m_phy->GetCurrentChannelNum();
2121  panDescriptor.m_superframeSpec = receivedMacPayload.GetSuperframeSpecField();
2122  panDescriptor.m_timeStamp = m_macBeaconRxTime;
2123 
2124  // Process beacon when device belongs to a PAN (associated device)
2125  if (!m_scanEvent.IsRunning() && m_macPanId == receivedMacHdr.GetDstPanId())
2126  {
2127  // We need to make sure to cancel any possible ongoing unslotted CSMA/CA
2128  // operations when receiving a beacon (e.g. Those taking place at the
2129  // beginning of an Association).
2130  m_csmaCa->Cancel();
2131 
2132  SuperframeField incomingSuperframe(
2133  receivedMacPayload.GetSuperframeSpecField());
2134 
2135  m_incomingBeaconOrder = incomingSuperframe.GetBeaconOrder();
2136  m_incomingSuperframeOrder = incomingSuperframe.GetFrameOrder();
2137  m_incomingFnlCapSlot = incomingSuperframe.GetFinalCapSlot();
2138 
2139  if (m_incomingBeaconOrder < 15)
2140  {
2141  // Start Beacon-enabled mode
2142  m_csmaCa->SetSlottedCsmaCa();
2144  (static_cast<uint32_t>(1 << m_incomingBeaconOrder)) *
2148  (static_cast<uint32_t>(1 << m_incomingSuperframeOrder));
2149 
2150  if (incomingSuperframe.IsBattLifeExt())
2151  {
2152  m_csmaCa->SetBatteryLifeExtension(true);
2153  }
2154  else
2155  {
2156  m_csmaCa->SetBatteryLifeExtension(false);
2157  }
2158 
2159  // TODO: get Incoming frame GTS Fields here
2160 
2161  // Begin CAP on the current device using info from
2162  // the Incoming superframe
2163  NS_LOG_DEBUG("Incoming superframe Active Portion "
2164  << "(Beacon + CAP + CFP): " << m_incomingSuperframeDuration
2165  << " symbols");
2166 
2168  this,
2170  }
2171  else
2172  {
2173  // Start non-beacon enabled mode
2174  m_csmaCa->SetUnSlottedCsmaCa();
2175  }
2176 
2177  m_setMacState =
2179  }
2180  else if (!m_scanEvent.IsRunning() && m_macPanId == 0xFFFF)
2181  {
2182  NS_LOG_DEBUG(this << " Device not associated, cannot process beacon");
2183  }
2184 
2185  if (m_macAutoRequest)
2186  {
2187  if (p->GetSize() > 0)
2188  {
2190  {
2191  // The beacon contains payload, send the beacon notification.
2192  MlmeBeaconNotifyIndicationParams beaconParams;
2193  beaconParams.m_bsn = receivedMacHdr.GetSeqNum();
2194  beaconParams.m_panDescriptor = panDescriptor;
2195  beaconParams.m_sduLength = p->GetSize();
2196  beaconParams.m_sdu = p;
2198  }
2199  }
2200 
2201  if (m_scanEvent.IsRunning())
2202  {
2203  // Channel scanning is taking place, save only unique PAN descriptors
2204  bool descriptorExists = false;
2205 
2206  for (const auto& descriptor : m_panDescriptorList)
2207  {
2208  if (descriptor.m_coorAddrMode == SHORT_ADDR)
2209  {
2210  // Found a coordinator in PAN descriptor list with the same
2211  // registered short address
2212  descriptorExists =
2213  (descriptor.m_coorShortAddr ==
2214  panDescriptor.m_coorShortAddr &&
2215  descriptor.m_coorPanId == panDescriptor.m_coorPanId);
2216  }
2217  else
2218  {
2219  // Found a coordinator in PAN descriptor list with the same
2220  // registered extended address
2221  descriptorExists =
2222  (descriptor.m_coorExtAddr == panDescriptor.m_coorExtAddr &&
2223  descriptor.m_coorPanId == panDescriptor.m_coorPanId);
2224  }
2225 
2226  if (descriptorExists)
2227  {
2228  break;
2229  }
2230  }
2231 
2232  if (!descriptorExists)
2233  {
2234  m_panDescriptorList.emplace_back(panDescriptor);
2235  }
2236  return;
2237  }
2238  else if (m_trackingEvent.IsRunning())
2239  {
2240  // check if MLME-SYNC.request was previously issued and running
2241  // Sync. is necessary to handle pending messages (indirect
2242  // transmissions)
2244  m_numLostBeacons = 0;
2245 
2246  if (m_beaconTrackingOn)
2247  {
2248  // if tracking option is on keep tracking the next beacon
2249  uint64_t searchSymbols;
2250  Time searchBeaconTime;
2251 
2252  searchSymbols =
2253  (static_cast<uint64_t>(1 << m_incomingBeaconOrder)) +
2255  searchBeaconTime =
2256  Seconds(static_cast<double>(searchSymbols / symbolRate));
2257  m_trackingEvent =
2258  Simulator::Schedule(searchBeaconTime,
2260  this);
2261  }
2262 
2263  PendingAddrFields pndAddrFields;
2264  pndAddrFields = receivedMacPayload.GetPndAddrFields();
2265 
2266  // TODO: Ignore pending data, and do not send data command request if
2267  // the address is in the GTS list.
2268  // If the address is not in the GTS list, then check if the
2269  // address is in the short address pending list or in the extended
2270  // address pending list and send a data command request.
2271  }
2272  }
2273  else
2274  {
2275  // m_macAutoRequest is FALSE
2276  // Data command request are not send, only the beacon notification.
2277  // see IEEE 802.15.4-2011 Section 6.2.4.1
2279  {
2280  MlmeBeaconNotifyIndicationParams beaconParams;
2281  beaconParams.m_bsn = receivedMacHdr.GetSeqNum();
2282  beaconParams.m_panDescriptor = panDescriptor;
2283  beaconParams.m_sduLength = p->GetSize();
2284  beaconParams.m_sdu = p;
2286  }
2287  }
2288  }
2289  else if (receivedMacHdr.IsCommand())
2290  {
2291  // Handle the reception of frame commands that do not require ACK
2292  // (i.e. Beacon Request, Orphan notification, Coordinator Realigment)
2293  CommandPayloadHeader receivedMacPayload;
2294  p->PeekHeader(receivedMacPayload);
2295 
2296  switch (receivedMacPayload.GetCommandFrameType())
2297  {
2299  if (m_csmaCa->IsUnSlottedCsmaCa() && m_coor)
2300  {
2301  SendOneBeacon();
2302  }
2303  else
2304  {
2305  m_macRxDropTrace(originalPkt);
2306  }
2307  break;
2310  {
2311  if (m_coor)
2312  {
2313  MlmeOrphanIndicationParams orphanParams;
2314  orphanParams.m_orphanAddr = receivedMacHdr.GetExtSrcAddr();
2315  m_mlmeOrphanIndicationCallback(orphanParams);
2316  }
2317  }
2318  break;
2321  {
2322  // Coordinator located, no need to keep scanning other channels
2324 
2325  m_macPanIdScan = 0;
2327  m_channelScanIndex = 0;
2328 
2329  // Update the device information with the received information
2330  // from the Coordinator Realigment command.
2331  m_macPanId = receivedMacPayload.GetPanId();
2332  m_shortAddress = receivedMacPayload.GetShortAddr();
2333  m_macCoordExtendedAddress = receivedMacHdr.GetExtSrcAddr();
2334  m_macCoordShortAddress = receivedMacPayload.GetCoordShortAddr();
2335 
2337  {
2338  MlmeScanConfirmParams confirmParams;
2339  confirmParams.m_scanType = m_scanParams.m_scanType;
2340  confirmParams.m_chPage = m_scanParams.m_chPage;
2341  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
2342  m_mlmeScanConfirmCallback(confirmParams);
2343  }
2344  m_scanParams = {};
2345  }
2346  // TODO: handle Coordinator realignment when not
2347  // used during an orphan scan.
2348  break;
2349  default:
2350  m_macRxDropTrace(originalPkt);
2351  break;
2352  }
2353  }
2354  else if (receivedMacHdr.IsData() && !m_mcpsDataIndicationCallback.IsNull())
2355  {
2356  // If it is a data frame, push it up the stack.
2357  NS_LOG_DEBUG("Data Packet is for me; forwarding up");
2359  }
2360  else if (receivedMacHdr.IsAcknowledgment() && m_txPkt &&
2362  {
2363  LrWpanMacHeader peekedMacHdr;
2364  m_txPkt->PeekHeader(peekedMacHdr);
2365  // If it is an ACK with the expected sequence number, finish the transmission
2366  if (receivedMacHdr.GetSeqNum() == peekedMacHdr.GetSeqNum())
2367  {
2370 
2371  // TODO: check if the IFS is the correct size after ACK.
2372  Time ifsWaitTime = Seconds((double)GetIfsSize() / symbolRate);
2373 
2374  // We received an ACK to a command
2375  if (peekedMacHdr.IsCommand())
2376  {
2377  // check the original sent command frame which belongs to this received
2378  // ACK
2379  Ptr<Packet> pkt = m_txPkt->Copy();
2380  LrWpanMacHeader macHdr;
2381  CommandPayloadHeader cmdPayload;
2382  pkt->RemoveHeader(macHdr);
2383  pkt->RemoveHeader(cmdPayload);
2384 
2385  switch (cmdPayload.GetCommandFrameType())
2386  {
2388  double symbolRate = m_phy->GetDataOrSymbolRate(false);
2389  Time waitTime = Seconds(static_cast<double>(m_macResponseWaitTime) /
2390  symbolRate);
2391  if (!m_beaconTrackingOn)
2392  {
2394  Simulator::Schedule(waitTime,
2396  this);
2397  }
2398  else
2399  {
2400  // TODO: The data must be extracted by the coordinator within
2401  // macResponseWaitTime on timeout, MLME-ASSOCIATE.confirm is set
2402  // with status NO_DATA, and this should trigger the cancellation
2403  // of the beacon tracking (MLME-SYNC.request trackBeacon
2404  // =FALSE)
2405  }
2406  break;
2407  }
2408 
2410  // MLME-comm-status.Indication generated as a result of an
2411  // association response command, therefore src and dst address use
2412  // extended mode (see 5.3.2.1)
2414  {
2415  MlmeCommStatusIndicationParams commStatusParams;
2416  commStatusParams.m_panId = m_macPanId;
2417  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2418  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2419  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2420  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2421  commStatusParams.m_status = LrWpanMacStatus::SUCCESS;
2422  m_mlmeCommStatusIndicationCallback(commStatusParams);
2423  }
2424  // Remove element from Pending Transaction List
2426  break;
2427  }
2428 
2430  // Schedule an event in case the Association Response Command never
2431  // reached this device during an association process.
2432  double symbolRate = m_phy->GetDataOrSymbolRate(false);
2433  Time waitTime = Seconds(
2434  static_cast<double>(m_assocRespCmdWaitTime) / symbolRate);
2436  Simulator::Schedule(waitTime,
2438  this);
2439 
2441  {
2442  MlmePollConfirmParams pollConfirmParams;
2443  pollConfirmParams.m_status = LrWpanMacStatus::SUCCESS;
2444  m_mlmePollConfirmCallback(pollConfirmParams);
2445  }
2446  break;
2447  }
2448 
2450  // ACK of coordinator realigment commands is not specified in the
2451  // standard, in here, we assume they are required as in other
2452  // commands.
2454  {
2455  MlmeCommStatusIndicationParams commStatusParams;
2456  commStatusParams.m_panId = m_macPanId;
2457  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2458  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2459  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2460  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2461  commStatusParams.m_status = LrWpanMacStatus::SUCCESS;
2462  m_mlmeCommStatusIndicationCallback(commStatusParams);
2463  }
2464  }
2465 
2466  default: {
2467  // TODO: add response to other request commands (e.g. Orphan)
2468  break;
2469  }
2470  }
2471  }
2472  else
2473  {
2475  {
2476  Ptr<TxQueueElement> txQElement = m_txQueue.front();
2477  McpsDataConfirmParams confirmParams;
2478  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2479  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
2480  m_mcpsDataConfirmCallback(confirmParams);
2481  }
2482  }
2483 
2484  // Ack was successfully received, wait for the Interframe Space (IFS) and
2485  // then proceed
2488  m_setMacState =
2490  m_ifsEvent = Simulator::Schedule(ifsWaitTime,
2492  this,
2493  ifsWaitTime);
2494  }
2495  else
2496  {
2497  // If it is an ACK with an unexpected sequence number, mark the current
2498  // transmission as failed and start a retransmit. (cf 7.5.6.4.3)
2500  if (!PrepareRetransmission())
2501  {
2504  this,
2505  MAC_IDLE);
2506  }
2507  else
2508  {
2511  this,
2512  MAC_CSMA);
2513  }
2514  }
2515  }
2516  }
2517  else
2518  {
2519  m_macRxDropTrace(originalPkt);
2520  }
2521  }
2522  }
2523 }
2524 
2525 void
2526 LrWpanMac::SendAck(uint8_t seqno)
2527 {
2528  NS_LOG_FUNCTION(this << static_cast<uint32_t>(seqno));
2529 
2531 
2532  // Generate a corresponding ACK Frame.
2534  LrWpanMacTrailer macTrailer;
2535  Ptr<Packet> ackPacket = Create<Packet>(0);
2536  ackPacket->AddHeader(macHdr);
2537  // Calculate FCS if the global attribute ChecksumEnabled is set.
2538  if (Node::ChecksumEnabled())
2539  {
2540  macTrailer.EnableFcs(true);
2541  macTrailer.SetFcs(ackPacket);
2542  }
2543  ackPacket->AddTrailer(macTrailer);
2544 
2545  // Enqueue the ACK packet for further processing
2546  // when the transmitter is activated.
2547  m_txPkt = ackPacket;
2548 
2549  // Switch transceiver to TX mode. Proceed sending the Ack on confirm.
2551  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
2552 }
2553 
2554 void
2556 {
2557  if (m_txQueue.size() < m_maxTxQueueSize)
2558  {
2559  m_txQueue.emplace_back(txQElement);
2560  m_macTxEnqueueTrace(txQElement->txQPkt);
2561  }
2562  else
2563  {
2565  {
2566  McpsDataConfirmParams confirmParams;
2567  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2569  m_mcpsDataConfirmCallback(confirmParams);
2570  }
2571  NS_LOG_DEBUG("TX Queue with size " << m_txQueue.size() << " is full, dropping packet");
2572  m_macTxDropTrace(txQElement->txQPkt);
2573  }
2574 }
2575 
2576 void
2578 {
2579  Ptr<TxQueueElement> txQElement = m_txQueue.front();
2580  Ptr<const Packet> p = txQElement->txQPkt;
2581  m_numCsmacaRetry += m_csmaCa->GetNB() + 1;
2582 
2583  Ptr<Packet> pkt = p->Copy();
2584  LrWpanMacHeader hdr;
2585  pkt->RemoveHeader(hdr);
2586  if (!hdr.GetShortDstAddr().IsBroadcast() && !hdr.GetShortDstAddr().IsMulticast())
2587  {
2589  }
2590 
2591  txQElement->txQPkt = nullptr;
2592  txQElement = nullptr;
2593  m_txQueue.pop_front();
2594  m_txPkt = nullptr;
2595  m_retransmission = 0;
2596  m_numCsmacaRetry = 0;
2598 }
2599 
2600 void
2602 {
2603  NS_LOG_FUNCTION(this);
2604 
2605  // TODO: If we are a PAN coordinator and this was an indirect transmission,
2606  // we will not initiate a retransmission. Instead we wait for the data
2607  // being extracted after a new data request command.
2608  if (!PrepareRetransmission())
2609  {
2611  }
2612  else
2613  {
2615  }
2616 }
2617 
2618 void
2620 {
2621  auto symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false);
2622  Time lifsTime = Seconds((double)m_macLIFSPeriod / symbolRate);
2623  Time sifsTime = Seconds((double)m_macSIFSPeriod / symbolRate);
2624 
2625  if (ifsTime == lifsTime)
2626  {
2627  NS_LOG_DEBUG("LIFS of " << m_macLIFSPeriod << " symbols (" << ifsTime.As(Time::S)
2628  << ") completed ");
2629  }
2630  else if (ifsTime == sifsTime)
2631  {
2632  NS_LOG_DEBUG("SIFS of " << m_macSIFSPeriod << " symbols (" << ifsTime.As(Time::S)
2633  << ") completed ");
2634  }
2635  else
2636  {
2637  NS_LOG_DEBUG("Unknown IFS size (" << ifsTime.As(Time::S) << ") completed ");
2638  }
2639 
2640  m_macIfsEndTrace(ifsTime);
2641  CheckQueue();
2642 }
2643 
2644 bool
2646 {
2647  NS_LOG_FUNCTION(this);
2648 
2649  // Max retransmissions reached without receiving ACK,
2650  // send the proper indication/confirmation
2651  // according to the frame type and call drop trace.
2653  {
2654  LrWpanMacHeader peekedMacHdr;
2655  m_txPkt->PeekHeader(peekedMacHdr);
2656 
2657  if (peekedMacHdr.IsCommand())
2658  {
2660 
2661  Ptr<Packet> pkt = m_txPkt->Copy();
2662  LrWpanMacHeader macHdr;
2663  CommandPayloadHeader cmdPayload;
2664  pkt->RemoveHeader(macHdr);
2665  pkt->RemoveHeader(cmdPayload);
2666 
2667  switch (cmdPayload.GetCommandFrameType())
2668  {
2670  m_macPanId = 0xffff;
2672  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2675  m_csmaCa->SetUnSlottedCsmaCa();
2676  m_incomingBeaconOrder = 15;
2678 
2680  {
2681  MlmeAssociateConfirmParams confirmParams;
2682  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
2683  confirmParams.m_status = LrWpanMacStatus::NO_ACK;
2684  m_mlmeAssociateConfirmCallback(confirmParams);
2685  }
2686  break;
2687  }
2689  // IEEE 802.15.4-2006 (Section 7.1.3.3.3 and 7.1.8.2.3)
2691  {
2692  MlmeCommStatusIndicationParams commStatusParams;
2693  commStatusParams.m_panId = m_macPanId;
2694  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2695  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2696  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2697  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2698  commStatusParams.m_status = LrWpanMacStatus::NO_ACK;
2699  m_mlmeCommStatusIndicationCallback(commStatusParams);
2700  }
2702  break;
2703  }
2705  // IEEE 802.15.4-2006 (Section 7.1.16.1.3)
2706  m_macPanId = 0xffff;
2708  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2711  m_csmaCa->SetUnSlottedCsmaCa();
2712  m_incomingBeaconOrder = 15;
2714 
2716  {
2717  MlmePollConfirmParams pollConfirmParams;
2718  pollConfirmParams.m_status = LrWpanMacStatus::NO_ACK;
2719  m_mlmePollConfirmCallback(pollConfirmParams);
2720  }
2721  break;
2722  }
2723  default: {
2724  // TODO: Specify other indications according to other commands
2725  break;
2726  }
2727  }
2728  }
2729  else
2730  {
2731  // Maximum number of retransmissions has been reached.
2732  // remove the copy of the DATA packet that was just sent
2733  Ptr<TxQueueElement> txQElement = m_txQueue.front();
2734  m_macTxDropTrace(txQElement->txQPkt);
2736  {
2737  McpsDataConfirmParams confirmParams;
2738  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2739  confirmParams.m_status = LrWpanMacStatus::NO_ACK;
2740  m_mcpsDataConfirmCallback(confirmParams);
2741  }
2742  }
2743 
2745  return false;
2746  }
2747  else
2748  {
2749  m_retransmission++;
2750  m_numCsmacaRetry += m_csmaCa->GetNB() + 1;
2751  // Start next CCA process for this packet.
2752  return true;
2753  }
2754 }
2755 
2756 void
2758 {
2759  Ptr<IndTxQueueElement> indTxQElement = Create<IndTxQueueElement>();
2760  LrWpanMacHeader peekedMacHdr;
2761  p->PeekHeader(peekedMacHdr);
2762 
2763  PurgeInd();
2764 
2765  NS_ASSERT(peekedMacHdr.GetDstAddrMode() == SHORT_ADDR ||
2766  peekedMacHdr.GetDstAddrMode() == EXT_ADDR);
2767 
2768  if (peekedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2769  {
2770  indTxQElement->dstShortAddress = peekedMacHdr.GetShortDstAddr();
2771  }
2772  else
2773  {
2774  indTxQElement->dstExtAddress = peekedMacHdr.GetExtDstAddr();
2775  }
2776 
2777  indTxQElement->seqNum = peekedMacHdr.GetSeqNum();
2778 
2779  // See IEEE 802.15.4-2006, Table 86
2780  uint32_t unit = 0; // The persistence time in symbols
2781  if (m_macBeaconOrder == 15)
2782  {
2783  // Non-beacon enabled mode
2785  }
2786  else
2787  {
2788  // Beacon-enabled mode
2789  unit = ((static_cast<uint32_t>(1) << m_macBeaconOrder) * lrwpan::aBaseSuperframeDuration) *
2791  }
2792 
2793  if (m_indTxQueue.size() < m_maxIndTxQueueSize)
2794  {
2795  double symbolRate = m_phy->GetDataOrSymbolRate(false);
2796  Time expireTime = Seconds(unit / symbolRate);
2797  expireTime += Simulator::Now();
2798  indTxQElement->expireTime = expireTime;
2799  indTxQElement->txQPkt = p;
2800  m_indTxQueue.emplace_back(indTxQElement);
2802  }
2803  else
2804  {
2806  {
2807  LrWpanMacHeader peekedMacHdr;
2808  indTxQElement->txQPkt->PeekHeader(peekedMacHdr);
2809  MlmeCommStatusIndicationParams commStatusParams;
2810  commStatusParams.m_panId = m_macPanId;
2811  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2812  commStatusParams.m_srcExtAddr = peekedMacHdr.GetExtSrcAddr();
2813  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2814  commStatusParams.m_dstExtAddr = peekedMacHdr.GetExtDstAddr();
2816  m_mlmeCommStatusIndicationCallback(commStatusParams);
2817  }
2819  }
2820 }
2821 
2822 bool
2824 {
2825  PurgeInd();
2826 
2827  for (auto iter = m_indTxQueue.begin(); iter != m_indTxQueue.end(); iter++)
2828  {
2829  if ((*iter)->dstExtAddress == dst)
2830  {
2831  *entry = **iter;
2832  m_macIndTxDequeueTrace((*iter)->txQPkt->Copy());
2833  m_indTxQueue.erase(iter);
2834  return true;
2835  }
2836  }
2837  return false;
2838 }
2839 
2840 void
2842 {
2843  for (uint32_t i = 0; i < m_indTxQueue.size();)
2844  {
2845  if (Simulator::Now() > m_indTxQueue[i]->expireTime)
2846  {
2847  // Transaction expired, remove and send proper confirmation/indication to a higher layer
2848  LrWpanMacHeader peekedMacHdr;
2849  m_indTxQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2850 
2851  if (peekedMacHdr.IsCommand())
2852  {
2853  // IEEE 802.15.4-2006 (Section 7.1.3.3.3)
2855  {
2856  MlmeCommStatusIndicationParams commStatusParams;
2857  commStatusParams.m_panId = m_macPanId;
2858  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2859  commStatusParams.m_srcExtAddr = peekedMacHdr.GetExtSrcAddr();
2860  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2861  commStatusParams.m_dstExtAddr = peekedMacHdr.GetExtDstAddr();
2863  m_mlmeCommStatusIndicationCallback(commStatusParams);
2864  }
2865  }
2866  else if (peekedMacHdr.IsData())
2867  {
2868  // IEEE 802.15.4-2006 (Section 7.1.1.1.3)
2870  {
2871  McpsDataConfirmParams confParams;
2873  m_mcpsDataConfirmCallback(confParams);
2874  }
2875  }
2876  m_macIndTxDropTrace(m_indTxQueue[i]->txQPkt->Copy());
2877  m_indTxQueue.erase(m_indTxQueue.begin() + i);
2878  }
2879  else
2880  {
2881  i++;
2882  }
2883  }
2884 }
2885 
2886 void
2887 LrWpanMac::PrintPendingTxQueue(std::ostream& os) const
2888 {
2889  LrWpanMacHeader peekedMacHdr;
2890 
2891  os << "Pending Transaction List [" << GetShortAddress() << " | " << GetExtendedAddress()
2892  << "] | CurrentTime: " << Simulator::Now().As(Time::S) << "\n"
2893  << " Destination |"
2894  << " Sequence Number |"
2895  << " Frame type |"
2896  << " Expire time\n";
2897 
2898  for (auto transaction : m_indTxQueue)
2899  {
2900  transaction->txQPkt->PeekHeader(peekedMacHdr);
2901  os << transaction->dstExtAddress << " "
2902  << static_cast<uint32_t>(transaction->seqNum) << " ";
2903 
2904  if (peekedMacHdr.IsCommand())
2905  {
2906  os << " Command Frame ";
2907  }
2908  else if (peekedMacHdr.IsData())
2909  {
2910  os << " Data Frame ";
2911  }
2912  else
2913  {
2914  os << " Unknown Frame ";
2915  }
2916 
2917  os << transaction->expireTime.As(Time::S) << "\n";
2918  }
2919 }
2920 
2921 void
2922 LrWpanMac::PrintTxQueue(std::ostream& os) const
2923 {
2924  LrWpanMacHeader peekedMacHdr;
2925 
2926  os << "\nTx Queue [" << GetShortAddress() << " | " << GetExtendedAddress()
2927  << "] | CurrentTime: " << Simulator::Now().As(Time::S) << "\n"
2928  << " Destination |"
2929  << " Sequence Number |"
2930  << " Dst PAN id |"
2931  << " Frame type |\n";
2932 
2933  for (auto transaction : m_txQueue)
2934  {
2935  transaction->txQPkt->PeekHeader(peekedMacHdr);
2936 
2937  os << "[" << peekedMacHdr.GetShortDstAddr() << "]"
2938  << ", [" << peekedMacHdr.GetExtDstAddr() << "] "
2939  << static_cast<uint32_t>(peekedMacHdr.GetSeqNum()) << " "
2940  << peekedMacHdr.GetDstPanId() << " ";
2941 
2942  if (peekedMacHdr.IsCommand())
2943  {
2944  os << " Command Frame ";
2945  }
2946  else if (peekedMacHdr.IsData())
2947  {
2948  os << " Data Frame ";
2949  }
2950  else
2951  {
2952  os << " Unknown Frame ";
2953  }
2954 
2955  os << "\n";
2956  }
2957  os << "\n";
2958 }
2959 
2960 void
2962 {
2963  LrWpanMacHeader peekedMacHdr;
2964  p->PeekHeader(peekedMacHdr);
2965 
2966  for (auto it = m_indTxQueue.begin(); it != m_indTxQueue.end(); it++)
2967  {
2968  if (peekedMacHdr.GetDstAddrMode() == EXT_ADDR)
2969  {
2970  if (((*it)->dstExtAddress == peekedMacHdr.GetExtDstAddr()) &&
2971  ((*it)->seqNum == peekedMacHdr.GetSeqNum()))
2972  {
2974  m_indTxQueue.erase(it);
2975  break;
2976  }
2977  }
2978  else if (peekedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2979  {
2980  if (((*it)->dstShortAddress == peekedMacHdr.GetShortDstAddr()) &&
2981  ((*it)->seqNum == peekedMacHdr.GetSeqNum()))
2982  {
2984  m_indTxQueue.erase(it);
2985  break;
2986  }
2987  }
2988  }
2989 
2990  p = nullptr;
2991 }
2992 
2993 void
2995 {
2997  NS_LOG_FUNCTION(this << status << m_txQueue.size());
2998 
2999  LrWpanMacHeader macHdr;
3000  Time ifsWaitTime;
3001  double symbolRate;
3002 
3003  symbolRate = m_phy->GetDataOrSymbolRate(false); // symbols per second
3004 
3005  m_txPkt->PeekHeader(macHdr);
3006 
3007  if (status == IEEE_802_15_4_PHY_SUCCESS)
3008  {
3009  if (!macHdr.IsAcknowledgment())
3010  {
3011  if (macHdr.IsBeacon())
3012  {
3013  // Start CAP only if we are in beacon mode (i.e. if slotted csma-ca is running)
3014  if (m_csmaCa->IsSlottedCsmaCa())
3015  {
3016  // The Tx Beacon in symbols
3017  // Beacon = 5 bytes Sync Header (SHR) + 1 byte PHY header (PHR) + PSDU (default
3018  // 17 bytes)
3019  uint64_t beaconSymbols = m_phy->GetPhySHRDuration() +
3020  1 * m_phy->GetPhySymbolsPerOctet() +
3021  (m_txPkt->GetSize() * m_phy->GetPhySymbolsPerOctet());
3022 
3023  // The beacon Tx time and start of the Outgoing superframe Active Period
3025  Simulator::Now() - Seconds(static_cast<double>(beaconSymbols) / symbolRate);
3026 
3028  this,
3030  NS_LOG_DEBUG("Beacon Sent (m_macBeaconTxTime: " << m_macBeaconTxTime.As(Time::S)
3031  << ")");
3032 
3034  {
3035  MlmeStartConfirmParams mlmeConfirmParams;
3036  mlmeConfirmParams.m_status = LrWpanMacStatus::SUCCESS;
3037  m_mlmeStartConfirmCallback(mlmeConfirmParams);
3038  }
3039  }
3040 
3041  ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
3042  m_txPkt = nullptr;
3043  }
3044  else if (macHdr.IsAckReq()) // We have sent a regular data packet, check if we have to
3045  // wait for an ACK.
3046  {
3047  // we sent a regular data frame or command frame (e.g. AssocReq command) that
3048  // require ACK wait for the ack or the next retransmission timeout start
3049  // retransmission timer
3050  Time waitTime = Seconds(static_cast<double>(GetMacAckWaitDuration()) / symbolRate);
3054  m_setMacState =
3056  return;
3057  }
3058  else if (macHdr.IsCommand())
3059  {
3060  // We handle commands that do not require ACK
3061  // (e.g. Coordinator realigment command in an orphan response)
3062  // Other command with ACK required are handle by the previous if statement.
3063 
3064  // Check the transmitted packet command type and issue the appropriate indication.
3065  Ptr<Packet> txOriginalPkt = m_txPkt->Copy();
3066  LrWpanMacHeader txMacHdr;
3067  txOriginalPkt->RemoveHeader(txMacHdr);
3068  CommandPayloadHeader txMacPayload;
3069  txOriginalPkt->RemoveHeader(txMacPayload);
3070 
3072  {
3074  {
3075  MlmeCommStatusIndicationParams commStatusParams;
3076  commStatusParams.m_panId = m_macPanId;
3077 
3078  commStatusParams.m_srcAddrMode = macHdr.GetSrcAddrMode();
3079  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
3080  commStatusParams.m_srcShortAddr = macHdr.GetShortSrcAddr();
3081 
3082  commStatusParams.m_dstAddrMode = macHdr.GetDstAddrMode();
3083  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
3084  commStatusParams.m_dstShortAddr = macHdr.GetShortDstAddr();
3085 
3086  commStatusParams.m_status = LrWpanMacStatus::SUCCESS;
3087  m_mlmeCommStatusIndicationCallback(commStatusParams);
3088  }
3089  }
3090 
3091  ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
3093  }
3094  else
3095  {
3097  // remove the copy of the packet that was just sent
3099  {
3100  McpsDataConfirmParams confirmParams;
3101  NS_ASSERT_MSG(!m_txQueue.empty(), "TxQsize = 0");
3102  Ptr<TxQueueElement> txQElement = m_txQueue.front();
3103  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
3104  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
3105  m_mcpsDataConfirmCallback(confirmParams);
3106  }
3107  ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
3109  }
3110  }
3111  else
3112  {
3113  // The packet sent was a successful ACK
3114 
3115  // Check the received frame before the transmission of the ACK,
3116  // and send the appropriate Indication or Confirmation
3117  Ptr<Packet> recvOriginalPkt = m_rxPkt->Copy();
3118  LrWpanMacHeader receivedMacHdr;
3119  recvOriginalPkt->RemoveHeader(receivedMacHdr);
3120 
3121  if (receivedMacHdr.IsCommand())
3122  {
3123  CommandPayloadHeader receivedMacPayload;
3124  recvOriginalPkt->RemoveHeader(receivedMacPayload);
3125 
3126  if (receivedMacPayload.GetCommandFrameType() ==
3128  {
3130  {
3131  // NOTE: The LQI parameter is not part of the standard but found
3132  // in some implementations as is required for higher layers (See Zboss
3133  // implementation).
3134  MlmeAssociateIndicationParams associateParams;
3135  associateParams.capabilityInfo = receivedMacPayload.GetCapabilityField();
3136  associateParams.m_extDevAddr = receivedMacHdr.GetExtSrcAddr();
3137  associateParams.lqi = m_lastRxFrameLqi;
3138  m_mlmeAssociateIndicationCallback(associateParams);
3139  }
3140 
3141  // Clear the packet buffer for the packet request received.
3142  m_rxPkt = nullptr;
3143  }
3144  else if (receivedMacPayload.GetCommandFrameType() ==
3146  {
3147  MlmeAssociateConfirmParams confirmParams;
3148 
3149  switch (static_cast<LrWpanMacStatus>(receivedMacPayload.GetAssociationStatus()))
3150  {
3152  // The assigned short address by the coordinator
3153  SetShortAddress(receivedMacPayload.GetShortAddr());
3154  m_macPanId = receivedMacHdr.GetSrcPanId();
3155 
3156  confirmParams.m_status = LrWpanMacStatus::SUCCESS;
3157  confirmParams.m_assocShortAddr = GetShortAddress();
3158  break;
3160  confirmParams.m_status = LrWpanMacStatus::FULL_CAPACITY;
3161  m_macPanId = 0xffff;
3163  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3166  m_csmaCa->SetUnSlottedCsmaCa();
3167  m_incomingBeaconOrder = 15;
3169  break;
3171  default:
3172  confirmParams.m_status = LrWpanMacStatus::ACCESS_DENIED;
3173  m_macPanId = 0xffff;
3175  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3178  m_csmaCa->SetUnSlottedCsmaCa();
3179  m_incomingBeaconOrder = 15;
3181  break;
3182  }
3183 
3185  {
3186  m_mlmeAssociateConfirmCallback(confirmParams);
3187  }
3188  }
3189  else if (receivedMacPayload.GetCommandFrameType() == CommandPayloadHeader::DATA_REQ)
3190  {
3191  // We enqueue the the Assoc Response command frame in the Tx queue
3192  // and the packet is transmitted as soon as the PHY is free and the IFS have
3193  // taken place.
3195  }
3196  }
3197 
3198  // Clear the packet buffer for the ACK packet sent.
3199  m_txPkt = nullptr;
3200  }
3201  }
3202  else if (status == IEEE_802_15_4_PHY_UNSPECIFIED)
3203  {
3204  if (!macHdr.IsAcknowledgment())
3205  {
3206  NS_ASSERT_MSG(!m_txQueue.empty(), "TxQsize = 0");
3207  Ptr<TxQueueElement> txQElement = m_txQueue.front();
3208  m_macTxDropTrace(txQElement->txQPkt);
3210  {
3211  McpsDataConfirmParams confirmParams;
3212  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
3213  confirmParams.m_status = LrWpanMacStatus::FRAME_TOO_LONG;
3214  m_mcpsDataConfirmCallback(confirmParams);
3215  }
3217  }
3218  else
3219  {
3220  NS_LOG_ERROR("Unable to send ACK");
3221  }
3222  }
3223  else
3224  {
3225  // Something went really wrong. The PHY is not in the correct state for
3226  // data transmission.
3227  NS_FATAL_ERROR("Transmission attempt failed with PHY status " << status);
3228  }
3229 
3230  if (!ifsWaitTime.IsZero())
3231  {
3232  m_ifsEvent =
3233  Simulator::Schedule(ifsWaitTime, &LrWpanMac::IfsWaitTimeout, this, ifsWaitTime);
3234  }
3235 
3238 }
3239 
3240 void
3242 {
3243  NS_LOG_FUNCTION(this << status);
3244  // Direct this call through the csmaCa object
3245  m_csmaCa->PlmeCcaConfirm(status);
3246 }
3247 
3248 void
3250 {
3251  NS_LOG_FUNCTION(this << status << energyLevel);
3252 
3253  if (energyLevel > m_maxEnergyLevel)
3254  {
3255  m_maxEnergyLevel = energyLevel;
3256  }
3257 
3259  Seconds(8.0 / m_phy->GetDataOrSymbolRate(false)))
3260  {
3261  m_phy->PlmeEdRequest();
3262  }
3263 }
3264 
3265 void
3268  Ptr<LrWpanPhyPibAttributes> attribute)
3269 {
3270  NS_LOG_FUNCTION(this << status << id << attribute);
3271 }
3272 
3273 void
3275 {
3276  NS_LOG_FUNCTION(this << status);
3277 
3278  if (m_lrWpanMacState == MAC_SENDING &&
3279  (status == IEEE_802_15_4_PHY_TX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
3280  {
3281  NS_ASSERT(m_txPkt);
3282 
3283  // Start sending if we are in state SENDING and the PHY transmitter was enabled.
3287  m_phy->PdDataRequest(m_txPkt->GetSize(), m_txPkt);
3288  }
3289  else if (m_lrWpanMacState == MAC_CSMA &&
3290  (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
3291  {
3292  // Start the CSMA algorithm as soon as the receiver is enabled.
3293  m_csmaCa->Start();
3294  }
3295  else if (m_lrWpanMacState == MAC_IDLE)
3296  {
3298  status == IEEE_802_15_4_PHY_TRX_OFF);
3299 
3301  {
3302  // Kick start Energy Detection Scan
3303  m_phy->PlmeEdRequest();
3304  }
3305  else if (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS)
3306  {
3307  // Check if there is not messages to transmit when going idle
3308  CheckQueue();
3309  }
3310  }
3311  else if (m_lrWpanMacState == MAC_ACK_PENDING)
3312  {
3314  }
3315  else
3316  {
3317  // TODO: What to do when we receive an error?
3318  // If we want to transmit a packet, but switching the transceiver on results
3319  // in an error, we have to recover somehow (and start sending again).
3320  NS_FATAL_ERROR("Error changing transceiver state");
3321  }
3322 }
3323 
3324 void
3326 {
3327  NS_LOG_FUNCTION(this << status << id);
3329  {
3331  {
3332  // get the first channel to scan from scan channel list
3333  bool channelFound = false;
3334  for (int i = m_channelScanIndex; i <= 26; i++)
3335  {
3336  if ((m_scanParams.m_scanChannels & (1 << m_channelScanIndex)) != 0)
3337  {
3338  channelFound = true;
3339  break;
3340  }
3342  }
3343 
3344  if (channelFound)
3345  {
3346  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
3347  pibAttr->phyCurrentChannel = m_channelScanIndex;
3348  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel,
3349  pibAttr);
3350  }
3351  }
3352  else
3353  {
3355  {
3356  MlmeScanConfirmParams confirmParams;
3357  confirmParams.m_scanType = m_scanParams.m_scanType;
3358  confirmParams.m_chPage = m_scanParams.m_chPage;
3360  m_mlmeScanConfirmCallback(confirmParams);
3361  }
3362  NS_LOG_ERROR(this << "Channel Scan: Invalid channel page");
3363  }
3364  }
3367  {
3369  {
3370  auto symbolRate = static_cast<uint64_t>(m_phy->GetDataOrSymbolRate(false));
3371  Time nextScanTime;
3372 
3374  {
3375  nextScanTime = Seconds(static_cast<double>(m_macResponseWaitTime) / symbolRate);
3376  }
3377  else
3378  {
3379  uint64_t scanDurationSym =
3381 
3382  nextScanTime = Seconds(static_cast<double>(scanDurationSym) / symbolRate);
3383  }
3384 
3385  switch (m_scanParams.m_scanType)
3386  {
3387  case MLMESCAN_ED:
3388  m_maxEnergyLevel = 0;
3391  // set phy to RX_ON and kick start the first PLME-ED.request
3392  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3393  break;
3394  case MLMESCAN_ACTIVE:
3397  break;
3398  case MLMESCAN_PASSIVE:
3400  // turn back the phy to RX_ON after setting Page/channel
3401  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3402  break;
3403  case MLMESCAN_ORPHAN:
3405  Simulator::Schedule(nextScanTime, &LrWpanMac::EndChannelScan, this);
3407  break;
3408 
3409  default:
3410  MlmeScanConfirmParams confirmParams;
3411  confirmParams.m_scanType = m_scanParams.m_scanType;
3412  confirmParams.m_chPage = m_scanParams.m_chPage;
3415  {
3416  m_mlmeScanConfirmCallback(confirmParams);
3417  }
3418  NS_LOG_ERROR("Scan Type currently not supported");
3419  return;
3420  }
3421  }
3422  else
3423  {
3425  {
3426  MlmeScanConfirmParams confirmParams;
3427  confirmParams.m_scanType = m_scanParams.m_scanType;
3428  confirmParams.m_chPage = m_scanParams.m_chPage;
3430  m_mlmeScanConfirmCallback(confirmParams);
3431  }
3432  NS_LOG_ERROR("Channel " << m_channelScanIndex
3433  << " could not be set in the current page");
3434  }
3435  }
3438  {
3440  {
3441  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
3442  pibAttr->phyCurrentChannel = m_startParams.m_logCh;
3443  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel,
3444  pibAttr);
3445  }
3446  else
3447  {
3449  {
3450  MlmeStartConfirmParams confirmParams;
3452  m_mlmeStartConfirmCallback(confirmParams);
3453  }
3454  NS_LOG_ERROR("Invalid page parameter in MLME-start");
3455  }
3456  }
3459  {
3461  {
3462  EndStartRequest();
3463  }
3464  else
3465  {
3467  {
3468  MlmeStartConfirmParams confirmParams;
3470  m_mlmeStartConfirmCallback(confirmParams);
3471  }
3472  NS_LOG_ERROR("Invalid channel parameter in MLME-start");
3473  }
3474  }
3477  {
3479  {
3480  Ptr<LrWpanPhyPibAttributes> pibAttr = Create<LrWpanPhyPibAttributes>();
3481  pibAttr->phyCurrentChannel = m_associateParams.m_chNum;
3482  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel,
3483  pibAttr);
3484  }
3485  else
3486  {
3487  m_macPanId = 0xffff;
3489  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3492  m_csmaCa->SetUnSlottedCsmaCa();
3493  m_incomingBeaconOrder = 15;
3495 
3497  {
3498  MlmeAssociateConfirmParams confirmParams;
3499  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3501  m_mlmeAssociateConfirmCallback(confirmParams);
3502  }
3503  NS_LOG_ERROR("Invalid page parameter in MLME-associate");
3504  }
3505  }
3508  {
3510  {
3512  }
3513  else
3514  {
3515  m_macPanId = 0xffff;
3517  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3520  m_csmaCa->SetUnSlottedCsmaCa();
3521  m_incomingBeaconOrder = 15;
3523 
3525  {
3526  MlmeAssociateConfirmParams confirmParams;
3527  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3529  m_mlmeAssociateConfirmCallback(confirmParams);
3530  }
3531  NS_LOG_ERROR("Invalid channel parameter in MLME-associate");
3532  }
3533  }
3534 }
3535 
3536 void
3538 {
3539  NS_LOG_FUNCTION(this << "mac state = " << macState);
3540 
3541  if (macState == MAC_IDLE)
3542  {
3544  if (m_macRxOnWhenIdle)
3545  {
3546  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3547  }
3548  else
3549  {
3550  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
3551  }
3552  }
3553  else if (macState == MAC_ACK_PENDING)
3554  {
3556  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3557  }
3558  else if (macState == MAC_CSMA)
3559  {
3562  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3563  }
3564  else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_IDLE)
3565  {
3566  // Channel is idle, set transmitter to TX_ON
3568  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
3569  }
3570  else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_ACCESS_FAILURE)
3571  {
3572  NS_ASSERT(m_txPkt);
3573 
3574  // Cannot find a clear channel, drop the current packet
3575  // and send the proper confirm/indication according to the packet type
3576  NS_LOG_DEBUG(this << " cannot find clear channel");
3577 
3579 
3580  Ptr<Packet> pkt = m_txPkt->Copy();
3581  LrWpanMacHeader macHdr;
3582  pkt->RemoveHeader(macHdr);
3583 
3584  if (macHdr.IsCommand())
3585  {
3586  CommandPayloadHeader cmdPayload;
3587  pkt->RemoveHeader(cmdPayload);
3588 
3589  switch (cmdPayload.GetCommandFrameType())
3590  {
3592  m_macPanId = 0xffff;
3594  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3597  m_csmaCa->SetUnSlottedCsmaCa();
3598  m_incomingBeaconOrder = 15;
3600 
3602  {
3603  MlmeAssociateConfirmParams confirmParams;
3604  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3606  m_mlmeAssociateConfirmCallback(confirmParams);
3607  }
3608  break;
3609  }
3612  {
3613  MlmeCommStatusIndicationParams commStatusParams;
3614  commStatusParams.m_panId = m_macPanId;
3615  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
3616  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
3617  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
3618  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
3620  m_mlmeCommStatusIndicationCallback(commStatusParams);
3621  }
3623  break;
3624  }
3626  m_macPanId = 0xffff;
3628  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3631  m_csmaCa->SetUnSlottedCsmaCa();
3632  m_incomingBeaconOrder = 15;
3634 
3636  {
3637  MlmePollConfirmParams pollConfirmParams;
3639  m_mlmePollConfirmCallback(pollConfirmParams);
3640  }
3641  break;
3642  }
3645  {
3646  MlmeCommStatusIndicationParams commStatusParams;
3647  commStatusParams.m_panId = m_macPanId;
3648  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
3649  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
3650  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
3651  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
3653  m_mlmeCommStatusIndicationCallback(commStatusParams);
3654  }
3655  break;
3656  }
3659  {
3660  m_unscannedChannels.emplace_back(m_phy->GetCurrentChannelNum());
3661  }
3662  // TODO: Handle orphan notification command during a
3663  // channel access failure when not is not scanning.
3664  break;
3665  }
3667  if (m_scanEvent.IsRunning())
3668  {
3669  m_unscannedChannels.emplace_back(m_phy->GetCurrentChannelNum());
3670  }
3671  // TODO: Handle beacon request command during a
3672  // channel access failure when not scanning.
3673  break;
3674  }
3675  default: {
3676  // TODO: Other commands(e.g. Disassociation notification, etc)
3677  break;
3678  }
3679  }
3681  }
3682  else if (macHdr.IsData())
3683  {
3685  {
3686  McpsDataConfirmParams confirmParams;
3687  confirmParams.m_msduHandle = m_txQueue.front()->txQMsduHandle;
3689  m_mcpsDataConfirmCallback(confirmParams);
3690  }
3691  // remove the copy of the packet that was just sent
3693  }
3694  else
3695  {
3696  // TODO:: specify behavior for other packets
3697  m_txPkt = nullptr;
3698  m_retransmission = 0;
3699  m_numCsmacaRetry = 0;
3700  }
3701 
3703  if (m_macRxOnWhenIdle)
3704  {
3705  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3706  }
3707  else
3708  {
3709  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
3710  }
3711  }
3712  else if (m_lrWpanMacState == MAC_CSMA && macState == MAC_CSMA_DEFERRED)
3713  {
3715  m_txPkt = nullptr;
3716  // The MAC is running on beacon mode and the current packet could not be sent in the
3717  // current CAP. The packet will be send on the next CAP after receiving the beacon.
3718  // The PHY state does not change from its current form. The PHY change (RX_ON) will be
3719  // triggered by the scheduled beacon event.
3720 
3721  NS_LOG_DEBUG("****** PACKET DEFERRED to the next superframe *****");
3722  }
3723 }
3724 
3725 void
3727 {
3729 }
3730 
3731 void
3733 {
3735 }
3736 
3737 uint16_t
3739 {
3740  return m_macPanId;
3741 }
3742 
3745 {
3746  return m_macCoordShortAddress;
3747 }
3748 
3751 {
3753 }
3754 
3755 void
3756 LrWpanMac::SetPanId(uint16_t panId)
3757 {
3758  m_macPanId = panId;
3759 }
3760 
3761 void
3763 {
3764  NS_LOG_LOGIC(this << " change lrwpan mac state from " << m_lrWpanMacState << " to "
3765  << newState);
3767  m_lrWpanMacState = newState;
3768 }
3769 
3770 uint64_t
3772 {
3773  return lrwpan::aUnitBackoffPeriod + lrwpan::aTurnaroundTime + m_phy->GetPhySHRDuration() +
3774  ceil(6 * m_phy->GetPhySymbolsPerOctet());
3775 }
3776 
3777 uint8_t
3779 {
3780  return m_macMaxFrameRetries;
3781 }
3782 
3783 void
3785 {
3786  NS_LOG_DEBUG("Transmit Queue Size: " << m_txQueue.size());
3787 }
3788 
3789 void
3791 {
3792  m_macMaxFrameRetries = retries;
3793 }
3794 
3795 bool
3797 {
3798  NS_ASSERT(m_txPkt);
3799  LrWpanMacHeader macHdr;
3800  m_txPkt->PeekHeader(macHdr);
3801 
3802  if (m_coor)
3803  {
3804  // The device is its coordinator and the packet is not to itself
3805  return false;
3806  }
3807  else if (m_macCoordShortAddress == macHdr.GetShortDstAddr() ||
3809  {
3810  return true;
3811  }
3812  else
3813  {
3814  NS_LOG_DEBUG("ERROR: Packet not for the coordinator!");
3815  return false;
3816  }
3817 }
3818 
3819 uint32_t
3821 {
3822  NS_ASSERT(m_txPkt);
3823 
3825  {
3826  return m_macSIFSPeriod;
3827  }
3828  else
3829  {
3830  return m_macLIFSPeriod;
3831  }
3832 }
3833 
3834 void
3836 {
3838 }
3839 
3840 void
3842 {
3844 }
3845 
3846 uint64_t
3848 {
3849  NS_ASSERT(m_txPkt);
3850  // Sync Header (SHR) + 8 bits PHY header (PHR) + PSDU
3851  return (m_phy->GetPhySHRDuration() + 1 * m_phy->GetPhySymbolsPerOctet() +
3852  (m_txPkt->GetSize() * m_phy->GetPhySymbolsPerOctet()));
3853 }
3854 
3855 bool
3857 {
3858  NS_ASSERT(m_txPkt);
3859  LrWpanMacHeader macHdr;
3860  m_txPkt->PeekHeader(macHdr);
3861 
3862  return macHdr.IsAckReq();
3863 }
3864 
3865 } // 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.
uint16_t GetSuperframeSpecField() const
Get the superframe specification field from the beacon payload header.
void SetSuperframeSpecField(uint16_t 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.
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:569
Implements the header for the MAC payload command frame according to the IEEE 802....
void SetPage(uint8_t page)
Set the logical channel page number.
void SetPanId(uint16_t id)
Get the PAN identifier.
Mac16Address GetShortAddr() const
Get the Short address assigned by the coordinator (Association Response and Coordinator Realigment co...
MacCommand GetCommandFrameType() const
Get the command frame type ID.
@ ASSOCIATION_RESP
Association response (RFD true: Rx)
@ BEACON_REQ
Beacon Request (RFD true: none )
@ DATA_REQ
Data Request (RFD true: Tx)
@ ORPHAN_NOTIF
Orphan Notification (RFD true: Tx)
@ ASSOCIATION_REQ
Association request (RFD true: Tx)
@ COOR_REALIGN
Coordinator Realignment (RFD true: Rx)
Mac16Address GetCoordShortAddr() const
Get the coordinator short address.
uint16_t GetPanId() const
Get the PAN identifier.
void SetCommandFrameType(MacCommand macCmd)
Set the command frame type.
void SetCoordShortAddr(Mac16Address addr)
Set the coordinator short address (16 bit address).
uint8_t GetCapabilityField() const
Get the Capability Information Field from the command payload header.
void SetAssociationStatus(uint8_t status)
Set status resulting from the association attempt (Association Response Command).
void SetCapabilityField(uint8_t cap)
Set the Capability Information Field to the command payload header (Association Request Command).
uint8_t GetAssociationStatus() const
Get the status resulting from an association request (Association Response Command).
void SetShortAddr(Mac16Address shortAddr)
Set the Short Address Assigned by the coordinator (Association Response and Coordinator Realigment Co...
void SetChannel(uint8_t channel)
Set the logical channel number.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
Represent the GTS information fields.
bool GetGtsPermit() const
Get the GTS Specification Permit.
Lr-wpan MAC layer abstraction.
MlmeOrphanIndicationCallback m_mlmeOrphanIndicationCallback
This callback is used to indicate the reception of a orphan notification command.
MlmeStartConfirmCallback m_mlmeStartConfirmCallback
This callback is used to report the start of a new PAN or the begin of a new superframe configuration...
MlmeCommStatusIndicationCallback m_mlmeCommStatusIndicationCallback
This callback is instigated through a response primitive.
McpsDataIndicationCallback m_mcpsDataIndicationCallback
This callback is used to notify incoming packets to the upper layers.
MlmeGetConfirmCallback m_mlmeGetConfirmCallback
This callback is used to report the result of an attribute read request to the upper layers.
MlmeBeaconNotifyIndicationCallback m_mlmeBeaconNotifyIndicationCallback
This callback is used to notify incoming beacon packets to the upper layers.
MlmeAssociateConfirmCallback m_mlmeAssociateConfirmCallback
This callback is used to report the status after a device request an association with a coordinator.
MlmeAssociateIndicationCallback m_mlmeAssociateIndicationCallback
This callback is used to indicate the reception of an association request command.
MlmeScanConfirmCallback m_mlmeScanConfirmCallback
This callback is used to report the result of a scan on a group of channels for the selected channel ...
McpsDataConfirmCallback m_mcpsDataConfirmCallback
This callback is used to report data transmission request status to the upper layers.
MlmePollConfirmCallback m_mlmePollConfirmCallback
This callback is used to report the status after a device send data command request to the coordinato...
MlmeSetConfirmCallback m_mlmeSetConfirmCallback
This callback is used to report the result of an attribute writing request to the upper layers.
MlmeSyncLossIndicationCallback m_mlmeSyncLossIndicationCallback
This callback is used to indicate the loss of synchronization with a coordinator.
Represent the Mac Header with the Frame Control and Sequence Number fields.
Mac16Address GetShortSrcAddr() const
Get the Source Short address.
@ LRWPAN_MAC_BEACON
LRWPAN_MAC_BEACON.
@ LRWPAN_MAC_COMMAND
LRWPAN_MAC_COMMAND.
@ LRWPAN_MAC_DATA
LRWPAN_MAC_DATA.
@ LRWPAN_MAC_ACKNOWLEDGMENT
LRWPAN_MAC_ACKNOWLEDGMENT.
@ LRWPAN_MAC_RESERVED
LRWPAN_MAC_RESERVED.
bool IsCommand() const
Returns true if the header is a command.
bool IsBeacon() const
Returns true if the header is a beacon.
Mac64Address GetExtSrcAddr() const
Get the Source Extended address.
void SetNoPanIdComp()
Set the Frame Control field "PAN ID Compression" bit to false.
uint8_t GetSrcAddrMode() const
Get the Source Addressing Mode of Frame control field.
void SetPanIdComp()
Set the Frame Control field "PAN ID Compression" bit to true.
void SetSrcAddrMode(uint8_t addrMode)
Set the Source address mode.
uint8_t GetDstAddrMode() const
Get the Dest.
void SetSecDisable()
Set the Frame Control field "Security Enabled" bit to false.
void SetSrcAddrFields(uint16_t panId, Mac16Address addr)
Set Source address fields.
bool IsAcknowledgment() const
Returns true if the header is an ack.
bool IsData() const
Returns true if the header is a data.
void SetDstAddrFields(uint16_t panId, Mac16Address addr)
Set Destination address fields.
uint8_t GetSeqNum() const
Get the frame Sequence number.
void SetDstAddrMode(uint8_t addrMode)
Set the Destination address mode.
void SetNoAckReq()
Set the Frame Control field "Ack. Request" bit to false.
Mac64Address GetExtDstAddr() const
Get the Destination Extended address.
LrWpanMacType GetType() const
Get the header type.
uint16_t GetDstPanId() const
Get the Destination PAN ID.
uint8_t GetFrameVer() const
Get the Frame Version of Frame control field.
void SetFrameVer(uint8_t ver)
Set the Frame version.
uint16_t GetSrcPanId() const
Get the Source PAN ID.
bool IsAckReq() const
Check if Ack.
Mac16Address GetShortDstAddr() const
Get the Destination Short address.
void SetAckReq()
Set the Frame Control field "Ack. Request" bit to true.
Class that implements the LR-WPAN MAC state machine.
Definition: lr-wpan-mac.h:161
uint32_t m_incomingBeaconInterval
Indication of the interval a node should receive a superframe expressed in symbols.
Definition: lr-wpan-mac.h:610
uint32_t GetIfsSize()
Get the size of the Interframe Space according to MPDU size (m_txPkt).
void McpsDataRequest(McpsDataRequestParams params, Ptr< Packet > p) override
IEEE 802.15.4-2006, section 7.1.1.1 MCPS-DATA.request Request to transfer a MSDU.
Definition: lr-wpan-mac.cc:384
Ptr< LrWpanCsmaCa > m_csmaCa
The CSMA/CA implementation used by this MAC.
Definition: lr-wpan-mac.h:1132
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:406
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:391
void PlmeCcaConfirm(LrWpanPhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.2.2 PLME-CCA.confirm status.
void MlmeAssociateRequest(MlmeAssociateRequestParams params) override
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:683
~LrWpanMac() override
Definition: lr-wpan-mac.cc:263
bool m_macRxOnWhenIdle
Indication of whether the MAC sublayer is to enable its receiver during idle periods.
Definition: lr-wpan-mac.h:544
bool m_macAssociationPermit
Indication of whether a coordinator is currently allowing association.
Definition: lr-wpan-mac.h:563
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:1029
uint64_t m_rxBeaconSymbols
The total size of the received beacon in symbols.
Definition: lr-wpan-mac.h:461
void SetRxOnWhenIdle(bool rxOnWhenIdle)
Set if the receiver should be enabled when the MAC is idle.
Definition: lr-wpan-mac.cc:337
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:587
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:1247
static TypeId GetTypeId()
Get the type ID.
Definition: lr-wpan-mac.cc:91
uint8_t m_deviceCapability
Indication of current device capability (FFD or RFD)
Definition: lr-wpan-mac.h:621
void AwaitBeacon()
Called after the end of an INCOMING superframe to start the moment a device waits for a new incoming ...
void MlmePollRequest(MlmePollRequestParams params) override
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:903
bool m_coor
Indicates if the current device is a coordinator type.
Definition: lr-wpan-mac.h:592
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:1308
uint32_t m_maxIndTxQueueSize
The maximum size of the indirect transmit queue (The pending transaction list).
Definition: lr-wpan-mac.h:1191
EventId m_assocResCmdWaitTimeout
Scheduler event for the lost of a association response command frame.
Definition: lr-wpan-mac.h:1268
void PurgeInd()
Purge expired transactions from the pending transactions list.
void MlmeAssociateResponse(MlmeAssociateResponseParams params) override
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:758
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:1063
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:1112
void SetExtendedAddress(Mac64Address address)
Set the extended address of this MAC.
Definition: lr-wpan-mac.cc:363
uint32_t m_macLIFSPeriod
The minimum time forming a Long InterFrame Spacing (LIFS) period.
Definition: lr-wpan-mac.h:550
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:1037
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:1013
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:1045
Mac16Address GetShortAddress() const
Get the short address of this MAC.
Definition: lr-wpan-mac.cc:370
void SendDataRequestCommand()
Used to send a data request command (i.e.
EventId m_cfpEvent
Scheduler event for the end of the outgoing superframe CFP.
Definition: lr-wpan-mac.h:1293
void PlmeGetAttributeConfirm(LrWpanPhyEnumeration status, LrWpanPibAttributeIdentifier id, Ptr< LrWpanPhyPibAttributes > attribute)
IEEE 802.15.4-2006 section 6.2.2.6 PLME-GET.confirm Get attributes per definition from Table 23 in se...
uint8_t m_macMaxFrameRetries
The maximum number of retries allowed after a transmission failure.
Definition: lr-wpan-mac.h:537
Mac64Address m_macCoordExtendedAddress
The extended address of the coordinator through which the device is associated.
Definition: lr-wpan-mac.h:422
PendingPrimitiveStatus m_pendPrimitive
Indicates the pending primitive when PLME.SET operation (page or channel switch) is called from withi...
Definition: lr-wpan-mac.h:1236
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:1230
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:1197
void SendBeaconRequestCommand()
Called to send a beacon request command.
EventId m_respWaitTimeout
Scheduler event for a response to a request command frame.
Definition: lr-wpan-mac.h:1263
uint32_t m_maxTxQueueSize
The maximum size of the transmit queue.
Definition: lr-wpan-mac.h:1186
Ptr< Packet > m_macBeaconPayload
The contents of the beacon payload.
Definition: lr-wpan-mac.h:525
std::deque< Ptr< TxQueueElement > > m_txQueue
The transmit queue used by the MAC.
Definition: lr-wpan-mac.h:1175
SequenceNumber8 m_macBsn
Sequence number added to transmitted beacon frame, 00-ff.
Definition: lr-wpan-mac.h:518
Ptr< Packet > m_rxPkt
The command request packet received.
Definition: lr-wpan-mac.h:1158
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:1005
void SetLrWpanMacState(LrWpanMacState macState)
CSMA-CA algorithm calls back the MAC after executing channel assessment.
Mac16Address m_shortAddress
The short address (16 bit address) used by this MAC.
Definition: lr-wpan-mac.h:1165
uint8_t m_macSuperframeOrder
Used by a PAN coordinator or coordinator.
Definition: lr-wpan-mac.h:444
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:1202
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.
Time m_macBeaconTxTime
The time that the device transmitted its last beacon frame.
Definition: lr-wpan-mac.h:383
uint16_t GetSuperframeField()
Constructs a Superframe specification field from the local information, the superframe Specification ...
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:1122
Mac64Address GetExtendedAddress() const
Get the extended address of this MAC.
Definition: lr-wpan-mac.cc:377
EventId m_setMacState
Scheduler event for a deferred MAC state change.
Definition: lr-wpan-mac.h:1273
uint64_t m_macResponseWaitTime
The maximum time, in multiples of aBaseSuperframeDuration, a device shall wait for a response command...
Definition: lr-wpan-mac.h:398
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:1323
bool PrepareRetransmission()
Check for remaining retransmissions for the packet currently being sent.
void EnqueueTxQElement(Ptr< TxQueueElement > txQElement)
Add an element to the transmission queue.
void SetPanId(uint16_t panId)
Set the PAN id used by this MAC.
EventId m_scanEvent
Scheduler event for the end of an ACTIVE or PASSIVE channel scan.
Definition: lr-wpan-mac.h:1313
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:1092
uint8_t m_incomingBeaconOrder
The beaconOrder value of the INCOMING frame.
Definition: lr-wpan-mac.h:473
SequenceNumber8 m_macDsn
Sequence number added to transmitted data or MAC command frame, 00-ff.
Definition: lr-wpan-mac.h:512
void SendOrphanNotificationCommand()
Called to send a orphan notification command.
void MlmeSyncRequest(MlmeSyncRequestParams params) override
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:863
uint32_t m_ifs
The value of the necessary InterFrame Space after the transmission of a packet.
Definition: lr-wpan-mac.h:582
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:455
Mac16Address GetCoordShortAddress() const
Get the coordinator short address currently associated to this device.
void ChangeMacState(LrWpanMacState newState)
Change the current MAC state to the given new state.
MlmeStartRequestParams m_startParams
The parameters used during a MLME-START.request.
Definition: lr-wpan-mac.h:1219
void AckWaitTimeout()
Handle an ACK timeout with a packet retransmission, if there are retransmission left,...
std::vector< uint8_t > m_unscannedChannels
The list of unscanned channels during a scan operation.
Definition: lr-wpan-mac.h:1207
Mac64Address GetCoordExtAddress() const
Get the coordinator extended address currently associated to this device.
void MlmeScanRequest(MlmeScanRequestParams params) override
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:623
uint8_t m_macBeaconOrder
Used by a PAN coordinator or coordinator.
Definition: lr-wpan-mac.h:436
TracedCallback< Time > m_macIfsEndTrace
The trace source is fired at the end of any Interframe Space (IFS).
Definition: lr-wpan-mac.h:969
TracedValue< SuperframeStatus > m_outSuperframeStatus
The current period of the outgoing superframe.
Definition: lr-wpan-mac.h:1147
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...
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:1225
LrWpanMac()
Default constructor.
Definition: lr-wpan-mac.cc:202
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:1258
void MlmeStartRequest(MlmeStartRequestParams params) override
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:584
bool m_macPromiscuousMode
Indicates if MAC sublayer is in receive all mode.
Definition: lr-wpan-mac.h:493
uint8_t m_fnlCapSlot
Indication of the Slot where the CAP portion of the OUTGOING Superframe ends.
Definition: lr-wpan-mac.h:466
uint32_t m_macSIFSPeriod
The minimum time forming a Short InterFrame Spacing (SIFS) period.
Definition: lr-wpan-mac.h:556
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:1181
void PrintPendingTxQueue(std::ostream &os) const
Print the Pending transaction list.
uint32_t m_beaconInterval
Indication of the Interval used by the coordinator to transmit beacon frames expressed in symbols.
Definition: lr-wpan-mac.h:598
TracedValue< LrWpanMacState > m_lrWpanMacState
The current state of the MAC layer.
Definition: lr-wpan-mac.h:1137
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:989
EventId m_capEvent
Scheduler event for the end of the outgoing superframe CAP.
Definition: lr-wpan-mac.h:1288
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets are being sent down to L1.
Definition: lr-wpan-mac.h:1020
uint16_t m_macPanId
16 bits id of PAN on which this device is operating.
Definition: lr-wpan-mac.h:500
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:268
void MlmeGetRequest(LrWpanMacPibAttributeIdentifier id) override
IEEE 802.15.4-2011, section 6.2.5.1 MLME-GET.request Request information about a given PIB attribute.
Definition: lr-wpan-mac.cc:962
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:1072
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:572
uint8_t m_incomingSuperframeOrder
Used by all devices that have a parent.
Definition: lr-wpan-mac.h:481
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:506
uint32_t m_macBeaconPayloadLength
The length, in octets, of the beacon payload.
Definition: lr-wpan-mac.h:531
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:997
void MlmeOrphanResponse(MlmeOrphanResponseParams params) override
IEEE 802.15.4-2011, section 6.2.7.2 MLME-ORPHAN.response Primitive used to initiatte a response to an...
Definition: lr-wpan-mac.cc:803
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:631
Ptr< Packet > m_txPkt
The packet which is currently being sent by the MAC layer.
Definition: lr-wpan-mac.h:1152
void SendAssocRequestCommand()
Called to send an associate request command.
uint8_t m_maxEnergyLevel
The maximum energy level detected during ED scan on the current channel.
Definition: lr-wpan-mac.h:577
void DoDispose() override
Destructor implementation.
Definition: lr-wpan-mac.cc:283
MlmeScanRequestParams m_scanParams
The parameters used during a MLME-SCAN.request.
Definition: lr-wpan-mac.h:1213
void SetPhy(Ptr< LrWpanPhy > phy)
Set the underlying PHY for the MAC.
Ptr< LrWpanPhy > GetPhy()
Get the underlying PHY of the MAC.
uint8_t m_lastRxFrameLqi
Keep track of the last received frame Link Quality Indicator.
Definition: lr-wpan-mac.h:1252
EventId m_scanOrphanEvent
Scheduler event for the end of an ORPHAN channel scan.
Definition: lr-wpan-mac.h:1318
void EndAssociateRequest()
Called to end an MLME-ASSOCIATE.request after changing the page and channel number.
Definition: lr-wpan-mac.cc:738
Mac64Address m_selfExt
The extended 64 address (IEEE EUI-64) used by this MAC.
Definition: lr-wpan-mac.h:1170
EventId m_incCapEvent
Scheduler event for the end of the incoming superframe CAP.
Definition: lr-wpan-mac.h:1298
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)
bool m_beaconTrackingOn
Indication of whether the current device is tracking incoming beacons.
Definition: lr-wpan-mac.h:626
uint32_t m_superframeDuration
Indication of the superframe duration in symbols.
Definition: lr-wpan-mac.h:604
bool GetRxOnWhenIdle() const
Check if the receiver will be enabled when the MAC is idle.
Definition: lr-wpan-mac.cc:331
Mac16Address m_macCoordShortAddress
The short address of the coordinator through which the device is associated.
Definition: lr-wpan-mac.h:415
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:1127
void MlmeSetRequest(LrWpanMacPibAttributeIdentifier id, Ptr< LrWpanMacPibAttributes > attribute) override
IEEE 802.15.4-2011, section 6.2.11.1 MLME-SET.request Attempts to write the given value to the indica...
Definition: lr-wpan-mac.cc:918
void EndChannelEnergyScan()
Called at the end of one ED channel scan.
void PrintTransmitQueueSize()
Print the number of elements in the packet transmit queue.
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:1054
EventId m_ifsEvent
Scheduler event for Interframe spacing wait time.
Definition: lr-wpan-mac.h:1278
EventId m_beaconEvent
Scheduler event for generation of one beacon.
Definition: lr-wpan-mac.h:1283
uint32_t m_incomingSuperframeDuration
Indication of the superframe duration in symbols (e.g.
Definition: lr-wpan-mac.h:616
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:981
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:356
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:1242
EventId m_incCfpEvent
Scheduler event for the end of the incoming superframe CFP.
Definition: lr-wpan-mac.h:1303
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:486
TracedValue< SuperframeStatus > m_incSuperframeStatus
The current period of the incoming superframe.
Definition: lr-wpan-mac.h:1142
void SetAssociatedCoor(Mac16Address mac)
Check if the packet destination is its coordinator.
Represent the Mac Trailer with the Frame Check Sequence field.
void SetFcs(Ptr< const Packet > p)
Calculate and set the FCS value based on the given packet.
bool CheckFcs(Ptr< const Packet > p)
Check the FCS of a given packet against the FCS value stored in the trailer.
void EnableFcs(bool enable)
Enable or disable FCS calculation for this trailer.
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
bool IsMulticast() const
Checks if the address is a multicast address according to RFC 4944 Section 9 (i.e....
bool IsBroadcast() const
Checks if the address is a broadcast address according to 802.15.4 scheme (i.e., 0xFFFF).
an EUI-64 address
Definition: mac64-address.h:46
static Mac64Address Allocate()
Allocate a new Mac64Address.
static bool ChecksumEnabled()
Definition: node.cc:285
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:359
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
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:861
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
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:571
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:217
Represent the Superframe Specification information field.
uint8_t GetFinalCapSlot() const
Get the the Final CAP Slot.
uint16_t GetSuperframe() const
Get the Superframe specification information field.
void SetAssocPermit(bool assocPermit)
Set the Superframe Specification Association Permit field.
void SetBattLifeExt(bool battLifeExt)
Set the Superframe Specification Battery Life Extension (BLE).
uint8_t GetBeaconOrder() const
Get the Superframe Specification Beacon Order field.
bool IsBattLifeExt() const
Check if the Battery Life Extension bit is enabled.
void SetFinalCapSlot(uint8_t capSlot)
Set the superframe specification Final CAP slot field.
void SetSuperframeOrder(uint8_t frmOrder)
Set the superframe specification Superframe Order field.
void SetPanCoor(bool panCoor)
Set the Superframe Specification PAN coordinator field.
void SetBeaconOrder(uint8_t bcnOrder)
Set the superframe specification Beacon Order field.
uint8_t GetFrameOrder() const
Get the Superframe Specification Frame Order field.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
@ S
second
Definition: nstime.h:116
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:315
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value drawn from the distribution.
constexpr uint32_t aMaxSIFSFrameSize
The maximum size of an MPDU, in octets, that can be followed by a Short InterFrame Spacing (SIFS) per...
constexpr uint32_t aMaxLostBeacons
The number of consecutive lost beacons that will cause the MAC sublayer of a receiving device to decl...
constexpr uint32_t aMaxBeaconPayloadLength
The maximum size, in octets, of a beacon payload.
constexpr uint32_t aMaxPhyPacketSize
The maximum packet size accepted by the PHY.
constexpr uint32_t aUnitBackoffPeriod
Number of symbols per CSMA/CA time unit, default 20 symbols.
constexpr uint32_t aTurnaroundTime
The turnaround time in symbol periods for switching the transceiver from RX to TX or vice-versa.
constexpr uint32_t aBaseSuperframeDuration
Length of a superframe in symbols.
constexpr uint32_t aMinMPDUOverhead
The minimum number of octets added by the MAC sublayer to the PSDU.
#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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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:72
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:111
LrWpanMacStatus
The status of a confirm or an indication primitive as a result of a previous request.
SuperframeType
Superframe type.
Definition: lr-wpan-mac.h:113
LrWpanMacPibAttributeIdentifier
IEEE802.15.4-2011 MAC PIB Attribute Identifiers Table 52 in section 6.4.2.
LrWpanPibAttributeIdentifier
IEEE802.15.4-2006 PHY PIB Attribute Identifiers Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:163
@ CHANNEL_ACCESS_FAILURE
CHANNEL_ACCESS_FAILURE.
Definition: lr-wpan-mac.h:77
@ MAC_IDLE
MAC_IDLE.
Definition: lr-wpan-mac.h:73
@ MAC_CSMA_DEFERRED
MAC_CSMA_DEFERRED.
Definition: lr-wpan-mac.h:82
@ MAC_CSMA
MAC_CSMA.
Definition: lr-wpan-mac.h:74
@ CHANNEL_IDLE
CHANNEL_IDLE.
Definition: lr-wpan-mac.h:78
@ MAC_GTS
MAC_GTS.
Definition: lr-wpan-mac.h:80
@ SET_PHY_TX_ON
SET_PHY_TX_ON.
Definition: lr-wpan-mac.h:79
@ MAC_INACTIVE
MAC_INACTIVE.
Definition: lr-wpan-mac.h:81
@ MAC_SENDING
MAC_SENDING.
Definition: lr-wpan-mac.h:75
@ MAC_ACK_PENDING
MAC_ACK_PENDING.
Definition: lr-wpan-mac.h:76
@ FFD
Full Functional Device (FFD)
@ MLMESCAN_PASSIVE
@ MLMESCAN_ORPHAN
@ MLMESCAN_ACTIVE
@ CFP
Contention Free Period.
Definition: lr-wpan-mac.h:103
@ INACTIVE
Inactive Period or unslotted CSMA-CA.
Definition: lr-wpan-mac.h:104
@ CAP
Contention Access Period.
Definition: lr-wpan-mac.h:102
@ BEACON
The Beacon transmission or reception Period.
Definition: lr-wpan-mac.h:101
@ IEEE_802_15_4_PHY_SUCCESS
Definition: lr-wpan-phy.h:119
@ IEEE_802_15_4_PHY_UNSPECIFIED
Definition: lr-wpan-phy.h:124
@ IEEE_802_15_4_PHY_TRX_OFF
Definition: lr-wpan-phy.h:120
@ IEEE_802_15_4_PHY_RX_ON
Definition: lr-wpan-phy.h:118
@ IEEE_802_15_4_PHY_TX_ON
Definition: lr-wpan-phy.h:121
@ TX_OPTION_ACK
TX_OPTION_ACK.
Definition: lr-wpan-mac.h:61
@ TX_OPTION_INDIRECT
TX_OPTION_INDIRECT.
Definition: lr-wpan-mac.h:63
@ TX_OPTION_GTS
TX_OPTION_GTS.
Definition: lr-wpan-mac.h:62
@ TRANSACTION_OVERFLOW
There is no capacity to store the transaction.
@ NO_BEACON
A scan operation failed to find any network beacons.
@ UNSUPPORTED_ATTRIBUTE
SET/GET request issued with a non supported ID.
@ NO_SHORT_ADDRESS
Failure due to unallocated 16-bit short address.
@ ACCESS_DENIED
PAN access denied.
@ BEACON_LOSS
The beacon was lost following a synchronization request.
@ READ_ONLY
SET/GET request issued for a read only attribute.
@ TRANSACTION_EXPIRED
The transaction expired and its information discarded.
@ SCAN_IN_PROGRESS
Scan failed because already performing another scan.
@ FRAME_TOO_LONG
Frame more than aMaxPHYPacketSize or too large for CAP or GTS.
@ INVALID_ADDRESS
Invalid source or destination address.
@ FULL_CAPACITY
PAN at capacity.
@ NO_ACK
No acknowledgment was received after macMaxFrameRetries.
@ NO_DATA
No response data were available following a request.
@ INVALID_PARAMETER
Primitive parameter not supported or out of range.
@ MLME_SCAN_REQ
Pending MLME-SCAN.request primitive.
Definition: lr-wpan-mac.h:127
@ MLME_ASSOC_REQ
Pending MLME-ASSOCIATION.request primitive.
Definition: lr-wpan-mac.h:128
@ MLME_START_REQ
Pending MLME-START.request primitive.
Definition: lr-wpan-mac.h:126
@ MLME_NONE
No pending primitive.
Definition: lr-wpan-mac.h:125
@ SHORT_ADDR
@ NO_PANID_ADDR
@ ADDR_MODE_RESERVED
@ INCOMING
Incoming Superframe.
Definition: lr-wpan-mac.h:115
@ OUTGOING
Outgoing Superframe.
Definition: lr-wpan-mac.h:114
@ pCurrentChannel
@ macBeaconPayloadLength
@ pCurrentPage
@ macShortAddress
@ macBeaconPayload
@ macExtendedAddress
@ phyCurrentChannel
Definition: lr-wpan-phy.h:164
@ phyCurrentPage
Definition: lr-wpan-phy.h:168
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
SequenceNumber< uint8_t, int8_t > SequenceNumber8
8 bit Sequence number.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.
@ SUCCESS
Definition: ff-mac-common.h:62
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:159
mac
Definition: third.py:92
phy
Definition: third.py:89
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
MCPS-DATA.confirm params.
LrWpanMacStatus m_status
The status of the last MSDU transmission.
uint8_t m_msduHandle
MSDU handle.
MCPS-DATA.indication params.
MCPS-DATA.request params.
MLME-ASSOCIATE.confirm params.
LrWpanMacStatus m_status
The status of a MLME-associate.request.
Mac16Address m_assocShortAddr
The short address used in the association request.
MLME-ASSOCIATE.indication params.
uint8_t capabilityInfo
The operational capabilities of the device requesting association.
uint8_t lqi
The link quality indicator of the received associate request command (Not officially supported in the...
Mac64Address m_extDevAddr
The extended address of the device requesting association.
MLME-ASSOCIATE.request params.
uint8_t m_chNum
The channel number on which to attempt association.
uint8_t m_coordAddrMode
The coordinator addressing mode for this primitive and subsequent MPDU.
uint8_t m_capabilityInfo
Specifies the operational capabilities of the associating device (bitmap).
Mac64Address m_coordExtAddr
The extended address of the coordinator with which to associate.
Mac16Address m_coordShortAddr
The short address of the coordinator with which to associate.
uint16_t m_coordPanId
The identifier of the PAN with which to associate.
MLME-ASSOCIATE.response params.
MLME-BEACON-NOTIFY.indication params.
uint32_t m_sduLength
The number of octets contained in the beacon payload.
uint8_t m_bsn
The beacon sequence number.
Ptr< Packet > m_sdu
The set of octets comprising the beacon payload.
PanDescriptor m_panDescriptor
The PAN descriptor for the received beacon.
MLME-COMM-STATUS.indication params.
Mac16Address m_srcShortAddr
The short address of the entity from which the frame causing the error originated.
Mac16Address m_dstShortAddr
The short address of the device for which the frame was intended.
Mac64Address m_dstExtAddr
The extended address of the device for which the frame was intended.
uint16_t m_panId
The PAN identifier of the device from which the frame was received or to which the frame was being se...
Mac64Address m_srcExtAddr
The extended address of the entity from which the frame causing the error originated.
uint8_t m_dstAddrMode
The destination addressing mode for this primitive.
uint8_t m_srcAddrMode
The source addressing mode for this primitive.
LrWpanMacStatus m_status
The communication status.
MLME-ORPHAN.indication params.
Mac64Address m_orphanAddr
The address of the orphaned device.
MLME-ORPHAN.response params.
MLME-START.confirm params.
LrWpanMacStatus m_status
The confirmation status resulting from a MLME-poll.request.
MLME-POLL.request params.
MLME-SCAN.confirm params.
std::vector< PanDescriptor > m_panDescList
A list of PAN descriptor, one for each beacon found (Not valid for ED and Orphan scans).
uint32_t m_chPage
The channel page on which the scan was performed.
uint8_t m_scanType
Indicates the type of scan performed (ED,ACTIVE,PASSIVE,ORPHAN).
std::vector< uint8_t > m_unscannedCh
A list of channels given in the request which were not scanned (Not valid for ED scans).
std::vector< uint8_t > m_energyDetList
A list of energy measurements, one for each channel searched during ED scan (Not valid for Active,...
LrWpanMacStatus m_status
The status of the scan request.
uint8_t m_resultListSize
The number of elements returned in the appropriate result list.
MLME-SCAN.request params.
uint32_t m_scanChannels
The channel numbers to be scanned.
uint32_t m_chPage
The channel page on which to perform scan.
uint8_t m_scanDuration
The factor (0-14) used to calculate the length of time to spend scanning.
LrWpanMlmeScanType m_scanType
Indicates the type of scan performed as described in IEEE 802.15.4-2011 (5.1.2.1).
MLME-SET.confirm params.
LrWpanMacStatus m_status
The result of the request to write the PIB attribute.
LrWpanMacPibAttributeIdentifier id
The id of the PIB attribute that was written.
MLME-START.confirm params.
LrWpanMacStatus m_status
The status of a MLME-start.request.
MLME-START.request params.
uint32_t m_logChPage
Logical channel page on which to start using the new superframe configuration.
uint8_t m_logCh
Logical channel on which to start using the new superframe configuration.
bool m_panCoor
On true this device will become coordinator.
bool m_coorRealgn
True if a realignment request command is to be transmitted prior changing the superframe.
uint8_t m_bcnOrd
Beacon Order, Used to calculate the beacon interval, a value of 15 indicates no periodic beacons will...
uint16_t m_PanId
Pan Identifier used by the device.
uint8_t m_sfrmOrd
Superframe Order, indicates the length of the CAP in time slots.
bool m_battLifeExt
Flag indicating whether or not the Battery life extension (BLE) features are used.
MLME-SYNC-LOSS.indication params.
uint16_t m_panId
The PAN identifier with which the device lost synchronization or to which it was realigned.
LrWpanMacStatus m_lossReason
The reason for the lost of synchronization.
MLME-SYNC.request params.
PAN Descriptor, Table 17 IEEE 802.15.4-2011.
LrWpanAddressMode m_coorAddrMode
The coordinator addressing mode corresponding to the received beacon frame.
uint16_t m_superframeSpec
The superframe specification as specified in the received beacon frame.
Mac64Address m_coorExtAddr
The coordinator extended address as specified in the coordinator address mode.
Mac16Address m_coorShortAddr
The coordinator short address as specified in the coordinator address mode.
uint8_t m_logChPage
The current channel page occupied by the network.
uint16_t m_coorPanId
The PAN ID of the coordinator as specified in the received beacon frame.
bool m_gtsPermit
TRUE if the beacon is from the PAN coordinator that is accepting GTS requests.
uint8_t m_linkQuality
The LQI at which the network beacon was received.
Time m_timeStamp
Beacon frame reception time.
uint8_t m_logCh
The current channel number occupied by the network.
std::ofstream queueSize