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 std::clog << "[address " << m_shortAddress << "] ";
43 
44 namespace ns3
45 {
46 
47 NS_LOG_COMPONENT_DEFINE("LrWpanMac");
49 
50 TypeId
52 {
53  static TypeId tid =
54  TypeId("ns3::LrWpanMac")
55  .SetParent<Object>()
56  .SetGroupName("LrWpan")
57  .AddConstructor<LrWpanMac>()
58  .AddAttribute("PanId",
59  "16-bit identifier of the associated PAN",
60  UintegerValue(),
62  MakeUintegerChecker<uint16_t>())
63  .AddTraceSource("MacTxEnqueue",
64  "Trace source indicating a packet has been "
65  "enqueued in the transaction queue",
67  "ns3::Packet::TracedCallback")
68  .AddTraceSource("MacTxDequeue",
69  "Trace source indicating a packet has was "
70  "dequeued from the transaction queue",
72  "ns3::Packet::TracedCallback")
73  .AddTraceSource("MacIndTxEnqueue",
74  "Trace source indicating a packet has been "
75  "enqueued in the indirect transaction queue",
77  "ns3::Packet::TracedCallback")
78  .AddTraceSource("MacIndTxDequeue",
79  "Trace source indicating a packet has was "
80  "dequeued from the indirect transaction queue",
82  "ns3::Packet::TracedCallback")
83  .AddTraceSource("MacTx",
84  "Trace source indicating a packet has "
85  "arrived for transmission by this device",
87  "ns3::Packet::TracedCallback")
88  .AddTraceSource("MacTxOk",
89  "Trace source indicating a packet has been "
90  "successfully sent",
92  "ns3::Packet::TracedCallback")
93  .AddTraceSource("MacTxDrop",
94  "Trace source indicating a packet has been "
95  "dropped during transmission",
97  "ns3::Packet::TracedCallback")
98  .AddTraceSource("MacIndTxDrop",
99  "Trace source indicating a packet has been "
100  "dropped from the indirect transaction queue"
101  "(The pending transaction list)",
103  "ns3::Packet::TracedCallback")
104  .AddTraceSource("MacPromiscRx",
105  "A packet has been received by this device, "
106  "has been passed up from the physical layer "
107  "and is being forwarded up the local protocol stack. "
108  "This is a promiscuous trace,",
110  "ns3::Packet::TracedCallback")
111  .AddTraceSource("MacRx",
112  "A packet has been received by this device, "
113  "has been passed up from the physical layer "
114  "and is being forwarded up the local protocol stack. "
115  "This is a non-promiscuous trace,",
117  "ns3::Packet::TracedCallback")
118  .AddTraceSource("MacRxDrop",
119  "Trace source indicating a packet was received, "
120  "but dropped before being forwarded up the stack",
122  "ns3::Packet::TracedCallback")
123  .AddTraceSource("Sniffer",
124  "Trace source simulating a non-promiscuous "
125  "packet sniffer attached to the device",
127  "ns3::Packet::TracedCallback")
128  .AddTraceSource("PromiscSniffer",
129  "Trace source simulating a promiscuous "
130  "packet sniffer attached to the device",
132  "ns3::Packet::TracedCallback")
133  .AddTraceSource("MacStateValue",
134  "The state of LrWpan Mac",
136  "ns3::TracedValueCallback::LrWpanMacState")
137  .AddTraceSource("MacIncSuperframeStatus",
138  "The period status of the incoming superframe",
140  "ns3::TracedValueCallback::SuperframeState")
141  .AddTraceSource("MacOutSuperframeStatus",
142  "The period status of the outgoing superframe",
144  "ns3::TracedValueCallback::SuperframeState")
145  .AddTraceSource("MacState",
146  "The state of LrWpan Mac",
148  "ns3::LrWpanMac::StateTracedCallback")
149  .AddTraceSource("MacSentPkt",
150  "Trace source reporting some information about "
151  "the sent packet",
153  "ns3::LrWpanMac::SentTracedCallback")
154  .AddTraceSource("IfsEnd",
155  "Trace source reporting the end of an "
156  "Interframe space (IFS)",
158  "ns3::Packet::TracedCallback");
159  return tid;
160 }
161 
163 {
164  // First set the state to a known value, call ChangeMacState to fire trace source.
166 
168 
171 
172  m_macRxOnWhenIdle = true;
173  m_macPanId = 0xffff;
175  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
179  m_macPromiscuousMode = false;
181  m_retransmission = 0;
182  m_numCsmacaRetry = 0;
183  m_txPkt = nullptr;
184  m_rxPkt = nullptr;
185  m_ifs = 0;
186 
187  m_macLIFSPeriod = 40;
188  m_macSIFSPeriod = 12;
189 
190  m_panCoor = false;
191  m_macBeaconOrder = 15;
193  m_macTransactionPersistenceTime = 500; // 0x01F5
194  m_macAssociationPermit = true;
195  m_macAutoRequest = true;
196 
199  m_beaconTrackingOn = false;
200  m_numLostBeacons = 0;
201 
203  m_channelScanIndex = 0;
204  m_maxEnergyLevel = 0;
205 
208 
209  m_maxTxQueueSize = m_txQueue.max_size();
210  m_maxIndTxQueueSize = m_indTxQueue.max_size();
211 
212  Ptr<UniformRandomVariable> uniformVar = CreateObject<UniformRandomVariable>();
213  uniformVar->SetAttribute("Min", DoubleValue(0.0));
214  uniformVar->SetAttribute("Max", DoubleValue(255.0));
215  m_macDsn = SequenceNumber8(uniformVar->GetValue());
216  m_macBsn = SequenceNumber8(uniformVar->GetValue());
217  m_macBeaconPayload = nullptr;
219  m_shortAddress = Mac16Address("FF:FF"); // FF:FF = The address is not assigned.
220 }
221 
223 {
224 }
225 
226 void
228 {
229  if (m_macRxOnWhenIdle)
230  {
231  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
232  }
233  else
234  {
235  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
236  }
237 
239 }
240 
241 void
243 {
244  if (m_csmaCa)
245  {
246  m_csmaCa->Dispose();
247  m_csmaCa = nullptr;
248  }
249  m_txPkt = nullptr;
250 
251  for (uint32_t i = 0; i < m_txQueue.size(); i++)
252  {
253  m_txQueue[i]->txQPkt = nullptr;
254  m_txQueue[i]->txQMsduHandle = 0;
255  }
256  m_txQueue.clear();
257 
258  for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
259  {
260  m_indTxQueue[i]->txQPkt = nullptr;
261  m_indTxQueue[i]->seqNum = 0;
262  m_indTxQueue[i]->dstExtAddress = nullptr;
263  m_indTxQueue[i]->dstShortAddress = nullptr;
264  }
265  m_indTxQueue.clear();
266 
267  m_phy = nullptr;
268  m_mcpsDataConfirmCallback = MakeNullCallback<void, McpsDataConfirmParams>();
269  m_mcpsDataIndicationCallback = MakeNullCallback<void, McpsDataIndicationParams, Ptr<Packet>>();
270  m_mlmeStartConfirmCallback = MakeNullCallback<void, MlmeStartConfirmParams>();
272  MakeNullCallback<void, MlmeBeaconNotifyIndicationParams>();
273  m_mlmeSyncLossIndicationCallback = MakeNullCallback<void, MlmeSyncLossIndicationParams>();
274  m_mlmePollConfirmCallback = MakeNullCallback<void, MlmePollConfirmParams>();
275  m_mlmeScanConfirmCallback = MakeNullCallback<void, MlmeScanConfirmParams>();
276  m_mlmeAssociateConfirmCallback = MakeNullCallback<void, MlmeAssociateConfirmParams>();
277  m_mlmeAssociateIndicationCallback = MakeNullCallback<void, MlmeAssociateIndicationParams>();
278  m_mlmeCommStatusIndicationCallback = MakeNullCallback<void, MlmeCommStatusIndicationParams>();
279 
281 
283 }
284 
285 bool
287 {
288  return m_macRxOnWhenIdle;
289 }
290 
291 void
292 LrWpanMac::SetRxOnWhenIdle(bool rxOnWhenIdle)
293 {
294  NS_LOG_FUNCTION(this << rxOnWhenIdle);
295  m_macRxOnWhenIdle = rxOnWhenIdle;
296 
297  if (m_lrWpanMacState == MAC_IDLE)
298  {
299  if (m_macRxOnWhenIdle)
300  {
301  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
302  }
303  else
304  {
305  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
306  }
307  }
308 }
309 
310 void
312 {
313  NS_LOG_FUNCTION(this << address);
315 }
316 
317 void
319 {
320  NS_LOG_FUNCTION(this << address);
321  m_selfExt = address;
322 }
323 
326 {
327  NS_LOG_FUNCTION(this);
328  return m_shortAddress;
329 }
330 
333 {
334  NS_LOG_FUNCTION(this);
335  return m_selfExt;
336 }
337 
338 void
340 {
341  NS_LOG_FUNCTION(this << p);
342 
343  McpsDataConfirmParams confirmParams;
344  confirmParams.m_msduHandle = params.m_msduHandle;
345 
346  // TODO: We need a drop trace for the case that the packet is too large or the request
347  // parameters are maleformed.
348  // The current tx drop trace is not suitable, because packets dropped using this trace
349  // carry the mac header and footer, while packets being dropped here do not have them.
350 
352  m_macDsn++;
353 
355  {
356  // Note, this is just testing maximum theoretical frame size per the spec
357  // The frame could still be too large once headers are put on
358  // in which case the phy will reject it instead
359  NS_LOG_ERROR(this << " packet too big: " << p->GetSize());
360  confirmParams.m_status = IEEE_802_15_4_FRAME_TOO_LONG;
362  {
363  m_mcpsDataConfirmCallback(confirmParams);
364  }
365  return;
366  }
367 
368  if ((params.m_srcAddrMode == NO_PANID_ADDR) && (params.m_dstAddrMode == NO_PANID_ADDR))
369  {
370  NS_LOG_ERROR(this << " Can not send packet with no Address field");
371  confirmParams.m_status = IEEE_802_15_4_INVALID_ADDRESS;
373  {
374  m_mcpsDataConfirmCallback(confirmParams);
375  }
376  return;
377  }
378  switch (params.m_srcAddrMode)
379  {
380  case NO_PANID_ADDR:
381  macHdr.SetSrcAddrMode(params.m_srcAddrMode);
382  macHdr.SetNoPanIdComp();
383  break;
384  case ADDR_MODE_RESERVED:
385  NS_ABORT_MSG("Can not set source address type to ADDR_MODE_RESERVED. Aborting.");
386  break;
387  case SHORT_ADDR:
388  macHdr.SetSrcAddrMode(params.m_srcAddrMode);
390  break;
391  case EXT_ADDR:
392  macHdr.SetSrcAddrMode(params.m_srcAddrMode);
394  break;
395  default:
396  NS_LOG_ERROR(this << " Can not send packet with incorrect Source Address mode = "
397  << params.m_srcAddrMode);
398  confirmParams.m_status = IEEE_802_15_4_INVALID_ADDRESS;
400  {
401  m_mcpsDataConfirmCallback(confirmParams);
402  }
403  return;
404  }
405  switch (params.m_dstAddrMode)
406  {
407  case NO_PANID_ADDR:
408  macHdr.SetDstAddrMode(params.m_dstAddrMode);
409  macHdr.SetNoPanIdComp();
410  break;
411  case ADDR_MODE_RESERVED:
412  NS_ABORT_MSG("Can not set destination address type to ADDR_MODE_RESERVED. Aborting.");
413  break;
414  case SHORT_ADDR:
415  macHdr.SetDstAddrMode(params.m_dstAddrMode);
416  macHdr.SetDstAddrFields(params.m_dstPanId, params.m_dstAddr);
417  break;
418  case EXT_ADDR:
419  macHdr.SetDstAddrMode(params.m_dstAddrMode);
420  macHdr.SetDstAddrFields(params.m_dstPanId, params.m_dstExtAddr);
421  break;
422  default:
423  NS_LOG_ERROR(this << " Can not send packet with incorrect Destination Address mode = "
424  << params.m_dstAddrMode);
425  confirmParams.m_status = IEEE_802_15_4_INVALID_ADDRESS;
427  {
428  m_mcpsDataConfirmCallback(confirmParams);
429  }
430  return;
431  }
432 
433  // IEEE 802.15.4-2006 (7.5.6.1)
434  // Src & Dst PANs are identical, PAN compression is ON
435  // only the dst PAN is serialized making the MAC header 2 bytes smaller
436  if ((params.m_dstAddrMode != NO_PANID_ADDR && params.m_srcAddrMode != NO_PANID_ADDR) &&
437  (macHdr.GetDstPanId() == macHdr.GetSrcPanId()))
438  {
439  macHdr.SetPanIdComp();
440  }
441 
442  macHdr.SetSecDisable();
443  // extract the first 3 bits in TxOptions
444  int b0 = params.m_txOptions & TX_OPTION_ACK;
445  int b1 = params.m_txOptions & TX_OPTION_GTS;
446  int b2 = params.m_txOptions & TX_OPTION_INDIRECT;
447 
448  if (b0 == TX_OPTION_ACK)
449  {
450  // Set AckReq bit only if the destination is not the broadcast address.
451  if (macHdr.GetDstAddrMode() == SHORT_ADDR)
452  {
453  // short address and ACK requested.
454  Mac16Address shortAddr = macHdr.GetShortDstAddr();
455  if (shortAddr.IsBroadcast() || shortAddr.IsMulticast())
456  {
457  NS_LOG_LOGIC("LrWpanMac::McpsDataRequest: requested an ACK on broadcast or "
458  "multicast destination ("
459  << shortAddr << ") - forcefully removing it.");
460  macHdr.SetNoAckReq();
461  params.m_txOptions &= ~uint8_t(TX_OPTION_ACK);
462  }
463  else
464  {
465  macHdr.SetAckReq();
466  }
467  }
468  else
469  {
470  // other address (not short) and ACK requested
471  macHdr.SetAckReq();
472  }
473  }
474  else
475  {
476  macHdr.SetNoAckReq();
477  }
478 
479  if (b1 == TX_OPTION_GTS)
480  {
481  // TODO:GTS Transmission
482  }
483  else if (b2 == TX_OPTION_INDIRECT)
484  {
485  // Indirect Tx
486  // A COORDINATOR will save the packet in the pending queue and await for data
487  // requests from its associated devices. The devices are aware of pending data,
488  // from the pending bit information extracted from the received beacon.
489  // A DEVICE must be tracking beacons (MLME-SYNC.request is running) before attempting
490  // request data from the coordinator.
491 
492  // TODO: Check if the current device is coordinator (not just pan coordinator)
493  // Indirect Transmission can only be done by PAN coordinator or coordinators.
495  p->AddHeader(macHdr);
496 
497  LrWpanMacTrailer macTrailer;
498  // Calculate FCS if the global attribute ChecksumEnable is set.
499  if (Node::ChecksumEnabled())
500  {
501  macTrailer.EnableFcs(true);
502  macTrailer.SetFcs(p);
503  }
504  p->AddTrailer(macTrailer);
505 
506  NS_LOG_ERROR(this << " Indirect transmissions not currently supported");
507  // Note: The current Pending transaction list should work for indirect transmissions.
508  // However, this is not tested yet. For now, we block the use of indirect transmissions.
509  // TODO: Save packet in the Pending Transaction list.
510  // EnqueueInd (p);
511  }
512  else
513  {
514  // Direct Tx
515  // From this point the packet will be pushed to a Tx queue and immediately
516  // use a slotted (beacon-enabled) or unslotted (nonbeacon-enabled) version of CSMA/CA
517  // before sending the packet, depending on whether it has previously
518  // received a valid beacon or not.
519 
520  p->AddHeader(macHdr);
521 
522  LrWpanMacTrailer macTrailer;
523  // Calculate FCS if the global attribute ChecksumEnable is set.
524  if (Node::ChecksumEnabled())
525  {
526  macTrailer.EnableFcs(true);
527  macTrailer.SetFcs(p);
528  }
529  p->AddTrailer(macTrailer);
530 
531  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
532  txQElement->txQMsduHandle = params.m_msduHandle;
533  txQElement->txQPkt = p;
534  EnqueueTxQElement(txQElement);
535  CheckQueue();
536  }
537 }
538 
539 void
541 {
542  NS_LOG_FUNCTION(this);
544 
545  MlmeStartConfirmParams confirmParams;
546 
547  if (GetShortAddress() == Mac16Address("ff:ff"))
548  {
549  NS_LOG_ERROR(this << " Invalid MAC short address");
550  confirmParams.m_status = MLMESTART_NO_SHORT_ADDRESS;
552  {
553  m_mlmeStartConfirmCallback(confirmParams);
554  }
555  return;
556  }
557 
558  if ((params.m_bcnOrd > 15) || (params.m_sfrmOrd > params.m_bcnOrd))
559  {
560  confirmParams.m_status = MLMESTART_INVALID_PARAMETER;
562  {
563  m_mlmeStartConfirmCallback(confirmParams);
564  }
565  NS_LOG_ERROR(this << "Incorrect superframe order or beacon order.");
566  return;
567  }
568 
569  // Mark primitive as pending and save the start params while the new page and channel is set.
572 
573  LrWpanPhyPibAttributes pibAttr;
575  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, &pibAttr);
576 }
577 
578 void
580 {
581  NS_LOG_FUNCTION(this);
582 
583  MlmeScanConfirmParams confirmParams;
584  confirmParams.m_scanType = params.m_scanType;
585  confirmParams.m_chPage = params.m_chPage;
586 
588  {
590  {
591  confirmParams.m_status = MLMESCAN_SCAN_IN_PROGRESS;
592  m_mlmeScanConfirmCallback(confirmParams);
593  }
594  NS_LOG_ERROR(this << " A channel scan is already in progress");
595  return;
596  }
597 
598  if (params.m_scanDuration > 14 || params.m_scanType > MLMESCAN_PASSIVE)
599  {
601  {
602  confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
603  m_mlmeScanConfirmCallback(confirmParams);
604  }
605  NS_LOG_ERROR(this << "Invalid scan duration or unsupported scan type");
606  return;
607  }
608  // Temporary store macPanId and set macPanId to 0xFFFF to accept all beacons.
610  m_macPanId = 0xFFFF;
611 
612  m_panDescriptorList.clear();
613  m_energyDetectList.clear();
614 
615  // TODO: stop beacon transmission
616 
617  // Cancel any ongoing CSMA/CA operations and set to unslotted mode for scan
618  m_csmaCa->Cancel();
619  m_capEvent.Cancel();
620  m_cfpEvent.Cancel();
624  m_csmaCa->SetUnSlottedCsmaCa();
625 
626  m_channelScanIndex = 0;
627 
628  // Mark primitive as pending and save the scan params while the new page and/or channel is set.
631 
632  LrWpanPhyPibAttributes pibAttr;
633  pibAttr.phyCurrentPage = params.m_chPage;
634  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, &pibAttr);
635 }
636 
637 void
639 {
640  NS_LOG_FUNCTION(this);
641 
642  // Association is typically preceded by beacon reception and a MLME-SCAN.request, therefore,
643  // the values of the Associate.request params usually come from the information
644  // obtained from those operations.
647  bool invalidRequest = false;
648 
649  if (params.m_coordPanId == 0xffff)
650  {
651  invalidRequest = true;
652  }
653 
654  if (!invalidRequest && params.m_coordAddrMode == SHORT_ADDR)
655  {
656  if (params.m_coordShortAddr == Mac16Address("ff:ff") ||
657  params.m_coordShortAddr == Mac16Address("ff:fe"))
658  {
659  invalidRequest = true;
660  }
661  }
662  else if (!invalidRequest && params.m_coordAddrMode == EXT_ADDR)
663  {
664  if (params.m_coordExtAddr == Mac64Address("ff:ff:ff:ff:ff:ff:ff:ff") ||
665  params.m_coordExtAddr == Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed"))
666  {
667  invalidRequest = true;
668  }
669  }
670 
671  if (invalidRequest)
672  {
675  NS_LOG_ERROR(this << " Invalid PAN id in Association request");
677  {
678  MlmeAssociateConfirmParams confirmParams;
679  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
680  confirmParams.m_status = MLMEASSOC_INVALID_PARAMETER;
681  m_mlmeAssociateConfirmCallback(confirmParams);
682  }
683  }
684  else
685  {
686  LrWpanPhyPibAttributes pibAttr;
687  pibAttr.phyCurrentPage = params.m_chPage;
688  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentPage, &pibAttr);
689  }
690 }
691 
692 void
694 {
695  // the primitive is no longer pending (channel & page are set)
697  // As described in IEEE 802.15.4-2011 (Section 5.1.3.1)
700  {
702  }
703  else
704  {
707  }
708 
710 }
711 
712 void
714 {
715  // Associate Short Address (m_assocShortAddr)
716  // FF:FF = Association Request failed
717  // FF:FE = The association request is accepted, but the device should use its extended address
718  // Other = The assigned short address by the coordinator
719 
720  NS_LOG_FUNCTION(this);
721 
723  m_macDsn++;
724  LrWpanMacTrailer macTrailer;
725  Ptr<Packet> commandPacket = Create<Packet>();
726 
727  // Mac header Assoc. Response Comm. See 802.15.4-2011 (Section 5.3.2.1)
730  macHdr.SetPanIdComp();
731  macHdr.SetDstAddrFields(m_macPanId, params.m_extDevAddr);
732  macHdr.SetSrcAddrFields(0xffff, GetExtendedAddress());
733 
735  macPayload.SetShortAddr(params.m_assocShortAddr);
736  switch (params.m_status)
737  {
740  break;
743  break;
746  break;
748  NS_LOG_ERROR("Error, Associated without address");
749  break;
751  NS_LOG_ERROR("Error, device not associated");
752  break;
753  }
754 
755  macHdr.SetSecDisable();
756  macHdr.SetAckReq();
757 
758  commandPacket->AddHeader(macPayload);
759  commandPacket->AddHeader(macHdr);
760 
761  // Calculate FCS if the global attribute ChecksumEnable is set.
762  if (Node::ChecksumEnabled())
763  {
764  macTrailer.EnableFcs(true);
765  macTrailer.SetFcs(commandPacket);
766  }
767 
768  commandPacket->AddTrailer(macTrailer);
769 
770  // Save packet in the Pending Transaction list.
771  EnqueueInd(commandPacket);
772 }
773 
774 void
776 {
777  NS_LOG_FUNCTION(this);
778  NS_ASSERT(params.m_logCh <= 26 && m_macPanId != 0xffff);
779 
780  uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
781  // change phy current logical channel
782  LrWpanPhyPibAttributes pibAttr;
783  pibAttr.phyCurrentChannel = params.m_logCh;
784  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, &pibAttr);
785 
786  // Enable Phy receiver
787  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
788 
789  uint64_t searchSymbols;
790  Time searchBeaconTime;
791 
793  {
795  }
796 
797  if (params.m_trackBcn)
798  {
799  m_numLostBeacons = 0;
800  // search for a beacon for a time = incomingSuperframe symbols + 960 symbols
801  searchSymbols =
803  searchBeaconTime = Seconds((double)searchSymbols / symbolRate);
804  m_beaconTrackingOn = true;
806  Simulator::Schedule(searchBeaconTime, &LrWpanMac::BeaconSearchTimeout, this);
807  }
808  else
809  {
810  m_beaconTrackingOn = false;
811  }
812 }
813 
814 void
816 {
817  NS_LOG_FUNCTION(this);
818 
820  m_macBsn++;
821 
823 
824  Ptr<Packet> beaconPacket = Create<Packet>();
825  // TODO: complete poll request (part of indirect transmissions)
826  NS_FATAL_ERROR(this << " Poll request currently not supported");
827 }
828 
829 void
831 {
832  MlmeSetConfirmParams confirmParams;
833  switch (id)
834  {
835  case macBeaconPayload:
836  if (attribute->macBeaconPayload->GetSize() > lrwpan::aMaxBeaconPayloadLenght)
837  {
838  confirmParams.m_status = MLMESET_INVALID_PARAMETER;
839  }
840  else
841  {
842  confirmParams.m_status = MLMESET_SUCCESS;
843  m_macBeaconPayload = attribute->macBeaconPayload;
844  m_macBeaconPayloadLength = attribute->macBeaconPayload->GetSize();
845  }
846  break;
848  confirmParams.m_status = MLMESET_INVALID_PARAMETER;
849  break;
850  default:
851  // TODO: Add support for setting other attributes
852  confirmParams.m_status = MLMESET_UNSUPPORTED_ATTRIBUTE;
853  break;
854  }
855 
857  {
858  confirmParams.id = id;
859  m_mlmeSetConfirmCallback(confirmParams);
860  }
861 }
862 
863 void
865 {
866  NS_LOG_FUNCTION(this);
868 
870  m_macBsn++;
871  BeaconPayloadHeader macPayload;
872  Ptr<Packet> beaconPacket;
873  LrWpanMacTrailer macTrailer;
874 
875  if (m_macBeaconPayload == nullptr)
876  {
877  beaconPacket = Create<Packet>();
878  }
879  else
880  {
881  beaconPacket = m_macBeaconPayload;
882  }
883 
885  macHdr.SetDstAddrFields(GetPanId(), Mac16Address("ff:ff"));
886 
887  // see IEEE 802.15.4-2011 Section 5.1.2.4
888  if (GetShortAddress() == Mac16Address("ff:fe"))
889  {
892  }
893  else
894  {
897  }
898 
899  macHdr.SetSecDisable();
900  macHdr.SetNoAckReq();
901 
903  macPayload.SetGtsFields(GetGtsFields());
905 
906  beaconPacket->AddHeader(macPayload);
907  beaconPacket->AddHeader(macHdr);
908 
909  // Calculate FCS if the global attribute ChecksumEnable is set.
910  if (Node::ChecksumEnabled())
911  {
912  macTrailer.EnableFcs(true);
913  macTrailer.SetFcs(beaconPacket);
914  }
915 
916  beaconPacket->AddTrailer(macTrailer);
917 
918  // Set the Beacon packet to be transmitted
919  m_txPkt = beaconPacket;
920 
921  if (m_csmaCa->IsSlottedCsmaCa())
922  {
924  NS_LOG_DEBUG("Outgoing superframe Active Portion (Beacon + CAP + CFP): "
925  << m_superframeDuration << " symbols");
926  }
927 
929  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
930 }
931 
932 void
934 {
935  NS_LOG_FUNCTION(this);
936 
938  m_macDsn++;
939  LrWpanMacTrailer macTrailer;
940  Ptr<Packet> commandPacket = Create<Packet>();
941 
942  // Beacon Request Command Mac header values See IEEE 802.15.4-2011 (Section 5.3.7)
943  macHdr.SetNoPanIdComp();
946 
947  macHdr.SetDstAddrFields(0xFFFF,
948  Mac16Address("FF:FF")); // Not associated PAN, broadcast dst address
949 
950  macHdr.SetSecDisable();
951  macHdr.SetNoAckReq();
952 
953  CommandPayloadHeader macPayload;
955 
956  commandPacket->AddHeader(macPayload);
957  commandPacket->AddHeader(macHdr);
958 
959  // Calculate FCS if the global attribute ChecksumEnable is set.
960  if (Node::ChecksumEnabled())
961  {
962  macTrailer.EnableFcs(true);
963  macTrailer.SetFcs(commandPacket);
964  }
965 
966  commandPacket->AddTrailer(macTrailer);
967 
968  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
969  txQElement->txQPkt = commandPacket;
970  EnqueueTxQElement(txQElement);
971  CheckQueue();
972 }
973 
974 void
976 {
977  NS_LOG_FUNCTION(this);
978 
980  m_macDsn++;
981  LrWpanMacTrailer macTrailer;
982  Ptr<Packet> commandPacket = Create<Packet>();
983 
984  // Assoc. Req. Comm. Mac header values See IEEE 802.15.4-2011 (Section 5.3.1.1)
986  macHdr.SetSrcAddrFields(0xffff, GetExtendedAddress());
987 
989  {
992  }
993  else
994  {
997  }
998 
999  macHdr.SetSecDisable();
1000  macHdr.SetAckReq();
1001 
1004 
1005  commandPacket->AddHeader(macPayload);
1006  commandPacket->AddHeader(macHdr);
1007 
1008  // Calculate FCS if the global attribute ChecksumEnable is set.
1009  if (Node::ChecksumEnabled())
1010  {
1011  macTrailer.EnableFcs(true);
1012  macTrailer.SetFcs(commandPacket);
1013  }
1014 
1015  commandPacket->AddTrailer(macTrailer);
1016 
1017  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1018  txQElement->txQPkt = commandPacket;
1019  EnqueueTxQElement(txQElement);
1020  CheckQueue();
1021 }
1022 
1023 void
1025 {
1026  // See IEEE 802.15.4-2011 (Section 5.3.5)
1027  // This command can be sent for 3 different situations:
1028  // a) In response to a beacon indicating that there is data for the device.
1029  // b) Triggered by MLME-POLL.request.
1030  // c) To follow an ACK of an Association Request command and continue the associate process.
1031 
1032  // TODO: Implementation of a) and b) will be done when Indirect transmissions are fully
1033  // supported.
1034  // for now, only case c) is considered.
1035 
1036  NS_LOG_FUNCTION(this);
1037 
1039  m_macDsn++;
1040  LrWpanMacTrailer macTrailer;
1041  Ptr<Packet> commandPacket = Create<Packet>();
1042 
1043  // Mac Header values (Section 5.3.5)
1045  macHdr.SetSrcAddrFields(0xffff, m_selfExt);
1046 
1047  if (m_macCoordShortAddress == Mac16Address("ff:fe"))
1048  {
1051  }
1052  else
1053  {
1056  }
1057 
1058  macHdr.SetSecDisable();
1059  macHdr.SetAckReq();
1060 
1062 
1063  commandPacket->AddHeader(macPayload);
1064  commandPacket->AddHeader(macHdr);
1065 
1066  // Calculate FCS if the global attribute ChecksumEnable is set.
1067  if (Node::ChecksumEnabled())
1068  {
1069  macTrailer.EnableFcs(true);
1070  macTrailer.SetFcs(commandPacket);
1071  }
1072 
1073  commandPacket->AddTrailer(macTrailer);
1074 
1075  // Set the Command packet to be transmitted
1076  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1077  txQElement->txQPkt = commandPacket;
1078  EnqueueTxQElement(txQElement);
1079  CheckQueue();
1080 }
1081 
1082 void
1084 {
1085  LrWpanMacHeader receivedMacHdr;
1086  rxDataReqPkt->RemoveHeader(receivedMacHdr);
1087  CommandPayloadHeader receivedMacPayload;
1088  rxDataReqPkt->RemoveHeader(receivedMacPayload);
1089 
1091 
1092  Ptr<IndTxQueueElement> indTxQElement = Create<IndTxQueueElement>();
1093  bool elementFound;
1094  elementFound = DequeueInd(receivedMacHdr.GetExtSrcAddr(), indTxQElement);
1095  if (elementFound)
1096  {
1097  Ptr<TxQueueElement> txQElement = Create<TxQueueElement>();
1098  txQElement->txQPkt = indTxQElement->txQPkt;
1099  m_txQueue.emplace_back(txQElement);
1100  }
1101  else
1102  {
1103  NS_LOG_DEBUG("Requested element not found in pending list");
1104  }
1105 }
1106 
1107 void
1109 {
1110  // Association response command was not received, return to default values.
1111  m_macPanId = 0xffff;
1113  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
1114 
1116  {
1117  MlmeAssociateConfirmParams confirmParams;
1118  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
1119  confirmParams.m_status = MLMEASSOC_NO_DATA;
1120  m_mlmeAssociateConfirmCallback(confirmParams);
1121  }
1122 }
1123 
1124 void
1126 {
1127  NS_LOG_FUNCTION(this);
1128  // The primitive is no longer pending (Channel & Page have been set)
1130 
1131  if (m_startParams.m_coorRealgn) // Coordinator Realignment
1132  {
1133  // TODO: Send realignment request command frame in CSMA/CA
1134  NS_LOG_ERROR(this << " Coordinator realignment request not supported");
1135  return;
1136  }
1137  else
1138  {
1140  {
1141  m_panCoor = true;
1143  }
1144 
1145  NS_ASSERT(m_startParams.m_PanId != 0xffff);
1146 
1148  if (m_macBeaconOrder == 15)
1149  {
1150  // Non-beacon enabled PAN
1151  // Cancel any ongoing events and CSMA-CA process
1152  m_macSuperframeOrder = 15;
1153  m_fnlCapSlot = 15;
1154  m_beaconInterval = 0;
1155 
1156  m_csmaCa->Cancel();
1157  m_capEvent.Cancel();
1158  m_cfpEvent.Cancel();
1162  m_scanEvent.Cancel();
1164 
1165  m_csmaCa->SetUnSlottedCsmaCa();
1166 
1168  {
1169  MlmeStartConfirmParams confirmParams;
1170  confirmParams.m_status = MLMESTART_SUCCESS;
1171  m_mlmeStartConfirmCallback(confirmParams);
1172  }
1173 
1174  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
1175  }
1176  else
1177  {
1179  m_csmaCa->SetBatteryLifeExtension(m_startParams.m_battLifeExt);
1180 
1181  m_csmaCa->SetSlottedCsmaCa();
1182 
1183  // TODO: Calculate the real Final CAP slot (requires GTS implementation)
1184  // FinalCapSlot = Superframe duration slots - CFP slots.
1185  // In the current implementation the value of the final cap slot is equal to
1186  // the total number of possible slots in the superframe (15).
1187  m_fnlCapSlot = 15;
1188 
1190  (static_cast<uint32_t>(1 << m_macBeaconOrder)) * lrwpan::aBaseSuperframeDuration;
1191  m_superframeDuration = (static_cast<uint32_t>(1 << m_macSuperframeOrder)) *
1193 
1194  // TODO: change the beacon sending according to the startTime parameter (if not PAN
1195  // coordinator)
1196 
1198  }
1199  }
1200 }
1201 
1202 void
1204 {
1205  NS_LOG_FUNCTION(this);
1206 
1208 
1209  bool channelFound = false;
1210 
1211  for (int i = m_channelScanIndex; i <= 26; i++)
1212  {
1213  if ((m_scanParams.m_scanChannels & (1 << m_channelScanIndex)) != 0)
1214  {
1215  channelFound = true;
1216  break;
1217  }
1219  }
1220 
1221  if (channelFound)
1222  {
1223  // Switch to the next channel in the list and restart scan
1224  LrWpanPhyPibAttributes pibAttr;
1226  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, &pibAttr);
1227  }
1228  else
1229  {
1230  // All scans on the channel list completed
1231  // Return to the MAC values previous to start of the first scan.
1233  m_macPanIdScan = 0;
1234 
1235  // TODO: restart beacon transmissions that were active before the beginning of the scan
1236  // (i.e when a coordinator perform a scan and it was already transmitting beacons)
1237 
1238  // All channels scanned, report success
1239  MlmeScanConfirmParams confirmParams;
1240  confirmParams.m_status = MLMESCAN_SUCCESS;
1241  confirmParams.m_chPage = m_scanParams.m_chPage;
1242  confirmParams.m_scanType = m_scanParams.m_scanType;
1243  confirmParams.m_energyDetList = {};
1244  confirmParams.m_panDescList = m_panDescriptorList;
1245 
1247  {
1248  m_mlmeScanConfirmCallback(confirmParams);
1249  }
1250 
1252  m_channelScanIndex = 0;
1253  m_scanParams = {};
1254  }
1255 }
1256 
1257 void
1259 {
1260  NS_LOG_FUNCTION(this);
1261  // Add the results of channel energy scan to the detectList
1263  m_maxEnergyLevel = 0;
1264 
1266 
1267  bool channelFound = false;
1268  for (int i = m_channelScanIndex; i <= 26; i++)
1269  {
1270  if ((m_scanParams.m_scanChannels & (1 << m_channelScanIndex)) != 0)
1271  {
1272  channelFound = true;
1273  break;
1274  }
1276  }
1277 
1278  if (channelFound)
1279  {
1280  // switch to the next channel in the list and restart scan
1281  LrWpanPhyPibAttributes pibAttr;
1283  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel, &pibAttr);
1284  }
1285  else
1286  {
1287  // Scan on all channels on the list completed
1288  // Return to the MAC values previous to start of the first scan.
1290  m_macPanIdScan = 0;
1291 
1292  // TODO: restart beacon transmissions that were active before the beginning of the scan
1293  // (i.e when a coordinator perform a scan and it was already transmitting beacons)
1294 
1295  // All channels scanned, report success
1297  {
1298  MlmeScanConfirmParams confirmParams;
1299  confirmParams.m_status = MLMESCAN_SUCCESS;
1300  confirmParams.m_chPage = m_phy->GetCurrentPage();
1301  confirmParams.m_scanType = m_scanParams.m_scanType;
1302  confirmParams.m_energyDetList = m_energyDetectList;
1303  m_mlmeScanConfirmCallback(confirmParams);
1304  }
1306  m_channelScanIndex = 0;
1307  m_scanParams = {};
1308  }
1309 }
1310 
1311 void
1313 {
1314  uint32_t activeSlot;
1315  uint64_t capDuration;
1316  Time endCapTime;
1317  uint64_t symbolRate;
1318 
1319  symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1320 
1321  if (superframeType == OUTGOING)
1322  {
1324  activeSlot = m_superframeDuration / 16;
1325  capDuration = activeSlot * (m_fnlCapSlot + 1);
1326  endCapTime = Seconds((double)capDuration / symbolRate);
1327  // Obtain the end of the CAP by adjust the time it took to send the beacon
1328  endCapTime -= (Simulator::Now() - m_macBeaconTxTime);
1329 
1330  NS_LOG_DEBUG("Outgoing superframe CAP duration " << (endCapTime.GetSeconds() * symbolRate)
1331  << " symbols (" << endCapTime.As(Time::S)
1332  << ")");
1333  NS_LOG_DEBUG("Active Slots duration " << activeSlot << " symbols");
1334 
1335  m_capEvent =
1337  }
1338  else
1339  {
1341  activeSlot = m_incomingSuperframeDuration / 16;
1342  capDuration = activeSlot * (m_incomingFnlCapSlot + 1);
1343  endCapTime = Seconds((double)capDuration / symbolRate);
1344  // Obtain the end of the CAP by adjust the time it took to receive the beacon
1345  endCapTime -= (Simulator::Now() - m_macBeaconRxTime);
1346 
1347  NS_LOG_DEBUG("Incoming superframe CAP duration " << (endCapTime.GetSeconds() * symbolRate)
1348  << " symbols (" << endCapTime.As(Time::S)
1349  << ")");
1350  NS_LOG_DEBUG("Active Slots duration " << activeSlot << " symbols");
1351 
1352  m_capEvent =
1354  }
1355 
1356  CheckQueue();
1357 }
1358 
1359 void
1361 {
1362  uint32_t activeSlot;
1363  uint64_t cfpDuration;
1364  Time endCfpTime;
1365  uint64_t symbolRate;
1366 
1367  symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1368 
1369  if (superframeType == INCOMING)
1370  {
1371  activeSlot = m_incomingSuperframeDuration / 16;
1372  cfpDuration = activeSlot * (15 - m_incomingFnlCapSlot);
1373  endCfpTime = Seconds((double)cfpDuration / symbolRate);
1374  if (cfpDuration > 0)
1375  {
1377  }
1378 
1379  NS_LOG_DEBUG("Incoming superframe CFP duration " << cfpDuration << " symbols ("
1380  << endCfpTime.As(Time::S) << ")");
1381 
1382  m_incCfpEvent = Simulator::Schedule(endCfpTime,
1384  this,
1386  }
1387  else
1388  {
1389  activeSlot = m_superframeDuration / 16;
1390  cfpDuration = activeSlot * (15 - m_fnlCapSlot);
1391  endCfpTime = Seconds((double)cfpDuration / symbolRate);
1392 
1393  if (cfpDuration > 0)
1394  {
1396  }
1397 
1398  NS_LOG_DEBUG("Outgoing superframe CFP duration " << cfpDuration << " symbols ("
1399  << endCfpTime.As(Time::S) << ")");
1400 
1401  m_cfpEvent = Simulator::Schedule(endCfpTime,
1403  this,
1405  }
1406  // TODO: Start transmit or receive GTS here.
1407 }
1408 
1409 void
1411 {
1412  uint64_t inactiveDuration;
1413  Time endInactiveTime;
1414  uint64_t symbolRate;
1415 
1416  symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1417 
1418  if (superframeType == INCOMING)
1419  {
1421  endInactiveTime = Seconds((double)inactiveDuration / symbolRate);
1422 
1423  if (inactiveDuration > 0)
1424  {
1426  }
1427 
1428  NS_LOG_DEBUG("Incoming superframe Inactive Portion duration "
1429  << inactiveDuration << " symbols (" << endInactiveTime.As(Time::S) << ")");
1430  m_beaconEvent = Simulator::Schedule(endInactiveTime, &LrWpanMac::AwaitBeacon, this);
1431  }
1432  else
1433  {
1434  inactiveDuration = m_beaconInterval - m_superframeDuration;
1435  endInactiveTime = Seconds((double)inactiveDuration / symbolRate);
1436 
1437  if (inactiveDuration > 0)
1438  {
1440  }
1441 
1442  NS_LOG_DEBUG("Outgoing superframe Inactive Portion duration "
1443  << inactiveDuration << " symbols (" << endInactiveTime.As(Time::S) << ")");
1444  m_beaconEvent = Simulator::Schedule(endInactiveTime, &LrWpanMac::SendOneBeacon, this);
1445  }
1446 }
1447 
1448 void
1450 {
1452 
1453  // TODO: If the device waits more than the expected time to receive the beacon (wait = 46
1454  // symbols for default beacon size)
1455  // it should continue with the start of the incoming CAP even if it did not receive the
1456  // beacon. At the moment, the start of the incoming CAP is only triggered if the beacon is
1457  // received. See MLME-SyncLoss for details.
1458 }
1459 
1460 void
1462 {
1463  uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1464 
1466  {
1467  MlmeSyncLossIndicationParams syncLossParams;
1468  // syncLossParams.m_logCh =
1469  syncLossParams.m_lossReason = MLMESYNCLOSS_BEACON_LOST;
1470  syncLossParams.m_panId = m_macPanId;
1471  m_mlmeSyncLossIndicationCallback(syncLossParams);
1472 
1473  m_beaconTrackingOn = false;
1474  m_numLostBeacons = 0;
1475  }
1476  else
1477  {
1478  m_numLostBeacons++;
1479 
1480  // Search for one more beacon
1481  uint64_t searchSymbols;
1482  Time searchBeaconTime;
1483  searchSymbols =
1485  searchBeaconTime = Seconds((double)searchSymbols / symbolRate);
1486  m_trackingEvent =
1487  Simulator::Schedule(searchBeaconTime, &LrWpanMac::BeaconSearchTimeout, this);
1488  }
1489 }
1490 
1491 void
1493 {
1494  NS_LOG_FUNCTION(this);
1495  // Pull a packet from the queue and start sending if we are not already sending.
1496  if (m_lrWpanMacState == MAC_IDLE && !m_txQueue.empty() && !m_setMacState.IsRunning())
1497  {
1498  // TODO: this should check if the node is a coordinator and using the outcoming superframe
1499  // not just the PAN coordinator
1500  if (m_csmaCa->IsUnSlottedCsmaCa() || (m_outSuperframeStatus == CAP && m_panCoor) ||
1502  {
1503  // check MAC is not in a IFS
1504  if (!m_ifsEvent.IsRunning())
1505  {
1506  Ptr<TxQueueElement> txQElement = m_txQueue.front();
1507  m_txPkt = txQElement->txQPkt;
1508 
1509  m_setMacState =
1511  }
1512  }
1513  }
1514 }
1515 
1518 {
1519  SuperframeField sfrmSpec;
1520 
1521  sfrmSpec.SetBeaconOrder(m_macBeaconOrder);
1523  sfrmSpec.SetFinalCapSlot(m_fnlCapSlot);
1524 
1525  if (m_csmaCa->GetBatteryLifeExtension())
1526  {
1527  sfrmSpec.SetBattLifeExt(true);
1528  }
1529 
1530  if (m_panCoor)
1531  {
1532  sfrmSpec.SetPanCoor(true);
1533  }
1534 
1535  // used to associate devices via Beacons
1537  {
1538  sfrmSpec.SetAssocPermit(true);
1539  }
1540 
1541  return sfrmSpec;
1542 }
1543 
1544 GtsFields
1546 {
1547  GtsFields gtsFields;
1548 
1549  // TODO: Logic to populate the GTS Fields from local information here
1550 
1551  return gtsFields;
1552 }
1553 
1556 {
1557  PendingAddrFields pndAddrFields;
1558 
1559  // TODO: Logic to populate the Pending Address Fields from local information here
1560  return pndAddrFields;
1561 }
1562 
1563 void
1565 {
1566  m_csmaCa = csmaCa;
1567 }
1568 
1569 void
1571 {
1572  m_phy = phy;
1573 }
1574 
1577 {
1578  return m_phy;
1579 }
1580 
1581 void
1583 {
1585 }
1586 
1587 void
1589 {
1591 }
1592 
1593 void
1595 {
1597 }
1598 
1599 void
1601 {
1603 }
1604 
1605 void
1607 {
1609 }
1610 
1611 void
1613 {
1615 }
1616 
1617 void
1619 {
1621 }
1622 
1623 void
1625 {
1627 }
1628 
1629 void
1631 {
1633 }
1634 
1635 void
1637 {
1639 }
1640 
1641 void
1643 {
1645 }
1646 
1647 void
1648 LrWpanMac::PdDataIndication(uint32_t psduLength, Ptr<Packet> p, uint8_t lqi)
1649 {
1652  NS_LOG_FUNCTION(this << psduLength << p << (uint16_t)lqi);
1653 
1654  bool acceptFrame;
1655 
1656  // from sec 7.5.6.2 Reception and rejection, Std802.15.4-2006
1657  // level 1 filtering, test FCS field and reject if frame fails
1658  // level 2 filtering if promiscuous mode pass frame to higher layer otherwise perform level 3
1659  // filtering level 3 filtering accept frame if Frame type and version is not reserved, and if
1660  // there is a dstPanId then dstPanId=m_macPanId or broadcastPanId, and if there is a
1661  // shortDstAddr then shortDstAddr =shortMacAddr or broadcastAddr, and if beacon frame then
1662  // srcPanId = m_macPanId if only srcAddr field in Data or Command frame,accept frame if
1663  // srcPanId=m_macPanId
1664 
1665  Ptr<Packet> originalPkt = p->Copy(); // because we will strip headers
1666  uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false); // symbols per second
1667  m_promiscSnifferTrace(originalPkt);
1668 
1669  m_macPromiscRxTrace(originalPkt);
1670  // XXX no rejection tracing (to macRxDropTrace) being performed below
1671 
1672  LrWpanMacTrailer receivedMacTrailer;
1673  p->RemoveTrailer(receivedMacTrailer);
1674  if (Node::ChecksumEnabled())
1675  {
1676  receivedMacTrailer.EnableFcs(true);
1677  }
1678 
1679  // level 1 filtering
1680  if (!receivedMacTrailer.CheckFcs(p))
1681  {
1682  m_macRxDropTrace(originalPkt);
1683  }
1684  else
1685  {
1686  LrWpanMacHeader receivedMacHdr;
1687  p->RemoveHeader(receivedMacHdr);
1688 
1690  params.m_dsn = receivedMacHdr.GetSeqNum();
1691  params.m_mpduLinkQuality = lqi;
1692  params.m_srcPanId = receivedMacHdr.GetSrcPanId();
1693  params.m_srcAddrMode = receivedMacHdr.GetSrcAddrMode();
1694  switch (params.m_srcAddrMode)
1695  {
1696  case SHORT_ADDR:
1697  params.m_srcAddr = receivedMacHdr.GetShortSrcAddr();
1698  break;
1699  case EXT_ADDR:
1700  params.m_srcExtAddr = receivedMacHdr.GetExtSrcAddr();
1701  break;
1702  default:
1703  break;
1704  }
1705  params.m_dstPanId = receivedMacHdr.GetDstPanId();
1706  params.m_dstAddrMode = receivedMacHdr.GetDstAddrMode();
1707  switch (params.m_dstAddrMode)
1708  {
1709  case SHORT_ADDR:
1710  params.m_dstAddr = receivedMacHdr.GetShortDstAddr();
1711  break;
1712  case EXT_ADDR:
1713  params.m_dstExtAddr = receivedMacHdr.GetExtDstAddr();
1714  break;
1715  default:
1716  break;
1717  }
1718 
1720  {
1721  // level 2 filtering
1722  if (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR)
1723  {
1724  NS_LOG_DEBUG("Packet from " << params.m_srcAddr);
1725  NS_LOG_DEBUG("Packet to " << params.m_dstAddr);
1726  }
1727  else if (receivedMacHdr.GetDstAddrMode() == EXT_ADDR)
1728  {
1729  NS_LOG_DEBUG("Packet from " << params.m_srcExtAddr);
1730  NS_LOG_DEBUG("Packet to " << params.m_dstExtAddr);
1731  }
1732 
1733  // TODO: Fix here, this should trigger different Indication Callbacks
1734  // depending the type of frame received (data,command, beacon)
1736  {
1737  NS_LOG_DEBUG("promiscuous mode, forwarding up");
1739  }
1740  else
1741  {
1742  NS_LOG_ERROR(this << " Data Indication Callback not initialized");
1743  }
1744  }
1745  else
1746  {
1747  // level 3 frame filtering
1748  acceptFrame = (receivedMacHdr.GetType() != LrWpanMacHeader::LRWPAN_MAC_RESERVED);
1749 
1750  if (acceptFrame)
1751  {
1752  acceptFrame = (receivedMacHdr.GetFrameVer() <= 1);
1753  }
1754 
1755  if (acceptFrame && (receivedMacHdr.GetDstAddrMode() > 1))
1756  {
1757  // Accept frame if:
1758 
1759  // 1) Have the same macPanId
1760  // 2) Or is Message to all PANs
1761  // 3) Or Is a beacon and the macPanId is not present (bootstrap)
1762  acceptFrame = ((receivedMacHdr.GetDstPanId() == m_macPanId ||
1763  receivedMacHdr.GetDstPanId() == 0xffff) ||
1764  (m_macPanId == 0xffff && receivedMacHdr.IsBeacon())) ||
1765  (m_macPanId == 0xffff && receivedMacHdr.IsCommand());
1766  }
1767 
1768  if (acceptFrame && (receivedMacHdr.GetShortDstAddr() == Mac16Address("FF:FF")))
1769  {
1770  // A broadcast message (e.g. beacons) should not be received by the device who
1771  // issues it.
1772  acceptFrame = (receivedMacHdr.GetShortSrcAddr() != GetShortAddress());
1773  // TODO: shouldn't this be filtered by the PHY?
1774  }
1775 
1776  if (acceptFrame && (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR))
1777  {
1778  if (receivedMacHdr.GetShortDstAddr() == m_shortAddress)
1779  {
1780  // unicast, for me
1781  acceptFrame = true;
1782  }
1783  else if (receivedMacHdr.GetShortDstAddr().IsBroadcast() ||
1784  receivedMacHdr.GetShortDstAddr().IsMulticast())
1785  {
1786  // broadcast or multicast
1787  if (receivedMacHdr.IsAckReq())
1788  {
1789  // discard broadcast/multicast with the ACK bit set
1790  acceptFrame = false;
1791  }
1792  else
1793  {
1794  acceptFrame = true;
1795  }
1796  }
1797  else
1798  {
1799  acceptFrame = false;
1800  }
1801  }
1802 
1803  if (acceptFrame && (receivedMacHdr.GetDstAddrMode() == EXT_ADDR))
1804  {
1805  acceptFrame = (receivedMacHdr.GetExtDstAddr() == m_selfExt);
1806  }
1807 
1808  // When PASSIVE or ACTIVE scan is running, reject any frames other than BEACON frames
1809  if (acceptFrame && (!receivedMacHdr.IsBeacon() && m_scanEvent.IsRunning()))
1810  {
1811  acceptFrame = false;
1812  }
1813 
1814  // Energy Scan is running, reject any frames
1816  {
1817  acceptFrame = false;
1818  }
1819 
1820  // Check device is panCoor with association permit when receiving Association Request
1821  // Commands.
1822  // TODO:: Simple coordinators should also be able to receive it (currently only Pan
1823  // Coordinators are checked)
1824  if (acceptFrame && (receivedMacHdr.IsCommand() && receivedMacHdr.IsAckReq()))
1825  {
1826  CommandPayloadHeader receivedMacPayload;
1827  p->PeekHeader(receivedMacPayload);
1828 
1829  if (receivedMacPayload.GetCommandFrameType() ==
1831  !(m_macAssociationPermit == true && m_panCoor == true))
1832  {
1833  acceptFrame = false;
1834  }
1835 
1836  // Although ACKs do not use CSMA to to be transmitted, we need to make sure
1837  // that the transmitted ACK will not collide with the transmission of a beacon
1838  // when beacon-enabled mode is running in the coordinator.
1839  if (acceptFrame && (m_csmaCa->IsSlottedCsmaCa() && m_capEvent.IsRunning()))
1840  {
1841  Time timeLeftInCap = Simulator::GetDelayLeft(m_capEvent);
1842  uint64_t ackSymbols = lrwpan::aTurnaroundTime + m_phy->GetPhySHRDuration() +
1843  ceil(6 * m_phy->GetPhySymbolsPerOctet());
1844  Time ackTime = Seconds((double)ackSymbols / symbolRate);
1845 
1846  if (ackTime >= timeLeftInCap)
1847  {
1848  NS_LOG_DEBUG("Command frame received but not enough time to transmit ACK "
1849  "before the end of CAP ");
1850  acceptFrame = false;
1851  }
1852  }
1853  }
1854 
1855  if (acceptFrame)
1856  {
1857  m_macRxTrace(originalPkt);
1858  // \todo: What should we do if we receive a frame while waiting for an ACK?
1859  // Especially if this frame has the ACK request bit set, should we reply with
1860  // an ACK, possibly missing the pending ACK?
1861 
1862  // If the received frame is a frame with the ACK request bit set, we immediately
1863  // send back an ACK. If we are currently waiting for a pending ACK, we assume the
1864  // ACK was lost and trigger a retransmission after sending the ACK.
1865  if ((receivedMacHdr.IsData() || receivedMacHdr.IsCommand()) &&
1866  receivedMacHdr.IsAckReq() &&
1867  !(receivedMacHdr.GetDstAddrMode() == SHORT_ADDR &&
1868  (receivedMacHdr.GetShortDstAddr().IsBroadcast() ||
1869  receivedMacHdr.GetShortDstAddr().IsMulticast())))
1870  {
1871  // If this is a data or mac command frame, which is not a broadcast or
1872  // multicast, with ack req set, generate and send an ack frame. If there is a
1873  // CSMA medium access in progress we cancel the medium access for sending the
1874  // ACK frame. A new transmission attempt will be started after the ACK was send.
1876  {
1879  }
1880  else if (m_lrWpanMacState == MAC_CSMA)
1881  {
1882  // \todo: If we receive a packet while doing CSMA/CA, should we drop the
1883  // packet because of channel busy,
1884  // or should we restart CSMA/CA for the packet after sending the ACK?
1885  // Currently we simply restart CSMA/CA after sending the ACK.
1886  NS_LOG_DEBUG("Received a packet with ACK required while in CSMA. Cancel "
1887  "current CSMA-CA");
1888  m_csmaCa->Cancel();
1889  }
1890  // Cancel any pending MAC state change, ACKs have higher priority.
1893 
1894  // save received packet to process the appropriate indication/response after
1895  // sending ACK (PD-DATA.confirm)
1896  m_rxPkt = originalPkt->Copy();
1897 
1898  // LOG Commands with ACK required.
1899  CommandPayloadHeader receivedMacPayload;
1900  p->PeekHeader(receivedMacPayload);
1901  switch (receivedMacPayload.GetCommandFrameType())
1902  {
1904  NS_LOG_DEBUG("Data Request Command Received; processing ACK");
1905  break;
1907  NS_LOG_DEBUG("Association Request Command Received; processing ACK");
1908  break;
1910  m_assocResCmdWaitTimeout.Cancel(); // cancel event to a lost assoc resp cmd.
1911  NS_LOG_DEBUG("Association Response Command Received; processing ACK");
1912  break;
1913  default:
1914  break;
1915  }
1916 
1918  this,
1919  receivedMacHdr.GetSeqNum());
1920  }
1921 
1922  if (receivedMacHdr.GetDstAddrMode() == SHORT_ADDR)
1923  {
1924  NS_LOG_DEBUG("Packet from " << params.m_srcAddr);
1925  NS_LOG_DEBUG("Packet to " << params.m_dstAddr);
1926  }
1927  else if (receivedMacHdr.GetDstAddrMode() == EXT_ADDR)
1928  {
1929  NS_LOG_DEBUG("Packet from " << params.m_srcExtAddr);
1930  NS_LOG_DEBUG("Packet to " << params.m_dstExtAddr);
1931  }
1932 
1933  if (receivedMacHdr.IsBeacon())
1934  {
1935  // The received beacon size in symbols
1936  // Beacon = 5 bytes Sync Header (SHR) + 1 byte PHY header (PHR) + PSDU (default
1937  // 17 bytes)
1938  m_rxBeaconSymbols = m_phy->GetPhySHRDuration() +
1939  1 * m_phy->GetPhySymbolsPerOctet() +
1940  (originalPkt->GetSize() * m_phy->GetPhySymbolsPerOctet());
1941 
1942  // The start of Rx beacon time and start of the Incoming superframe Active
1943  // Period
1945  Simulator::Now() - Seconds(double(m_rxBeaconSymbols) / symbolRate);
1946 
1947  NS_LOG_DEBUG("Beacon Received; forwarding up (m_macBeaconRxTime: "
1948  << m_macBeaconRxTime.As(Time::S) << ")");
1949 
1950  BeaconPayloadHeader receivedMacPayload;
1951  p->RemoveHeader(receivedMacPayload);
1952 
1953  // Fill the PAN descriptor
1954  PanDescriptor panDescriptor;
1955 
1956  if (receivedMacHdr.GetSrcAddrMode() == SHORT_ADDR)
1957  {
1958  panDescriptor.m_coorAddrMode = SHORT_ADDR;
1959  panDescriptor.m_coorShortAddr = receivedMacHdr.GetShortSrcAddr();
1960  }
1961  else
1962  {
1963  panDescriptor.m_coorAddrMode = EXT_ADDR;
1964  panDescriptor.m_coorExtAddr = receivedMacHdr.GetExtSrcAddr();
1965  }
1966 
1967  panDescriptor.m_coorPanId = receivedMacHdr.GetSrcPanId();
1968  panDescriptor.m_gtsPermit = receivedMacPayload.GetGtsFields().GetGtsPermit();
1969  panDescriptor.m_linkQuality = lqi;
1970  panDescriptor.m_logChPage = m_phy->GetCurrentPage();
1971  panDescriptor.m_logCh = m_phy->GetCurrentChannelNum();
1972  panDescriptor.m_superframeSpec = receivedMacPayload.GetSuperframeSpecField();
1973  panDescriptor.m_timeStamp = m_macBeaconRxTime;
1974 
1975  // Process beacon when device belongs to a PAN (associated device)
1976  if (!m_scanEvent.IsRunning() && m_macPanId == receivedMacHdr.GetDstPanId())
1977  {
1978  // We need to make sure to cancel any possible ongoing unslotted CSMA/CA
1979  // operations when receiving a beacon (e.g. Those taking place at the
1980  // beginning of an Association).
1981  m_csmaCa->Cancel();
1982 
1983  SuperframeField incomingSuperframe;
1984  incomingSuperframe = receivedMacPayload.GetSuperframeSpecField();
1985 
1986  m_incomingBeaconOrder = incomingSuperframe.GetBeaconOrder();
1987  m_incomingSuperframeOrder = incomingSuperframe.GetFrameOrder();
1988  m_incomingFnlCapSlot = incomingSuperframe.GetFinalCapSlot();
1989 
1991  (static_cast<uint32_t>(1 << m_incomingBeaconOrder)) *
1995  (static_cast<uint32_t>(1 << m_incomingSuperframeOrder));
1996 
1997  if (incomingSuperframe.IsBattLifeExt())
1998  {
1999  m_csmaCa->SetBatteryLifeExtension(true);
2000  }
2001  else
2002  {
2003  m_csmaCa->SetBatteryLifeExtension(false);
2004  }
2005 
2006  if (m_incomingBeaconOrder < 15 && !m_csmaCa->IsSlottedCsmaCa())
2007  {
2008  m_csmaCa->SetSlottedCsmaCa();
2009  }
2010 
2011  // TODO: get Incoming frame GTS Fields here
2012 
2013  // Begin CAP on the current device using info from the Incoming superframe
2014  NS_LOG_DEBUG("Incoming superframe Active Portion (Beacon + CAP + CFP): "
2015  << m_incomingSuperframeDuration << " symbols");
2017  this,
2019  m_setMacState =
2021  }
2022  else if (!m_scanEvent.IsRunning() && m_macPanId == 0xFFFF)
2023  {
2024  NS_LOG_DEBUG(this << " Device not associated, cannot process beacon");
2025  }
2026 
2027  if (m_macAutoRequest)
2028  {
2029  if (p->GetSize() > 0)
2030  {
2032  {
2033  // The beacon contains payload, send the beacon notification.
2034  MlmeBeaconNotifyIndicationParams beaconParams;
2035  beaconParams.m_bsn = receivedMacHdr.GetSeqNum();
2036  beaconParams.m_panDescriptor = panDescriptor;
2037  beaconParams.m_sduLength = p->GetSize();
2038  beaconParams.m_sdu = p;
2040  }
2041  }
2042 
2043  if (m_scanEvent.IsRunning())
2044  {
2045  // Channel scanning is taking place, save only unique PAN descriptors
2046  bool descriptorExists = false;
2047 
2048  for (const auto& descriptor : m_panDescriptorList)
2049  {
2050  if (descriptor.m_coorAddrMode == SHORT_ADDR)
2051  {
2052  // Found a coordinator in PAN descriptor list with the same
2053  // registered short address
2054  descriptorExists =
2055  (descriptor.m_coorShortAddr ==
2056  panDescriptor.m_coorShortAddr &&
2057  descriptor.m_coorPanId == panDescriptor.m_coorPanId);
2058  }
2059  else
2060  {
2061  // Found a coordinator in PAN descriptor list with the same
2062  // registered extended address
2063  descriptorExists =
2064  (descriptor.m_coorExtAddr == panDescriptor.m_coorExtAddr &&
2065  descriptor.m_coorPanId == panDescriptor.m_coorPanId);
2066  }
2067 
2068  if (descriptorExists)
2069  {
2070  break;
2071  }
2072  }
2073 
2074  if (!descriptorExists)
2075  {
2076  m_panDescriptorList.push_back(panDescriptor);
2077  }
2078  return;
2079  }
2080  else if (m_trackingEvent.IsRunning())
2081  {
2082  // check if MLME-SYNC.request was previously issued and running
2083  // Sync. is necessary to handle pending messages (indirect
2084  // transmissions)
2086  m_numLostBeacons = 0;
2087 
2088  if (m_beaconTrackingOn)
2089  {
2090  // if tracking option is on keep tracking the next beacon
2091  uint64_t searchSymbols;
2092  Time searchBeaconTime;
2093 
2094  searchSymbols =
2095  (static_cast<uint64_t>(1 << m_incomingBeaconOrder)) +
2097  searchBeaconTime =
2098  Seconds(static_cast<double>(searchSymbols / symbolRate));
2099  m_trackingEvent =
2100  Simulator::Schedule(searchBeaconTime,
2102  this);
2103  }
2104 
2105  PendingAddrFields pndAddrFields;
2106  pndAddrFields = receivedMacPayload.GetPndAddrFields();
2107 
2108  // TODO: Ignore pending data, and do not send data command request if
2109  // the address is in the GTS list.
2110  // If the address is not in the GTS list, then check if the
2111  // address is in the short address pending list or in the extended
2112  // address pending list and send a data command request.
2113  }
2114  }
2115  else
2116  {
2117  // m_macAutoRequest is FALSE
2118  // Data command request are not send, only the beacon notification.
2119  // see IEEE 802.15.4-2011 Section 6.2.4.1
2121  {
2122  MlmeBeaconNotifyIndicationParams beaconParams;
2123  beaconParams.m_bsn = receivedMacHdr.GetSeqNum();
2124  beaconParams.m_panDescriptor = panDescriptor;
2125  beaconParams.m_sduLength = p->GetSize();
2126  beaconParams.m_sdu = p;
2128  }
2129  }
2130  }
2131  else if (receivedMacHdr.IsCommand())
2132  {
2133  // Handle the reception of frame commands that do not require ACK (i.e. Beacon
2134  // Request Command)
2135  CommandPayloadHeader receivedMacPayload;
2136  p->PeekHeader(receivedMacPayload);
2137  if (receivedMacPayload.GetCommandFrameType() ==
2139  {
2140  // TODO: check that node is any coordinator not just pan coordinator
2141  if (m_csmaCa->IsUnSlottedCsmaCa() && m_panCoor)
2142  {
2143  SendOneBeacon();
2144  }
2145  else
2146  {
2147  m_macRxDropTrace(originalPkt);
2148  }
2149  }
2150  }
2151  else if (receivedMacHdr.IsData() && !m_mcpsDataIndicationCallback.IsNull())
2152  {
2153  // If it is a data frame, push it up the stack.
2154  NS_LOG_DEBUG("Data Packet is for me; forwarding up");
2156  }
2157  else if (receivedMacHdr.IsAcknowledgment() && m_txPkt &&
2159  {
2160  LrWpanMacHeader peekedMacHdr;
2161  m_txPkt->PeekHeader(peekedMacHdr);
2162  // If it is an ACK with the expected sequence number, finish the transmission
2163  if (receivedMacHdr.GetSeqNum() == peekedMacHdr.GetSeqNum())
2164  {
2167 
2168  // TODO: check if the IFS is the correct size after ACK.
2169  Time ifsWaitTime = Seconds((double)GetIfsSize() / symbolRate);
2170 
2171  // We received an ACK to a command
2172  if (peekedMacHdr.IsCommand())
2173  {
2174  // check the original sent command frame which belongs to this received
2175  // ACK
2176  Ptr<Packet> pkt = m_txPkt->Copy();
2177  LrWpanMacHeader macHdr;
2178  CommandPayloadHeader cmdPayload;
2179  pkt->RemoveHeader(macHdr);
2180  pkt->RemoveHeader(cmdPayload);
2181 
2182  switch (cmdPayload.GetCommandFrameType())
2183  {
2185  double symbolRate = m_phy->GetDataOrSymbolRate(false);
2186  Time waitTime = Seconds(static_cast<double>(m_macResponseWaitTime) /
2187  symbolRate);
2188  if (!m_beaconTrackingOn)
2189  {
2191  Simulator::Schedule(waitTime,
2193  this);
2194  }
2195  else
2196  {
2197  // TODO: The data must be extracted by the coordinator within
2198  // macResponseWaitTime on timeout, MLME-ASSOCIATE.confirm is set
2199  // with status NO_DATA, and this should trigger the cancellation
2200  // of the beacon tracking (MLME-SYNC.request trackBeacon
2201  // =FALSE)
2202  }
2203  break;
2204  }
2205 
2207  // MLME-comm-status.Indication generated as a result of an
2208  // association response command, therefore src and dst address use
2209  // extended mode (see 5.3.2.1)
2211  {
2212  MlmeCommStatusIndicationParams commStatusParams;
2213  commStatusParams.m_panId = m_macPanId;
2214  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2215  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2216  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2217  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2218  commStatusParams.m_status =
2220  m_mlmeCommStatusIndicationCallback(commStatusParams);
2221  }
2222  // Remove element from Pending Transaction List
2224  break;
2225  }
2226 
2228  // Schedule an event in case the Association Response Command never
2229  // reached this device during an association process.
2230  double symbolRate = m_phy->GetDataOrSymbolRate(false);
2231  Time waitTime = Seconds(
2232  static_cast<double>(m_assocRespCmdWaitTime) / symbolRate);
2234  Simulator::Schedule(waitTime,
2236  this);
2237 
2239  {
2240  MlmePollConfirmParams pollConfirmParams;
2241  pollConfirmParams.m_status =
2243  m_mlmePollConfirmCallback(pollConfirmParams);
2244  }
2245  break;
2246  }
2247 
2248  default: {
2249  // TODO: add response to other request commands (e.g. Orphan)
2250  break;
2251  }
2252  }
2253  }
2254  else
2255  {
2257  {
2258  Ptr<TxQueueElement> txQElement = m_txQueue.front();
2259  McpsDataConfirmParams confirmParams;
2260  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2261  confirmParams.m_status = IEEE_802_15_4_SUCCESS;
2262  m_mcpsDataConfirmCallback(confirmParams);
2263  }
2264  }
2265 
2266  // Ack was successfully received, wait for the Interframe Space (IFS) and
2267  // then proceed
2270  m_setMacState =
2272  m_ifsEvent = Simulator::Schedule(ifsWaitTime,
2274  this,
2275  ifsWaitTime);
2276  }
2277  else
2278  {
2279  // If it is an ACK with an unexpected sequence number, mark the current
2280  // transmission as failed and start a retransmit. (cf 7.5.6.4.3)
2282  if (!PrepareRetransmission())
2283  {
2286  this,
2287  MAC_IDLE);
2288  }
2289  else
2290  {
2293  this,
2294  MAC_CSMA);
2295  }
2296  }
2297  }
2298  }
2299  else
2300  {
2301  m_macRxDropTrace(originalPkt);
2302  }
2303  }
2304  }
2305 }
2306 
2307 void
2308 LrWpanMac::SendAck(uint8_t seqno)
2309 {
2310  NS_LOG_FUNCTION(this << static_cast<uint32_t>(seqno));
2311 
2313 
2314  // Generate a corresponding ACK Frame.
2316  LrWpanMacTrailer macTrailer;
2317  Ptr<Packet> ackPacket = Create<Packet>(0);
2318  ackPacket->AddHeader(macHdr);
2319  // Calculate FCS if the global attribute ChecksumEnable is set.
2320  if (Node::ChecksumEnabled())
2321  {
2322  macTrailer.EnableFcs(true);
2323  macTrailer.SetFcs(ackPacket);
2324  }
2325  ackPacket->AddTrailer(macTrailer);
2326 
2327  // Enqueue the ACK packet for further processing
2328  // when the transmitter is activated.
2329  m_txPkt = ackPacket;
2330 
2331  // Switch transceiver to TX mode. Proceed sending the Ack on confirm.
2333  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
2334 }
2335 
2336 void
2338 {
2339  if (m_txQueue.size() < m_maxTxQueueSize)
2340  {
2341  m_txQueue.emplace_back(txQElement);
2342  m_macTxEnqueueTrace(txQElement->txQPkt);
2343  }
2344  else
2345  {
2347  {
2348  McpsDataConfirmParams confirmParams;
2349  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2351  m_mcpsDataConfirmCallback(confirmParams);
2352  }
2353  NS_LOG_DEBUG("TX Queue with size " << m_txQueue.size() << " is full, dropping packet");
2354  m_macTxDropTrace(txQElement->txQPkt);
2355  }
2356 }
2357 
2358 void
2360 {
2361  Ptr<TxQueueElement> txQElement = m_txQueue.front();
2362  Ptr<const Packet> p = txQElement->txQPkt;
2363  m_numCsmacaRetry += m_csmaCa->GetNB() + 1;
2364 
2365  Ptr<Packet> pkt = p->Copy();
2366  LrWpanMacHeader hdr;
2367  pkt->RemoveHeader(hdr);
2368  if (!hdr.GetShortDstAddr().IsBroadcast() && !hdr.GetShortDstAddr().IsMulticast())
2369  {
2371  }
2372 
2373  txQElement->txQPkt = nullptr;
2374  txQElement = nullptr;
2375  m_txQueue.pop_front();
2376  m_txPkt = nullptr;
2377  m_retransmission = 0;
2378  m_numCsmacaRetry = 0;
2380 }
2381 
2382 void
2384 {
2385  NS_LOG_FUNCTION(this);
2386 
2387  // TODO: If we are a PAN coordinator and this was an indirect transmission,
2388  // we will not initiate a retransmission. Instead we wait for the data
2389  // being extracted after a new data request command.
2390  if (!PrepareRetransmission())
2391  {
2393  }
2394  else
2395  {
2397  }
2398 }
2399 
2400 void
2402 {
2403  uint64_t symbolRate = (uint64_t)m_phy->GetDataOrSymbolRate(false);
2404  Time lifsTime = Seconds((double)m_macLIFSPeriod / symbolRate);
2405  Time sifsTime = Seconds((double)m_macSIFSPeriod / symbolRate);
2406 
2407  if (ifsTime == lifsTime)
2408  {
2409  NS_LOG_DEBUG("LIFS of " << m_macLIFSPeriod << " symbols (" << ifsTime.As(Time::S)
2410  << ") completed ");
2411  }
2412  else if (ifsTime == sifsTime)
2413  {
2414  NS_LOG_DEBUG("SIFS of " << m_macSIFSPeriod << " symbols (" << ifsTime.As(Time::S)
2415  << ") completed ");
2416  }
2417  else
2418  {
2419  NS_LOG_DEBUG("Unknown IFS size (" << ifsTime.As(Time::S) << ") completed ");
2420  }
2421 
2422  m_macIfsEndTrace(ifsTime);
2423  CheckQueue();
2424 }
2425 
2426 bool
2428 {
2429  NS_LOG_FUNCTION(this);
2430 
2431  // Max retransmissions reached without receiving ACK,
2432  // send the proper indication/confirmation
2433  // according to the frame type and call drop trace.
2435  {
2436  LrWpanMacHeader peekedMacHdr;
2437  m_txPkt->PeekHeader(peekedMacHdr);
2438 
2439  if (peekedMacHdr.IsCommand())
2440  {
2442 
2443  Ptr<Packet> pkt = m_txPkt->Copy();
2444  LrWpanMacHeader macHdr;
2445  CommandPayloadHeader cmdPayload;
2446  pkt->RemoveHeader(macHdr);
2447  pkt->RemoveHeader(cmdPayload);
2448 
2449  switch (cmdPayload.GetCommandFrameType())
2450  {
2452  m_macPanId = 0xffff;
2454  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2457  m_csmaCa->SetUnSlottedCsmaCa();
2458  m_incomingBeaconOrder = 15;
2460 
2462  {
2463  MlmeAssociateConfirmParams confirmParams;
2464  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
2465  confirmParams.m_status = MLMEASSOC_NO_ACK;
2466  m_mlmeAssociateConfirmCallback(confirmParams);
2467  }
2468  break;
2469  }
2471  // IEEE 802.15.4-2006 (Section 7.1.3.3.3 and 7.1.8.2.3)
2473  {
2474  MlmeCommStatusIndicationParams commStatusParams;
2475  commStatusParams.m_panId = m_macPanId;
2476  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2477  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
2478  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2479  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
2481  m_mlmeCommStatusIndicationCallback(commStatusParams);
2482  }
2484  break;
2485  }
2487  // IEEE 802.15.4-2006 (Section 7.1.16.1.3)
2488  m_macPanId = 0xffff;
2490  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2493  m_csmaCa->SetUnSlottedCsmaCa();
2494  m_incomingBeaconOrder = 15;
2496 
2498  {
2499  MlmePollConfirmParams pollConfirmParams;
2501  m_mlmePollConfirmCallback(pollConfirmParams);
2502  }
2503  break;
2504  }
2505  default: {
2506  // TODO: Specify other indications according to other commands
2507  break;
2508  }
2509  }
2510  }
2511  else
2512  {
2513  // Maximum number of retransmissions has been reached.
2514  // remove the copy of the DATA packet that was just sent
2515  Ptr<TxQueueElement> txQElement = m_txQueue.front();
2516  m_macTxDropTrace(txQElement->txQPkt);
2518  {
2519  McpsDataConfirmParams confirmParams;
2520  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2521  confirmParams.m_status = IEEE_802_15_4_NO_ACK;
2522  m_mcpsDataConfirmCallback(confirmParams);
2523  }
2524  }
2525 
2527  return false;
2528  }
2529  else
2530  {
2531  m_retransmission++;
2532  m_numCsmacaRetry += m_csmaCa->GetNB() + 1;
2533  // Start next CCA process for this packet.
2534  return true;
2535  }
2536 }
2537 
2538 void
2540 {
2541  Ptr<IndTxQueueElement> indTxQElement = Create<IndTxQueueElement>();
2542  LrWpanMacHeader peekedMacHdr;
2543  p->PeekHeader(peekedMacHdr);
2544 
2545  PurgeInd();
2546 
2547  NS_ASSERT(peekedMacHdr.GetDstAddrMode() == SHORT_ADDR ||
2548  peekedMacHdr.GetDstAddrMode() == EXT_ADDR);
2549 
2550  if (peekedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2551  {
2552  indTxQElement->dstShortAddress = peekedMacHdr.GetShortDstAddr();
2553  }
2554  else
2555  {
2556  indTxQElement->dstExtAddress = peekedMacHdr.GetExtDstAddr();
2557  }
2558 
2559  indTxQElement->seqNum = peekedMacHdr.GetSeqNum();
2560 
2561  // See IEEE 802.15.4-2006, Table 86
2562  uint32_t unit = 0; // The persistence time in symbols
2563  if (m_macBeaconOrder == 15)
2564  {
2565  // Non-beacon enabled mode
2567  }
2568  else
2569  {
2570  // Beacon-enabled mode
2571  unit = ((static_cast<uint32_t>(1) << m_macBeaconOrder) * lrwpan::aBaseSuperframeDuration) *
2573  }
2574 
2575  if (m_indTxQueue.size() < m_maxIndTxQueueSize)
2576  {
2577  double symbolRate = m_phy->GetDataOrSymbolRate(false);
2578  Time expireTime = Seconds(unit / symbolRate);
2579  expireTime += Simulator::Now();
2580  indTxQElement->expireTime = expireTime;
2581  indTxQElement->txQPkt = p;
2582  m_indTxQueue.emplace_back(indTxQElement);
2584  }
2585  else
2586  {
2588  {
2589  LrWpanMacHeader peekedMacHdr;
2590  indTxQElement->txQPkt->PeekHeader(peekedMacHdr);
2591  MlmeCommStatusIndicationParams commStatusParams;
2592  commStatusParams.m_panId = m_macPanId;
2593  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2594  commStatusParams.m_srcExtAddr = peekedMacHdr.GetExtSrcAddr();
2595  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2596  commStatusParams.m_dstExtAddr = peekedMacHdr.GetExtDstAddr();
2597  commStatusParams.m_status = MLMECOMMSTATUS_TRANSACTION_OVERFLOW;
2598  m_mlmeCommStatusIndicationCallback(commStatusParams);
2599  }
2601  }
2602 }
2603 
2604 bool
2606 {
2607  PurgeInd();
2608 
2609  for (auto iter = m_indTxQueue.begin(); iter != m_indTxQueue.end(); iter++)
2610  {
2611  if ((*iter)->dstExtAddress == dst)
2612  {
2613  *entry = **iter;
2614  m_macIndTxDequeueTrace((*iter)->txQPkt->Copy());
2615  m_indTxQueue.erase(iter);
2616  return true;
2617  }
2618  }
2619  return false;
2620 }
2621 
2622 void
2624 {
2625  for (uint32_t i = 0; i < m_indTxQueue.size();)
2626  {
2627  if (Simulator::Now() > m_indTxQueue[i]->expireTime)
2628  {
2629  // Transaction expired, remove and send proper confirmation/indication to a higher layer
2630  LrWpanMacHeader peekedMacHdr;
2631  m_indTxQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2632 
2633  if (peekedMacHdr.IsCommand())
2634  {
2635  // IEEE 802.15.4-2006 (Section 7.1.3.3.3)
2637  {
2638  MlmeCommStatusIndicationParams commStatusParams;
2639  commStatusParams.m_panId = m_macPanId;
2640  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
2641  commStatusParams.m_srcExtAddr = peekedMacHdr.GetExtSrcAddr();
2642  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
2643  commStatusParams.m_dstExtAddr = peekedMacHdr.GetExtDstAddr();
2644  commStatusParams.m_status =
2646  m_mlmeCommStatusIndicationCallback(commStatusParams);
2647  }
2648  }
2649  else if (peekedMacHdr.IsData())
2650  {
2651  // IEEE 802.15.4-2006 (Section 7.1.1.1.3)
2653  {
2654  McpsDataConfirmParams confParams;
2656  m_mcpsDataConfirmCallback(confParams);
2657  }
2658  }
2659  m_macIndTxDropTrace(m_indTxQueue[i]->txQPkt->Copy());
2660  m_indTxQueue.erase(m_indTxQueue.begin() + i);
2661  }
2662  else
2663  {
2664  i++;
2665  }
2666  }
2667 }
2668 
2669 void
2670 LrWpanMac::PrintPendTxQ(std::ostream& os) const
2671 {
2672  LrWpanMacHeader peekedMacHdr;
2673 
2674  os << "Pending Transaction List [" << GetShortAddress() << " | " << GetExtendedAddress()
2675  << "] | CurrentTime: " << Simulator::Now().As(Time::S) << "\n"
2676  << " Destination | Sequence Number | Frame type | Expire time\n";
2677 
2678  for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
2679  {
2680  m_indTxQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2681  os << m_indTxQueue[i]->dstExtAddress << " "
2682  << static_cast<uint32_t>(m_indTxQueue[i]->seqNum) << " ";
2683 
2684  if (peekedMacHdr.IsCommand())
2685  {
2686  os << "Cmd Frame ";
2687  }
2688  else if (peekedMacHdr.IsData())
2689  {
2690  os << "Data Frame ";
2691  }
2692  else
2693  {
2694  os << "Unk Frame ";
2695  }
2696 
2697  os << m_indTxQueue[i]->expireTime.As(Time::S) << "\n";
2698  }
2699 }
2700 
2701 void
2702 LrWpanMac::PrintTxQueue(std::ostream& os) const
2703 {
2704  LrWpanMacHeader peekedMacHdr;
2705 
2706  os << "\nTx Queue [" << GetShortAddress() << " | " << GetExtendedAddress()
2707  << "] | CurrentTime: " << Simulator::Now().As(Time::S) << "\n"
2708  << " Destination | Sequence Number | Dst PAN id | Frame type |\n";
2709 
2710  for (uint32_t i = 0; i < m_indTxQueue.size(); i++)
2711  {
2712  m_txQueue[i]->txQPkt->PeekHeader(peekedMacHdr);
2713 
2714  os << "[" << peekedMacHdr.GetShortDstAddr() << "]"
2715  << ", [" << peekedMacHdr.GetExtDstAddr() << "] "
2716  << static_cast<uint32_t>(peekedMacHdr.GetSeqNum()) << " "
2717  << peekedMacHdr.GetDstPanId() << " ";
2718 
2719  if (peekedMacHdr.IsCommand())
2720  {
2721  os << "Cmd Frame ";
2722  }
2723  else if (peekedMacHdr.IsData())
2724  {
2725  os << "Data Frame ";
2726  }
2727  else
2728  {
2729  os << "Unk Frame ";
2730  }
2731 
2732  os << "\n";
2733  }
2734  os << "\n";
2735 }
2736 
2737 void
2739 {
2740  LrWpanMacHeader peekedMacHdr;
2741  p->PeekHeader(peekedMacHdr);
2742 
2743  for (auto it = m_indTxQueue.begin(); it != m_indTxQueue.end(); it++)
2744  {
2745  if (peekedMacHdr.GetDstAddrMode() == EXT_ADDR)
2746  {
2747  if (((*it)->dstExtAddress == peekedMacHdr.GetExtDstAddr()) &&
2748  ((*it)->seqNum == peekedMacHdr.GetSeqNum()))
2749  {
2751  m_indTxQueue.erase(it);
2752  break;
2753  }
2754  }
2755  else if (peekedMacHdr.GetDstAddrMode() == SHORT_ADDR)
2756  {
2757  if (((*it)->dstShortAddress == peekedMacHdr.GetShortDstAddr()) &&
2758  ((*it)->seqNum == peekedMacHdr.GetSeqNum()))
2759  {
2761  m_indTxQueue.erase(it);
2762  break;
2763  }
2764  }
2765  }
2766 
2767  p = nullptr;
2768 }
2769 
2770 void
2772 {
2774  NS_LOG_FUNCTION(this << status << m_txQueue.size());
2775 
2776  LrWpanMacHeader macHdr;
2777  Time ifsWaitTime;
2778  double symbolRate;
2779 
2780  symbolRate = m_phy->GetDataOrSymbolRate(false); // symbols per second
2781 
2782  m_txPkt->PeekHeader(macHdr);
2783 
2784  if (status == IEEE_802_15_4_PHY_SUCCESS)
2785  {
2786  if (!macHdr.IsAcknowledgment())
2787  {
2788  if (macHdr.IsBeacon())
2789  {
2790  // Start CAP only if we are in beacon mode (i.e. if slotted csma-ca is running)
2791  if (m_csmaCa->IsSlottedCsmaCa())
2792  {
2793  // The Tx Beacon in symbols
2794  // Beacon = 5 bytes Sync Header (SHR) + 1 byte PHY header (PHR) + PSDU (default
2795  // 17 bytes)
2796  uint64_t beaconSymbols = m_phy->GetPhySHRDuration() +
2797  1 * m_phy->GetPhySymbolsPerOctet() +
2798  (m_txPkt->GetSize() * m_phy->GetPhySymbolsPerOctet());
2799 
2800  // The beacon Tx time and start of the Outgoing superframe Active Period
2802  Simulator::Now() - Seconds(static_cast<double>(beaconSymbols) / symbolRate);
2803 
2805  this,
2807  NS_LOG_DEBUG("Beacon Sent (m_macBeaconTxTime: " << m_macBeaconTxTime.As(Time::S)
2808  << ")");
2809 
2811  {
2812  MlmeStartConfirmParams mlmeConfirmParams;
2813  mlmeConfirmParams.m_status = MLMESTART_SUCCESS;
2814  m_mlmeStartConfirmCallback(mlmeConfirmParams);
2815  }
2816  }
2817 
2818  ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
2819  m_txPkt = nullptr;
2820  }
2821  else if (macHdr.IsAckReq()) // We have sent a regular data packet, check if we have to
2822  // wait for an ACK.
2823  {
2824  // we sent a regular data frame or command frame (e.g. AssocReq command) that
2825  // require ACK wait for the ack or the next retransmission timeout start
2826  // retransmission timer
2827  Time waitTime = Seconds(static_cast<double>(GetMacAckWaitDuration()) / symbolRate);
2831  m_setMacState =
2833  return;
2834  }
2835  else if (macHdr.IsCommand())
2836  {
2837  // We handle commands that do not require ACK (e.g. BeaconReq command)
2838  // other command are handle by the previous if statement.
2840  }
2841  else
2842  {
2844  // remove the copy of the packet that was just sent
2846  {
2847  McpsDataConfirmParams confirmParams;
2848  NS_ASSERT_MSG(!m_txQueue.empty(), "TxQsize = 0");
2849  Ptr<TxQueueElement> txQElement = m_txQueue.front();
2850  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2851  confirmParams.m_status = IEEE_802_15_4_SUCCESS;
2852  m_mcpsDataConfirmCallback(confirmParams);
2853  }
2854  ifsWaitTime = Seconds(static_cast<double>(GetIfsSize()) / symbolRate);
2856  }
2857  }
2858  else
2859  {
2860  // The packet sent was a successful ACK
2861 
2862  // Check the received frame before the transmission of the ACK,
2863  // and send the appropriate Indication or Confirmation
2864  Ptr<Packet> recvOriginalPkt = m_rxPkt->Copy();
2865  LrWpanMacHeader receivedMacHdr;
2866  recvOriginalPkt->RemoveHeader(receivedMacHdr);
2867 
2868  if (receivedMacHdr.IsCommand())
2869  {
2870  CommandPayloadHeader receivedMacPayload;
2871  recvOriginalPkt->RemoveHeader(receivedMacPayload);
2872 
2873  if (receivedMacPayload.GetCommandFrameType() ==
2875  {
2877  {
2878  MlmeAssociateIndicationParams associateParams;
2879  associateParams.capabilityInfo = receivedMacPayload.GetCapabilityField();
2880  associateParams.m_extDevAddr = receivedMacHdr.GetExtSrcAddr();
2881  m_mlmeAssociateIndicationCallback(associateParams);
2882  }
2883 
2884  // Clear the packet buffer for the packet request received.
2885  m_rxPkt = nullptr;
2886  }
2887  else if (receivedMacPayload.GetCommandFrameType() ==
2889  {
2890  MlmeAssociateConfirmParams confirmParams;
2891 
2892  switch (receivedMacPayload.GetAssociationStatus())
2893  {
2895  confirmParams.m_status =
2897  // The original short address used in the association
2898  // used in the association request
2899  confirmParams.m_assocShortAddr = GetShortAddress();
2900 
2901  // The assigned short address by the coordinator
2902  SetShortAddress(receivedMacPayload.GetShortAddr());
2903  m_macPanId = receivedMacHdr.GetSrcPanId();
2904  break;
2906  confirmParams.m_status =
2908  m_macPanId = 0xffff;
2910  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2913  m_csmaCa->SetUnSlottedCsmaCa();
2914  m_incomingBeaconOrder = 15;
2916  break;
2918  confirmParams.m_status =
2920  m_macPanId = 0xffff;
2922  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
2925  m_csmaCa->SetUnSlottedCsmaCa();
2926  m_incomingBeaconOrder = 15;
2928  break;
2929  }
2930 
2932  {
2933  m_mlmeAssociateConfirmCallback(confirmParams);
2934  }
2935  }
2936  else if (receivedMacPayload.GetCommandFrameType() == CommandPayloadHeader::DATA_REQ)
2937  {
2938  // We enqueue the the Assoc Response command frame in the Tx queue
2939  // and the packet is transmitted as soon as the PHY is free and the IFS have
2940  // taken place.
2942  }
2943  }
2944 
2945  // Clear the packet buffer for the ACK packet sent.
2946  m_txPkt = nullptr;
2947  }
2948  }
2949  else if (status == IEEE_802_15_4_PHY_UNSPECIFIED)
2950  {
2951  if (!macHdr.IsAcknowledgment())
2952  {
2953  NS_ASSERT_MSG(!m_txQueue.empty(), "TxQsize = 0");
2954  Ptr<TxQueueElement> txQElement = m_txQueue.front();
2955  m_macTxDropTrace(txQElement->txQPkt);
2957  {
2958  McpsDataConfirmParams confirmParams;
2959  confirmParams.m_msduHandle = txQElement->txQMsduHandle;
2960  confirmParams.m_status = IEEE_802_15_4_FRAME_TOO_LONG;
2961  m_mcpsDataConfirmCallback(confirmParams);
2962  }
2964  }
2965  else
2966  {
2967  NS_LOG_ERROR("Unable to send ACK");
2968  }
2969  }
2970  else
2971  {
2972  // Something went really wrong. The PHY is not in the correct state for
2973  // data transmission.
2974  NS_FATAL_ERROR("Transmission attempt failed with PHY status " << status);
2975  }
2976 
2977  if (!ifsWaitTime.IsZero())
2978  {
2979  m_ifsEvent =
2980  Simulator::Schedule(ifsWaitTime, &LrWpanMac::IfsWaitTimeout, this, ifsWaitTime);
2981  }
2982 
2985 }
2986 
2987 void
2989 {
2990  NS_LOG_FUNCTION(this << status);
2991  // Direct this call through the csmaCa object
2992  m_csmaCa->PlmeCcaConfirm(status);
2993 }
2994 
2995 void
2997 {
2998  NS_LOG_FUNCTION(this << status << energyLevel);
2999 
3000  if (energyLevel > m_maxEnergyLevel)
3001  {
3002  m_maxEnergyLevel = energyLevel;
3003  }
3004 
3006  Seconds(8.0 / m_phy->GetDataOrSymbolRate(false)))
3007  {
3008  m_phy->PlmeEdRequest();
3009  }
3010 }
3011 
3012 void
3015  LrWpanPhyPibAttributes* attribute)
3016 {
3017  NS_LOG_FUNCTION(this << status << id << attribute);
3018 }
3019 
3020 void
3022 {
3023  NS_LOG_FUNCTION(this << status);
3024 
3025  if (m_lrWpanMacState == MAC_SENDING &&
3026  (status == IEEE_802_15_4_PHY_TX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
3027  {
3028  NS_ASSERT(m_txPkt);
3029 
3030  // Start sending if we are in state SENDING and the PHY transmitter was enabled.
3034  m_phy->PdDataRequest(m_txPkt->GetSize(), m_txPkt);
3035  }
3036  else if (m_lrWpanMacState == MAC_CSMA &&
3037  (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS))
3038  {
3039  // Start the CSMA algorithm as soon as the receiver is enabled.
3040  m_csmaCa->Start();
3041  }
3042  else if (m_lrWpanMacState == MAC_IDLE)
3043  {
3045  status == IEEE_802_15_4_PHY_TRX_OFF);
3046 
3048  {
3049  // Kick start Energy Detection Scan
3050  m_phy->PlmeEdRequest();
3051  }
3052  else if (status == IEEE_802_15_4_PHY_RX_ON || status == IEEE_802_15_4_PHY_SUCCESS)
3053  {
3054  // Check if there is not messages to transmit when going idle
3055  CheckQueue();
3056  }
3057  }
3058  else if (m_lrWpanMacState == MAC_ACK_PENDING)
3059  {
3061  }
3062  else
3063  {
3064  // TODO: What to do when we receive an error?
3065  // If we want to transmit a packet, but switching the transceiver on results
3066  // in an error, we have to recover somehow (and start sending again).
3067  NS_FATAL_ERROR("Error changing transceiver state");
3068  }
3069 }
3070 
3071 void
3073 {
3074  NS_LOG_FUNCTION(this << status << id);
3076  {
3078  {
3079  // get the first channel to scan from scan channel list
3080  bool channelFound = false;
3081  for (int i = m_channelScanIndex; i <= 26; i++)
3082  {
3083  if ((m_scanParams.m_scanChannels & (1 << m_channelScanIndex)) != 0)
3084  {
3085  channelFound = true;
3086  break;
3087  }
3089  }
3090 
3091  if (channelFound)
3092  {
3093  LrWpanPhyPibAttributes pibAttr;
3095  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel,
3096  &pibAttr);
3097  }
3098  }
3099  else
3100  {
3102  {
3103  MlmeScanConfirmParams confirmParams;
3104  confirmParams.m_scanType = m_scanParams.m_scanType;
3105  confirmParams.m_chPage = m_scanParams.m_chPage;
3106  confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3107  m_mlmeScanConfirmCallback(confirmParams);
3108  }
3109  NS_LOG_ERROR(this << "Channel Scan: Invalid channel page");
3110  }
3111  }
3114  {
3116  {
3117  uint64_t symbolRate = static_cast<uint64_t>(m_phy->GetDataOrSymbolRate(false));
3118  uint64_t scanDuration = lrwpan::aBaseSuperframeDuration *
3119  ((static_cast<uint32_t>(1 << m_scanParams.m_scanDuration)) + 1);
3120  Time nextScanTime = Seconds(static_cast<double>(scanDuration / symbolRate));
3121 
3122  switch (m_scanParams.m_scanType)
3123  {
3124  case MLMESCAN_ED:
3125  m_maxEnergyLevel = 0;
3128  // set phy to RX_ON and kick start the first PLME-ED.request
3129  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3130  break;
3131  case MLMESCAN_ACTIVE:
3134  break;
3135  case MLMESCAN_PASSIVE:
3137  // turn back the phy to RX_ON after setting Page/channel
3138  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3139  break;
3140  case MLMESCAN_ORPHAN:
3141  // TODO: add orphan scan support
3142  NS_LOG_ERROR("Scan Type currently not supported");
3143  break;
3144 
3145  default:
3146  MlmeScanConfirmParams confirmParams;
3147  confirmParams.m_scanType = m_scanParams.m_scanType;
3148  confirmParams.m_chPage = m_scanParams.m_chPage;
3149  confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3151  {
3152  m_mlmeScanConfirmCallback(confirmParams);
3153  }
3154  NS_LOG_ERROR("Scan Type currently not supported");
3155  return;
3156  }
3157  }
3158  else
3159  {
3161  {
3162  MlmeScanConfirmParams confirmParams;
3163  confirmParams.m_scanType = m_scanParams.m_scanType;
3164  confirmParams.m_chPage = m_scanParams.m_chPage;
3165  confirmParams.m_status = MLMESCAN_INVALID_PARAMETER;
3166  m_mlmeScanConfirmCallback(confirmParams);
3167  }
3168  NS_LOG_ERROR("Channel " << m_channelScanIndex
3169  << " could not be set in the current page");
3170  }
3171  }
3174  {
3176  {
3177  LrWpanPhyPibAttributes pibAttr;
3179  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel,
3180  &pibAttr);
3181  }
3182  else
3183  {
3185  {
3186  MlmeStartConfirmParams confirmParams;
3187  confirmParams.m_status = MLMESTART_INVALID_PARAMETER;
3188  m_mlmeStartConfirmCallback(confirmParams);
3189  }
3190  NS_LOG_ERROR("Invalid page parameter in MLME-start");
3191  }
3192  }
3195  {
3197  {
3198  EndStartRequest();
3199  }
3200  else
3201  {
3203  {
3204  MlmeStartConfirmParams confirmParams;
3205  confirmParams.m_status = MLMESTART_INVALID_PARAMETER;
3206  m_mlmeStartConfirmCallback(confirmParams);
3207  }
3208  NS_LOG_ERROR("Invalid channel parameter in MLME-start");
3209  }
3210  }
3213  {
3215  {
3216  LrWpanPhyPibAttributes pibAttr;
3218  m_phy->PlmeSetAttributeRequest(LrWpanPibAttributeIdentifier::phyCurrentChannel,
3219  &pibAttr);
3220  }
3221  else
3222  {
3223  m_macPanId = 0xffff;
3225  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3228  m_csmaCa->SetUnSlottedCsmaCa();
3229  m_incomingBeaconOrder = 15;
3231 
3233  {
3234  MlmeAssociateConfirmParams confirmParams;
3235  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3236  confirmParams.m_status = MLMEASSOC_INVALID_PARAMETER;
3237  m_mlmeAssociateConfirmCallback(confirmParams);
3238  }
3239  NS_LOG_ERROR("Invalid page parameter in MLME-associate");
3240  }
3241  }
3244  {
3246  {
3248  }
3249  else
3250  {
3251  m_macPanId = 0xffff;
3253  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3256  m_csmaCa->SetUnSlottedCsmaCa();
3257  m_incomingBeaconOrder = 15;
3259 
3261  {
3262  MlmeAssociateConfirmParams confirmParams;
3263  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3264  confirmParams.m_status = MLMEASSOC_INVALID_PARAMETER;
3265  m_mlmeAssociateConfirmCallback(confirmParams);
3266  }
3267  NS_LOG_ERROR("Invalid channel parameter in MLME-associate");
3268  }
3269  }
3270 }
3271 
3272 void
3274 {
3275  NS_LOG_FUNCTION(this << "mac state = " << macState);
3276 
3277  if (macState == MAC_IDLE)
3278  {
3280  if (m_macRxOnWhenIdle)
3281  {
3282  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3283  }
3284  else
3285  {
3286  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
3287  }
3288  }
3289  else if (macState == MAC_ACK_PENDING)
3290  {
3292  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3293  }
3294  else if (macState == MAC_CSMA)
3295  {
3298  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3299  }
3300  else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_IDLE)
3301  {
3302  // Channel is idle, set transmitter to TX_ON
3304  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TX_ON);
3305  }
3306  else if (m_lrWpanMacState == MAC_CSMA && macState == CHANNEL_ACCESS_FAILURE)
3307  {
3308  NS_ASSERT(m_txPkt);
3309 
3310  // Cannot find a clear channel, drop the current packet
3311  // and send the proper confirm/indication according to the packet type
3312  NS_LOG_DEBUG(this << " cannot find clear channel");
3313 
3315 
3316  Ptr<Packet> pkt = m_txPkt->Copy();
3317  LrWpanMacHeader macHdr;
3318  pkt->RemoveHeader(macHdr);
3319 
3320  if (macHdr.IsCommand())
3321  {
3322  CommandPayloadHeader cmdPayload;
3323  pkt->RemoveHeader(cmdPayload);
3324 
3325  switch (cmdPayload.GetCommandFrameType())
3326  {
3328  m_macPanId = 0xffff;
3330  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3333  m_csmaCa->SetUnSlottedCsmaCa();
3334  m_incomingBeaconOrder = 15;
3336 
3338  {
3339  MlmeAssociateConfirmParams confirmParams;
3340  confirmParams.m_assocShortAddr = Mac16Address("FF:FF");
3342  m_mlmeAssociateConfirmCallback(confirmParams);
3343  }
3344  break;
3345  }
3348  {
3349  MlmeCommStatusIndicationParams commStatusParams;
3350  commStatusParams.m_panId = m_macPanId;
3351  commStatusParams.m_srcAddrMode = LrWpanMacHeader::EXTADDR;
3352  commStatusParams.m_srcExtAddr = macHdr.GetExtSrcAddr();
3353  commStatusParams.m_dstAddrMode = LrWpanMacHeader::EXTADDR;
3354  commStatusParams.m_dstExtAddr = macHdr.GetExtDstAddr();
3355  commStatusParams.m_status =
3357  m_mlmeCommStatusIndicationCallback(commStatusParams);
3358  }
3360  break;
3361  }
3363  m_macPanId = 0xffff;
3365  m_macCoordExtendedAddress = Mac64Address("ff:ff:ff:ff:ff:ff:ff:ed");
3368  m_csmaCa->SetUnSlottedCsmaCa();
3369  m_incomingBeaconOrder = 15;
3371 
3373  {
3374  MlmePollConfirmParams pollConfirmParams;
3375  pollConfirmParams.m_status =
3377  m_mlmePollConfirmCallback(pollConfirmParams);
3378  }
3379  break;
3380  }
3381  default: {
3382  // TODO: Other commands(e.g. Orphan Request)
3383  break;
3384  }
3385  }
3387  }
3388  else if (macHdr.IsData())
3389  {
3391  {
3392  McpsDataConfirmParams confirmParams;
3393  confirmParams.m_msduHandle = m_txQueue.front()->txQMsduHandle;
3395  m_mcpsDataConfirmCallback(confirmParams);
3396  }
3397  // remove the copy of the packet that was just sent
3399  }
3400  else
3401  {
3402  // TODO:: specify behavior for other packets
3403  m_txPkt = nullptr;
3404  m_retransmission = 0;
3405  m_numCsmacaRetry = 0;
3406  }
3407 
3409  if (m_macRxOnWhenIdle)
3410  {
3411  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_RX_ON);
3412  }
3413  else
3414  {
3415  m_phy->PlmeSetTRXStateRequest(IEEE_802_15_4_PHY_TRX_OFF);
3416  }
3417  }
3418  else if (m_lrWpanMacState == MAC_CSMA && macState == MAC_CSMA_DEFERRED)
3419  {
3421  m_txPkt = nullptr;
3422  // The MAC is running on beacon mode and the current packet could not be sent in the
3423  // current CAP. The packet will be send on the next CAP after receiving the beacon.
3424  // The PHY state does not change from its current form. The PHY change (RX_ON) will be
3425  // triggered by the scheduled beacon event.
3426 
3427  NS_LOG_DEBUG("****** PACKET DEFERRED to the next superframe *****");
3428  }
3429 }
3430 
3433 {
3434  return m_associationStatus;
3435 }
3436 
3437 void
3439 {
3440  m_associationStatus = status;
3441 }
3442 
3443 void
3444 LrWpanMac::SetTxQMaxSize(uint32_t queueSize)
3445 {
3446  m_maxTxQueueSize = queueSize;
3447 }
3448 
3449 void
3450 LrWpanMac::SetIndTxQMaxSize(uint32_t queueSize)
3451 {
3452  m_maxIndTxQueueSize = queueSize;
3453 }
3454 
3455 uint16_t
3457 {
3458  return m_macPanId;
3459 }
3460 
3463 {
3464  return m_macCoordShortAddress;
3465 }
3466 
3469 {
3471 }
3472 
3473 void
3474 LrWpanMac::SetPanId(uint16_t panId)
3475 {
3476  m_macPanId = panId;
3477 }
3478 
3479 void
3481 {
3482  NS_LOG_LOGIC(this << " change lrwpan mac state from " << m_lrWpanMacState << " to "
3483  << newState);
3485  m_lrWpanMacState = newState;
3486 }
3487 
3488 uint64_t
3490 {
3491  return lrwpan::aUnitBackoffPeriod + lrwpan::aTurnaroundTime + m_phy->GetPhySHRDuration() +
3492  ceil(6 * m_phy->GetPhySymbolsPerOctet());
3493 }
3494 
3495 uint8_t
3497 {
3498  return m_macMaxFrameRetries;
3499 }
3500 
3501 void
3503 {
3504  NS_LOG_DEBUG("Transmit Queue Size: " << m_txQueue.size());
3505 }
3506 
3507 void
3509 {
3510  m_macMaxFrameRetries = retries;
3511 }
3512 
3513 bool
3515 {
3516  NS_ASSERT(m_txPkt);
3517  LrWpanMacHeader macHdr;
3518  m_txPkt->PeekHeader(macHdr);
3519 
3520  if (m_panCoor)
3521  {
3522  // The device is the PAN coordinator and the packet is not to itself
3523  return false;
3524  }
3525  else if (m_macCoordShortAddress == macHdr.GetShortDstAddr() ||
3527  {
3528  return true;
3529  }
3530  else
3531  {
3532  NS_LOG_DEBUG("ERROR: Packet not for the coordinator!");
3533  return false;
3534  }
3535 }
3536 
3537 uint32_t
3539 {
3540  NS_ASSERT(m_txPkt);
3541 
3543  {
3544  return m_macSIFSPeriod;
3545  }
3546  else
3547  {
3548  return m_macLIFSPeriod;
3549  }
3550 }
3551 
3552 void
3554 {
3556 }
3557 
3558 void
3560 {
3562 }
3563 
3564 uint64_t
3566 {
3567  NS_ASSERT(m_txPkt);
3568  // Sync Header (SHR) + 8 bits PHY header (PHR) + PSDU
3569  return (m_phy->GetPhySHRDuration() + 1 * m_phy->GetPhySymbolsPerOctet() +
3570  (m_txPkt->GetSize() * m_phy->GetPhySymbolsPerOctet()));
3571 }
3572 
3573 bool
3575 {
3576  NS_ASSERT(m_txPkt);
3577  LrWpanMacHeader macHdr;
3578  m_txPkt->PeekHeader(macHdr);
3579 
3580  return macHdr.IsAckReq();
3581 }
3582 
3583 } // namespace ns3
Implements the header for the MAC payload beacon frame according to the IEEE 802.15....
GtsFields GetGtsFields() const
Get the Guaranteed Time Slots (GTS) fields from the beacon payload header.
PendingAddrFields GetPndAddrFields() const
Get the pending address fields from the beacon payload header.
void SetSuperframeSpecField(SuperframeField sfrmField)
Set the superframe specification field to the beacon payload header.
void SetGtsFields(GtsFields gtsFields)
Set the superframe Guaranteed Time Slot (GTS) fields to the beacon payload header.
SuperframeField GetSuperframeSpecField() const
Get the superframe specification field from the beacon payload header.
void SetPndAddrFields(PendingAddrFields pndAddrFields)
Set the superframe Pending Address fields to the beacon payload header.
bool IsNull() const
Check for null implementation.
Definition: callback.h:572
Implements the header for the MAC payload command frame according to the IEEE 802....
@ SUCCESSFUL
Association successful.
CapabilityField GetCapabilityField() const
Get the Capability Information Field from the command payload header.
Mac16Address GetShortAddr() const
Get the Short address assigned by the coordinator (Association Response Command).
void SetCapabilityField(CapabilityField cap)
Set the Capability Information Field to the command payload header (Association Request Command).
AssocStatus GetAssociationStatus() const
Get the status resulting from an association request (Association Response Command).
void SetAssociationStatus(AssocStatus status)
Set status resulting from the association attempt (Association Response Command).
MacCommand GetCommandFrameType() const
Get the command frame type ID.
@ ASSOCIATION_RESP
Association response (RFD true: Rx)
@ BEACON_REQ
Beacon Request (RFD true: none )
@ DATA_REQ
Data Request (RFD true: Tx)
@ ASSOCIATION_REQ
Association request (RFD true: Tx)
void SetCommandFrameType(MacCommand macCmd)
Set the command frame type.
void SetShortAddr(Mac16Address shortAddr)
Set the Short Address Assigned by the coordinator (Association Response Command).
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
bool IsRunning() const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:76
Represent the GTS information fields.
bool GetGtsPermit() const
Get the GTS Specification Permit.
Represent the Mac Header with the Frame Control and Sequence Number fields.
Mac16Address GetShortSrcAddr() const
Get the Source Short address.
@ LRWPAN_MAC_BEACON
LRWPAN_MAC_BEACON.
@ LRWPAN_MAC_COMMAND
LRWPAN_MAC_COMMAND.
@ LRWPAN_MAC_DATA
LRWPAN_MAC_DATA.
@ LRWPAN_MAC_ACKNOWLEDGMENT
LRWPAN_MAC_ACKNOWLEDGMENT.
@ LRWPAN_MAC_RESERVED
LRWPAN_MAC_RESERVED.
bool IsCommand() const
Returns true if the header is a command.
bool IsBeacon() const
Returns true if the header is a beacon.
Mac64Address GetExtSrcAddr() const
Get the Source Extended address.
void SetNoPanIdComp()
Set the Frame Control field "PAN ID Compression" bit to false.
uint8_t GetSrcAddrMode() const
Get the Source Addressing Mode of Frame control field.
void SetPanIdComp()
Set the Frame Control field "PAN ID Compression" bit to true.
void SetSrcAddrMode(uint8_t addrMode)
Set the Source address mode.
uint8_t GetDstAddrMode() const
Get the Dest.
void SetSecDisable()
Set the Frame Control field "Security Enabled" bit to false.
void SetSrcAddrFields(uint16_t panId, Mac16Address addr)
Set Source address fields.
LrWpanMacType GetType() const
Get the header type.
bool IsAcknowledgment() const
Returns true if the header is an ack.
bool IsData() const
Returns true if the header is a data.
void SetDstAddrFields(uint16_t panId, Mac16Address addr)
Set Destination address fields.
uint8_t GetSeqNum() const
Get the frame Sequence number.
void SetDstAddrMode(uint8_t addrMode)
Set the Destination address mode.
void SetNoAckReq()
Set the Frame Control field "Ack. Request" bit to false.
Mac64Address GetExtDstAddr() const
Get the Destination Extended address.
uint16_t GetDstPanId() const
Get the Destination PAN ID.
uint8_t GetFrameVer() const
Get the Frame Version of Frame control field.
uint16_t GetSrcPanId() const
Get the Source PAN ID.
bool IsAckReq() const
Check if Ack.
Mac16Address GetShortDstAddr() const
Get the Destination Short address.
void SetAckReq()
Set the Frame Control field "Ack. Request" bit to true.
Class that implements the LR-WPAN MAC state machine.
Definition: lr-wpan-mac.h:769
uint32_t m_incomingBeaconInterval
Indication of the interval a node should receive a superframe expressed in symbols.
Definition: lr-wpan-mac.h:1381
uint32_t GetIfsSize()
Get the size of the Interframe Space according to MPDU size (m_txPkt).
Ptr< LrWpanCsmaCa > m_csmaCa
The CSMA/CA implementation used by this MAC.
Definition: lr-wpan-mac.h:1896
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:1182
McpsDataConfirmCallback m_mcpsDataConfirmCallback
This callback is used to report data transmission request status to the upper layers.
Definition: lr-wpan-mac.h:1968
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:1167
void PlmeCcaConfirm(LrWpanPhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.2.2 PLME-CCA.confirm status.
~LrWpanMac() override
Definition: lr-wpan-mac.cc:222
bool m_macRxOnWhenIdle
Indication of whether the MAC sublayer is to enable its receiver during idle periods.
Definition: lr-wpan-mac.h:1320
bool m_macAssociationPermit
Indication of whether a coordinator is currently allowing association.
Definition: lr-wpan-mac.h:1339
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:1793
void SetMlmeBeaconNotifyIndicationCallback(MlmeBeaconNotifyIndicationCallback c)
Set the callback for the indication of an incoming beacon packet.
uint64_t m_rxBeaconSymbols
The total size of the received beacon in symbols.
Definition: lr-wpan-mac.h:1237
void SetRxOnWhenIdle(bool rxOnWhenIdle)
Set if the receiver should be enabled when the MAC is idle.
Definition: lr-wpan-mac.cc:292
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:1363
void SetMlmeAssociateIndicationCallback(MlmeAssociateIndicationCallback c)
Set the callback for the indication of an incoming associate request command.
void PlmeSetTRXStateConfirm(LrWpanPhyEnumeration status)
IEEE 802.15.4-2006 section 6.2.2.8 PLME-SET-TRX-STATE.confirm Set PHY state.
uint8_t m_numCsmacaRetry
The number of CSMA/CA retries used for sending the current packet.
Definition: lr-wpan-mac.h:2083
void MlmeSyncRequest(MlmeSyncRequestParams params)
IEEE 802.15.4-2011, section 6.2.13.1 MLME-SYNC.request Request to synchronize with the coordinator by...
Definition: lr-wpan-mac.cc:775
static TypeId GetTypeId()
Get the type ID.
Definition: lr-wpan-mac.cc:51
MlmeStartConfirmCallback m_mlmeStartConfirmCallback
This callback is used to report the start of a new PAN or the begin of a new superframe configuration...
Definition: lr-wpan-mac.h:1943
uint8_t m_deviceCapability
Indication of current device capability (FFD or RFD)
Definition: lr-wpan-mac.h:1392
void AwaitBeacon()
Called after the end of an INCOMING superframe to start the moment a device waits for a new incoming ...
void LostAssocRespCommand()
Called after m_assocRespCmdWaitTime timeout while waiting for an association response command.
bool isCoordDest()
Check if the packet destination is its coordinator.
EventId m_trackingEvent
Scheduler event to track the incoming beacons.
Definition: lr-wpan-mac.h:2139
void SetMlmeScanConfirmCallback(MlmeScanConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
uint32_t m_maxIndTxQueueSize
The maximum size of the indirect transmit queue (The pending transaction list).
Definition: lr-wpan-mac.h:2032
EventId m_assocResCmdWaitTimeout
Scheduler event for the lost of a association response command frame.
Definition: lr-wpan-mac.h:2099
void PurgeInd()
Purge expired transactions from the pending transactions list.
void SetMlmePollConfirmCallback(MlmePollConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
void RemoveFirstTxQElement()
Remove the tip of the transmission queue, including clean up related to the last packet transmission.
void PlmeEdConfirm(LrWpanPhyEnumeration status, uint8_t energyLevel)
IEEE 802.15.4-2006 section 6.2.2.4 PLME-ED.confirm status and energy level.
TracedCallback< Ptr< const Packet > > m_macRxTrace
The trace source fired for packets successfully received by the device immediately before being forwa...
Definition: lr-wpan-mac.h:1827
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:1876
void SetExtendedAddress(Mac64Address address)
Set the extended address of this MAC.
Definition: lr-wpan-mac.cc:318
void MlmeStartRequest(MlmeStartRequestParams params)
IEEE 802.15.4-2006, section 7.1.14.1 MLME-START.request Request to allow a PAN coordinator to initiat...
Definition: lr-wpan-mac.cc:540
uint32_t m_macLIFSPeriod
The minimum time forming a Long InterFrame Spacing (LIFS) period.
Definition: lr-wpan-mac.h:1326
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:1801
void SetMcpsDataIndicationCallback(McpsDataIndicationCallback c)
Set the callback for the indication of an incoming data packet.
TracedCallback< Ptr< const Packet > > m_macIndTxDequeueTrace
The trace source fired when packets are dequeued from the L3/l2 indirect transmission queue (Pending ...
Definition: lr-wpan-mac.h:1777
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:1809
void SetMlmeAssociateConfirmCallback(MlmeAssociateConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
MlmeScanConfirmCallback m_mlmeScanConfirmCallback
This callback is used to report the result of a scan on a group of channels for the selected channel ...
Definition: lr-wpan-mac.h:1922
Mac16Address GetShortAddress() const
Get the short address of this MAC.
Definition: lr-wpan-mac.cc:325
void SendDataRequestCommand()
Used to send a data request command (i.e.
void SetMlmeStartConfirmCallback(MlmeStartConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
SuperframeField GetSuperframeField()
Constructs a Superframe specification field from the local information, the superframe Specification ...
EventId m_cfpEvent
Scheduler event for the end of the outgoing superframe CFP.
Definition: lr-wpan-mac.h:2124
uint8_t m_macMaxFrameRetries
The maximum number of retries allowed after a transmission failure.
Definition: lr-wpan-mac.h:1313
Mac64Address m_macCoordExtendedAddress
The extended address of the coordinator through which the device is associated.
Definition: lr-wpan-mac.h:1198
MlmeSyncLossIndicationCallback m_mlmeSyncLossIndicationCallback
This callback is used to indicate the loss of synchronization with a coordinator.
Definition: lr-wpan-mac.h:1915
PendingPrimitiveStatus m_pendPrimitive
Indicates the pending primitive when PLME.SET operation (page or channel switch) is called from withi...
Definition: lr-wpan-mac.h:2072
MlmePollConfirmCallback m_mlmePollConfirmCallback
This callback is used to report the status after a device send data command request to the coordinato...
Definition: lr-wpan-mac.h:1936
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:2066
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:2038
void SendBeaconRequestCommand()
Called to send a beacon request command.
Definition: lr-wpan-mac.cc:933
EventId m_respWaitTimeout
Scheduler event for a response to a request command frame.
Definition: lr-wpan-mac.h:2094
uint32_t m_maxTxQueueSize
The maximum size of the transmit queue.
Definition: lr-wpan-mac.h:2027
Ptr< Packet > m_macBeaconPayload
The contents of the beacon payload.
Definition: lr-wpan-mac.h:1301
std::deque< Ptr< TxQueueElement > > m_txQueue
The transmit queue used by the MAC.
Definition: lr-wpan-mac.h:2016
SequenceNumber8 m_macBsn
Sequence number added to transmitted beacon frame, 00-ff.
Definition: lr-wpan-mac.h:1294
LrWpanAssociationStatus m_associationStatus
The current association status of the MAC layer.
Definition: lr-wpan-mac.h:1988
Ptr< Packet > m_rxPkt
The command request packet received.
Definition: lr-wpan-mac.h:1999
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:1769
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:2006
uint8_t m_macSuperframeOrder
Used by a PAN coordinator or coordinator.
Definition: lr-wpan-mac.h:1220
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:2043
void PdDataIndication(uint32_t psduLength, Ptr< Packet > p, uint8_t lqi)
IEEE 802.15.4-2006 section 6.2.1.3 PD-DATA.indication Indicates the transfer of an MPDU from PHY to M...
void SendOneBeacon()
Called to send a single beacon frame.
Definition: lr-wpan-mac.cc:864
Time m_macBeaconTxTime
The time that the device transmitted its last beacon frame.
Definition: lr-wpan-mac.h:1159
MlmeBeaconNotifyIndicationCallback m_mlmeBeaconNotifyIndicationCallback
This callback is used to notify incoming beacon packets to the upper layers.
Definition: lr-wpan-mac.h:1909
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:1886
Mac64Address GetExtendedAddress() const
Get the extended address of this MAC.
Definition: lr-wpan-mac.cc:332
EventId m_setMacState
Scheduler event for a deferred MAC state change.
Definition: lr-wpan-mac.h:2104
uint64_t m_macResponseWaitTime
The maximum time, in multiples of aBaseSuperframeDuration, a device shall wait for a response command...
Definition: lr-wpan-mac.h:1174
void EnqueueInd(Ptr< Packet > p)
Adds a packet to the pending transactions list (Indirect transmissions).
void SendAssocResponseCommand(Ptr< Packet > rxDataReqPkt)
Called to send an associate response command.
void SetMlmeSetConfirmCallback(MlmeSetConfirmCallback c)
Set the callback for the confirmation of an attempt to write an attribute.
void StartCFP(SuperframeType superframeType)
Called to begin the Contention Free Period (CFP) in a beacon-enabled mode.
EventId m_scanEnergyEvent
Scheduler event for the end of a ED channel scan.
Definition: lr-wpan-mac.h:2149
void SetMcpsDataConfirmCallback(McpsDataConfirmCallback c)
Set the callback for the confirmation of a data transmission request.
bool PrepareRetransmission()
Check for remaining retransmissions for the packet currently being sent.
void SetAssociationStatus(LrWpanAssociationStatus status)
Set the current association status.
void MlmeAssociateRequest(MlmeAssociateRequestParams params)
IEEE 802.15.4-2011, section 6.2.2.1 MLME-ASSOCIATE.request Request primitive used by a device to requ...
Definition: lr-wpan-mac.cc:638
void EnqueueTxQElement(Ptr< TxQueueElement > txQElement)
Add an element to the transmission queue.
void SetPanId(uint16_t panId)
Set the PAN id used by this MAC.
EventId m_scanEvent
Scheduler event for the end of a channel scan.
Definition: lr-wpan-mac.h:2144
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:1856
uint8_t m_incomingBeaconOrder
The beaconOrder value of the INCOMING frame.
Definition: lr-wpan-mac.h:1249
SequenceNumber8 m_macDsn
Sequence number added to transmitted data or MAC command frame, 00-ff.
Definition: lr-wpan-mac.h:1288
void SetMlmeSyncLossIndicationCallback(MlmeSyncLossIndicationCallback c)
Set the callback for the loss of synchronization with a coordinator.
uint32_t m_ifs
The value of the necessary InterFrame Space after the transmission of a packet.
Definition: lr-wpan-mac.h:1358
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:1231
Mac16Address GetCoordShortAddress() const
Get the coordinator short address currently associated to this device.
void ChangeMacState(LrWpanMacState newState)
Change the current MAC state to the given new state.
void PlmeGetAttributeConfirm(LrWpanPhyEnumeration status, LrWpanPibAttributeIdentifier id, LrWpanPhyPibAttributes *attribute)
IEEE 802.15.4-2006 section 6.2.2.6 PLME-GET.confirm Get attributes per definition from Table 23 in se...
MlmeStartRequestParams m_startParams
The parameters used during a MLME-START.request.
Definition: lr-wpan-mac.h:2055
void AckWaitTimeout()
Handle an ACK timeout with a packet retransmission, if there are retransmission left,...
void MlmeScanRequest(MlmeScanRequestParams params)
IEEE 802.15.4-2011, section 6.2.10.1 MLME-SCAN.request Request primitive used to initiate a channel s...
Definition: lr-wpan-mac.cc:579
LrWpanAssociationStatus GetAssociationStatus() const
Get the current association status.
Mac64Address GetCoordExtAddress() const
Get the coordinator extended address currently associated to this device.
uint8_t m_macBeaconOrder
Used by a PAN coordinator or coordinator.
Definition: lr-wpan-mac.h:1212
TracedCallback< Time > m_macIfsEndTrace
The trace source is fired at the end of any Interframe Space (IFS).
Definition: lr-wpan-mac.h:1733
TracedValue< SuperframeStatus > m_outSuperframeStatus
The current period of the outgoing superframe.
Definition: lr-wpan-mac.h:1983
void PlmeSetAttributeConfirm(LrWpanPhyEnumeration status, LrWpanPibAttributeIdentifier id)
IEEE 802.15.4-2006 section 6.2.2.10 PLME-SET.confirm Set attributes per definition from Table 23 in s...
void SetMlmeCommStatusIndicationCallback(MlmeCommStatusIndicationCallback c)
Set the callback for the indication to a response primitive.
bool DequeueInd(Mac64Address dst, Ptr< IndTxQueueElement > entry)
Extracts a packet from pending transactions list (Indirect transmissions).
MlmeAssociateRequestParams m_associateParams
The parameters used during a MLME-ASSOCIATE.request.
Definition: lr-wpan-mac.h:2061
LrWpanMac()
Default constructor.
Definition: lr-wpan-mac.cc:162
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:2089
MlmeAssociateConfirmCallback m_mlmeAssociateConfirmCallback
This callback is used to report the status after a device request an association with a coordinator.
Definition: lr-wpan-mac.h:1929
bool m_macPromiscuousMode
Indicates if MAC sublayer is in receive all mode.
Definition: lr-wpan-mac.h:1269
uint8_t m_fnlCapSlot
Indication of the Slot where the CAP portion of the OUTGOING Superframe ends.
Definition: lr-wpan-mac.h:1242
uint32_t m_macSIFSPeriod
The minimum time forming a Short InterFrame Spacing (SIFS) period.
Definition: lr-wpan-mac.h:1332
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:2022
uint32_t m_beaconInterval
Indication of the Interval used by the coordinator to transmit beacon frames expressed in symbols.
Definition: lr-wpan-mac.h:1369
TracedValue< LrWpanMacState > m_lrWpanMacState
The current state of the MAC layer.
Definition: lr-wpan-mac.h:1973
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:1753
EventId m_capEvent
Scheduler event for the end of the outgoing superframe CAP.
Definition: lr-wpan-mac.h:2119
TracedCallback< Ptr< const Packet > > m_macTxTrace
The trace source fired when packets are being sent down to L1.
Definition: lr-wpan-mac.h:1784
uint16_t m_macPanId
16 bits id of PAN on which this device is operating.
Definition: lr-wpan-mac.h:1276
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:227
void MlmeAssociateResponse(MlmeAssociateResponseParams params)
IEEE 802.15.4-2011, section 6.2.2.3 MLME-ASSOCIATE.response Primitive used to initiate a response to ...
Definition: lr-wpan-mac.cc:713
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:1836
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:1348
uint8_t m_incomingSuperframeOrder
Used by all devices that have a parent.
Definition: lr-wpan-mac.h:1257
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:1282
uint32_t m_macBeaconPayloadLength
The length, in octets, of the beacon payload.
Definition: lr-wpan-mac.h:1307
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:1761
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:1402
Ptr< Packet > m_txPkt
The packet which is currently being sent by the MAC layer.
Definition: lr-wpan-mac.h:1993
void McpsDataRequest(McpsDataRequestParams params, Ptr< Packet > p)
IEEE 802.15.4-2006, section 7.1.1.1 MCPS-DATA.request Request to transfer a MSDU.
Definition: lr-wpan-mac.cc:339
void SendAssocRequestCommand()
Called to send an associate request command.
Definition: lr-wpan-mac.cc:975
uint8_t m_maxEnergyLevel
The maximum energy level detected during ED scan on the current channel.
Definition: lr-wpan-mac.h:1353
void DoDispose() override
Destructor implementation.
Definition: lr-wpan-mac.cc:242
MlmeScanRequestParams m_scanParams
The parameters used during a MLME-SCAN.request.
Definition: lr-wpan-mac.h:2049
MlmeAssociateIndicationCallback m_mlmeAssociateIndicationCallback
This callback is used to indicate the reception of an association request command.
Definition: lr-wpan-mac.h:1955
void SetPhy(Ptr< LrWpanPhy > phy)
Set the underlying PHY for the MAC.
Ptr< LrWpanPhy > GetPhy()
Get the underlying PHY of the MAC.
void EndAssociateRequest()
Called to end an MLME-ASSOCIATE.request after changing the page and channel number.
Definition: lr-wpan-mac.cc:693
MlmeSetConfirmCallback m_mlmeSetConfirmCallback
This callback is used to report the result of an attribute writing request to the upper layers.
Definition: lr-wpan-mac.h:1903
Mac64Address m_selfExt
The extended 64 address (IEEE EUI-64) used by this MAC.
Definition: lr-wpan-mac.h:2011
EventId m_incCapEvent
Scheduler event for the end of the incoming superframe CAP.
Definition: lr-wpan-mac.h:2129
void SetTxQMaxSize(uint32_t queueSize)
Set the max size of the transmit queue.
void SetIndTxQMaxSize(uint32_t queueSize)
Set the max size of the indirect transmit queue (Pending Transaction list)
McpsDataIndicationCallback m_mcpsDataIndicationCallback
This callback is used to notify incoming packets to the upper layers.
Definition: lr-wpan-mac.h:1949
bool m_beaconTrackingOn
Indication of whether the current device is tracking incoming beacons.
Definition: lr-wpan-mac.h:1397
uint32_t m_superframeDuration
Indication of the superframe duration in symbols.
Definition: lr-wpan-mac.h:1375
bool GetRxOnWhenIdle() const
Check if the receiver will be enabled when the MAC is idle.
Definition: lr-wpan-mac.cc:286
Mac16Address m_macCoordShortAddress
The short address of the coordinator through which the device is associated.
Definition: lr-wpan-mac.h:1191
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:1891
void EndChannelEnergyScan()
Called at the end of one ED channel scan.
void PrintTransmitQueueSize()
Print the number of elements in the packet transmit queue.
void PrintPendTxQ(std::ostream &os) const
Print the Pending transaction list.
void MlmeSetRequest(LrWpanMacPibAttributeIdentifier id, Ptr< LrWpanMacPibAttributes > attribute)
IEEE 802.15.4-2011, section 6.2.11.1 MLME-SET.request Attempts to write the given value to the indica...
Definition: lr-wpan-mac.cc:830
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:1818
void MlmePollRequest(MlmePollRequestParams params)
IEEE 802.15.4-2011, section 6.2.14.2 MLME-POLL.request Prompts the device to request data from the co...
Definition: lr-wpan-mac.cc:815
EventId m_ifsEvent
Scheduler event for Interframe spacing wait time.
Definition: lr-wpan-mac.h:2109
EventId m_beaconEvent
Scheduler event for generation of one beacon.
Definition: lr-wpan-mac.h:2114
uint32_t m_incomingSuperframeDuration
Indication of the superframe duration in symbols (e.g.
Definition: lr-wpan-mac.h:1387
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:1745
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:311
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:2078
EventId m_incCfpEvent
Scheduler event for the end of the incoming superframe CFP.
Definition: lr-wpan-mac.h:2134
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:1262
MlmeCommStatusIndicationCallback m_mlmeCommStatusIndicationCallback
This callback is instigated through a response primitive.
Definition: lr-wpan-mac.h:1961
TracedValue< SuperframeStatus > m_incSuperframeStatus
The current period of the incoming superframe.
Definition: lr-wpan-mac.h:1978
void SetAssociatedCoor(Mac16Address mac)
Check if the packet destination is its coordinator.
Represent the Mac Trailer with the Frame Check Sequence field.
void SetFcs(Ptr< const Packet > p)
Calculate and set the FCS value based on the given packet.
bool CheckFcs(Ptr< const Packet > p)
Check the FCS of a given packet against the FCS value stored in the trailer.
void EnableFcs(bool enable)
Enable or disable FCS calculation for this trailer.
This class can contain 16 bit addresses.
Definition: mac16-address.h:44
bool IsMulticast() const
Checks if the address is a multicast address according to RFC 4944 Section 9 (i.e....
bool IsBroadcast() const
Checks if the address is a broadcast address according to 802.15.4 scheme (i.e., 0xFFFF).
an EUI-64 address
Definition: mac64-address.h:46
static Mac64Address Allocate()
Allocate a new Mac64Address.
static bool ChecksumEnabled()
Definition: node.cc:290
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
A base class which provides memory management and object aggregation.
Definition: object.h:89
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:360
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:353
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
uint32_t RemoveTrailer(Trailer &trailer)
Remove a deserialized trailer from the internal buffer.
Definition: packet.cc:336
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:863
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
void AddTrailer(const Trailer &trailer)
Add trailer to this packet.
Definition: packet.cc:324
Represent the Pending Address Specification field.
NUMERIC_TYPE GetValue() const
Extracts the numeric value of the sequence number.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:568
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:199
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:606
static Time GetDelayLeft(const EventId &id)
Get the remaining time until this event will execute.
Definition: simulator.cc:208
Represent the Superframe Specification information field.
uint8_t GetFinalCapSlot() const
Get the the Final CAP Slot.
void SetAssocPermit(bool assocPermit)
Set the Superframe Specification Association Permit field.
void SetBattLifeExt(bool battLifeExt)
Set the Superframe Specification Battery Life Extension (BLE).
uint8_t GetBeaconOrder() const
Get the Superframe Specification Beacon Order field.
bool IsBattLifeExt() const
Check if the Battery Life Extension bit is enabled.
void SetFinalCapSlot(uint8_t capSlot)
Set the superframe specification Final CAP slot field.
void SetSuperframeOrder(uint8_t frmOrder)
Set the superframe specification Superframe Order field.
void SetPanCoor(bool panCoor)
Set the Superframe Specification PAN coordinator field.
void SetBeaconOrder(uint8_t bcnOrder)
Set the superframe specification Beacon Order field.
uint8_t GetFrameOrder() const
Get the Superframe Specification Frame Order field.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:417
@ S
second
Definition: nstime.h:116
bool IsZero() const
Exactly equivalent to t == 0.
Definition: nstime.h:314
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Hold an unsigned integer type.
Definition: uinteger.h:45
double GetValue(double min, double max)
Get the next random value 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 aMaxPhyPacketSize
The maximum packet size accepted by the PHY.
constexpr uint32_t aMaxBeaconPayloadLenght
The maximum size, in octets, of a beacon payload.
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
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:46
#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:73
LrWpanPhyEnumeration
IEEE802.15.4-2006 PHY Emumerations Table 18 in section 6.2.3.
Definition: lr-wpan-phy.h:109
LrWpanAssociationStatus
table 83 of 802.15.4
Definition: lr-wpan-mac.h:166
SuperframeType
Superframe type.
Definition: lr-wpan-mac.h:105
LrWpanMacPibAttributeIdentifier
IEEE802.15.4-2011 MAC PIB Attribute Identifiers Table 52 in section 6.4.2.
Definition: lr-wpan-mac.h:333
LrWpanPibAttributeIdentifier
IEEE802.15.4-2006 PHY PIB Attribute Identifiers Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:143
@ MLMEPOLL_SUCCESS
Definition: lr-wpan-mac.h:301
@ MLMEPOLL_NO_ACK
Definition: lr-wpan-mac.h:303
@ MLMEPOLL_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:302
@ CHANNEL_ACCESS_FAILURE
CHANNEL_ACCESS_FAILURE.
Definition: lr-wpan-mac.h:78
@ MAC_IDLE
MAC_IDLE.
Definition: lr-wpan-mac.h:74
@ MAC_CSMA_DEFERRED
MAC_CSMA_DEFERRED.
Definition: lr-wpan-mac.h:83
@ MAC_CSMA
MAC_CSMA.
Definition: lr-wpan-mac.h:75
@ CHANNEL_IDLE
CHANNEL_IDLE.
Definition: lr-wpan-mac.h:79
@ MAC_SENDING
MAC_SENDING.
Definition: lr-wpan-mac.h:76
@ MAC_ACK_PENDING
MAC_ACK_PENDING.
Definition: lr-wpan-mac.h:77
@ FFD
Full Functional Device (FFD)
@ MLMESCAN_ED
Definition: lr-wpan-mac.h:181
@ MLMESCAN_PASSIVE
Definition: lr-wpan-mac.h:183
@ MLMESCAN_ORPHAN
Definition: lr-wpan-mac.h:184
@ MLMESCAN_ACTIVE
Definition: lr-wpan-mac.h:182
@ IEEE_802_15_4_TRANSACTION_OVERFLOW
Definition: lr-wpan-mac.h:195
@ IEEE_802_15_4_NO_ACK
Definition: lr-wpan-mac.h:200
@ IEEE_802_15_4_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:197
@ IEEE_802_15_4_INVALID_ADDRESS
Definition: lr-wpan-mac.h:198
@ IEEE_802_15_4_SUCCESS
Definition: lr-wpan-mac.h:194
@ IEEE_802_15_4_FRAME_TOO_LONG
Definition: lr-wpan-mac.h:202
@ IEEE_802_15_4_TRANSACTION_EXPIRED
Definition: lr-wpan-mac.h:196
@ MLMESCAN_SUCCESS
Definition: lr-wpan-mac.h:234
@ MLMESCAN_SCAN_IN_PROGRESS
Definition: lr-wpan-mac.h:237
@ MLMESCAN_INVALID_PARAMETER
Definition: lr-wpan-mac.h:242
@ CFP
Contention Free Period.
Definition: lr-wpan-mac.h:95
@ INACTIVE
Inactive Period or unslotted CSMA-CA.
Definition: lr-wpan-mac.h:96
@ CAP
Contention Access Period.
Definition: lr-wpan-mac.h:94
@ BEACON
The Beacon transmission or reception Period.
Definition: lr-wpan-mac.h:93
@ IEEE_802_15_4_PHY_SUCCESS
Definition: lr-wpan-phy.h:117
@ IEEE_802_15_4_PHY_UNSPECIFIED
Definition: lr-wpan-phy.h:122
@ IEEE_802_15_4_PHY_TRX_OFF
Definition: lr-wpan-phy.h:118
@ IEEE_802_15_4_PHY_RX_ON
Definition: lr-wpan-phy.h:116
@ IEEE_802_15_4_PHY_TX_ON
Definition: lr-wpan-phy.h:119
@ MLMESET_INVALID_PARAMETER
Definition: lr-wpan-mac.h:323
@ MLMESET_SUCCESS
Definition: lr-wpan-mac.h:319
@ MLMESET_UNSUPPORTED_ATTRIBUTE
Definition: lr-wpan-mac.h:321
@ TX_OPTION_ACK
TX_OPTION_ACK.
Definition: lr-wpan-mac.h:62
@ TX_OPTION_INDIRECT
TX_OPTION_INDIRECT.
Definition: lr-wpan-mac.h:64
@ TX_OPTION_GTS
TX_OPTION_GTS.
Definition: lr-wpan-mac.h:63
@ ASSOCIATED
Definition: lr-wpan-mac.h:167
@ PAN_ACCESS_DENIED
Definition: lr-wpan-mac.h:169
@ ASSOCIATED_WITHOUT_ADDRESS
Definition: lr-wpan-mac.h:170
@ PAN_AT_CAPACITY
Definition: lr-wpan-mac.h:168
@ DISASSOCIATED
Definition: lr-wpan-mac.h:171
@ MLMESTART_INVALID_PARAMETER
Definition: lr-wpan-mac.h:219
@ MLMESTART_SUCCESS
Definition: lr-wpan-mac.h:215
@ MLMESTART_NO_SHORT_ADDRESS
Definition: lr-wpan-mac.h:216
@ MLME_SCAN_REQ
Pending MLME-SCAN.request primitive.
Definition: lr-wpan-mac.h:119
@ MLME_ASSOC_REQ
Pending MLME-ASSOCIATION.request primitive.
Definition: lr-wpan-mac.h:120
@ MLME_START_REQ
Pending MLME-START.request primitive.
Definition: lr-wpan-mac.h:118
@ MLME_NONE
No pending primitive.
Definition: lr-wpan-mac.h:117
@ SHORT_ADDR
Definition: lr-wpan-mac.h:156
@ NO_PANID_ADDR
Definition: lr-wpan-mac.h:154
@ EXT_ADDR
Definition: lr-wpan-mac.h:157
@ ADDR_MODE_RESERVED
Definition: lr-wpan-mac.h:155
@ MLMEASSOC_NO_DATA
Definition: lr-wpan-mac.h:257
@ MLMEASSOC_ACCESS_DENIED
Definition: lr-wpan-mac.h:254
@ MLMEASSOC_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:255
@ MLMEASSOC_SUCCESS
Definition: lr-wpan-mac.h:252
@ MLMEASSOC_INVALID_PARAMETER
Definition: lr-wpan-mac.h:261
@ MLMEASSOC_NO_ACK
Definition: lr-wpan-mac.h:256
@ MLMEASSOC_FULL_CAPACITY
Definition: lr-wpan-mac.h:253
@ INCOMING
Incoming Superframe.
Definition: lr-wpan-mac.h:107
@ OUTGOING
Outgoing Superframe.
Definition: lr-wpan-mac.h:106
@ MLMECOMMSTATUS_SUCCESS
Definition: lr-wpan-mac.h:284
@ MLMECOMMSTATUS_TRANSACTION_OVERFLOW
Definition: lr-wpan-mac.h:285
@ MLMECOMMSTATUS_TRANSACTION_EXPIRED
Definition: lr-wpan-mac.h:286
@ MLMECOMMSTATUS_CHANNEL_ACCESS_FAILURE
Definition: lr-wpan-mac.h:287
@ MLMECOMMSTATUS_NO_ACK
Definition: lr-wpan-mac.h:288
@ macBeaconPayloadLength
Definition: lr-wpan-mac.h:335
@ macBeaconPayload
Definition: lr-wpan-mac.h:334
@ phyCurrentChannel
Definition: lr-wpan-phy.h:144
@ phyCurrentPage
Definition: lr-wpan-phy.h:148
@ MLMESYNCLOSS_BEACON_LOST
Definition: lr-wpan-mac.h:273
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h: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:1336
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
address
Definition: first.py:40
Every class exported by the ns3 library is enclosed in the ns3 namespace.
mac
Definition: third.py:85
phy
Definition: third.py:82
params
Fit Fluctuating Two Ray model to the 3GPP TR 38.901 using the Anderson-Darling goodness-of-fit ##.
IEEE802.15.4-2006 PHY PIB Attributes Table 23 in section 6.4.2.
Definition: lr-wpan-phy.h:160
uint8_t phyCurrentPage
Current channel page.
Definition: lr-wpan-phy.h:167
uint8_t phyCurrentChannel
The RF channel to use.
Definition: lr-wpan-phy.h:161
MCPS-DATA.confirm params.
Definition: lr-wpan-mac.h:400
LrWpanMcpsDataConfirmStatus m_status
The status of the last MSDU transmission.
Definition: lr-wpan-mac.h:402
uint8_t m_msduHandle
MSDU handle.
Definition: lr-wpan-mac.h:401
MCPS-DATA.indication params.
Definition: lr-wpan-mac.h:412
MCPS-DATA.request params.
Definition: lr-wpan-mac.h:384
MLME-ASSOCIATE.confirm params.
Definition: lr-wpan-mac.h:563
LrWpanMlmeAssociateConfirmStatus m_status
The status of a MLME-associate.request.
Definition: lr-wpan-mac.h:565
Mac16Address m_assocShortAddr
The short address used in the association request.
Definition: lr-wpan-mac.h:564
MLME-ASSOCIATE.indication params.
Definition: lr-wpan-mac.h:431
Mac64Address m_extDevAddr
The extended address of the device requesting association.
Definition: lr-wpan-mac.h:432
CapabilityField capabilityInfo
The operational capabilities of the device requesting association.
Definition: lr-wpan-mac.h:434
MLME-ASSOCIATE.request params.
Definition: lr-wpan-mac.h:543
uint8_t m_chNum
The channel number on which to attempt association.
Definition: lr-wpan-mac.h:544
CapabilityField m_capabilityInfo
Specifies the operational capabilities of the associating device.
Definition: lr-wpan-mac.h:554
uint8_t m_coordAddrMode
The coordinator addressing mode for this primitive and subsequent MPDU.
Definition: lr-wpan-mac.h:546
Mac64Address m_coordExtAddr
The extended address of the coordinator with which to associate.
Definition: lr-wpan-mac.h:552
Mac16Address m_coordShortAddr
The short address of the coordinator with which to associate.
Definition: lr-wpan-mac.h:550
uint16_t m_coordPanId
The identifier of the PAN with which to associate.
Definition: lr-wpan-mac.h:548
MLME-ASSOCIATE.response params.
Definition: lr-wpan-mac.h:443
MLME-BEACON-NOTIFY.indication params.
Definition: lr-wpan-mac.h:586
uint32_t m_sduLength
The number of octets contained in the beacon payload.
Definition: lr-wpan-mac.h:589
uint8_t m_bsn
The beacon sequence number.
Definition: lr-wpan-mac.h:587
Ptr< Packet > m_sdu
The set of octets comprising the beacon payload.
Definition: lr-wpan-mac.h:590
PanDescriptor m_panDescriptor
The PAN descriptor for the received beacon.
Definition: lr-wpan-mac.h:588
MLME-COMM-STATUS.indication params.
Definition: lr-wpan-mac.h:614
LrWpanMlmeCommStatus m_status
The communication status.
Definition: lr-wpan-mac.h:627
Mac64Address m_dstExtAddr
The extended address of the device for which the frame was intended.
Definition: lr-wpan-mac.h:626
uint16_t m_panId
The PAN identifier of the device from which the frame was received or to which the frame was being se...
Definition: lr-wpan-mac.h:615
Mac64Address m_srcExtAddr
The extended address of the entity from which the frame causing the error originated.
Definition: lr-wpan-mac.h:620
uint8_t m_dstAddrMode
The destination addressing mode for this primitive.
Definition: lr-wpan-mac.h:622
uint8_t m_srcAddrMode
The source addressing mode for this primitive.
Definition: lr-wpan-mac.h:617
MLME-START.confirm params.
Definition: lr-wpan-mac.h:636
LrWpanMlmePollConfirmStatus m_status
The confirmation status resulting from a MLME-poll.request.
Definition: lr-wpan-mac.h:637
MLME-POLL.request params.
Definition: lr-wpan-mac.h:493
MLME-SCAN.confirm params.
Definition: lr-wpan-mac.h:522
std::vector< PanDescriptor > m_panDescList
A list of PAN descriptor, one for each beacon found (Not valid for ED and Orphan scans).
Definition: lr-wpan-mac.h:533
LrWpanMlmeScanType m_scanType
Indicates the type of scan performed (ED,ACTIVE,PASSIVE,ORPHAN).
Definition: lr-wpan-mac.h:525
uint32_t m_chPage
The channel page on which the scan was performed.
Definition: lr-wpan-mac.h:527
LrWpanMlmeScanConfirmStatus m_status
The status of the scan request.
Definition: lr-wpan-mac.h:523
std::vector< uint8_t > m_energyDetList
A list of energy measurements, one for each channel searched during ED scan (Not valid for Active,...
Definition: lr-wpan-mac.h:531
MLME-SCAN.request params.
Definition: lr-wpan-mac.h:507
uint32_t m_scanChannels
The channel numbers to be scanned.
Definition: lr-wpan-mac.h:510
uint32_t m_chPage
The channel page on which to perform scan.
Definition: lr-wpan-mac.h:513
uint8_t m_scanDuration
A value used to calculate the length of time to spend scanning [aBaseSuperframeDuration * (2^m_scanDu...
Definition: lr-wpan-mac.h:511
LrWpanMlmeScanType m_scanType
Indicates the type of scan performed as described in IEEE 802.15.4-2011 (5.1.2.1).
Definition: lr-wpan-mac.h:508
MLME-SET.confirm params.
Definition: lr-wpan-mac.h:648
LrWpanMlmeSetConfirmStatus m_status
The result of the request to write the PIB attribute.
Definition: lr-wpan-mac.h:649
LrWpanMacPibAttributeIdentifier id
The id of the PIB attribute that was written.
Definition: lr-wpan-mac.h:652
MLME-START.confirm params.
Definition: lr-wpan-mac.h:575
LrWpanMlmeStartConfirmStatus m_status
The status of a MLME-start.request.
Definition: lr-wpan-mac.h:576
MLME-START.request params.
Definition: lr-wpan-mac.h:457
uint32_t m_logChPage
Logical channel page on which to start using the new superframe configuration.
Definition: lr-wpan-mac.h:461
uint8_t m_logCh
Logical channel on which to start using the new superframe configuration.
Definition: lr-wpan-mac.h:459
bool m_panCoor
On true this device will become coordinator.
Definition: lr-wpan-mac.h:468
bool m_coorRealgn
True if a realignment request command is to be transmitted prior changing the superframe.
Definition: lr-wpan-mac.h:471
uint8_t m_bcnOrd
Beacon Order, Used to calculate the beacon interval, a value of 15 indicates no periodic beacons will...
Definition: lr-wpan-mac.h:465
uint16_t m_PanId
Pan Identifier used by the device.
Definition: lr-wpan-mac.h:458
uint8_t m_sfrmOrd
Superframe Order, indicates the length of the CAP in time slots.
Definition: lr-wpan-mac.h:467
bool m_battLifeExt
Flag indicating whether or not the Battery life extension (BLE) features are used.
Definition: lr-wpan-mac.h:469
MLME-SYNC-LOSS.indication params.
Definition: lr-wpan-mac.h:599
uint16_t m_panId
The PAN identifier with which the device lost synchronization or to which it was realigned.
Definition: lr-wpan-mac.h:602
LrWpanSyncLossReason m_lossReason
The reason for the lost of synchronization.
Definition: lr-wpan-mac.h:600
MLME-SYNC.request params.
Definition: lr-wpan-mac.h:481
PAN Descriptor, Table 17 IEEE 802.15.4-2011.
Definition: lr-wpan-mac.h:357
LrWpanAddressMode m_coorAddrMode
The coordinator addressing mode corresponding to the received beacon frame.
Definition: lr-wpan-mac.h:358
Mac64Address m_coorExtAddr
The coordinator extended address as specified in the coordinator address mode.
Definition: lr-wpan-mac.h:364
Mac16Address m_coorShortAddr
The coordinator short address as specified in the coordinator address mode.
Definition: lr-wpan-mac.h:362
uint8_t m_logChPage
The current channel page occupied by the network.
Definition: lr-wpan-mac.h:367
uint16_t m_coorPanId
The PAN ID of the coordinator as specified in the received beacon frame.
Definition: lr-wpan-mac.h:360
bool m_gtsPermit
TRUE if the beacon is from the PAN coordinator that is accepting GTS requests.
Definition: lr-wpan-mac.h:370
SuperframeField m_superframeSpec
The superframe specification as specified in the received beacon frame.
Definition: lr-wpan-mac.h:368
uint8_t m_linkQuality
The LQI at which the network beacon was received.
Definition: lr-wpan-mac.h:372
Time m_timeStamp
Beacon frame reception time.
Definition: lr-wpan-mac.h:374
uint8_t m_logCh
The current channel number occupied by the network.
Definition: lr-wpan-mac.h:366