A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
zigbee-nwk.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Tokushima University, Japan
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors:
7 *
8 * Alberto Gallegos Ramonet <alramonet@is.tokushima-u.ac.jp>
9 * Ryo Okuda <c611901200@tokushima-u.ac.jp>
10 */
11
12#include "zigbee-nwk.h"
13
14#include "zigbee-nwk-tables.h"
15
16#include "ns3/log.h"
17#include "ns3/packet.h"
18#include "ns3/simulator.h"
19
20using namespace ns3::lrwpan;
21
22#undef NS_LOG_APPEND_CONTEXT
23#define NS_LOG_APPEND_CONTEXT \
24 std::clog << "[" << m_nwkNetworkAddress << " | " << m_nwkIeeeAddress << "] ";
25
26namespace ns3
27{
28namespace zigbee
29{
30
31NS_LOG_COMPONENT_DEFINE("ZigbeeNwk");
33
36{
37 static TypeId tid =
38 TypeId("ns3::zigbee::ZigbeeNwk")
40 .SetGroupName("Zigbee")
41 .AddConstructor<ZigbeeNwk>()
42 .AddAttribute("NwkcCoordinatorCapable",
43 "[Constant] Indicates whether the device is capable of becoming a"
44 "Zigbee coordinator.",
45 BooleanValue(true),
48 .AddAttribute("NwkcProtocolVersion",
49 "[Constant] The version of the Zigbee NWK protocol in"
50 "the device (placeholder)",
51 UintegerValue(0x02),
54 .AddAttribute("NwkcRouteDiscoveryTime",
55 "[Constant] The duration until a route discovery expires",
56 TimeValue(MilliSeconds(0x2710)),
59
60 .AddAttribute("NwkcInitialRREQRetries",
61 "[Constant] The number of times the first broadcast transmission"
62 "of a RREQ cmd frame is retried.",
63 UintegerValue(0x03),
66 .AddAttribute("NwkcRREQRetries",
67 "[Constant] The number of times the broadcast transmission of a"
68 "RREQ cmd frame is retried on relay by intermediate router or"
69 "coordinator.",
70 UintegerValue(0x02),
73 .AddAttribute("NwkcRREQRetryInterval",
74 "[Constant] The duration between retries of a broadcast RREQ "
75 "cmd frame.",
79 .AddAttribute("NwkcMinRREQJitter",
80 "[Constant] The minimum jitter for broadcast retransmission "
81 "of a RREQ (msec)",
82 DoubleValue(2),
85 .AddAttribute("NwkcMaxRREQJitter",
86 "[Constant] The duration between retries of a broadcast RREQ (msec)",
87 DoubleValue(128),
90 .AddAttribute("MaxPendingTxQueueSize",
91 "The maximum size of the table storing pending packets awaiting "
92 "to be transmitted after discovering a route to the destination.",
93 UintegerValue(10),
96 .AddTraceSource("RreqRetriesExhausted",
97 "Trace source indicating when a node has "
98 "reached the maximum allowed number of RREQ retries during a "
99 "route discovery request",
101 "ns3::zigbee::ZigbeeNwk::RreqRetriesExhaustedTracedCallback");
102 return tid;
103}
104
109
110void
112{
113 NS_LOG_FUNCTION(this);
114
117 m_uniformRandomVariable->SetAttribute("Min", DoubleValue(0.0));
118 m_uniformRandomVariable->SetAttribute("Max", DoubleValue(255.0));
119
121
122 m_netFormParams = {};
123 m_netFormParamsGen = nullptr;
124 m_beaconPayload = nullptr;
126 m_nwkPanId = 0xffff;
127 m_nwkExtendedPanId = 0xffffffffffffffff;
129
132 m_nwkMaxDepth = 5;
133 m_nwkMaxChildren = 20;
134 m_nwkMaxRouters = 6;
136 m_nwkUseTreeRouting = false;
137
139 m_nwkSymLink = false;
140
143
144 m_nwkIsConcentrator = false;
147
148 // TODO, set according to equation 3.5.2.1?
150
155
157 m_rreqJitter->SetAttribute("Min", DoubleValue(m_nwkcMinRREQJitter));
158 m_rreqJitter->SetAttribute("Max", DoubleValue(m_nwkcMaxRREQJitter));
159
161}
162
167
168void
174
175void
207
208void
213
216{
217 return m_mac;
218}
219
220void
222{
223 std::ostream* os = stream->GetStream();
224 std::ios oldState(nullptr);
225 oldState.copyfmt(*os);
226
227 std::ostringstream nwkAddr;
228 std::ostringstream ieeeAddr;
229
230 nwkAddr << m_nwkNetworkAddress;
231 ieeeAddr << m_nwkIeeeAddress;
232
233 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
234 *os << "[" << ieeeAddr.str() << " | " << nwkAddr.str() << "] | ";
235 *os << "Time: " << Simulator::Now().As(Time::S) << " | ";
236 m_nwkRoutingTable.Print(stream);
237}
238
239void
241{
242 std::ostream* os = stream->GetStream();
243 std::ios oldState(nullptr);
244 oldState.copyfmt(*os);
245
246 std::ostringstream nwkAddr;
247 std::ostringstream ieeeAddr;
248
249 nwkAddr << m_nwkNetworkAddress;
250 ieeeAddr << m_nwkIeeeAddress;
251
252 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
253 *os << "[" << ieeeAddr.str() << " | " << nwkAddr.str() << "] | ";
254 *os << "Time: " << Simulator::Now().As(Time::S) << " | ";
256}
257
258void
260{
261 std::ostream* os = stream->GetStream();
262 std::ios oldState(nullptr);
263 oldState.copyfmt(*os);
264
265 std::ostringstream nwkAddr;
266 std::ostringstream ieeeAddr;
267
268 nwkAddr << m_nwkNetworkAddress;
269 ieeeAddr << m_nwkIeeeAddress;
270
271 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
272 *os << "[" << ieeeAddr.str() << " | " << nwkAddr.str() << "] | ";
273 *os << "Time: " << Simulator::Now().As(Time::S) << " | ";
275}
276
277void
279{
280 std::ostream* os = stream->GetStream();
281 std::ios oldState(nullptr);
282 oldState.copyfmt(*os);
283
284 std::ostringstream nwkAddr;
285 std::ostringstream ieeeAddr;
286
287 nwkAddr << m_nwkNetworkAddress;
288 ieeeAddr << m_nwkIeeeAddress;
289
290 *os << std::resetiosflags(std::ios::adjustfield) << std::setiosflags(std::ios::left);
291 *os << "[" << ieeeAddr.str() << " | " << nwkAddr.str() << "] | ";
292 *os << "Time: " << Simulator::Now().As(Time::S) << " | ";
293 m_rreqRetryTable.Print(stream);
294}
295
298{
299 Ptr<NeighborTableEntry> neighborEntry;
300 if (m_nwkNeighborTable.LookUpEntry(dst, neighborEntry))
301 {
302 neighbor = true;
303 return dst;
304 }
305
307 if (m_nwkRoutingTable.LookUpEntry(dst, entry))
308 {
309 if (entry->GetStatus() == ROUTE_ACTIVE)
310 {
311 neighbor = false;
312 return entry->GetNextHopAddr();
313 }
314 }
315
316 neighbor = false;
317 return Mac16Address("FF:FF"); // route not found
318}
319
325
328{
329 return m_nwkIeeeAddress;
330}
331
332void
334{
335 NS_LOG_FUNCTION(this);
336
337 ZigbeeNwkHeader nwkHeader;
338 msdu->RemoveHeader(nwkHeader);
339
340 // Decrease the radius in the network header as it might be retransmitted
341 // to a next hop.
342 uint8_t radius = nwkHeader.GetRadius();
343 nwkHeader.SetRadius(radius - 1);
344
345 // Check if the received frame is from a neighbor and update LQI if necessary
346 Ptr<NeighborTableEntry> neighborEntry;
347 if (m_nwkNeighborTable.LookUpEntry(nwkHeader.GetSrcAddr(), neighborEntry))
348 {
349 neighborEntry->SetLqi(params.m_mpduLinkQuality);
350 neighborEntry->SetOutgoingCost(GetLQINonLinearValue(params.m_mpduLinkQuality));
351 }
352
353 switch (nwkHeader.GetFrameType())
354 {
355 case DATA:
356 if (nwkHeader.IsMulticast())
357 {
358 // DATA MULTICAST
359 NS_FATAL_ERROR("Multicast DATA transmission not supported");
360 }
361 else if (IsBroadcastAddress(nwkHeader.GetDstAddr()))
362 {
363 // DATA BROADCAST
364
366 if (m_btt.LookUpEntry(nwkHeader.GetSeqNum(), btr))
367 {
368 return;
369 }
370
371 // Check the capabilities of the current device
372 CapabilityInformation capability;
374
375 bool rebroadcastFlag = false;
376
377 if (nwkHeader.GetDstAddr() == 0xFFFF ||
378 (nwkHeader.GetDstAddr() == 0xFFFD && capability.IsReceiverOnWhenIdle()) ||
379 (nwkHeader.GetDstAddr() == 0xFFFC && capability.GetDeviceType() != ENDDEVICE))
380 {
381 rebroadcastFlag = true;
382 }
383 else if (nwkHeader.GetDstAddr() == 0xFFFB)
384 {
385 NS_FATAL_ERROR("Broadcast to low power routers not supported");
386 return;
387 }
388
389 if (rebroadcastFlag && nwkHeader.GetRadius() > 0)
390 {
391 Ptr<Packet> rebroadcastPkt = msdu->Copy();
392 rebroadcastPkt->AddHeader(nwkHeader);
393 SendDataBcst(rebroadcastPkt, 0);
394 }
395
396 // Add a new broadcast transaction record to the
397 // broadcasst transaction table
399 nwkHeader.GetSeqNum(),
402 m_btt.AddEntry(btr);
403
405 {
406 NldeDataIndicationParams dataParams;
407 dataParams.m_srcAddr = nwkHeader.GetSrcAddr();
408 dataParams.m_dstAddr = nwkHeader.GetDstAddr();
409 dataParams.m_dstAddrMode = UCST_BCST;
410 dataParams.m_linkQuality = params.m_mpduLinkQuality;
411 dataParams.m_nsduLength = msdu->GetSize();
412 dataParams.m_rxTime = Simulator::Now();
413 dataParams.m_securityUse = false;
414 m_nldeDataIndicationCallback(dataParams, msdu);
415 }
416 }
417 else
418 {
419 // DATA UNICAST
420 if (nwkHeader.GetDstAddr() == m_nwkNetworkAddress)
421 {
422 // Zigbee specification r22.1.0 Sections 3.6.2.2 and 3.6.3.3
424 {
425 NldeDataIndicationParams dataParams;
426 dataParams.m_srcAddr = nwkHeader.GetSrcAddr();
427 dataParams.m_dstAddr = nwkHeader.GetDstAddr();
428 dataParams.m_dstAddrMode = UCST_BCST;
429 dataParams.m_linkQuality = params.m_mpduLinkQuality;
430 dataParams.m_nsduLength = msdu->GetSize();
431 dataParams.m_rxTime = Simulator::Now();
432 dataParams.m_securityUse = false;
433 m_nldeDataIndicationCallback(dataParams, msdu);
434 }
435 }
436 else
437 {
438 // This is not the packet destination,
439 // Add again the network header to the DATA packet and
440 // route the packet to the next hop
441 msdu->AddHeader(nwkHeader);
442 SendDataUcst(msdu, 0);
443 }
444 }
445 break;
446 case NWK_COMMAND: {
447 ZigbeePayloadType payloadType;
448 msdu->RemoveHeader(payloadType);
449
450 if (payloadType.GetCmdType() == ROUTE_REQ_CMD || payloadType.GetCmdType() == ROUTE_REP_CMD)
451 {
452 CapabilityInformation capability;
454 if (capability.GetDeviceType() != ROUTER)
455 {
456 // Received RREQ or RREP but the device
457 // has no routing capabilities
458 return;
459 }
460 }
461 // NOTE: this cover the cases for MESH routing
462 // TREE routing is not supported
463 uint8_t linkCost = GetLinkCost(params.m_mpduLinkQuality);
464
465 if (payloadType.GetCmdType() == ROUTE_REQ_CMD)
466 {
468 msdu->RemoveHeader(payload);
469 // Zigbee specification r22.1.0 Section 3.6.3.5.2
470 ReceiveRREQ(params.m_srcAddr, linkCost, nwkHeader, payload);
471 }
472 else if (payloadType.GetCmdType() == ROUTE_REP_CMD)
473 {
475 msdu->RemoveHeader(payload);
476 // Zigbee specification r22.1.0 Section 3.6.3.5.3
477 ReceiveRREP(params.m_srcAddr, linkCost, nwkHeader, payload);
478 }
479 break;
480 }
481 case INTER_PAN:
482 NS_LOG_ERROR("Inter PAN frame received but not supported");
483 break;
484 default:
485 NS_LOG_ERROR("Unknown frame received in NWK layer");
486 }
487}
488
489void
491 uint8_t linkCost,
492 ZigbeeNwkHeader nwkHeader,
494{
495 NS_LOG_FUNCTION(this);
496
497 if (nwkHeader.GetSrcAddr() == m_nwkNetworkAddress)
498 {
499 // I am the original initiator of the RREQ, ignore request
500 return;
501 }
502
503 // Calculate the pathcost on the RREQ receiving device
504 uint8_t pathCost = linkCost + payload.GetPathCost();
505
506 // Many-to-one routing
507
509 {
510 RouteDiscoveryStatus routeStatus =
511 ProcessManyToOneRoute(macSrcAddr, pathCost, nwkHeader, payload);
512
513 // Update the path cost of the RREQ
514 payload.SetPathCost(pathCost);
515
516 // Note: At this point we already have the updated radius, which was updated as soon
517 // as the frame was received (i.e. In the MCPS-DATA.indication).
518
519 if (routeStatus == MANY_TO_ONE_ROUTE || routeStatus == ROUTE_UPDATED)
520 {
523 this,
524 nwkHeader,
525 payload,
526 0);
529 }
530 return;
531 }
532
533 // Mesh Routing
534
535 Mac16Address nextHop;
536 RouteDiscoveryStatus nextHopStatus =
537 FindNextHop(macSrcAddr, pathCost, nwkHeader, payload, nextHop);
538
539 if (payload.GetDstAddr() == m_nwkNetworkAddress || nextHopStatus == ROUTE_FOUND)
540 {
541 // RREQ is for this device or its children
542 NS_LOG_DEBUG("RREQ is for me or my children, sending a RREP to [" << macSrcAddr << "]");
543
544 SendRREP(macSrcAddr,
545 nwkHeader.GetSrcAddr(),
546 payload.GetDstAddr(),
547 payload.GetRouteReqId(),
548 pathCost);
549 }
550 else if (nextHopStatus == ROUTE_NOT_FOUND || nextHopStatus == ROUTE_UPDATED)
551 {
552 NS_LOG_DEBUG("Route for device [" << payload.GetDstAddr()
553 << "] not found, forwarding RREQ");
554
555 // Update path cost and resend the RREQ
556 payload.SetPathCost(pathCost);
559 this,
560 nwkHeader,
561 payload,
563 }
564}
565
566void
568 uint8_t linkCost,
569 ZigbeeNwkHeader nwkHeader,
571{
572 NS_LOG_FUNCTION(this);
573
574 // RREP received, cancel any ongoing RREQ retry events for that
575 // RREQ ID and remove entry from RREQ retry table.
576 Ptr<RreqRetryTableEntry> rreqRetryTableEntry;
577 if (m_rreqRetryTable.LookUpEntry(payload.GetRouteReqId(), rreqRetryTableEntry))
578 {
579 rreqRetryTableEntry->GetRreqEventId().Cancel();
581 }
582
583 uint8_t pathCost = linkCost + payload.GetPathCost();
584
585 if (payload.GetOrigAddr() == m_nwkNetworkAddress)
586 {
587 // The RREP is destined for this device
590 payload.GetOrigAddr(),
591 discEntry))
592 {
593 Ptr<RoutingTableEntry> routeEntry;
594 if (m_nwkRoutingTable.LookUpEntry(payload.GetRespAddr(), routeEntry))
595 {
596 if (routeEntry->GetStatus() == ROUTE_DISCOVERY_UNDERWAY)
597 {
598 if (routeEntry->IsGroupIdPresent())
599 {
600 routeEntry->SetStatus(ROUTE_VALIDATION_UNDERWAY);
601 }
602 else
603 {
604 routeEntry->SetStatus(ROUTE_ACTIVE);
605 }
606 routeEntry->SetNextHopAddr(macSrcAddr);
607 discEntry->SetResidualCost(pathCost);
608 }
609 else if (routeEntry->GetStatus() == ROUTE_VALIDATION_UNDERWAY ||
610 routeEntry->GetStatus() == ROUTE_ACTIVE)
611 {
612 if (pathCost < discEntry->GetResidualCost())
613 {
614 routeEntry->SetNextHopAddr(macSrcAddr);
615 discEntry->SetResidualCost(pathCost);
616 }
617 }
618
619 NS_LOG_DEBUG("RREP from source [" << payload.GetRespAddr()
620 << "] is for me; received from last hop ["
621 << macSrcAddr << "]");
622
624 {
625 // We only report the result of the route discovery request
626 // with the first RREP received.
629 {
630 NlmeRouteDiscoveryConfirmParams routeDiscConfirmParams;
631 routeDiscConfirmParams.m_status = NwkStatus::SUCCESS;
632 m_nlmeRouteDiscoveryConfirmCallback(routeDiscConfirmParams);
633 }
634 }
635
637 if (!m_pendingTxQueue.empty() &&
638 DequeuePendingTx(payload.GetRespAddr(), pendingTxPkt))
639 {
640 // Buffer a copy of the DATA packet that will be transmitted
641 // for handling after transmission (i.e. NSDE-DATA.confirm)
642 BufferTxPkt(pendingTxPkt->txPkt->Copy(),
644 pendingTxPkt->nsduHandle);
645
646 // There is a pending packet awaiting to be transmitted
647 // to the next hop, send it.
648 McpsDataRequestParams mcpsDataparams;
649 mcpsDataparams.m_txOptions = 0x01; // Acknowledment on.
650 mcpsDataparams.m_dstPanId = m_nwkPanId;
651 mcpsDataparams.m_msduHandle = m_macHandle.GetValue();
652 mcpsDataparams.m_srcAddrMode = SHORT_ADDR;
653 mcpsDataparams.m_dstAddrMode = SHORT_ADDR;
654 mcpsDataparams.m_dstAddr = routeEntry->GetNextHopAddr();
655 m_macHandle++;
656
658 m_mac,
659 mcpsDataparams,
660 pendingTxPkt->txPkt);
661 }
662 }
663 else
664 {
666 }
667 }
668 }
669 else
670 {
671 // The RREP is NOT destined for this device
674 payload.GetOrigAddr(),
675 discEntry))
676 {
677 if (payload.GetPathCost() < discEntry->GetResidualCost())
678 {
679 Ptr<RoutingTableEntry> routeEntry;
680 if (m_nwkRoutingTable.LookUpEntry(payload.GetRespAddr(), routeEntry))
681 {
682 routeEntry->SetNextHopAddr(macSrcAddr);
683 routeEntry->SetStatus(ROUTE_ACTIVE);
684 discEntry->SetResidualCost(pathCost);
685 // Forward route reply to the next hop back to the original route requester
686 SendRREP(discEntry->GetSenderAddr(),
687 payload.GetOrigAddr(),
688 payload.GetRespAddr(),
689 payload.GetRouteReqId(),
690 pathCost);
691 }
692 else
693 {
694 NS_LOG_ERROR("Route discovery entry detected but no corresponding routing "
695 "table entry found");
696 }
697 }
698 }
699 }
700}
701
702bool
704{
705 return address == "FF:FF" || address == "FF:FD" || address == "FF:FC" || address == "FF:FB";
706}
707
710 uint8_t pathCost,
711 ZigbeeNwkHeader nwkHeader,
713 Mac16Address& nextHop)
714{
715 NS_LOG_FUNCTION(this);
716
717 // Mesh routing
718
719 // Check if the destination is our neighbor
720 Ptr<NeighborTableEntry> neighborEntry;
721 if (m_nwkNeighborTable.LookUpEntry(payload.GetDstAddr(), neighborEntry))
722 {
723 nextHop = payload.GetDstAddr();
724 return ROUTE_FOUND;
725 }
726
728 if (m_nwkRoutingTable.LookUpEntry(payload.GetDstAddr(), entry))
729 {
730 if (!(entry->GetStatus() == ROUTE_ACTIVE) &&
731 !(entry->GetStatus() == ROUTE_VALIDATION_UNDERWAY))
732 {
733 // Entry found but is not valid
734 entry->SetStatus(ROUTE_DISCOVERY_UNDERWAY);
735 }
736 else
737 {
738 // Entry found
739 nextHop = entry->GetNextHopAddr();
740 return ROUTE_FOUND;
741 }
742 }
744 {
745 // Check that the max routing capacity has not been reached. If the capacity was reached,
746 // attempt to delete the first found expired entry, if the table persist to be full
747 // then send a route error.
749 {
751
753 {
755 {
757 confirmParams.m_status = ROUTE_ERROR;
760 }
761 return TABLE_FULL;
762 }
763 }
764
765 // Entry not found
766 Ptr<RoutingTableEntry> newRoutingEntry =
769 true, // TODO no route cache
770 false, // TODO: Many to one
771 false, // TODO: Route record
772 false, // TODO: Group id
773 Mac16Address("FF:FF"));
774 newRoutingEntry->SetLifeTime(Simulator::Now() + m_routeExpiryTime);
775
776 m_nwkRoutingTable.AddEntry(newRoutingEntry);
777 }
778 else
779 {
781 {
783 confirmParams.m_status = ROUTE_ERROR;
786 }
787 return NO_DISCOVER_ROUTE;
788 }
789
790 // 2- Find entry in DISCOVERY TABLE
793 nwkHeader.GetSrcAddr(),
794 discEntry))
795 {
796 // Entry Found
797 if (pathCost < discEntry->GetForwardCost())
798 {
799 // More optimal route found, update route discovery values.
800 discEntry->SetSenderAddr(macSrcAddr);
801 discEntry->SetForwardCost(pathCost);
802 discEntry->SetExpTime(Simulator::Now() + m_nwkcRouteDiscoveryTime);
803 return ROUTE_UPDATED;
804 }
805 else
806 {
807 return DISCOVER_UNDERWAY;
808 }
809 }
810 else
811 {
812 // Entry NOT found, add NEW entry to route discovery table.
813 Ptr<RouteDiscoveryTableEntry> newDiscEntry =
815 nwkHeader.GetSrcAddr(),
816 macSrcAddr, // macSrcAddr,
817 pathCost, // payload.GetPathCost(), // Forward cost
818 0xff, // Residual cost
820
821 if (!m_nwkRouteDiscoveryTable.AddEntry(newDiscEntry))
822 {
823 return TABLE_FULL;
824 }
825 }
826 return ROUTE_NOT_FOUND;
827}
828
831 uint8_t pathCost,
832 ZigbeeNwkHeader nwkHeader,
834{
837 nwkHeader.GetSrcAddr(),
838 discEntry))
839 {
840 Ptr<RoutingTableEntry> routeEntry;
841 if (m_nwkRoutingTable.LookUpEntry(nwkHeader.GetSrcAddr(), routeEntry))
842 {
843 if (routeEntry->GetStatus() == ROUTE_VALIDATION_UNDERWAY ||
844 routeEntry->GetStatus() == ROUTE_ACTIVE)
845 {
846 if (pathCost < discEntry->GetForwardCost())
847 {
848 // Update with a better route.
849 routeEntry->SetNextHopAddr(macSrcAddr);
850 discEntry->SetForwardCost(pathCost);
851 discEntry->SetExpTime(Simulator::Now() + m_nwkcRouteDiscoveryTime);
852 return ROUTE_UPDATED;
853 }
854 return NO_ROUTE_CHANGE;
855 }
856 }
857 else
858 {
859 NS_LOG_ERROR("Entry found in the discovery table but not the routing table");
860 return NO_ROUTE_CHANGE;
861 }
862 }
863 else
864 {
865 // Entry NOT found, add NEW entry to route discovery table.
866 Ptr<RouteDiscoveryTableEntry> newDiscEntry =
868 nwkHeader.GetSrcAddr(),
869 macSrcAddr, // previous hop address
870 pathCost, // Forward cost
871 0xff, // Residual cost (not used by Many-to-One)
873
874 // TODO: what to do if route discovery table is full?
876
877 // Define the type of Many-To-One routing (with or without route record)
878 bool routeRecord = false;
880 {
881 routeRecord = true;
882 }
883
884 Ptr<RoutingTableEntry> routeEntry;
885 if (m_nwkRoutingTable.LookUpEntry(nwkHeader.GetSrcAddr(), routeEntry))
886 {
887 if (routeEntry->GetStatus() == ROUTE_VALIDATION_UNDERWAY ||
888 routeEntry->GetStatus() == ROUTE_ACTIVE)
889 {
890 // The entry exist in routing table but it was not in discovery table
891 // Refresh the Route
892 routeEntry->SetNextHopAddr(macSrcAddr);
893 // TODO: other parameters
894 return ROUTE_UPDATED;
895 }
896 return NO_ROUTE_CHANGE;
897 }
898 else
899 {
900 // New routing table entry
901 // Check that the max routing capacity has not been reached. If the capacity was
902 // reached, attempt to delete the first found expired entry, if the table persist to be
903 // full then send a route error.
905 {
907
909 {
911 {
913 confirmParams.m_status = ROUTE_ERROR;
916 }
917 return TABLE_FULL;
918 }
919 }
920
921 Ptr<RoutingTableEntry> newRoutingEntry =
924 true, // TODO no route cache
925 true, // TODO: Many to one
926 routeRecord, // TODO: Route record
927 false, // TODO: Group id
928 macSrcAddr);
929
930 newRoutingEntry->SetLifeTime(Simulator::Now() + m_routeExpiryTime);
931
932 m_nwkRoutingTable.AddEntry(newRoutingEntry);
933 return MANY_TO_ONE_ROUTE;
934 }
935 }
936 return NO_ROUTE_CHANGE;
937}
938
939void
940ZigbeeNwk::SendDataUcst(Ptr<Packet> packet, uint8_t nwkHandle)
941{
942 NS_LOG_FUNCTION(this);
943
944 // Obtain information from the DATA packet
945 ZigbeeNwkHeader nwkHeaderData;
946 packet->PeekHeader(nwkHeaderData);
947
948 // Construct a RREQ network header and payload for possible
949 // route discovery request
950
951 ZigbeeNwkHeader nwkHeaderRreq;
952 nwkHeaderRreq.SetFrameType(NWK_COMMAND);
954 nwkHeaderRreq.SetDiscoverRoute(nwkHeaderData.GetDiscoverRoute());
955 // See r22.1.0, Table 3-69
956 // Set destination to broadcast (all routers and coordinator)
957 nwkHeaderRreq.SetDstAddr(Mac16Address("FF:FC"));
958 nwkHeaderRreq.SetSrcAddr(m_nwkNetworkAddress);
959 nwkHeaderRreq.SetSeqNum(m_nwkSequenceNumber.GetValue());
960 // see Zigbee specification 3.2.2.33.3
961 if (nwkHeaderData.GetRadius() == 0)
962 {
963 nwkHeaderRreq.SetRadius(m_nwkMaxDepth * 2);
964 }
965 else
966 {
967 nwkHeaderRreq.SetRadius(nwkHeaderData.GetRadius());
968 }
969
972 payloadRreq.SetDstAddr(nwkHeaderData.GetDstAddr());
973 payloadRreq.SetPathCost(0);
974
975 Mac16Address nextHop;
976 RouteDiscoveryStatus nextHopStatus =
977 FindNextHop(m_nwkNetworkAddress, 0, nwkHeaderRreq, payloadRreq, nextHop);
978
979 if (nextHopStatus == ROUTE_FOUND)
980 {
981 // Buffer a copy of the DATA packet that will be transmitted
982 // for handling after transmission (i.e. NSDE-DATA.confirm)
983 BufferTxPkt(packet->Copy(), m_macHandle.GetValue(), nwkHandle);
984
985 // Parameters as described in Section 3.6.3.3
986 McpsDataRequestParams mcpsDataparams;
987 mcpsDataparams.m_dstPanId = m_nwkPanId;
988 mcpsDataparams.m_msduHandle = m_macHandle.GetValue();
989 mcpsDataparams.m_txOptions = 0x01; // Acknowledment on.
990 mcpsDataparams.m_srcAddrMode = SHORT_ADDR;
991 mcpsDataparams.m_dstAddrMode = SHORT_ADDR;
992 mcpsDataparams.m_dstAddr = nextHop;
993 m_macHandle++;
995 }
996 else if (nextHopStatus == ROUTE_NOT_FOUND)
997 {
998 // Route not found. Route marked as DISCOVER UNDERWAY,
999 // packet added to pending Tx Queue and we initiate route
1000 // discovery
1001
1002 EnqueuePendingTx(packet, nwkHandle);
1003
1006 this,
1007 nwkHeaderRreq,
1008 payloadRreq,
1010
1013 }
1014}
1015
1016void
1017ZigbeeNwk::SendDataBcst(Ptr<Packet> packet, uint8_t nwkHandle)
1018{
1019 // Buffer a copy of the DATA packet that will be transmitted
1020 // for handling after transmission (i.e. NSDE-DATA.confirm)
1021 BufferTxPkt(packet->Copy(), m_macHandle.GetValue(), nwkHandle);
1022
1023 // Parameters as described in Section 3.6.5
1024 McpsDataRequestParams mcpsDataparams;
1025 mcpsDataparams.m_dstPanId = m_nwkPanId;
1026 mcpsDataparams.m_msduHandle = m_macHandle.GetValue();
1027 mcpsDataparams.m_srcAddrMode = SHORT_ADDR;
1028 mcpsDataparams.m_dstAddrMode = SHORT_ADDR;
1029 mcpsDataparams.m_dstAddr = Mac16Address("FF:FF");
1030 m_macHandle++;
1032}
1033
1034void
1036{
1037 Ptr<TxPkt> bufferedElement;
1038 if (RetrieveTxPkt(params.m_msduHandle, bufferedElement))
1039 {
1040 ZigbeeNwkHeader nwkHeader;
1041 bufferedElement->txPkt->PeekHeader(nwkHeader);
1042
1043 if (nwkHeader.GetFrameType() == DATA)
1044 {
1045 if (IsBroadcastAddress(nwkHeader.GetDstAddr()))
1046 {
1047 }
1048 else if (nwkHeader.GetSrcAddr() == m_nwkNetworkAddress)
1049 {
1050 // Send the confirmation to next layer after the packet transmission,
1051 // only if packet transmitted was in the initiator of the NLDE-DATA.request
1052
1054 {
1055 // Zigbee Specification r22.1.0, End of Section 3.2.1.1.3
1056 // Report the the results of a request to a transmission of a packet
1057 NldeDataConfirmParams nldeDataConfirmParams;
1058 // nldeDataConfirmParams.m_status =
1059 // static_cast<ZigbeeNwkStatus>(params.m_status);
1060 nldeDataConfirmParams.m_nsduHandle = bufferedElement->nwkHandle;
1061 m_nldeDataConfirmCallback(nldeDataConfirmParams);
1062 }
1063 }
1064 }
1065 }
1066}
1067
1068void
1070{
1071 NS_LOG_FUNCTION(this);
1072
1073 if (m_pendPrimitiveNwk == NLME_NETWORK_FORMATION && params.m_scanType == MLMESCAN_ED)
1074 {
1075 if (params.m_status != MacStatus::SUCCESS)
1076 {
1078 m_netFormParams = {};
1079 m_netFormParamsGen = nullptr;
1080
1081 // See Zigbee specification r22.1.0, Section 3.2.2.5.3, (6.b.i)
1083 {
1085 confirmParams.m_status = GetNwkStatus(params.m_status);
1087 }
1088 }
1089 else
1090 {
1091 // TODO: Continue energy detection (ED) scan in other interfaces if supported.
1092
1093 // See Zigbee specification r22.1.0, Section 3.2.2.5.3, (6.b.ii)
1094 // Pick the list of acceptable channels on which to continue doing an ACTIVE scan
1095 std::vector<uint8_t> energyList = params.m_energyDetList;
1097
1098 NS_LOG_DEBUG("[NLME-NETWORK-FORMATION.request]: \n "
1099 << "EnergyThreshold: " << m_scanEnergyThreshold << " | ChannelMask: 0x"
1100 << std::hex << channelMask << std::dec << " | EnergyList: " << energyList);
1101
1103 uint32_t countAcceptableChannels = 0;
1104 uint8_t energyListPos = 0;
1105 for (uint32_t i = 0; i < 32; i++)
1106 {
1107 // check if the i position exist in the ChannelMask
1108 if (channelMask & (1 << i))
1109 {
1110 if (energyList[energyListPos] <= m_scanEnergyThreshold)
1111 {
1112 m_filteredChannelMask |= (1 << i);
1113 countAcceptableChannels++;
1114 }
1115 energyListPos++;
1116 }
1117 }
1118
1119 NS_LOG_DEBUG("[NLME-NETWORK-FORMATION.request]:\n "
1120 << "Energy scan complete, " << countAcceptableChannels
1121 << " acceptable channels found : 0x" << std::hex << m_filteredChannelMask
1122 << std::dec);
1123
1124 if (countAcceptableChannels == 0)
1125 {
1127 m_netFormParams = {};
1128 m_netFormParamsGen = nullptr;
1129
1131 {
1133 confirmParams.m_status = NwkStatus::STARTUP_FAILURE;
1135 }
1136 }
1137 else
1138 {
1139 // See Zigbee specification r22.1.0, Section 3.2.2.5.3, (6.c)
1140 MlmeScanRequestParams mlmeParams;
1141 mlmeParams.m_chPage = (m_filteredChannelMask >> 27) & (0x01F);
1144 mlmeParams.m_scanType = MLMESCAN_ACTIVE;
1146 }
1147 }
1148 }
1149 else if (m_pendPrimitiveNwk == NLME_NETWORK_FORMATION && params.m_scanType == MLMESCAN_ACTIVE)
1150 {
1151 if (params.m_status == MacStatus::NO_BEACON || params.m_status == MacStatus::SUCCESS)
1152 {
1153 // TODO: We should ACTIVE scan channels on each interface
1154 // (only possible when more interfaces (nwkMacInterfaceTable) are supported)
1155 // for now, only a single interface is considered.
1156
1157 // See Zigbee specification r22.1.0, (3.2.2.5.3, 6.d.ii)
1158 // Check results of an ACTIVE scan an select a different PAN ID and channel:
1159 // Choose a random PAN ID
1160 // Page is always 0 until more interfaces supported
1161 uint8_t channel = 0;
1162 uint8_t page = 0;
1163 uint16_t panId = m_uniformRandomVariable->GetInteger(1, 0xFFF7);
1164
1165 std::vector<uint8_t> pansPerChannel(27);
1166 uint32_t secondFilteredChannelMask = m_filteredChannelMask;
1167 for (const auto& panDescriptor : params.m_panDescList)
1168 {
1169 // Clear all the bit positions of channels with active PAN networks
1170 // (The channels with PAN descriptors received)
1171 secondFilteredChannelMask &= ~(1 << panDescriptor.m_logCh);
1172 // Add to the number of PAN detected in this channel
1173 pansPerChannel[panDescriptor.m_logCh] += 1;
1174 }
1175
1176 for (uint32_t i = 0; i < 32; i++)
1177 {
1178 // Pick the first channel in the list that does not contain
1179 // any PAN network
1180 if (secondFilteredChannelMask & (1 << i))
1181 {
1182 channel = i;
1183 break;
1184 }
1185 }
1186
1187 if (channel < 11 || channel > 26)
1188 {
1189 // Extreme case: All the channels in the previous step contained PAN networks
1190 // therefore choose the channel with the least PAN networks.
1191 uint8_t channelIndex = 0;
1192 uint8_t lowestPanNum = 99;
1193 for (const auto& numPans : pansPerChannel)
1194 {
1195 if (numPans != 0 && numPans <= lowestPanNum)
1196 {
1197 channel = channelIndex;
1198 lowestPanNum = numPans;
1199 }
1200 channelIndex++;
1201 }
1202
1203 NS_ASSERT_MSG(channel < 11 || channel > 26,
1204 "Invalid channel in PAN descriptor list during ACTIVE scan");
1205 }
1206
1207 // store the chosen page, channel and pan Id.
1209 m_netFormParamsGen->page = page;
1210 m_netFormParamsGen->channel = channel;
1211 m_netFormParamsGen->panId = panId;
1212
1213 NS_LOG_DEBUG("[NLME-NETWORK-FORMATION.request]:\n "
1214 << "Active scan complete, page " << std::dec << page << ", channel "
1215 << std::dec << channel << " and PAN ID 0x" << std::hex << panId << std::dec
1216 << " chosen.");
1217
1218 // Set the device short address (3.2.2.5.3 , 6.f)
1221 {
1222 pibAttr->macShortAddress = m_netFormParams.m_distributedNetworkAddress;
1224 }
1225 else
1226 {
1227 pibAttr->macShortAddress = Mac16Address("00:00");
1229 }
1230 // Set Short Address and continue with beacon payload afterwards.
1232 m_mac,
1233 MacPibAttributeIdentifier::macShortAddress,
1234 pibAttr);
1235 }
1236 else
1237 {
1238 // Error occurred during network formation active scan
1239 // report to higher layer (Section 3.2.2.5.3, 6.d)
1240
1242 m_netFormParams = {};
1243 m_netFormParamsGen = nullptr;
1244
1246 {
1248 confirmParams.m_status = GetNwkStatus(params.m_status);
1250 }
1251 }
1252 }
1253 else if (m_pendPrimitiveNwk == NLME_NET_DISCV && params.m_scanType == MLMESCAN_ACTIVE)
1254 {
1255 NlmeNetworkDiscoveryConfirmParams netDiscConfirmParams;
1257
1258 if (params.m_status == MacStatus::SUCCESS)
1259 {
1260 NS_LOG_DEBUG("[NLME-NETWORK-DISCOVERY.request]:\n "
1261 << "Active scan, " << m_networkDescriptorList.size()
1262 << " PARENT capable device(s) found");
1263
1264 netDiscConfirmParams.m_netDescList = m_networkDescriptorList;
1265 netDiscConfirmParams.m_networkCount = m_networkDescriptorList.size();
1266 netDiscConfirmParams.m_status = NwkStatus::SUCCESS;
1268 }
1269 else
1270 {
1271 NS_LOG_DEBUG("[NLME-NETWORK-DISCOVERY.request]: Active scan failed with"
1272 " status: "
1273 << GetNwkStatus(params.m_status));
1274 netDiscConfirmParams.m_status = GetNwkStatus(params.m_status);
1275 }
1276
1278 {
1279 m_nlmeNetworkDiscoveryConfirmCallback(netDiscConfirmParams);
1280 }
1281 }
1282 else if (m_pendPrimitiveNwk == NLME_JOIN && params.m_scanType == MLMESCAN_ORPHAN)
1283 {
1284 // TODO: Add macInterfaceIndex and channelListStructure params when supported
1285 if (params.m_status == MacStatus::SUCCESS)
1286 {
1287 // Orphan scan was successful (Join success), first update the extended
1288 // PAN id and the capability information, then the
1289 // the nwkNetworkAddress with the macShortAddress, this
1290 // will be followed by an update of the m_nwkPanId with macPanId
1291 // and finally the join confirmation
1295 m_mac,
1296 MacPibAttributeIdentifier::macShortAddress);
1297 }
1298 else
1299 {
1301 m_joinParams = {};
1302 NS_LOG_DEBUG("[NLME-JOIN.request]: Orphan scan completed but no networks found");
1303
1305 {
1306 NlmeJoinConfirmParams joinConfirmParams;
1307 joinConfirmParams.m_status = NwkStatus::NO_NETWORKS;
1308 m_nlmeJoinConfirmCallback(joinConfirmParams);
1309 }
1310 }
1311 }
1312}
1313
1314void
1316{
1317 NS_LOG_FUNCTION(this);
1318
1320 {
1321 NlmeJoinConfirmParams joinConfirmParams;
1322 joinConfirmParams.m_extendedPanId = m_joinParams.m_extendedPanId;
1323 joinConfirmParams.m_enhancedBeacon = false; // hardcoded, no support
1324 joinConfirmParams.m_macInterfaceIndex = 0; // hardcoded, no support
1325 joinConfirmParams.m_networkAddress = params.m_assocShortAddr;
1326
1328
1329 if (params.m_status == MacStatus::SUCCESS)
1330 {
1331 joinConfirmParams.m_status = NwkStatus::SUCCESS;
1332 joinConfirmParams.m_networkAddress = params.m_assocShortAddr;
1333
1334 // Update NWK NIB values
1335 m_nwkNetworkAddress = params.m_assocShortAddr;
1338
1339 // Update relationship
1341 {
1343 {
1344 entry->SetRelationship(NBR_PARENT);
1345
1346 NS_LOG_DEBUG("[NLME-JOIN.request]:\n "
1347 << "Status: " << joinConfirmParams.m_status << " | PAN ID: 0x"
1348 << std::hex << m_nwkPanId << " | Extended PAN ID: 0x"
1349 << m_nwkExtendedPanId << std::dec);
1350 }
1351 else
1352 {
1353 NS_LOG_ERROR("Entry not found while updating relationship");
1354 }
1355 }
1356 else
1357 {
1359 {
1360 entry->SetRelationship(NBR_PARENT);
1361
1362 NS_LOG_DEBUG("[NLME-JOIN.request]:\n "
1363 << "Status: " << joinConfirmParams.m_status << " | PAN ID: 0x"
1364 << std::hex << m_nwkPanId << " | Extended PAN ID: 0x"
1365 << m_nwkExtendedPanId << std::dec);
1366 }
1367 else
1368 {
1369 NS_LOG_ERROR("Entry not found while updating relationship");
1370 }
1371 }
1372
1373 // TODO:m_nwkUpdateId
1374 }
1375 else
1376 {
1377 if (params.m_status == MacStatus::FULL_CAPACITY)
1378 {
1379 // Discard neighbor as potential parent
1381 {
1383 {
1384 entry->SetPotentialParent(false);
1385 }
1386 else
1387 {
1388 NS_LOG_ERROR("Neighbor not found when discarding as potential parent");
1389 }
1390 }
1391 else
1392 {
1394 {
1395 entry->SetPotentialParent(false);
1396 }
1397 else
1398 {
1399 NS_LOG_ERROR("Neighbor not found when discarding as potential parent");
1400 }
1401 }
1402
1403 joinConfirmParams.m_status = NwkStatus::NEIGHBOR_TABLE_FULL;
1404 }
1405 else
1406 {
1407 joinConfirmParams.m_status = GetNwkStatus(params.m_status);
1408 }
1409 }
1410
1412 m_joinParams = {};
1413 m_associateParams = {};
1414
1416 {
1417 m_nlmeJoinConfirmCallback(joinConfirmParams);
1418 }
1419 }
1420}
1421
1422void
1424{
1425 NS_LOG_FUNCTION(this);
1426
1427 NwkStatus nwkConfirmStatus;
1428 nwkConfirmStatus = GetNwkStatus(params.m_status);
1429
1430 if (nwkConfirmStatus != NwkStatus::SUCCESS)
1431 {
1432 m_nwkExtendedPanId = 0xffffffffffffffed;
1434 m_nwkPanId = 0xffff;
1435 }
1436
1438 {
1439 NS_LOG_DEBUG("[NLME-NETWORK-FORMATION.request]:\n "
1440 << "Status: " << nwkConfirmStatus << " | PAN ID:" << std::hex << m_nwkPanId
1441 << " | Extended PAN ID: 0x" << m_nwkExtendedPanId << std::dec);
1442
1444 m_netFormParams = {};
1445 m_netFormParamsGen = nullptr;
1446
1448 {
1450 confirmParams.m_status = nwkConfirmStatus;
1452 }
1453 }
1455 {
1456 NS_LOG_DEBUG("[NLME-START-ROUTER.request]:\n "
1457 << "Status: " << nwkConfirmStatus << " | PAN ID: 0x" << std::hex << m_nwkPanId
1458 << " | Extended PAN ID: 0x" << m_nwkExtendedPanId << std::dec);
1459
1460 if (nwkConfirmStatus != NwkStatus::SUCCESS)
1461 {
1465 {
1466 NlmeStartRouterConfirmParams confirmParams;
1467 confirmParams.m_status = nwkConfirmStatus;
1468 m_nlmeStartRouterConfirmCallback(confirmParams);
1469 }
1470 }
1471 else
1472 {
1474 }
1475 }
1476}
1477
1478void
1480{
1481 NS_LOG_FUNCTION(this << params.id);
1482
1484 {
1485 if (params.m_status == MacStatus::SUCCESS &&
1486 params.id == MacPibAttributeIdentifier::macShortAddress)
1487 {
1488 // Section (3.2.2.5.3 , 6.g)
1489 // Getting this device MAC extended address using MLME-GET
1491 m_mac,
1492 MacPibAttributeIdentifier::macExtendedAddress);
1493 }
1494 else if (params.m_status == MacStatus::SUCCESS &&
1495 params.id == MacPibAttributeIdentifier::macBeaconPayload)
1496 {
1497 // Finalize Network Formation (Start network)
1498 MlmeStartRequestParams startParams;
1499 startParams.m_logCh = m_netFormParamsGen->channel;
1500 startParams.m_logChPage = m_netFormParamsGen->page;
1501 startParams.m_PanId = m_netFormParamsGen->panId;
1505 startParams.m_coorRealgn = false;
1506 startParams.m_panCoor = true;
1508 }
1509 else if (params.m_status == MacStatus::SUCCESS &&
1510 params.id == MacPibAttributeIdentifier::macBeaconPayloadLength)
1511 {
1513 }
1514 else
1515 {
1517 m_netFormParams = {};
1518 m_netFormParamsGen = nullptr;
1519
1521 {
1523 confirmParams.m_status = NwkStatus::STARTUP_FAILURE;
1525 }
1526 }
1527 }
1529 {
1530 if (params.m_status == MacStatus::SUCCESS &&
1531 params.id == MacPibAttributeIdentifier::macBeaconPayloadLength)
1532 {
1534 }
1535 else
1536 {
1538
1540 m_joinIndParams = {};
1541
1543 {
1544 m_nlmeJoinIndicationCallback(joinIndParams);
1545 }
1546 }
1547 }
1549 {
1550 if (params.m_status == MacStatus::SUCCESS &&
1551 params.id == MacPibAttributeIdentifier::macBeaconPayloadLength)
1552 {
1554 }
1555 else if (params.m_status == MacStatus::SUCCESS &&
1556 params.id == MacPibAttributeIdentifier::macBeaconPayload)
1557 {
1561 {
1562 NlmeStartRouterConfirmParams confirmParams;
1563 confirmParams.m_status = NwkStatus::SUCCESS;
1564 m_nlmeStartRouterConfirmCallback(confirmParams);
1565 }
1566 }
1567 else
1568 {
1569 NS_LOG_ERROR("Beacon payload update failed during a NLME-START-ROUTER.request");
1570 }
1571 }
1572}
1573
1574void
1577 Ptr<MacPibAttributes> attribute)
1578{
1579 NS_LOG_FUNCTION(this);
1580
1581 // Update the values of attributes in the network layer
1582 if (status == MacStatus::SUCCESS)
1583 {
1584 if (id == MacPibAttributeIdentifier::macExtendedAddress)
1585 {
1586 m_nwkIeeeAddress = attribute->macExtendedAddress;
1587 }
1588 else if (id == MacPibAttributeIdentifier::macShortAddress)
1589 {
1590 m_nwkNetworkAddress = attribute->macShortAddress;
1591 }
1592 else if (id == MacPibAttributeIdentifier::macPanId)
1593 {
1594 m_nwkPanId = attribute->macPanId;
1595 }
1596 else if (id == MacPibAttributeIdentifier::pCurrentChannel)
1597 {
1598 m_currentChannel = attribute->pCurrentChannel;
1599 }
1600 }
1601
1603 {
1604 if (id == MacPibAttributeIdentifier::macExtendedAddress && status == MacStatus::SUCCESS)
1605 {
1606 // Section (3.2.2.5.3 , 6.g)
1607 // Set nwkExtendedPanId and m_nwkIeeeAddress and nwkPanId
1610
1611 // Configure the capability information of the PAN coordinator
1612 CapabilityInformation capaInfo;
1615
1616 // Set Beacon payload size followed by the beacon payload content
1617 // before starting a network
1618 // See Figure 3-37 Establishing a Network
1619 // See also 3.6.7.
1621 }
1622 else
1623 {
1625 m_netFormParams = {};
1626 m_netFormParamsGen = nullptr;
1627
1629 {
1631 confirmParams.m_status = NwkStatus::STARTUP_FAILURE;
1633 }
1634 }
1635 }
1636 else if (m_pendPrimitiveNwk == PendingPrimitiveNwk::NLME_JOIN && status == MacStatus::SUCCESS)
1637 {
1638 if (id == MacPibAttributeIdentifier::macShortAddress)
1639 {
1641 m_mac,
1642 MacPibAttributeIdentifier::macPanId);
1643 }
1644 else if (id == MacPibAttributeIdentifier::macPanId)
1645 {
1646 NlmeJoinConfirmParams joinConfirmParams;
1647 joinConfirmParams.m_channelList = m_joinParams.m_scanChannelList;
1648 joinConfirmParams.m_status = NwkStatus::SUCCESS;
1649 joinConfirmParams.m_networkAddress = m_nwkNetworkAddress;
1650 joinConfirmParams.m_extendedPanId = m_nwkExtendedPanId;
1651 joinConfirmParams.m_enhancedBeacon = false;
1652
1654 m_joinParams = {};
1655
1657 {
1658 m_nlmeJoinConfirmCallback(joinConfirmParams);
1659 }
1660 }
1661 }
1663 status == MacStatus::SUCCESS)
1664 {
1665 if (id == MacPibAttributeIdentifier::pCurrentChannel)
1666 {
1667 // TODO: MLME-START.request should be issue sequentially to all the interfaces in the
1668 // nwkMacInterfaceTable (currently not supported), for the moment only a single
1669 // interface is supported.
1670 MlmeStartRequestParams startParams;
1671 startParams.m_logCh = m_currentChannel;
1672 startParams.m_logChPage = 0; // In zigbee, only page 0 is supported.
1673 startParams.m_PanId = m_nwkPanId;
1677 startParams.m_coorRealgn = false;
1678 startParams.m_panCoor = false;
1679
1681 }
1682 }
1683}
1684
1685void
1687{
1688 NS_LOG_FUNCTION(this);
1689
1691 MlmeOrphanResponseParams respParams;
1692
1693 if (m_nwkNeighborTable.LookUpEntry(params.m_orphanAddr, entry))
1694 {
1695 respParams.m_assocMember = true;
1696 respParams.m_orphanAddr = params.m_orphanAddr;
1697 respParams.m_shortAddr = entry->GetNwkAddr();
1698
1699 // Temporarily store the NLME-JOIN.indications parameters that will be
1700 // returned after the DIRECT_JOIN process concludes.
1701 // (after MLME-COMM-STATUS.indication is received)
1702 CapabilityInformation capability;
1703 capability.SetReceiverOnWhenIdle(entry->IsRxOnWhenIdle());
1704
1705 if (entry->GetDeviceType() == NwkDeviceType::ZIGBEE_ROUTER)
1706 {
1708 }
1709 else if (entry->GetDeviceType() == NwkDeviceType::ZIGBEE_ENDDEVICE)
1710 {
1712 }
1714 m_joinIndParams.m_extendedAddress = params.m_orphanAddr;
1715 m_joinIndParams.m_networkAddress = entry->GetNwkAddr();
1717
1718 NS_LOG_DEBUG("[NLME-JOIN.request]: ["
1719 << params.m_orphanAddr << " | " << entry->GetNwkAddr()
1720 << "] found in neighbor table, responding to orphaned device");
1721
1723 }
1724}
1725
1726void
1728{
1729 NS_LOG_FUNCTION(this);
1730
1731 // Return the results to the next layer of the router or coordinator
1732 // only after a SUCCESSFUL join to the network.
1733 if (params.m_status == MacStatus::SUCCESS)
1734 {
1735 if (params.m_dstExtAddr == m_joinIndParams.m_extendedAddress &&
1737 {
1739 m_joinIndParams = {};
1740
1742 {
1743 m_nlmeJoinIndicationCallback(joinIndParams);
1744 }
1745 }
1746 else if (params.m_dstExtAddr == m_joinIndParams.m_extendedAddress &&
1748 {
1751 }
1752 }
1753
1754 // TODO: Handle other situations for MlmeCommStatusIndication according
1755 // to the status and primitive in use.
1756}
1757
1758void
1760{
1761 NS_LOG_FUNCTION(this);
1762
1763 // Zigbee specification Section 3.6.1.3
1764 // Update Neighbor Table with information of the beacon payload
1765 // during a network-discovery
1766
1767 if ((params.m_sdu->GetSize() == 0) ||
1768 (params.m_panDescriptor.m_coorAddrMode != lrwpan::AddressMode::SHORT_ADDR))
1769 {
1770 // The beacon do not contain beacon payload or is for a different network
1771 // stop any further process.
1772 return;
1773 }
1774
1775 ZigbeeBeaconPayload beaconPayload;
1776 params.m_sdu->RemoveHeader(beaconPayload);
1777
1778 if (beaconPayload.GetProtocolId() != 0)
1779 {
1780 return;
1781 }
1782
1783 // TODO: Add a Permit to join, stack profile , update id and capability check
1784
1786 {
1787 // Keep a network descriptor list from the information in the beacon
1788 // to later on pass to the next higher layer when the network-discovery
1789 // process is over (NLME-NETWORK-DISCOVERY.confirm)
1790 NetworkDescriptor descriptor;
1791 descriptor.m_extPanId = beaconPayload.GetExtPanId();
1792 descriptor.m_panId = params.m_panDescriptor.m_coorPanId;
1793 descriptor.m_updateId = 0; // TODO: unknown
1794 descriptor.m_logCh = params.m_panDescriptor.m_logCh;
1795 descriptor.m_stackProfile = static_cast<StackProfile>(beaconPayload.GetStackProfile());
1796 descriptor.m_zigbeeVersion = beaconPayload.GetProtocolId();
1797
1798 SuperframeInformation superframe(params.m_panDescriptor.m_superframeSpec);
1799 descriptor.m_beaconOrder = superframe.GetBeaconOrder();
1800 descriptor.m_superframeOrder = superframe.GetFrameOrder();
1801 descriptor.m_permitJoining = superframe.IsAssocPermit();
1802
1803 descriptor.m_routerCapacity = beaconPayload.GetRouterCapacity();
1804 descriptor.m_endDeviceCapacity = beaconPayload.GetEndDevCapacity();
1805 m_networkDescriptorList.emplace_back(descriptor);
1806
1807 // Keep track of the pan id (16 bits) and the extended PAN id for
1808 // future join (association) procedures.
1809 m_panIdTable.AddEntry(descriptor.m_extPanId, descriptor.m_panId);
1810 // NOTE: In Zigbee all PAN coordinators or routers work with a
1811 // SOURCE short address addressing mode, therefore the PAN descriptors only
1812 // contain the short address.
1813 NS_LOG_DEBUG("Received beacon frame from [" << params.m_panDescriptor.m_coorShortAddr
1814 << "]");
1815 }
1816
1818 if (m_nwkNeighborTable.LookUpEntry(params.m_panDescriptor.m_coorShortAddr, entry))
1819 {
1820 // Update Neighbor table with the info of the received beacon
1821
1822 entry->SetNwkAddr(params.m_panDescriptor.m_coorShortAddr);
1823 entry->SetTimeoutCounter(Seconds(15728640));
1825 entry->SetLqi(params.m_panDescriptor.m_linkQuality);
1826 entry->SetOutgoingCost(GetLQINonLinearValue(params.m_panDescriptor.m_linkQuality));
1827 // m_nwkNeighborTable.Update(params.m_panDescriptor.m_coorShortAddr, entry);
1828 // TODO: Update other fields if necessary and
1829 // Additional and optional fields.
1830 }
1831 else
1832 {
1833 // Add a new entry to the neighbor table, information comes from
1834 // the MAC PAN descriptor and the beacon payload received.
1835 NwkDeviceType devType;
1836 if (params.m_panDescriptor.m_coorShortAddr == Mac16Address("00:00"))
1837 {
1839 }
1840 else
1841 {
1843 }
1844
1845 // Create neighbor table entry with the basic fields
1846 Ptr<NeighborTableEntry> newEntry =
1847 Create<NeighborTableEntry>(Mac64Address("FF:FF:FF:FF:FF:FF:FF:FF"),
1848 params.m_panDescriptor.m_coorShortAddr,
1849 devType,
1850 true,
1851 0,
1852 Seconds(15728640),
1854 NBR_NONE,
1855 0,
1856 params.m_panDescriptor.m_linkQuality,
1857 GetLQINonLinearValue(params.m_panDescriptor.m_linkQuality),
1858 0,
1859 false,
1860 0);
1861
1862 // If necessary add information to the
1863 // additional and optional fields. Currently only 2 additional fields are added:
1864 newEntry->SetExtPanId(beaconPayload.GetExtPanId());
1865 newEntry->SetLogicalCh(params.m_panDescriptor.m_logCh);
1866
1867 m_nwkNeighborTable.AddEntry(newEntry);
1868 }
1869}
1870
1871void
1873{
1874 NS_LOG_FUNCTION(this);
1875
1876 // Joining Procedure through Association (Parent procedure)
1877 // Zigbee Specification 3.6.1.4.1
1878
1879 CapabilityInformation receivedCapability(params.capabilityInfo);
1880 auto devType = static_cast<NwkDeviceType>(receivedCapability.GetDeviceType());
1881
1883 if (m_nwkNeighborTable.LookUpEntry(params.m_extDevAddr, entry))
1884 {
1885 if (entry->GetDeviceType() == devType)
1886 {
1887 MlmeAssociateResponseParams responseParams;
1888 responseParams.m_status = MacStatus::SUCCESS;
1889 responseParams.m_assocShortAddr = entry->GetNwkAddr();
1890 responseParams.m_extDevAddr = entry->GetExtAddr();
1892 }
1893 else
1894 {
1895 m_nwkNeighborTable.Delete(params.m_extDevAddr);
1897 }
1898 }
1899 else
1900 {
1901 // Device currently do not exist in coordinator,
1902 // allocate an address and add to neighbor table.
1903
1904 Mac16Address allocatedAddr;
1905 if (receivedCapability.IsAllocateAddrOn())
1906 {
1907 allocatedAddr = AllocateNetworkAddress();
1908 }
1909 else
1910 {
1911 // The device is associated but it will only use its
1912 // extended address (EUI-64 also known as IEEE Address)
1913 allocatedAddr = Mac16Address("FF:FE");
1914 }
1915
1916 CapabilityInformation capability(params.capabilityInfo);
1917
1918 Ptr<NeighborTableEntry> newEntry =
1919 Create<NeighborTableEntry>(params.m_extDevAddr,
1920 allocatedAddr,
1921 devType,
1922 capability.IsReceiverOnWhenIdle(),
1923 0,
1924 Seconds(15728640),
1926 NBR_CHILD,
1927 0,
1928 params.lqi,
1929 0,
1930 0,
1931 true,
1932 0);
1933 // Optional parameters
1934 newEntry->SetExtPanId(m_nwkExtendedPanId);
1935
1936 MlmeAssociateResponseParams responseParams;
1937 responseParams.m_extDevAddr = params.m_extDevAddr;
1938
1939 if (m_nwkNeighborTable.AddEntry(newEntry))
1940 {
1941 responseParams.m_status = MacStatus::SUCCESS;
1942 responseParams.m_assocShortAddr = allocatedAddr;
1943
1944 // Temporarily store the NLME-JOIN.indications parameters that will be
1945 // returned after the association process concludes.
1946 // (after MLME-COMM-STATUS.indication received and beacon payload updated)
1947 m_joinIndParams.m_capabilityInfo = receivedCapability.GetCapability();
1948 m_joinIndParams.m_extendedAddress = params.m_extDevAddr;
1949 m_joinIndParams.m_networkAddress = allocatedAddr;
1951 }
1952 else
1953 {
1954 responseParams.m_status = MacStatus::FULL_CAPACITY;
1955 responseParams.m_assocShortAddr = Mac16Address("FF:FF");
1956 }
1957
1958 NS_LOG_DEBUG("\n "
1959 << "Storing an Associate response command with the allocated address "
1960 << "[" << responseParams.m_assocShortAddr << "]");
1961
1963 }
1964}
1965
1966void
1968{
1969 NS_LOG_FUNCTION(this << packet);
1970
1971 if (params.m_dstAddr == m_nwkNetworkAddress)
1972 {
1973 NS_LOG_DEBUG("The source and the destination of the route request are the same!");
1974 return;
1975 }
1976
1977 // Zigbee specification r22.1.0, Section 3.2.1.1.3 and Section 3.6.2.1
1978 // check that we are associated
1979 if (m_nwkNetworkAddress == "FF:FF")
1980 {
1981 NS_LOG_DEBUG("Cannot send data, the device is not currently associated");
1982
1984 {
1985 NldeDataConfirmParams confirmParams;
1986 confirmParams.m_status = NwkStatus::INVALID_REQUEST;
1987 confirmParams.m_txTime = Simulator::Now();
1988 confirmParams.m_nsduHandle = params.m_nsduHandle;
1989 m_nldeDataConfirmCallback(confirmParams);
1990 }
1991 return;
1992 }
1993
1994 // Constructing the NPDU (Zigbee specification r22.1.0, Section 3.2.1.1.3 and Section 3.6.2.1)
1995 ZigbeeNwkHeader nwkHeader;
1996 nwkHeader.SetFrameType(DATA);
1997 nwkHeader.SetProtocolVer(3);
1998 nwkHeader.SetDiscoverRoute(static_cast<DiscoverRouteType>(params.m_discoverRoute));
1999 nwkHeader.SetDstAddr(params.m_dstAddr);
2000
2001 if (params.m_useAlias)
2002 {
2003 nwkHeader.SetSrcAddr(params.m_aliasSrcAddr);
2004 nwkHeader.SetSeqNum(params.m_aliasSeqNumber.GetValue());
2005 }
2006 else
2007 {
2010 }
2011
2012 if (params.m_radius == 0)
2013 {
2014 nwkHeader.SetRadius(m_nwkMaxDepth * 2);
2015 }
2016 else
2017 {
2018 nwkHeader.SetRadius(params.m_radius);
2019 }
2020
2021 if (params.m_securityEnable)
2022 {
2023 // TODO: Secure processing (Section 3.6.2.1)
2024 NS_ABORT_MSG("Security processing is currently not supported");
2025 }
2026
2027 // Check the current device capabilities
2028 CapabilityInformation capability;
2030
2031 if (capability.GetDeviceType() == ENDDEVICE)
2032 {
2033 nwkHeader.SetEndDeviceInitiator();
2034 }
2035
2036 if (params.m_dstAddrMode == MCST)
2037 {
2038 nwkHeader.SetMulticast();
2039 // TODO:
2040 // set the nwkHeader multicast control according to
2041 // the values of the non-member radios parameter
2042 // See 3.2.1.1.3
2043 }
2044
2045 packet->AddHeader(nwkHeader);
2046
2047 if (capability.GetDeviceType() == ROUTER)
2048 {
2049 if (params.m_dstAddrMode == MCST)
2050 {
2051 // The destination is MULTICAST (See 3.6.2)
2052 NS_ABORT_MSG("Multicast is currently not supported");
2053 // TODO
2054 return;
2055 }
2056 else if (IsBroadcastAddress(params.m_dstAddr))
2057 {
2058 // The destination is BROADCAST (See 3.6.5)
2059 SendDataBcst(packet, params.m_nsduHandle);
2060 }
2061 else
2062 {
2063 // The destination is UNICAST (See 3.6.3.3)
2064 SendDataUcst(packet, params.m_nsduHandle);
2065 }
2066 }
2067 else
2068 {
2069 // The device is an END DEVICE
2070 // direct message to its Parent device (Coordinator)
2072 if (m_nwkNeighborTable.GetParent(entry))
2073 {
2074 // Buffer a copy of the DATA packet that will be transmitted
2075 // for handling after transmission (i.e. NSDE-DATA.confirm)
2076 BufferTxPkt(packet->Copy(), m_macHandle.GetValue(), params.m_nsduHandle);
2077
2078 McpsDataRequestParams mcpsDataparams;
2079 mcpsDataparams.m_txOptions = 0x01; // Acknowledment on.
2080 mcpsDataparams.m_dstPanId = m_nwkPanId;
2081 mcpsDataparams.m_msduHandle = m_macHandle.GetValue();
2082 mcpsDataparams.m_srcAddrMode = SHORT_ADDR;
2083 mcpsDataparams.m_dstAddrMode = SHORT_ADDR;
2084 mcpsDataparams.m_dstAddr = entry->GetNwkAddr();
2085 m_macHandle++;
2087 }
2088 else
2089 {
2090 // Section 3.6.3.7.1
2091 // Link failure with Parent device
2092 // TODO
2093 /*
2094 if (!m_nlmeNwkStatusIndicationCallback.IsNull())
2095 {
2096 NlmeNetworkStatusIndication indicationParams;
2097
2098 m_networkStatusCode = PARENT_LINK_FAILURE;
2099 m_nlmeNwkStatusIndicationCallback(confirmParams);
2100 }
2101 */
2102 }
2103 }
2105}
2106
2107void
2109{
2110 NS_LOG_FUNCTION(this);
2111
2114 "channelsField and its channelPageCount size do not match "
2115 "in networkFormationParams");
2116
2118 {
2120 m_netFormParams = {};
2121 m_netFormParamsGen = nullptr;
2122
2124 {
2126 confirmParams.m_status = NwkStatus::INVALID_REQUEST;
2128 }
2129 return;
2130 }
2131
2132 if (params.m_distributedNetwork)
2133 {
2134 // Zigbee Specification r22.1.0, 3.2.2.5 , 3)
2135 // Verify Distributed Network Address is in a valid range.
2136 // TODO: Verify the address is not > 0xFFF7
2137 if (params.m_distributedNetwork == Mac16Address("00:00"))
2138 {
2140 m_netFormParams = {};
2141 m_netFormParamsGen = nullptr;
2142
2144 {
2146 confirmParams.m_status = NwkStatus::INVALID_REQUEST;
2148 }
2149 return;
2150 }
2151 }
2152
2153 // 4. On receipt of this primitive the NLME shall first validate the
2154 // ChannelListStructure parameter according to section 3.2.2.2.2.
2155 // (if nwkMacInterfaceTable support is added)
2156 // If validation fails the NLME-NETWORK-FORMATION.confirm
2157 // primitive shall be issued with a Status parameter set to INVALID_PARAMETER.
2158
2159 if (params.m_scanChannelList.channelPageCount != 1)
2160 {
2161 NS_FATAL_ERROR("Multi page scanning not supported");
2162 }
2163
2164 // Only page 0 is supported (O-QPSK 250 kbps)
2165 // Take 5 MSB bits: b27-b31 to check the page
2166 uint32_t page = (params.m_scanChannelList.channelsField[0] >> 27) & (0x01F);
2167
2168 if (page != 0)
2169 {
2170 NS_FATAL_ERROR("PHY band not supported (Only page 0 is supported)");
2171 }
2172
2173 uint8_t channelsCount = 0;
2174 for (int i = 11; i <= 26; i++)
2175 {
2176 channelsCount += (params.m_scanChannelList.channelsField[0] >> i) & 1;
2177 }
2178
2180 m_netFormParams = params;
2181
2182 if (channelsCount == 1)
2183 {
2184 // There is only 1 channel, skip energy scan and go directly to
2185 // active scan instead
2186 MlmeScanRequestParams mlmeParams;
2187 mlmeParams.m_chPage = page;
2188 mlmeParams.m_scanChannels = params.m_scanChannelList.channelsField[0];
2189 mlmeParams.m_scanDuration = params.m_scanDuration;
2190 mlmeParams.m_scanType = MLMESCAN_ACTIVE;
2192 }
2193 else if (channelsCount > 1)
2194 {
2195 MlmeScanRequestParams mlmeParams;
2196 mlmeParams.m_chPage = page;
2197 mlmeParams.m_scanChannels = params.m_scanChannelList.channelsField[0];
2198 mlmeParams.m_scanDuration = params.m_scanDuration;
2199 mlmeParams.m_scanType = MLMESCAN_ED;
2201 }
2202}
2203
2204void
2206{
2207 NS_LOG_FUNCTION(this);
2208
2209 if (params.m_dstAddr == m_nwkNetworkAddress && params.m_dstAddrMode == UCST_BCST)
2210 {
2211 NS_FATAL_ERROR("The source and the destination of the route request are the same!");
2212 return;
2213 }
2214
2215 // (See 3.2.2.33.3)
2216 // - Check the device has routing capacity
2217 // - Check the device dstAddrMode != NO_ADDRESS && dst != Broadcast address
2218 if (params.m_dstAddrMode != NO_ADDRESS && IsBroadcastAddress(params.m_dstAddr))
2219 {
2221 {
2222 NlmeRouteDiscoveryConfirmParams confirmParams;
2223 confirmParams.m_status = NwkStatus::INVALID_REQUEST;
2225 }
2226 return;
2227 }
2228
2229 CapabilityInformation capability;
2231 if (capability.GetDeviceType() != ROUTER && params.m_dstAddrMode != NO_ADDRESS)
2232 {
2234 {
2235 NlmeRouteDiscoveryConfirmParams confirmParams;
2236 confirmParams.m_status = NwkStatus::ROUTE_ERROR;
2238 }
2239 return;
2240 }
2241
2243
2244 ZigbeeNwkHeader nwkHeader;
2245 nwkHeader.SetFrameType(NWK_COMMAND);
2248 // See r22.1.0, Table 3-69
2249 // Set destination to broadcast (all routers and coordinator)
2250 nwkHeader.SetDstAddr(Mac16Address("FF:FC"));
2253
2256 payload.SetPathCost(0);
2257
2258 if (params.m_dstAddrMode == UCST_BCST)
2259 {
2260 // Set the rest of the nwkHeader and command payload parameters
2261 // as described in Zigbee specification, Section 3.2.2.33.3
2262 if (params.m_radius == 0)
2263 {
2264 nwkHeader.SetRadius(m_nwkMaxDepth * 2);
2265 }
2266 else
2267 {
2268 nwkHeader.SetRadius(params.m_radius);
2269 }
2270
2271 payload.SetDstAddr(params.m_dstAddr);
2272
2273 Mac16Address nextHop;
2274 RouteDiscoveryStatus routeStatus =
2275 FindNextHop(m_nwkNetworkAddress, 0, nwkHeader, payload, nextHop);
2276
2277 if (routeStatus == ROUTE_FOUND)
2278 {
2280 {
2281 NlmeRouteDiscoveryConfirmParams confirmParams;
2282 confirmParams.m_status = NwkStatus::SUCCESS;
2284 }
2285 }
2286 else if (routeStatus == ROUTE_NOT_FOUND)
2287 {
2288 // Route not found. Route marked as DISCOVER UNDERWAY,
2289 // we initiate route discovery.
2292 this,
2293 nwkHeader,
2294 payload,
2296
2299 }
2300 }
2301 else if (params.m_dstAddrMode == MCST)
2302 {
2303 NS_ABORT_MSG("Multicast Route discovery not supported");
2304 }
2305 else if (params.m_dstAddrMode == NO_ADDRESS)
2306 {
2307 // Many-to-one route discovery.
2308 // (See Last paragraph of Zigbee Specification, Section 3.6.3.5.1)
2309 m_nwkIsConcentrator = true;
2310
2312
2313 payload.SetDstAddr(Mac16Address("FF:FF"));
2314 if (params.m_noRouteCache)
2315 {
2317 }
2318 else
2319 {
2321 }
2322
2323 RouteDiscoveryStatus routeStatus =
2324 ProcessManyToOneRoute(m_nwkNetworkAddress, 0, nwkHeader, payload);
2325
2326 if (routeStatus == MANY_TO_ONE_ROUTE || routeStatus == ROUTE_UPDATED)
2327 {
2328 // TODO if nwkConcentratorDiscoveryTime != 0, schedule
2329 // RREQ every nwkConcentratorDiscovery time.
2330
2333 this,
2334 nwkHeader,
2335 payload,
2336 0);
2339 }
2340 }
2341}
2342
2343void
2345{
2346 NS_LOG_FUNCTION(this);
2347
2348 if (params.m_scanDuration > 14)
2349 {
2350 NS_FATAL_ERROR("Scan duration must be an int between 0 and 14");
2351 }
2352
2353 if (params.m_scanChannelList.channelPageCount != params.m_scanChannelList.channelsField.size())
2354 {
2355 NS_FATAL_ERROR("In scanChannelList parameter, channelPageCount "
2356 "and the channelsField structure size does not match");
2357 }
2358
2359 // TODO: Add support to scan other MAC interfaces, for the moment
2360 // only a single interface and only Page 0 is supported (PHY O-QPSK 250 kbps)
2361
2362 if (params.m_scanChannelList.channelsField.size() != 1)
2363 {
2364 NS_FATAL_ERROR("Only a single MAC interface supported");
2365 }
2366
2367 uint8_t page = (params.m_scanChannelList.channelsField[0] >> 27) & (0x01F);
2368 if (page != 0)
2369 {
2370 NS_FATAL_ERROR("Only Page 0 (O-QPSK 250 kbps) is supported.");
2371 }
2372
2374
2375 MlmeScanRequestParams scanParams;
2376 scanParams.m_chPage = 0; // Only page 0 is supported.
2377 scanParams.m_scanChannels = params.m_scanChannelList.channelsField[0];
2378 scanParams.m_scanDuration = params.m_scanDuration;
2379 scanParams.m_scanType = MLMESCAN_ACTIVE;
2380
2381 NS_LOG_DEBUG("Active scanning started, "
2382 << " on page " << page << " and channels 0x" << std::hex
2383 << params.m_scanChannelList.channelsField[0] << std::dec);
2384
2386}
2387
2388void
2390{
2391 NS_LOG_FUNCTION(this);
2392
2393 // TODO: Check the device is router or coordinator, send invalid_request
2394 // status otherwise. See 3.6.1.4.3.
2395
2397 if (m_nwkNeighborTable.LookUpEntry(params.m_deviceAddr, entry))
2398 {
2399 NS_LOG_WARN("[NLME-DIRECT-JOIN.request]: "
2400 "Device already present in neighbor table. ");
2401
2403 {
2404 NlmeDirectJoinConfirmParams confirmParams;
2405 confirmParams.m_status = NwkStatus::ALREADY_PRESENT;
2406 confirmParams.m_deviceAddr = params.m_deviceAddr;
2407 m_nlmeDirectJoinConfirmCallback(confirmParams);
2408 }
2409 }
2410 else
2411 {
2412 CapabilityInformation capaInfo;
2413 capaInfo.SetCapability(params.m_capabilityInfo);
2414
2415 Mac16Address allocatedAddr;
2416 if (capaInfo.IsAllocateAddrOn())
2417 {
2418 allocatedAddr = AllocateNetworkAddress();
2419 }
2420 else
2421 {
2422 // The device is associated but it will only use its
2423 // extended address (EUI-64 also known as IEEE Address)
2424 allocatedAddr = Mac16Address("FF:FE");
2425 }
2426
2427 NwkDeviceType devType;
2428 if (capaInfo.GetDeviceType() == MacDeviceType::ROUTER)
2429 {
2431 }
2432 else
2433 {
2435 }
2436
2437 Ptr<NeighborTableEntry> newEntry =
2438 Create<NeighborTableEntry>(params.m_deviceAddr,
2439 allocatedAddr,
2440 devType,
2441 capaInfo.IsReceiverOnWhenIdle(),
2442 0,
2443 Seconds(15728640),
2445 NBR_CHILD,
2446 0,
2447 255,
2448 0,
2449 0,
2450 true,
2451 0);
2452
2453 NlmeDirectJoinConfirmParams confirmParams;
2454
2455 if (m_nwkNeighborTable.AddEntry(newEntry))
2456 {
2457 NS_LOG_DEBUG("Device added to neighbor table (" << m_nwkNeighborTable.GetSize()
2458 << ") with address [" << allocatedAddr
2459 << " | " << params.m_deviceAddr << "]");
2461 {
2462 confirmParams.m_status = NwkStatus::SUCCESS;
2463 confirmParams.m_deviceAddr = params.m_deviceAddr;
2464 m_nlmeDirectJoinConfirmCallback(confirmParams);
2465 }
2466 }
2467 else
2468 {
2469 NS_LOG_WARN("Error, neighbor table is full");
2471 {
2473 confirmParams.m_deviceAddr = params.m_deviceAddr;
2474 m_nlmeDirectJoinConfirmCallback(confirmParams);
2475 }
2476 }
2477 }
2478}
2479
2480void
2482{
2483 NS_LOG_FUNCTION(this);
2484
2485 if (params.m_scanDuration > 14)
2486 {
2487 NS_FATAL_ERROR("Scan duration must be an int between 0 and 14");
2488 }
2489
2490 if (params.m_scanChannelList.channelPageCount != params.m_scanChannelList.channelsField.size())
2491 {
2492 NS_FATAL_ERROR("In scanChannelList parameter, channelPageCount "
2493 "and the channelsField structure size does not match");
2494 }
2495
2496 // TODO: Add support to scan other MAC interfaces, for the moment
2497 // only a single interface and only Page 0 is supported (PHY O-QPSK 250 kbps)
2498
2499 // TODO: Only devices who have not join another network can call JOIN.
2500
2501 if (params.m_scanChannelList.channelsField.size() != 1)
2502 {
2503 NS_FATAL_ERROR("Only a single MAC interface supported");
2504 }
2505
2506 uint8_t page = (params.m_scanChannelList.channelsField[0] >> 27) & (0x01F);
2507 if (page != 0)
2508 {
2509 NS_FATAL_ERROR("Only Page 0 (O-QPSK 250 kbps) is supported.");
2510 }
2511
2513 m_joinParams = params;
2514
2515 if (params.m_rejoinNetwork == DIRECT_OR_REJOIN)
2516 {
2517 // Zigbee specification r22.1.0 Section 3.6.1.4.3.1,
2518 // Child procedure for joining or re-joining a network through
2519 // orphaning (DIRECT JOIN procedure).
2520
2521 MlmeScanRequestParams scanParams;
2522 scanParams.m_chPage = page;
2523 scanParams.m_scanChannels = params.m_scanChannelList.channelsField[0];
2524
2525 // Note: Scan duration is fixed to a macResponseWaitTime in an Orphan scan
2526 // (i.e. It does not use the scanDuration parameter)
2527 scanParams.m_scanType = MLMESCAN_ORPHAN;
2528 NS_LOG_DEBUG("Orphan scanning started, "
2529 << "sending orphan notifications on page " << page << " and channels "
2530 << std::hex << params.m_scanChannelList.channelsField[0]);
2531
2533 }
2534 else if (params.m_rejoinNetwork == ASSOCIATION)
2535 {
2536 // Check if we have the MAC pan id info recorded during the discovery process
2537 uint16_t panId;
2538 if (!m_panIdTable.GetEntry(params.m_extendedPanId, panId))
2539 {
2540 NS_LOG_ERROR("Error PAN id of neighbor device not found");
2541 }
2542
2543 // Zigbee specification r22.1.0 Section 3.6.1.4.1
2544 // Child procedure for joining a network through ASSOCIATION.
2545
2546 NlmeJoinConfirmParams joinConfirmParams;
2547 Ptr<NeighborTableEntry> bestParentEntry;
2548
2549 if (m_nwkNeighborTable.LookUpForBestParent(params.m_extendedPanId, bestParentEntry))
2550 {
2551 MlmeAssociateRequestParams assocParams;
2552 m_nwkCapabilityInformation = params.m_capabilityInfo;
2553
2554 assocParams.m_chNum = bestParentEntry->GetLogicalCh();
2555 assocParams.m_chPage = 0; // Zigbee assumes Page is always 0
2556 assocParams.m_capabilityInfo = params.m_capabilityInfo;
2557 assocParams.m_coordPanId = panId;
2558
2559 if (bestParentEntry->GetNwkAddr() != Mac16Address("FF:FE"))
2560 {
2562 assocParams.m_coordShortAddr = bestParentEntry->GetNwkAddr();
2563 NS_LOG_DEBUG("\n "
2564 << "Send Association Request [" << bestParentEntry->GetNwkAddr()
2565 << "] | PAN ID: " << std::hex << "0x" << panId
2566 << " | Extended PAN ID: 0x" << params.m_extendedPanId << std::dec);
2567 }
2568 else
2569 {
2571 assocParams.m_coordExtAddr = bestParentEntry->GetExtAddr();
2572 NS_LOG_DEBUG("Send Assoc. Req. to [" << bestParentEntry->GetNwkAddr()
2573 << "] in \nPAN id and Ext PAN id: " << std::hex
2574 << "(0x" << panId << " | 0x"
2575 << params.m_extendedPanId << ")" << std::dec);
2576 }
2577
2579 m_nwkCapabilityInformation = params.m_capabilityInfo;
2580
2581 // Temporarily store MLME-ASSOCIATE.request parameters until the JOIN process concludes
2582 m_associateParams = assocParams;
2583
2585 }
2586 else
2587 {
2589 m_joinParams = {};
2590
2592 {
2593 joinConfirmParams.m_extendedPanId = params.m_extendedPanId;
2594 joinConfirmParams.m_networkAddress = Mac16Address("FF:FF");
2595 joinConfirmParams.m_enhancedBeacon = false;
2596 joinConfirmParams.m_macInterfaceIndex = 0;
2597 joinConfirmParams.m_status = NwkStatus::NOT_PERMITED;
2598 m_nlmeJoinConfirmCallback(joinConfirmParams);
2599 }
2600 }
2601 }
2602 else
2603 {
2604 NS_FATAL_ERROR("Joining method not supported");
2605 }
2606}
2607
2608void
2610{
2611 NS_LOG_FUNCTION(this);
2612
2613 NS_ASSERT_MSG(params.m_beaconOrder == 15, "Beacon mode not supported for zigbee");
2614 NS_ASSERT_MSG(params.m_superframeOrder == 15, "Beacon mode not supported for zigbee");
2615
2616 CapabilityInformation capability;
2618
2619 if (capability.GetDeviceType() != MacDeviceType::ROUTER)
2620 {
2624 {
2625 NlmeStartRouterConfirmParams confirmParams;
2626 confirmParams.m_status = NwkStatus::INVALID_REQUEST;
2627 m_nlmeStartRouterConfirmCallback(confirmParams);
2628 }
2629 NS_LOG_ERROR("This device is not a Zigbee Router or is not joined to this network");
2630 }
2631 else
2632 {
2634 // store the NLME-START-ROUTER.request params while request the current channel
2635 m_startRouterParams = params;
2636 // request an update of the current channel in use in the PHY
2638 m_mac,
2639 MacPibAttributeIdentifier::pCurrentChannel);
2640 }
2641}
2642
2643void
2648
2649void
2654
2655void
2660
2661void
2666
2667void
2672
2673void
2678
2679void
2684
2685void
2690
2691void
2696
2697void
2699{
2700 // TODO : PurgeTxQueue();
2702 {
2703 ZigbeeNwkHeader peekedNwkHeader;
2704 p->PeekHeader(peekedNwkHeader);
2705
2706 Ptr<PendingTxPkt> pendingTxPkt = Create<PendingTxPkt>();
2707 pendingTxPkt->dstAddr = peekedNwkHeader.GetDstAddr();
2708 pendingTxPkt->nsduHandle = nsduHandle;
2709 pendingTxPkt->txPkt = p;
2710 // TODO: expiration time here
2711 m_pendingTxQueue.emplace_back(pendingTxPkt);
2712 // TODO: pending trace here
2713 }
2714 else
2715 {
2716 // TODO: Drop trace here
2717 }
2718}
2719
2720bool
2722{
2723 // TODO : PurgeTxQueue();
2724
2725 /* std::erase_if(m_pendingTxQueue, [&dst](Ptr<PendingTxPkt> pkt) {
2726 return pkt->dstAddr == dst;
2727 });*/
2728
2729 for (auto iter = m_pendingTxQueue.begin(); iter != m_pendingTxQueue.end(); iter++)
2730 {
2731 if ((*iter)->dstAddr == dst)
2732 {
2733 *entry = **iter;
2734 // TODO: Dequeue trace if needed here.
2735 m_pendingTxQueue.erase(iter);
2736 return true;
2737 }
2738 }
2739 return false;
2740}
2741
2742void
2744{
2745 for (auto element : m_pendingTxQueue)
2746 {
2747 element = nullptr;
2748 }
2749 m_pendingTxQueue.clear();
2750}
2751
2752void
2753ZigbeeNwk::BufferTxPkt(Ptr<Packet> p, uint8_t macHandle, uint8_t nwkHandle)
2754{
2755 if (m_txBuffer.size() < m_txBufferMaxSize)
2756 {
2757 Ptr<TxPkt> txPkt = Create<TxPkt>();
2758 txPkt->macHandle = macHandle;
2759 txPkt->nwkHandle = nwkHandle;
2760 txPkt->txPkt = p;
2761 m_txBuffer.emplace_back(txPkt);
2762 }
2763 else
2764 {
2765 NS_LOG_DEBUG("Zigbee Tx Buffer is full, packet dropped.");
2766 // TODO : Drop trace for TX buffer
2767 }
2768}
2769
2770bool
2771ZigbeeNwk::RetrieveTxPkt(uint8_t macHandle, Ptr<TxPkt>& txPkt)
2772{
2773 for (auto bufferedPkt : m_txBuffer)
2774 {
2775 if (bufferedPkt->macHandle == macHandle)
2776 {
2777 txPkt = bufferedPkt;
2778
2779 std::erase_if(m_txBuffer,
2780 [&macHandle](Ptr<TxPkt> pkt) { return pkt->macHandle == macHandle; });
2781
2782 return true;
2783 }
2784 }
2785 return false;
2786}
2787
2788void
2790{
2791 for (auto element : m_txBuffer)
2792 {
2793 element = nullptr;
2794 }
2795 m_txBuffer.clear();
2796}
2797
2800{
2801 return static_cast<NwkStatus>(macStatus);
2802}
2803
2806{
2807 NS_LOG_FUNCTION(this);
2808
2810 {
2811 NS_FATAL_ERROR("Distributed allocation not supported");
2812 return Mac16Address("FF:FF");
2813 }
2814 else if (m_nwkAddrAlloc == STOCHASTIC_ALLOC)
2815 {
2816 // See nwkNetworkAddress valid range Zigbee specification r22.1.0, 3.5.2
2817 // Valid values in the Zigbee specification goes from 1 to 0xFFF7,
2818 // However, the range 0x8000 to 0x9FFF is used for multicast in other networks
2819 // (i.e. IPV6 over IEEE 802.15.4) for this reason, we avoid this range as well.
2820 // See RFC 4944, Section 9
2821 uint16_t rndValue = m_uniformRandomVariable->GetInteger(1, 0x7FFF);
2822 uint16_t rndValue2 = m_uniformRandomVariable->GetInteger(0xA000, 0xFFF7);
2823 uint16_t rndValue3 = m_uniformRandomVariable->GetInteger(1, 2);
2824
2825 Mac16Address allocAddr;
2826 if (rndValue3 == 1)
2827 {
2828 allocAddr = Mac16Address(rndValue);
2829 }
2830 else
2831 {
2832 allocAddr = Mac16Address(rndValue2);
2833 }
2834 return allocAddr;
2835 }
2836 else
2837 {
2838 NS_FATAL_ERROR("Address allocation method not supported");
2839 return Mac16Address("FF:FF");
2840 }
2841}
2842
2843uint8_t
2845{
2846 uint8_t mappedValue;
2847
2848 if (lqi > 50)
2849 {
2850 mappedValue = 1;
2851 }
2852 else if ((lqi <= 50) && (lqi > 45))
2853 {
2854 mappedValue = 2;
2855 }
2856 else if ((lqi <= 45) && (lqi > 40))
2857 {
2858 mappedValue = 3;
2859 }
2860 else if ((lqi <= 40) && (lqi > 38))
2861 {
2862 mappedValue = 4;
2863 }
2864 else if ((lqi <= 38) && (lqi > 35))
2865 {
2866 mappedValue = 5;
2867 }
2868 else if ((lqi <= 35) && (lqi > 24))
2869 {
2870 mappedValue = 6;
2871 }
2872 else
2873 {
2874 mappedValue = 7;
2875 }
2876
2877 return mappedValue;
2878}
2879
2880uint8_t
2881ZigbeeNwk::GetLinkCost(uint8_t lqi) const
2882{
2883 NS_LOG_FUNCTION(this);
2884
2886 {
2887 // Hop count based. Report constant value
2888 return 7;
2889 }
2890 else
2891 {
2892 // Based on non-linear mapping of LQI
2893 return GetLQINonLinearValue(lqi);
2894 }
2895}
2896
2897void
2900 uint8_t rreqRetries)
2901{
2902 NS_LOG_FUNCTION(this);
2903
2904 ZigbeePayloadType payloadType(ROUTE_REQ_CMD);
2905
2906 Ptr<Packet> nsdu = Create<Packet>();
2907 nsdu->AddHeader(payload);
2908 nsdu->AddHeader(payloadType);
2909 nsdu->AddHeader(nwkHeader);
2910
2912 nwkHeader.GetRadius() != 0)
2913 {
2914 // Set RREQ RETRIES
2915 Time rreqRetryTime = m_nwkcRREQRetryInterval + MilliSeconds(m_rreqJitter->GetValue());
2916
2917 Ptr<RreqRetryTableEntry> rreqRetryTableEntry;
2918 if (m_rreqRetryTable.LookUpEntry(payload.GetRouteReqId(), rreqRetryTableEntry))
2919 {
2920 if (rreqRetryTableEntry->GetRreqRetryCount() >= rreqRetries)
2921 {
2922 NS_LOG_DEBUG("Maximum RREQ retries reached for dst [" << payload.GetDstAddr()
2923 << "] and rreq ID "
2924 << payload.GetRouteReqId());
2925 // Note: The value of the maximum number of retries (rreqRetries) is either
2926 // nwkcInitialRREQRetries or nwkcRREQRetries depending on where the RREQ is
2927 // transmitted. See Zigbee specification r22.1.0, Section 3.6.3.5.1 This trace here
2928 // is used to keep track when the maximum RREQ retries is reached.
2930 payload.GetDstAddr(),
2931 rreqRetries);
2932 }
2933 else
2934 {
2935 // Schedule the next RREQ RETRY event and update entry.
2936 EventId rreqRetryEvent = Simulator::Schedule(rreqRetryTime,
2938 this,
2939 nwkHeader,
2940 payload,
2941 rreqRetries);
2942
2943 rreqRetryTableEntry->SetRreqRetryCount(rreqRetryTableEntry->GetRreqRetryCount() +
2944 1);
2945 rreqRetryTableEntry->SetRreqEventId(rreqRetryEvent);
2946 }
2947 }
2948 else
2949 {
2950 // Schedule the next RREQ RETRY and add a new record of the event.
2951 EventId rreqRetryEvent = Simulator::Schedule(rreqRetryTime,
2953 this,
2954 nwkHeader,
2955 payload,
2956 rreqRetries);
2957
2958 Ptr<RreqRetryTableEntry> newEntry =
2959 Create<RreqRetryTableEntry>(payload.GetRouteReqId(), rreqRetryEvent, 0);
2960
2961 m_rreqRetryTable.AddEntry(newEntry);
2962 }
2963 }
2964
2965 // Send the RREQ
2966 // See Section 3.4.1.1 Mac Data Service Requirements for RREQ
2967 if (nwkHeader.GetRadius() != 0)
2968 {
2969 McpsDataRequestParams params;
2970 params.m_dstPanId = m_nwkPanId;
2971 params.m_srcAddrMode = SHORT_ADDR;
2972 params.m_dstAddrMode = SHORT_ADDR;
2973 params.m_dstAddr = Mac16Address::GetBroadcast();
2974 params.m_msduHandle = m_macHandle.GetValue();
2975 m_macHandle++;
2977 }
2978 else
2979 {
2980 NS_LOG_DEBUG("Maximum radius reached, dropping RREQ");
2981 }
2982}
2983
2984void
2986 Mac16Address originator,
2987 Mac16Address responder,
2988 uint8_t rreqId,
2989 uint8_t pathcost)
2990{
2991 NS_LOG_FUNCTION(this);
2992
2993 ZigbeeNwkHeader nwkHeader;
2994 nwkHeader.SetFrameType(NWK_COMMAND);
2997
2998 nwkHeader.SetDstAddr(nextHop);
3002 // see Zigbee specification 3.4.2.2
3003 // Use the maximum possible radius
3004 nwkHeader.SetRadius(m_nwkMaxDepth * 2);
3005
3006 ZigbeePayloadType payloadType(ROUTE_REP_CMD);
3007
3009 payload.SetRouteReqId(rreqId);
3010 payload.SetOrigAddr(originator);
3011 payload.SetRespAddr(responder);
3012 payload.SetPathCost(pathcost);
3013
3014 // See Section 3.4.2 Mac Data Service Requirements for RREP
3015 McpsDataRequestParams params;
3016 params.m_dstPanId = m_nwkPanId;
3017 params.m_srcAddrMode = SHORT_ADDR;
3018 params.m_dstAddrMode = SHORT_ADDR;
3019 params.m_dstAddr = nextHop;
3020 params.m_msduHandle = m_macHandle.GetValue();
3021 m_macHandle++;
3022
3023 Ptr<Packet> nsdu = Create<Packet>();
3024 nsdu->AddHeader(payload);
3025 nsdu->AddHeader(payloadType);
3026 nsdu->AddHeader(nwkHeader);
3027
3029}
3030
3031int64_t
3033{
3034 NS_LOG_FUNCTION(this << stream);
3035 m_uniformRandomVariable->SetStream(stream);
3036 return 1;
3037}
3038
3039void
3041{
3042 NS_LOG_FUNCTION(this);
3043
3044 ZigbeeBeaconPayload beaconPayloadHeader;
3045 beaconPayloadHeader.SetStackProfile(static_cast<uint8_t>(m_nwkStackProfile));
3046 beaconPayloadHeader.SetRouterCapacity(m_nwkcCoordinatorCapable);
3047 beaconPayloadHeader.SetDeviceDepth(0); // Not used by stack profile (0x02 =ZIGBEE pro)
3048 beaconPayloadHeader.SetEndDevCapacity(true);
3049 beaconPayloadHeader.SetExtPanId(m_nwkExtendedPanId);
3050 beaconPayloadHeader.SetTxOffset(0xFFFFFF);
3051 // TODO: beaconPayload.SetNwkUpdateId(m_nwkUpdateId);
3052
3053 // Set the beacon payload length in the MAC PIBs and then proceed to
3054 // update the beacon payload
3056 m_beaconPayload->AddHeader(beaconPayloadHeader);
3058 pibAttr->macBeaconPayloadLength = m_beaconPayload->GetSize();
3060 m_mac,
3061 MacPibAttributeIdentifier::macBeaconPayloadLength,
3062 pibAttr);
3063}
3064
3065void
3067{
3068 NS_LOG_FUNCTION(this);
3069
3070 // Extract octets from m_beaconPayload and copy them into the
3071 // macBeaconPayload attribute
3073 pibAttr->macBeaconPayload.resize(m_beaconPayload->GetSize());
3074 m_beaconPayload->CopyData(pibAttr->macBeaconPayload.data(), m_beaconPayload->GetSize());
3075 m_beaconPayload = nullptr;
3077 m_mac,
3078 MacPibAttributeIdentifier::macBeaconPayload,
3079 pibAttr);
3080}
3081
3082std::ostream&
3083operator<<(std::ostream& os, const NwkStatus& state)
3084{
3085 switch (state)
3086 {
3087 case NwkStatus::SUCCESS:
3088 os << "SUCCESS";
3089 break;
3091 os << "FULL CAPACITY";
3092 break;
3094 os << "ACCESS DENIED";
3095 break;
3097 os << "COUNTER ERROR";
3098 break;
3100 os << "IMPROPER KEY TYPE";
3101 break;
3103 os << "IMPROPER SECURITY LEVEL";
3104 break;
3106 os << "UNSUPPORTED LEGACY";
3107 break;
3109 os << "UNSUPPORTED SECURITY";
3110 break;
3112 os << "BEACON LOSS";
3113 break;
3115 os << "CHANNEL ACCESS FAILURE";
3116 break;
3117 case NwkStatus::DENIED:
3118 os << "DENIED";
3119 break;
3121 os << "DISABLE TRX FAILURE";
3122 break;
3124 os << "SECURITY ERROR";
3125 break;
3127 os << "FRAME TOO LONG";
3128 break;
3130 os << "INVALID GTS";
3131 break;
3133 os << "INVALID HANDLE";
3134 break;
3136 os << "INVALID PARAMETER MAC";
3137 break;
3138 case NwkStatus::NO_ACK:
3139 os << "NO ACKNOLEDGMENT";
3140 break;
3142 os << "NO BEACON";
3143 break;
3144 case NwkStatus::NO_DATA:
3145 os << "NO DATA";
3146 break;
3148 os << "NO SHORT ADDRESS";
3149 break;
3151 os << "OUT OF CAP";
3152 break;
3154 os << "PAN ID CONFLICT";
3155 break;
3157 os << "REALIGMENT";
3158 break;
3160 os << "TRANSACTION EXPIRED";
3161 break;
3163 os << "TRANSACTION OVERFLOW";
3164 break;
3166 os << "TX ACTIVE";
3167 break;
3169 os << "UNAVAILABLE KEY";
3170 break;
3172 os << "INVALID ADDRESS";
3173 break;
3175 os << "ON TIME TOO LONG";
3176 break;
3178 os << "PAST TIME";
3179 break;
3181 os << "TRACKING OFF";
3182 break;
3184 os << "INVALID INDEX";
3185 break;
3187 os << "READ ONLY";
3188 break;
3190 os << "SUPERFRAME OVERLAP";
3191 break;
3193 os << "INVALID PARAMETER";
3194 break;
3196 os << "INVALID REQUEST";
3197 break;
3199 os << "NO PERMITED";
3200 break;
3202 os << "STARTUP FAILURE";
3203 break;
3205 os << "ALREADY PRESENT";
3206 break;
3208 os << "SYNC FAILURE";
3209 break;
3211 os << "NEIGHBOR TABLE FULL";
3212 break;
3214 os << "UNKNOWN DEVICE";
3215 break;
3217 os << "UNSUPPORTED ATTRIBUTE";
3218 break;
3220 os << "NO NETWORKS";
3221 break;
3223 os << "MAX FRAME COUNTER";
3224 break;
3225 case NwkStatus::NO_KEY:
3226 os << "NO KEY";
3227 break;
3229 os << "BAD CCM OUTPUT";
3230 break;
3232 os << "ROUTE DISCOVERY FAILED";
3233 break;
3235 os << "ROUTE ERROR";
3236 break;
3238 os << "BT TABLE FULL";
3239 break;
3241 os << "FRAME NOT BUFFERED";
3242 break;
3244 os << "INVALID INTERFACE";
3245 break;
3247 os << "LIMIT REACHED";
3248 break;
3250 os << "SCAN IN PROGRESS";
3251 break;
3252 }
3253 return os;
3254}
3255
3256std::ostream&
3257operator<<(std::ostream& os, const std::vector<uint8_t>& vec)
3258{
3259 std::copy(vec.begin(), vec.end(), std::ostream_iterator<uint16_t>(os, " "));
3260 return os;
3261}
3262
3263std::ostream&
3264operator<<(std::ostream& os, const uint8_t& num)
3265{
3266 os << static_cast<uint16_t>(num);
3267 return os;
3268}
3269
3270} // namespace zigbee
3271} // namespace ns3
bool IsNull() const
Check for null implementation.
Definition callback.h:555
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
An identifier for simulation events.
Definition event-id.h:45
This class can contain 16 bit addresses.
static Mac16Address GetBroadcast()
an EUI-64 address
uint64_t ConvertToInt() const
A base class which provides memory management and object aggregation.
Definition object.h:78
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:440
virtual void DoDispose()
Destructor implementation.
Definition object.cc:433
void AddHeader(const Header &header)
Add header to this packet.
Definition packet.cc:257
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition packet.h:850
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition packet.cc:389
Smart pointer class similar to boost::intrusive_ptr.
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:560
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
@ S
second
Definition nstime.h:105
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
virtual void McpsDataRequest(McpsDataRequestParams params, Ptr< Packet > p)=0
IEEE 802.15.4-2006, section 7.1.1.1 MCPS-DATA.request Request to transfer a MSDU.
virtual void MlmeOrphanResponse(MlmeOrphanResponseParams params)=0
IEEE 802.15.4-2011, section 6.2.7.2 MLME-ORPHAN.response Primitive used to initiatte a response to an...
virtual void MlmeGetRequest(MacPibAttributeIdentifier id)=0
IEEE 802.15.4-2006, section 7.1.6.1 MLME-GET.request Request information about a given PIB attribute.
virtual void MlmeScanRequest(MlmeScanRequestParams params)=0
IEEE 802.15.4-2011, section 6.2.10.1 MLME-SCAN.request Request primitive used to initiate a channel s...
virtual void MlmeAssociateResponse(MlmeAssociateResponseParams params)=0
IEEE 802.15.4-2011, section 6.2.2.3 MLME-ASSOCIATE.response Primitive used to initiate a response to ...
virtual void MlmeStartRequest(MlmeStartRequestParams params)=0
IEEE 802.15.4-2006, section 7.1.14.1 MLME-START.request Request to allow a PAN coordinator to initiat...
virtual void MlmeAssociateRequest(MlmeAssociateRequestParams params)=0
IEEE 802.15.4-2011, section 6.2.2.1 MLME-ASSOCIATE.request Request primitive used by a device to requ...
virtual void MlmeSetRequest(MacPibAttributeIdentifier id, Ptr< MacPibAttributes > attribute)=0
IEEE 802.15.4-2011, section 6.2.11.1 MLME-SET.request Attempts to write the given value to the indica...
void Dispose()
Dispose of all broadcast transaction records (BTR) in the broadcast transaction table(BTT).
bool AddEntry(Ptr< BroadcastTransactionRecord > entry)
Add a broadcast transaction record (BTR) to the broadcast transaction table(BTT).
bool LookUpEntry(uint8_t seq, Ptr< BroadcastTransactionRecord > &entryFound)
Look up for broadcast transaction record in the broadcast transaction table (BTT).
Represent the the Capability Information Bit fields See zigbe Specification r22.1....
uint8_t GetCapability() const
Used to obtain the complete capability information bit map.
void SetCapability(uint8_t capability)
Set the Capability Information bit map.
MacDeviceType GetDeviceType() const
This field will have a value of ROUTER if the joining device is a Zigbee router.
bool IsReceiverOnWhenIdle() const
This field will be set to the value of the lowest-order bit of the RxOnWhenIdle parameter passed to t...
void SetDeviceType(MacDeviceType devType)
Set the device type bit for the capability information field.
void SetReceiverOnWhenIdle(bool value)
Set the Receiver On When Idle bit for the capability information field.
bool IsAllocateAddrOn() const
This field will have a value of true in implementations of this specification, indicating that the jo...
bool GetParent(Ptr< NeighborTableEntry > &entryFound)
Look for this device Parent neighbor (A.K.A coordinator).
void Dispose()
Dispose of the table and all its elements.
bool LookUpForBestParent(uint64_t epid, Ptr< NeighborTableEntry > &entryFound)
Perform a search for the best candidate parent based on some attributes.
bool AddEntry(Ptr< NeighborTableEntry > entry)
Add an entry to the neighbor table.
void Print(Ptr< OutputStreamWrapper > stream) const
Print the neighbor table.
bool LookUpEntry(Mac16Address nwkAddr, Ptr< NeighborTableEntry > &entryFound)
Look and return and entry if exists in the neighbor table.
uint32_t GetSize()
Get the size of the neighbor table.
void Delete(Mac64Address extAddr)
Delete the specified entry from the neighbor table.
bool GetEntry(uint64_t extPanId, uint16_t &panId)
Get the 16 bit MAC PAN id based on the reference extended PAN id.
void AddEntry(uint64_t extPanId, uint16_t panId)
Add an entry to the PAN Id table.
void Dispose()
Dispose of the table and all its elements.
void Dispose()
Dispose of the table and all its elements.
void Delete(uint8_t id, Mac16Address src)
Delete an entry from the route discovery table.
bool AddEntry(Ptr< RouteDiscoveryTableEntry > rt)
Add an entry to the route discovery table, in essence the contents of a RREQ command.
bool LookUpEntry(uint8_t id, Mac16Address src, Ptr< RouteDiscoveryTableEntry > &entryFound)
Look up for a route discovery table entry, the seareched entry must match the id and the src address ...
void Print(Ptr< OutputStreamWrapper > stream)
Print the contents of the route discovery table.
void DeleteExpiredEntry()
Delete the first occrurance of an expired entry (ROUTE_INACTIVE status)
bool AddEntry(Ptr< RoutingTableEntry > rt)
Adds an entry to the routing table.
uint32_t GetMaxTableSize() const
Get the maximum size of the routing table.
void Print(Ptr< OutputStreamWrapper > stream) const
Print the Routing table.
uint32_t GetSize()
Get the size of the routing table.
bool LookUpEntry(Mac16Address dstAddr, Ptr< RoutingTableEntry > &entryFound)
Look for an specific entry in the routing table.
void Dispose()
Dispose of the table and all its elements.
void Print(Ptr< OutputStreamWrapper > stream) const
Print the neighbor table.
void Dispose()
Dispose of the table and all its elements.
bool LookUpEntry(uint8_t rreqId, Ptr< RreqRetryTableEntry > &entryFound)
Look up for an entry in the table.
void Delete(uint8_t rreqId)
Delete an entry from the table using the RREQ ID.
bool AddEntry(Ptr< RreqRetryTableEntry > entry)
Adds an entry to the table.
Represent the Superframe Specification information field.
bool IsAssocPermit() const
Check if the Association Permit bit is enabled.
uint8_t GetFrameOrder() const
Get the Superframe Specification Frame Order field.
uint8_t GetBeaconOrder() const
Get the Superframe Specification Beacon Order field.
Represents the payload portion of a beacon frame.
bool GetRouterCapacity() const
Get the router capacity capability.
void SetDeviceDepth(uint8_t deviceDepth)
Set the cevice depth object.
uint8_t GetProtocolId() const
Get the Protocol Id used.
uint8_t GetStackProfile() const
Get the Stack Profile used.
void SetRouterCapacity(bool routerCapacity)
Set the Router Capacity capability True = The device is able to accept join.request from router-capab...
uint64_t GetExtPanId() const
Get the extended PAN identifier.
void SetStackProfile(uint8_t stackProfile)
Set the network profile identifier.
void SetEndDevCapacity(bool endDevCapacity)
Set the end device Capacity.
bool GetEndDevCapacity() const
Get the end dev capacity.
void SetTxOffset(uint32_t txOffset)
Set the Tx Offset time in symbols.
void SetExtPanId(uint64_t extPanId)
Set the extended PAN id.
Represent the NWK Header with the Frame Control and Routing fields Zigbee Specification r22....
void SetMulticast()
Set to true the value of the multicast flag in the frame control field.
void SetDiscoverRoute(enum DiscoverRouteType discoverRoute)
Suppress or enable route discovery for this frame.
void SetSrcAddr(Mac16Address addr)
Set Source address.
void SetEndDeviceInitiator()
This flag is used by the NWK to indicate if the the initiator device of the message is an end device ...
void SetProtocolVer(uint8_t ver)
Set the Protocol version.
bool IsMulticast() const
Inform whether or not the current frame is used in multicast.
void SetSeqNum(uint8_t seqNum)
Set the Sequence number.
uint8_t GetRadius() const
Get the Radius.
uint8_t GetSeqNum() const
Get the frame Sequence number.
NwkType GetFrameType() const
Set the Frame Control field "Frame Type" bits.
void SetRadius(uint8_t radius)
Set the Radius.
void SetFrameType(enum NwkType nwkType)
Set the Frame type used (Data or Command)
Mac16Address GetDstAddr() const
Get the Destination address.
void SetDstAddr(Mac16Address addr)
Set Destination address.
DiscoverRouteType GetDiscoverRoute() const
Get the status of frame discovery route (suppress or enabled)
Mac16Address GetSrcAddr() const
Get the Source address.
Class that implements the Zigbee Specification Network Layer.
Definition zigbee-nwk.h:690
void SendDataUcst(Ptr< Packet > packet, uint8_t nwkHandle)
Send a data unicast packet, and if necessary look for the next hop route and store the pending data t...
NeighborTable m_nwkNeighborTable
The network layer neighbor table See Zigbee specification r22.1.0, 3.6.1.5.
RouteDiscoveryStatus ProcessManyToOneRoute(Mac16Address macSrcAddr, uint8_t pathCost, ZigbeeNwkHeader nwkHeader, ZigbeePayloadRouteRequestCommand payload)
Process Many-To-One routes.
ZigbeeNwk()
Default constructor.
Mac64Address GetIeeeAddress() const
Obtain this device 64 bit IEEE address (A.K.A.
NlmeStartRouterRequestParams m_startRouterParams
Temporarily store the NLME-START-ROUTER.request parameters during the router initialization process.
uint8_t m_nwkConcentratorDiscoveryTime
The time in seconds between concentrator route discoveries.
void DisposePendingTx()
Dispose of all PendingTxPkt accumulated in the pending transmission queue.
uint8_t m_nwkCapabilityInformation
This NIB attribute contains the device capability information established at network joining time.
void MlmeOrphanIndication(lrwpan::MlmeOrphanIndicationParams params)
IEEE 802.15.4-2011 sections 6.2.7.1, Zigbee Specification r22.1.0 Section 3.6.1.4....
void UpdateBeaconPayload()
Updates the content of the beacon payload with the most recent information in the NWK.
TracedCallback< uint8_t, Mac16Address, uint8_t > m_rreqRetriesExhaustedTrace
A trace source that fires when a node has reached the maximum number of RREQ retries allowed.
Mac16Address AllocateNetworkAddress()
Used by a Zigbee coordinator or router to allocate a 16 bit address (A.K.A short address or network a...
void NlmeDirectJoinRequest(NlmeDirectJoinRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.16 and 3.6.1.4.3 NLME-DIRECT-JOIN.request Allows the next...
RoutingTable m_nwkRoutingTable
The network layer routing table See Zigbee specification r22.1.0, 3.6.3.2.
double m_nwkcMinRREQJitter
Minimum Route request broadcast jitter time (msec).
SequenceNumber8 m_nwkSequenceNumber
The sequence number used to identify outgoing frames See Zigbee specification r22....
NlmeNetworkFormationRequestParams m_netFormParams
The parameters used during a NLME-NETWORK-FORMATION.request.
void McpsDataConfirm(lrwpan::McpsDataConfirmParams params)
IEEE 802.15.4-2011 section 6.3.2 MCPS-DATA.confirm Reports the results of a request to a transfer dat...
Ptr< UniformRandomVariable > m_uniformRandomVariable
Provides uniform random values.
NlmeJoinIndicationParams m_joinIndParams
Temporarily store the NLME-JOIN.indication parameters while the join operations (asocciation) conclud...
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream) const
Print the entries in the routing table.
Mac16Address FindRoute(Mac16Address dst, bool &neighbor)
Search for a specific destination in this device neighbor and routing tables.
void SetNlmeJoinConfirmCallback(NlmeJoinConfirmCallback c)
Set the callback as part of the interconnections between the NWK and the APS sublayer (or any other h...
void NlmeStartRouterRequest(NlmeStartRouterRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.9 NLME-START-ROUTER.request This primitive allows the nex...
void SetNlmeRouteDiscoveryConfirmCallback(NlmeRouteDiscoveryConfirmCallback c)
Set the callback as part of the interconnections between the NWK and the APS sublayer (or any other h...
uint8_t m_currentChannel
Used to store the value of the PHY current channel.
Time m_routeExpiryTime
The expiration time of routing table entry.
static TypeId GetTypeId()
Get the type ID.
Definition zigbee-nwk.cc:35
void NldeDataRequest(NldeDataRequestParams params, Ptr< Packet > packet)
Zigbee Specification r22.1.0, Section 3.2.1.1 NLDE-DATA.request Request to transfer a NSDU.
void SendRREP(Mac16Address nextHop, Mac16Address originator, Mac16Address responder, uint8_t rreqId, uint8_t pathcost)
Construct and send a route reply command.
void PrintNeighborTable(Ptr< OutputStreamWrapper > stream) const
Print the entries in the neighbor table.
void MlmeSetConfirm(lrwpan::MlmeSetConfirmParams params)
IEEE 802.15.4-2011 section 6.2.11.2 MLME-SET.confirm Reports the result of an attempt to change a MAC...
void UpdateBeaconPayloadLength()
Create and store a MAC beacon payload, then updates its registered size in the MAC.
StackProfile m_nwkStackProfile
Describes the current stack profile used in this NWK layer.
NlmeDirectJoinConfirmCallback m_nlmeDirectJoinConfirmCallback
This callback is used by the next layer of a zigbee coordinator or router to be notified of the resul...
bool m_nwkReportConstantCost
If false, the NWK layer shall calculate the link cost from all neighbor nodes using the LQI values re...
Time m_nwkcRREQRetryInterval
Duration between retries of a broadcast route request command frame.
void DoInitialize() override
Initialize() implementation.
NlmeNetworkFormationConfirmCallback m_nlmeNetworkFormationConfirmCallback
This callback is used to to notify the results of a network formation to the APS sublayer making the ...
void MlmeCommStatusIndication(lrwpan::MlmeCommStatusIndicationParams params)
IEEE 802.15.4-2011 section 6.2.4.2 MLME-COMM-STATUS.indication Allows the MAC MLME to indicate a comm...
PanIdTable m_panIdTable
Use to keep track of neighboring 16 bit PAN id.
Mac16Address m_nwkNetworkAddress
The 16-bit address that the device uses to communicate with the PAN.
RouteDiscoveryStatus FindNextHop(Mac16Address macSrcAddr, uint8_t pathCost, ZigbeeNwkHeader nwkHeader, ZigbeePayloadRouteRequestCommand payload, Mac16Address &nextHop)
Find the next hop in route to a destination.
void SetMac(Ptr< lrwpan::LrWpanMacBase > mac)
Set the underlying MAC to use in this Zigbee NWK.
uint8_t m_nwkParentInformation
The behavior depends upon whether the device is a FFD or RFD.
SequenceNumber8 m_macHandle
The handle assigned when doing a transmission request to the MAC layer.
NlmeJoinRequestParams m_joinParams
The parameters used during a NLME-JOIN.request.
void MlmeBeaconNotifyIndication(lrwpan::MlmeBeaconNotifyIndicationParams params)
IEEE 802.15.4-2011, Section 6.2.4.1 MLME-BEACON-NOTIFY.indication Allows the MAC MLME to indicate the...
void SetNlmeJoinIndicationCallback(NlmeJoinIndicationCallback c)
Set the callback as part of the interconnections between the NWK and the APS sublayer (or any other h...
uint8_t m_nwkcInitialRREQRetries
The number of times the first broadcast transmission of a route request command frame is retried.
void SetNlmeNetworkDiscoveryConfirmCallback(NlmeNetworkDiscoveryConfirmCallback c)
Set the callback as part of the interconnections between the NWK and the APS sublayer (or any other h...
void MlmeAssociateConfirm(lrwpan::MlmeAssociateConfirmParams params)
IEEE 802.15.4-2011 section MlME-ASSOCIATE.confirm Report the results of an associate request attempt.
void EnqueuePendingTx(Ptr< Packet > p, uint8_t nsduHandle)
Enqueue a packet in the pending transmission queue until a route is discovered for its destination.
void NlmeNetworkDiscoveryRequest(NlmeNetworkDiscoveryRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.3 NLME-NETWORK-DISCOVERY.request Allows the next higher l...
Ptr< NetFormPendingParamsGen > m_netFormParamsGen
The values temporarily stored as a result of the initial steps of a NLME-NETWORK-FORMATION....
NlmeStartRouterConfirmCallback m_nlmeStartRouterConfirmCallback
This callback is used by the next layer of a zigbee router or device to be notified of the result of ...
NlmeJoinConfirmCallback m_nlmeJoinConfirmCallback
This callback is used by the next layer of a zigbee router or device to be notified of the result of ...
int64_t AssignStreams(int64_t stream)
Assign a fixed random variable stream number to the random variables used by this model.
void NlmeJoinRequest(NlmeJoinRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.13 NLME-JOIN.request This primitive allows the next highe...
uint8_t m_nwkConcentratorRadius
This NIB attribute indicates the hop count radius for concentrator route discoveries (Used by Many-To...
double m_nwkcMaxRREQJitter
Maximum Route request broadcast jitter time (msec).
Mac64Address m_nwkIeeeAddress
The EUI 64 bit IEEE address of the local device.
void SetNlmeStartRouterConfirmCallback(NlmeStartRouterConfirmCallback c)
Set the callback as part of the interconnections between the NWK and the APS sublayer (or any other h...
void ReceiveRREP(Mac16Address macSrcAddr, uint8_t linkCost, ZigbeeNwkHeader nwkHeader, ZigbeePayloadRouteReplyCommand payload)
Handles the reception of a route reply command.
uint16_t m_nwkPanId
This NIB attribute should, at all times, have the same value as macPANId .
void SetNldeDataConfirmCallback(NldeDataConfirmCallback c)
Set the callback as part of the interconnections between the NWK and the APS sublayer (or any other h...
Ptr< Packet > m_beaconPayload
Points to the beacon payload used during the network formation process.
uint8_t m_countRREQRetries
Count the number of retries this device has transmitted an RREQ.
PendingPrimitiveNwk m_pendPrimitiveNwk
Indicates the current primitive in use in the NWK layer.
bool IsBroadcastAddress(Mac16Address address)
Returns true if the address is a broadcast address according to Zigbee specification r22....
BroadcastTransactionTable m_btt
The broadcast transaction table.
void NotifyConstructionCompleted() override
Notifier called once the ObjectBase is fully constructed.
uint8_t m_nwkMaxBroadcastRetries
The maximum number of retries allowed after a broadcast transmission failure See Zigbe Specification ...
uint32_t m_maxPendingTxQueueSize
The maximum size of the pending transaction queue.
uint8_t m_nwkMaxDepth
The depth a device can have.
AddrAllocMethod m_nwkAddrAlloc
A value that determines the method used to assign addresses.
std::vector< NetworkDescriptor > m_networkDescriptorList
Temporarily store beacons information from POS routers and PAN coordinators during a network-discover...
NldeDataConfirmCallback m_nldeDataConfirmCallback
This callback is used to respond to data PDU (NSDU) transfer request issued by APS sublayer to the NW...
Ptr< lrwpan::LrWpanMacBase > m_mac
Pointer to the underlying MAC connected to this Zigbee NWK.
void MlmeStartConfirm(lrwpan::MlmeStartConfirmParams params)
IEEE 802.15.4-2011 section 7.1.14.2 MLME-START.confirm Reports the results of a network start request...
uint8_t GetLinkCost(uint8_t lqi) const
Obtain the link cost based on the value of the nwkReportConstantCost.
void MlmeAssociateIndication(lrwpan::MlmeAssociateIndicationParams params)
IEEE 802.15.4-2011, Section 6.2.2.2.
void ReceiveRREQ(Mac16Address macSrcAddr, uint8_t linkCost, ZigbeeNwkHeader nwkHeader, ZigbeePayloadRouteRequestCommand payload)
Handles the reception of a route request command.
void PrintRREQRetryTable(Ptr< OutputStreamWrapper > stream) const
Print the entries in the RREQ retry table.
void PrintRouteDiscoveryTable(Ptr< OutputStreamWrapper > stream)
Print the entries in the route discovery table.
Ptr< UniformRandomVariable > m_rreqJitter
Provides uniform random values for the route request jitter.
NwkStatus GetNwkStatus(lrwpan::MacStatus macStatus) const
Cast a Mac layer status to a NWK layer status.
uint16_t m_nwkMaxChildren
The number of children a device is allowed to have on its current network.
uint8_t m_scanEnergyThreshold
The maximum acceptable energy level used in an energy scan taking place during a NLME-NETWORK-FORMATI...
void MlmeScanConfirm(lrwpan::MlmeScanConfirmParams params)
IEEE 802.15.4-2011 section 6.2.10.2 MLME-SCAN.confirm Reports the results of a scan request.
void NlmeNetworkFormationRequest(NlmeNetworkFormationRequestParams params)
Zigbee Specification r22.1.0, Section 3.2.2.5 and 3.6.1.1 NLME-NETWORK-FORMATION.request Request the ...
SequenceNumber8 m_routeRequestId
The counter used to identify route request commands.
NlmeNetworkDiscoveryConfirmCallback m_nlmeNetworkDiscoveryConfirmCallback
This callback is used to to notify the results of a network formation to the APS sublayer making the ...
uint16_t m_nwkEndDeviceTimeoutDefault
Indicates the index of the requested timeout field that contains the timeout in minutes for any end d...
void DisposeTxPktBuffer()
Dispose of all the entries in the TxPkt Buffer.
bool m_nwkIsConcentrator
This NIB attribute is a flag determining if this device is a concentrator (Use in Many-To-One routing...
Time m_nwkcRouteDiscoveryTime
Indicates the duration until a route discovery expires.
uint8_t m_txBufferMaxSize
The maximum size of the transmission buffer.
lrwpan::MlmeAssociateRequestParams m_associateParams
Temporarily store MLME-ASSOCIATE.request parameters during a NLME-JOIN.request.
void SendRREQ(ZigbeeNwkHeader nwkHeader, ZigbeePayloadRouteRequestCommand payload, uint8_t rreqRetries)
Send a route request command.
RreqRetryTable m_rreqRetryTable
Keep track of all the route request retries.
bool m_nwkUseTreeRouting
This NIB attribute indicates whether the NWK layer should assume the ability to use hierarchical rout...
void SetNlmeNetworkFormationConfirmCallback(NlmeNetworkFormationConfirmCallback c)
Set the callback as part of the interconnections between the NWK and the APS sublayer (or any other h...
Time m_nwkNetworkBroadcastDeliveryTime
Time duration that a broadcast message needs to encompass the entire network.
NlmeRouteDiscoveryConfirmCallback m_nlmeRouteDiscoveryConfirmCallback
This callback is used to to notify the results of a network formation to the APS sublayer making the ...
void SetNlmeDirectJoinConfirmCallback(NlmeDirectJoinConfirmCallback c)
Set the callback as part of the interconnections between the NWK and the APS sublayer (or any other h...
bool m_nwkSymLink
Describes the current route symmetry: True: Routes are considered to be symmetric links.
uint32_t m_filteredChannelMask
Contains the list of channels with acceptable energy levels in a bitmap form.
std::deque< Ptr< PendingTxPkt > > m_pendingTxQueue
The pending transaction queue of data packets awaiting to be transmitted until a route to the destina...
uint16_t m_nwkMaxRouters
The number of routers any one device is allowed to have as children.
bool m_nwkcCoordinatorCapable
Indicates whether the device is capable of becoming the ZigBee coordinator Zigbee Specification r22....
void McpsDataIndication(lrwpan::McpsDataIndicationParams params, Ptr< Packet > msdu)
IEEE 802.15.4-2011 section 6.3.3 MCPS-DATA.indication Indicates the reception of an MSDU from MAC to ...
void BufferTxPkt(Ptr< Packet > p, uint8_t macHandle, uint8_t nwkHandle)
Buffer a copy of a DATA frame for post transmission handling (Transmission failure counts,...
bool RetrieveTxPkt(uint8_t macHandle, Ptr< TxPkt > &txPkt)
Retrieves a previously DATA frame buffered in the TxPkt buffer.
void NlmeRouteDiscoveryRequest(NlmeRouteDiscoveryRequestParams params)
Zigbee Specification r22.1.0, section 3.2.2.33.3 and 3.6.3.5 NLME-ROUTE-DISCOVERY....
std::deque< Ptr< TxPkt > > m_txBuffer
The transmission buffer.
Ptr< lrwpan::LrWpanMacBase > GetMac() const
Get the underlying MAC used by the current Zigbee NWK.
uint8_t GetLQINonLinearValue(uint8_t lqi) const
Get a non linear representation of a Link Quality Indicator (LQI).
void SetNldeDataIndicationCallback(NldeDataIndicationCallback c)
Set the callback for the end of a RX, as part of the interconnections between the NWK and the APS sub...
void DoDispose() override
Destructor implementation.
uint8_t m_nwkcRREQRetries
The number of times the broadcast transmission of a route request command frame is retried on relay b...
bool DequeuePendingTx(Mac16Address dst, Ptr< PendingTxPkt > entry)
Dequeue a packet previously enqueued in the pending transmission queue.
uint8_t m_nwkcProtocolVersion
Indicates the version of the ZigBee NWK protocol in the device.
void SendDataBcst(Ptr< Packet > packet, uint8_t nwkHandle)
Send a data broadcast packet, and add a record to the broadcast transaction table (BTT).
Mac16Address GetNetworkAddress() const
Obtain this device 16 bit network address (A.K.A.
void MlmeGetConfirm(lrwpan::MacStatus status, lrwpan::MacPibAttributeIdentifier id, Ptr< lrwpan::MacPibAttributes > attribute)
IEEE 802.15.4-2011 section 6.2.5.1 MLME-GET.confirm Reports the result of an attempt to obtain a MAC ...
NldeDataIndicationCallback m_nldeDataIndicationCallback
This callback is used to notify incoming packets to the APS sublayer.
RouteDiscoveryTable m_nwkRouteDiscoveryTable
The network route discovery table See Zigbee specification r22.1.0, 3.6.3.2.
uint64_t m_nwkExtendedPanId
The extended PAN identifier for the PAN of which the device is a member.
NlmeJoinIndicationCallback m_nlmeJoinIndicationCallback
This callback is used by the next layer of a zigbee coordinator or router to be notified when a new d...
Represent a variable portion of the zigbee payload header that includes the route reply command.
void SetRouteReqId(uint8_t rid)
Set the Route request identifier.
Mac16Address GetRespAddr() const
Get the Responder address.
Mac16Address GetOrigAddr() const
Get the Originator address.
void SetRespAddr(Mac16Address addr)
Set Responder address.
uint8_t GetRouteReqId() const
Get the Route request identifier.
void SetOrigAddr(Mac16Address addr)
Set Originator address.
void SetPathCost(uint8_t cost)
Set the path cost.
Represent a variable portion of the zigbee payload header that includes the route request command.
uint8_t GetRouteReqId() const
Get the Route request identifier.
void SetCmdOptManyToOneField(enum ManyToOne manyToOne)
Set the command option field Many To One.
uint8_t GetCmdOptManyToOneField() const
Get the command option field Many To One.
void SetRouteReqId(uint8_t id)
Set the Route request identifier.
void SetDstAddr(Mac16Address addr)
Set Destination address.
Mac16Address GetDstAddr() const
Get the Destination address.
Represent the static portion of the zigbee payload header that describes the payload command type.
NwkCommandType GetCmdType() const
Get the command frame type.
#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:75
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
MacPibAttributeIdentifier
IEEE 802.15.4-2006 PHY and MAC PIB Attribute Identifiers Table 23 and Table 86.
MacStatus
The status of a confirm or an indication primitive as a result of a previous request.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
SequenceNumber< uint8_t, int8_t > SequenceNumber8
8 bit Sequence number.
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1344
Time Minutes(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1332
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1356
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
NwkDeviceType
The network layer device type.
static const double RequestedTimeoutField[15]
Requested Timeout Field See Zigbee Specification r22.1.0, 3.4.11.3.1.
NwkStatus
Network layer status values Combines Zigbee Specification r22.1.0 Table 3-73 and and IEEE 802....
Definition zigbee-nwk.h:151
@ ZIGBEE_COORDINATOR
Zigbee coordinator.
@ ZIGBEE_ENDDEVICE
Zigbee end device.
@ ZIGBEE_ROUTER
Zigbee router.
@ ROUTE_VALIDATION_UNDERWAY
Route discovery validation underway.
@ ROUTE_ACTIVE
Route active.
@ ROUTE_DISCOVERY_UNDERWAY
Route discovery underway.
@ NO_ROUTING_CAPACITY
No routing capacity.
Definition zigbee-nwk.h:249
@ NO_ROUTE_AVAILABLE
No route available.
Definition zigbee-nwk.h:245
@ ENDDEVICE
End device or router treated as an end device.
@ ROUTER
Router device.
@ MCST
Multicast Address mode.
Definition zigbee-nwk.h:77
@ NO_ADDRESS
No destination address.
Definition zigbee-nwk.h:76
@ UCST_BCST
Unicast or Broadcast address mode.
Definition zigbee-nwk.h:78
@ NLME_NET_DISCV
Pending NLME-NETWORK-DISCOVERY.request primitive.
Definition zigbee-nwk.h:63
@ NLME_NETWORK_FORMATION
Pending NLME-NETWORK-FORMATION.request primitive.
Definition zigbee-nwk.h:59
@ NLME_JOIN
Pending NLME-JOIN.request primitive.
Definition zigbee-nwk.h:61
@ NLDE_NLME_NONE
No pending primitive.
Definition zigbee-nwk.h:58
@ NLME_START_ROUTER
Pending NLME-START-ROUTER.request primitive.
Definition zigbee-nwk.h:62
@ NLME_JOIN_INDICATION
Pending NLME-JOIN.indication primitive.
Definition zigbee-nwk.h:64
@ NLME_ROUTE_DISCOVERY
Pending NLME-ROUTE-DISCOVERY.request primitive.
Definition zigbee-nwk.h:65
@ NBR_CHILD
Neighbor is the child.
@ NBR_PARENT
Neighbor is the parent.
@ NBR_NONE
No relationship.
@ BEACON_LOSS
The beacon was lost following a synchronization request.
Definition zigbee-nwk.h:161
@ UNSUPPORTED_LEGACY
Deprecated security used in IEEE 802.15.4-2003.
Definition zigbee-nwk.h:159
@ ALREADY_PRESENT
Already present (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:193
@ READ_ONLY
SET/GET request issued for a read only attribute.
Definition zigbee-nwk.h:186
@ MAX_FRM_COUNTER
Max Frame counter (IEEE 802.15.4, Zigbee specification r22.1.0)
Definition zigbee-nwk.h:199
@ UNSUPPORTED_SECURITY
The security applied is not supported.
Definition zigbee-nwk.h:160
@ DISABLE_TRX_FAILURE
The attempt to disable the transceier has failed.
Definition zigbee-nwk.h:164
@ FULL_CAPACITY
PAN at capacity.
Definition zigbee-nwk.h:154
@ NO_DATA
No response data were available following a request.
Definition zigbee-nwk.h:172
@ IMPROPER_KEY_TYPE
The key is not allowed to be used with that frame type.
Definition zigbee-nwk.h:157
@ INVALID_PARAMETER_MAC
Invalid parameter in response to a request passed to the MAC.
Definition zigbee-nwk.h:169
@ TRANSACTION_OVERFLOW
There is no capacity to store the transaction.
Definition zigbee-nwk.h:178
@ SUPERFRAME_OVERLAP
Coordinator sperframe and this device superframe tx overlap.
Definition zigbee-nwk.h:187
@ NOT_PERMITED
Not permitted (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:191
@ INVALID_REQUEST
Invalid request (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:190
@ OUT_OF_CAP
(Deprecated) See IEEE 802.15.4-2003
Definition zigbee-nwk.h:174
@ NO_NETWORKS
No network (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:198
@ SECURITY_ERROR
Cryptographic process of the frame failed(FAILED_SECURITY_CHECK).
Definition zigbee-nwk.h:165
@ UNSUPPORTED_ATTRIBUTE
Unsupported attribute (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:197
@ TRANSACTION_EXPIRED
The transaction expired and its information discarded.
Definition zigbee-nwk.h:177
@ REALIGMENT
A coordinator realigment command has been received.
Definition zigbee-nwk.h:176
@ SUCCESS
The operation was completed successfully.
Definition zigbee-nwk.h:153
@ LIMIT_REACHED
Limit reached during network scan (IEEE 802.15.4-2011)
Definition zigbee-nwk.h:207
@ NO_SHORT_ADDRESS
Failure due to unallocated 16-bit short address.
Definition zigbee-nwk.h:173
@ INVALID_INTERFACE
Invalid interface (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:206
@ INVALID_INDEX
A MAC PIB write failed because specified index is out of range.
Definition zigbee-nwk.h:185
@ UNAVAILABLE_KEY
Unavailable key, unknown or blacklisted.
Definition zigbee-nwk.h:180
@ INVALID_PARAMETER
Invalid Parameter (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:189
@ INVALID_ADDRESS
Invalid source or destination address.
Definition zigbee-nwk.h:181
@ FRAME_NOT_BUFFERED
Frame not buffered (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:205
@ IMPROPER_SECURITY_LEVEL
Insufficient security level expected by the recipient.
Definition zigbee-nwk.h:158
@ INVALID_HANDLE
When purging from TX queue handle was not found.
Definition zigbee-nwk.h:168
@ CHANNEL_ACCESS_FAILURE
A Tx could not take place due to activity in the CH.
Definition zigbee-nwk.h:162
@ TX_ACTIVE
The transceiver was already enabled.
Definition zigbee-nwk.h:179
@ BAD_CCM_OUTPUT
Bad ccm output (IEEE 802.15.4, Zigbee specification r22.1.0)
Definition zigbee-nwk.h:201
@ UNKNOWN_DEVICE
Unknown device (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:196
@ ACCESS_DENIED
PAN access denied.
Definition zigbee-nwk.h:155
@ NEIGHBOR_TABLE_FULL
Neighbor table full (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:195
@ FRAME_TOO_LONG
Frame more than aMaxPHYPacketSize or too large for CAP or GTS.
Definition zigbee-nwk.h:166
@ BT_TABLE_FULL
Bt table full (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:204
@ DENIED
The GTS request has been denied by the PAN coordinator.
Definition zigbee-nwk.h:163
@ ROUTE_DISCOVERY_FAILED
Route discovery failed (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:202
@ SYNC_FAILURE
Sync Failure (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:194
@ TRACKING_OFF
This device is currently not tracking beacons.
Definition zigbee-nwk.h:184
@ COUNTER_ERROR
The frame counter of the received frame is invalid.
Definition zigbee-nwk.h:156
@ NO_ACK
No acknowledgment was received after macMaxFrameRetries.
Definition zigbee-nwk.h:170
@ STARTUP_FAILURE
Startup failure (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:192
@ ON_TIME_TOO_LONG
RX enable request fail due to syms.
Definition zigbee-nwk.h:182
@ NO_BEACON
A scan operation failed to find any network beacons.
Definition zigbee-nwk.h:171
@ SCAN_IN_PROGRESS
The dev was scanning during this call (IEEE 802.5.4)
Definition zigbee-nwk.h:208
@ PAST_TIME
Rx enable request fail due to lack of time in superframe.
Definition zigbee-nwk.h:183
@ PAN_ID_CONFLICT
PAN id conflict detected and informed to the coordinator.
Definition zigbee-nwk.h:175
@ ROUTE_ERROR
Route error (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:203
@ NO_KEY
No Key (Zigbee specification r22.1.0)
Definition zigbee-nwk.h:200
@ INVALID_GTS
Missing GTS transmit or undefined direction.
Definition zigbee-nwk.h:167
@ STOCHASTIC_ALLOC
Stochastic address allocation (Zigbee Specification r22.1.0 Section 3.6.1.7)
Definition zigbee-nwk.h:89
@ DISTRIBUTED_ALLOC
Distributed address allocation (Zigbee Specification r22.1.0 Section 3.6.1.6)
Definition zigbee-nwk.h:87
DiscoverRouteType
Zigbee Specification r22.1.0, Values of the discover route sub-field (Table 3-47)
@ ENABLE_ROUTE_DISCOVERY
Enable route discovery.
@ ASSOCIATION
The device is requesting to join a network through association.
Definition zigbee-nwk.h:108
@ DIRECT_OR_REJOIN
The device is joining directly or rejoining using the orphaning procedure.
Definition zigbee-nwk.h:109
@ NWK_COMMAND
Network command frame type.
@ DATA
Data frame type.
@ INTER_PAN
Inter-Pan frame type.
@ ROUTE_REP_CMD
Route response command.
@ ROUTE_REQ_CMD
Route request command.
StackProfile
Use to describe the identifier of the zigbee stack profile.
Definition zigbee-nwk.h:97
@ ZIGBEE_PRO
Zigbee stack profile 0x02 (Zigbee Pro, also known as r22.1.0, 3.0)
Definition zigbee-nwk.h:99
std::ostream & operator<<(std::ostream &os, const NwkStatus &state)
Overloaded operator to print the value of a NwkStatus.
RouteDiscoveryStatus
The status returned while attempting to find the next hop in route towards a specific destination or ...
Definition zigbee-nwk.h:121
@ NO_DISCOVER_ROUTE
We are currently not allowed to perform a route discovery for this route (RouteDiscover flag in netwo...
Definition zigbee-nwk.h:129
@ ROUTE_NOT_FOUND
The next hop was not found.
Definition zigbee-nwk.h:124
@ MANY_TO_ONE_ROUTE
A new Many-To-One route was created.
Definition zigbee-nwk.h:134
@ ROUTE_FOUND
The next hop toward the destination was found in our routing table or neighbor table (Mesh route).
Definition zigbee-nwk.h:122
@ NO_ROUTE_CHANGE
No route entry was created or updated during a Many-To-One process.
Definition zigbee-nwk.h:135
@ DISCOVER_UNDERWAY
The route was found in the tables but currently has no next hop.
Definition zigbee-nwk.h:131
@ ROUTE_UPDATED
A route was found and updated with a better route (Mesh route or Many-To-One route)
Definition zigbee-nwk.h:127
@ TABLE_FULL
Either the routing or neighbor table are full.
Definition zigbee-nwk.h:126
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition nstime.h:1432
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32
Ptr< const AttributeChecker > MakeTimeChecker()
Helper to make an unbounded Time checker.
Definition nstime.h:1452
AddressMode m_dstAddrMode
Destination address mode.
Mac16Address m_dstAddr
Destination address.
uint16_t m_dstPanId
Destination PAN identifier.
AddressMode m_srcAddrMode
Source address mode.
uint8_t m_txOptions
Tx Options (bitfield)
MLME-ASSOCIATE.confirm params.
MLME-ASSOCIATE.indication params.
MLME-ASSOCIATE.request params.
Mac64Address m_coordExtAddr
The extended address of the coordinator with which to associate.
uint8_t m_coordAddrMode
The coordinator addressing mode for this primitive and subsequent MPDU.
uint8_t m_capabilityInfo
Specifies the operational capabilities of the associating device (bitmap).
Mac16Address m_coordShortAddr
The short address of the coordinator with which to associate.
uint8_t m_chNum
The channel number on which to attempt association.
uint32_t m_chPage
The channel page on which to attempt association.
uint16_t m_coordPanId
The identifier of the PAN with which to associate.
MLME-ASSOCIATE.response params.
Mac16Address m_assocShortAddr
The short address allocated by the coordinator on successful assoc.
MacStatus m_status
The status of the association attempt (As defined on Table 83 IEEE 802.15.4-2006)
Mac64Address m_extDevAddr
The extended address of the device requesting association.
MLME-BEACON-NOTIFY.indication params.
MLME-COMM-STATUS.indication params.
MLME-ORPHAN.indication params.
bool m_assocMember
T = allocated with this coord | F = otherwise.
Mac64Address m_orphanAddr
The address of the orphaned device.
Mac16Address m_shortAddr
The short address allocated.
MlmeScanType m_scanType
Indicates the type of scan performed as described in IEEE 802.15.4-2011 (5.1.2.1).
uint32_t m_scanChannels
The channel numbers to be scanned.
uint8_t m_scanDuration
The factor (0-14) used to calculate the length of time to spend scanning.
uint32_t m_chPage
The channel page on which to perform scan.
bool m_battLifeExt
Flag indicating whether or not the Battery life extension (BLE) features are used.
uint8_t m_logCh
Logical channel on which to start using the new superframe configuration.
uint32_t m_logChPage
Logical channel page on which to start using the new superframe configuration.
bool m_coorRealgn
True if a realignment request command is to be transmitted prior changing the superframe.
uint8_t m_bcnOrd
Beacon Order, Used to calculate the beacon interval, a value of 15 indicates no periodic beacons will...
bool m_panCoor
On true this device will become coordinator.
uint8_t m_sfrmOrd
Superframe Order, indicates the length of the CAP in time slots.
uint16_t m_PanId
Pan Identifier used by the device.
uint8_t channelPageCount
The number of the channel page structures contained in the channel list structure.
Definition zigbee-nwk.h:274
std::vector< uint32_t > channelsField
The set of channels for a given page.
Definition zigbee-nwk.h:276
Network Descriptor, Zigbee Specification r22.1.0, 3.2.2.4, Table 3-12.
Definition zigbee-nwk.h:473
uint16_t m_panId
The 16-bit PAN identifier of the network.
Definition zigbee-nwk.h:475
uint8_t m_updateId
The value of the UpdateID from the NIB.
Definition zigbee-nwk.h:476
uint8_t m_superframeOrder
The superframe order value of the underlying MAC (Determinates the value of the active period)
Definition zigbee-nwk.h:484
bool m_routerCapacity
TRUE = The device is able to accept join requests from router-capable devices.
Definition zigbee-nwk.h:488
bool m_endDeviceCapacity
TRUE= The device is able to accept join request from end devices.
Definition zigbee-nwk.h:490
StackProfile m_stackProfile
The Zigbee stack profile identifier in use in the discovered network.
Definition zigbee-nwk.h:478
uint8_t m_logCh
The current channel number occupied by the network.
Definition zigbee-nwk.h:477
uint8_t m_beaconOrder
The beacon order value of the underlying MAC.
Definition zigbee-nwk.h:482
uint8_t m_zigbeeVersion
The version of the zigbee protocol in use in the discovered network.
Definition zigbee-nwk.h:480
uint64_t m_extPanId
The 64-bit PAN identifier of the network.
Definition zigbee-nwk.h:474
bool m_permitJoining
TRUE = Indicates that at least one zigbee router on the network currently permits joining.
Definition zigbee-nwk.h:486
NLDE-DATA.confirm params.
Definition zigbee-nwk.h:291
uint8_t m_nsduHandle
The handle associated with the NSDU being confirmed.
Definition zigbee-nwk.h:294
NwkStatus m_status
The status of the corresponding request.
Definition zigbee-nwk.h:292
Time m_txTime
The time indication for the transmitted packet based on the local clock.
Definition zigbee-nwk.h:295
NLDE-DATA.indication params.
Definition zigbee-nwk.h:305
AddressMode m_dstAddrMode
Destination address mode.
Definition zigbee-nwk.h:306
Time m_rxTime
A time indication for the received packet based on the local clock.
Definition zigbee-nwk.h:312
uint32_t m_nsduLength
The number of octets comprising the NSDU being indicated.
Definition zigbee-nwk.h:310
uint8_t m_linkQuality
LQI value delivered by the MAC on receipt of this frame.
Definition zigbee-nwk.h:311
bool m_securityUse
An indication of whether the received data is using security.
Definition zigbee-nwk.h:314
Mac16Address m_srcAddr
The individual device address from which the NSDU originated.
Definition zigbee-nwk.h:309
Mac16Address m_dstAddr
The destination address to which the NSDU was sent.
Definition zigbee-nwk.h:308
NLDE-DATA.request params.
Definition zigbee-nwk.h:323
NLME-DIRECT-JOIN.confirm params.
Definition zigbee-nwk.h:447
NwkStatus m_status
The status the corresponding request.
Definition zigbee-nwk.h:448
Mac64Address m_deviceAddr
The IEEE EUI-64 address in the request to which this is a confirmation.
Definition zigbee-nwk.h:450
NLME-DIRECT-JOIN.request params.
Definition zigbee-nwk.h:434
NLME-JOIN.confirm params.
Definition zigbee-nwk.h:537
Mac16Address m_networkAddress
The 16 bit network address that was allocated to this device.
Definition zigbee-nwk.h:540
NwkStatus m_status
The status of the corresponding request.
Definition zigbee-nwk.h:538
uint8_t m_macInterfaceIndex
The value of the MAC index from nwkMacInterfaceTable.
Definition zigbee-nwk.h:548
uint64_t m_extendedPanId
The extended 64 bit PAN ID for the network of which the device is now a member.
Definition zigbee-nwk.h:543
ChannelList m_channelList
The structure indicating the current channel of the network that has been joined.
Definition zigbee-nwk.h:545
bool m_enhancedBeacon
True if using enhanced beacons (placeholder, not supported)
Definition zigbee-nwk.h:547
NLME-JOIN.indication params.
Definition zigbee-nwk.h:569
Mac64Address m_extendedAddress
The EUI-64 bit address of an entity that has been added to the network.
Definition zigbee-nwk.h:572
uint8_t m_capabilityInfo
Specifies the operational capabilities of the joining device.
Definition zigbee-nwk.h:574
JoiningMethod m_rejoinNetwork
This parameter indicates the method used to join the network.
Definition zigbee-nwk.h:576
Mac16Address m_networkAddress
The 16 bit network address of an entity that has been added to the network.
Definition zigbee-nwk.h:570
NLME-JOIN.request params.
Definition zigbee-nwk.h:515
ChannelList m_scanChannelList
The list of all channel pages and the associated channels that shall be scanned.
Definition zigbee-nwk.h:520
uint8_t m_capabilityInfo
The operating capabilities of the device being directly joined (Bit map).
Definition zigbee-nwk.h:524
uint64_t m_extendedPanId
The 64 bit PAN identifier of the the network to join.
Definition zigbee-nwk.h:516
NLME-NETWORK-DISCOVERY.confirm params.
Definition zigbee-nwk.h:500
uint8_t m_networkCount
Gives the number of networks discovered by the search.
Definition zigbee-nwk.h:503
std::vector< NetworkDescriptor > m_netDescList
A list of descriptors, one for each of the networks discovered.
Definition zigbee-nwk.h:504
NwkStatus m_status
The status of the corresponding request.
Definition zigbee-nwk.h:501
NLME-NETWORK-DISCOVERY.request params.
Definition zigbee-nwk.h:461
NLME-NETWORK-FORMATION.confirm params.
Definition zigbee-nwk.h:393
NwkStatus m_status
The status as a result of this request.
Definition zigbee-nwk.h:394
NLME-NETWORK-FORMATION.request params.
Definition zigbee-nwk.h:348
Mac16Address m_distributedNetworkAddress
The address of the device in a distributed network.
Definition zigbee-nwk.h:359
uint8_t m_superFrameOrder
The superframe order.
Definition zigbee-nwk.h:355
bool m_batteryLifeExtension
True: The zigbee coordinator is started supporting battery extension mode.
Definition zigbee-nwk.h:356
bool m_distributedNetwork
Indicates that distributed security will be used.
Definition zigbee-nwk.h:358
ChannelList m_scanChannelList
A structure that contain a description on the pages and their channels to be scanned.
Definition zigbee-nwk.h:349
uint8_t m_scanDuration
The time spent of each channel in symbols: aBaseSuperframeDuriantion * (2n+1).
Definition zigbee-nwk.h:352
NLME-ROUTE-DISCOVERY.confirm params.
Definition zigbee-nwk.h:419
NwkStatus m_status
The status as a result of this request.
Definition zigbee-nwk.h:420
NetworkStatusCode m_networkStatusCode
In case where.
Definition zigbee-nwk.h:422
NLME-ROUTE-DISCOVERY.request params.
Definition zigbee-nwk.h:404
NLME-START-ROUTER.confirm params.
Definition zigbee-nwk.h:601
NwkStatus m_status
The status of the corresponding request.
Definition zigbee-nwk.h:602
NLME-START-ROUTER.request params.
Definition zigbee-nwk.h:588
uint8_t m_beaconOrder
The beacon order of the network.
Definition zigbee-nwk.h:589
bool m_batteryLifeExt
True if the router supports battery life extension mode.
Definition zigbee-nwk.h:591
uint8_t m_superframeOrder
The superframe order of the network.
Definition zigbee-nwk.h:590