1 /*
2  *  Copyright (c) 2016-2017, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *  This file defines OpenThread instance class.
32  */
33 
34 #ifndef INSTANCE_HPP_
35 #define INSTANCE_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdbool.h>
40 #include <stdint.h>
41 
42 #include <openthread/heap.h>
43 #include <openthread/platform/logging.h>
44 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
45 #include <openthread/platform/memory.h>
46 #endif
47 
48 #include "common/error.hpp"
49 #include "common/non_copyable.hpp"
50 #include "common/random_manager.hpp"
51 #include "common/tasklet.hpp"
52 #include "common/time_ticker.hpp"
53 #include "common/timer.hpp"
54 #include "diags/factory_diags.hpp"
55 #include "radio/radio.hpp"
56 
57 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
58 #include "common/message.hpp"
59 #include "mac/link_raw.hpp"
60 #endif
61 #if OPENTHREAD_FTD || OPENTHREAD_MTD
62 #include "common/code_utils.hpp"
63 #include "common/notifier.hpp"
64 #include "common/settings.hpp"
65 #include "crypto/mbedtls.hpp"
66 #include "meshcop/border_agent.hpp"
67 #if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
68 #include "meshcop/dataset_updater.hpp"
69 #endif
70 #include "net/ip6.hpp"
71 #include "thread/announce_sender.hpp"
72 #include "thread/link_quality.hpp"
73 #include "thread/thread_netif.hpp"
74 #include "thread/tmf.hpp"
75 #include "utils/heap.hpp"
76 #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
77 #include "utils/ping_sender.hpp"
78 #endif
79 #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && OPENTHREAD_FTD
80 #include "utils/channel_manager.hpp"
81 #endif
82 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
83 #include "utils/channel_monitor.hpp"
84 #endif
85 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
86 #include "utils/history_tracker.hpp"
87 #endif
88 
89 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
90 #include "backbone_router/bbr_leader.hpp"
91 
92 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
93 #include "backbone_router/bbr_local.hpp"
94 #endif
95 
96 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
97 #include "thread/link_metrics.hpp"
98 #endif
99 
100 #endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
101 
102 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
103 #include "border_router/routing_manager.hpp"
104 #endif
105 
106 #endif // OPENTHREAD_FTD || OPENTHREAD_MTD
107 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
108 #include "common/extension.hpp"
109 #endif
110 #if OPENTHREAD_CONFIG_OTNS_ENABLE
111 #include "utils/otns.hpp"
112 #endif
113 /**
114  * @addtogroup core-instance
115  *
116  * @brief
117  *   This module includes definitions for OpenThread instance.
118  *
119  * @{
120  *
121  */
122 
123 /**
124  * This struct represents an opaque (and empty) type corresponding to an OpenThread instance object.
125  *
126  */
127 typedef struct otInstance
128 {
129 } otInstance;
130 
131 namespace ot {
132 
133 /**
134  * This class represents an OpenThread instance.
135  *
136  * This class contains all the components used by OpenThread.
137  *
138  */
139 class Instance : public otInstance, private NonCopyable
140 {
141 public:
142 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
143     /**
144       * This static method initializes the OpenThread instance.
145       *
146       * This function must be called before any other calls on OpenThread instance.
147       *
148       * @param[in]    aBuffer      The buffer for OpenThread to use for allocating the Instance.
149       * @param[inout] aBufferSize  On input, the size of `aBuffer`. On output, if not enough space for `Instance`, the
150                                    number of bytes required for `Instance`.
151       *
152       * @returns  A pointer to the new OpenThread instance.
153       *
154       */
155     static Instance *Init(void *aBuffer, size_t *aBufferSize);
156 
157 #else // OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
158 
159     /**
160      * This static method initializes the single OpenThread instance.
161      *
162      * This method initializes OpenThread and prepares it for subsequent OpenThread API calls. This function must be
163      * called before any other calls to OpenThread.
164      *
165      * @returns A reference to the single OpenThread instance.
166      *
167      */
168     static Instance &InitSingle(void);
169 
170     /**
171      * This static method returns a reference to the single OpenThread instance.
172      *
173      * @returns A reference to the single OpenThread instance.
174      *
175      */
176     static Instance &Get(void);
177 #endif
178 
179     /**
180      * This method indicates whether or not the instance is valid/initialized and not yet finalized.
181      *
182      * @returns TRUE if the instance is valid/initialized, FALSE otherwise.
183      *
184      */
IsInitialized(void) const185     bool IsInitialized(void) const { return mIsInitialized; }
186 
187     /**
188      * This method triggers a platform reset.
189      *
190      * The reset process ensures that all the OpenThread state/info (stored in volatile memory) is erased. Note that
191      * this method does not erase any persistent state/info saved in non-volatile memory.
192      *
193      */
194     void Reset(void);
195 
196     /**
197      * This method returns the active log level.
198      *
199      * @returns The log level.
200      *
201      */
GetLogLevel(void) const202     otLogLevel GetLogLevel(void) const
203 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
204     {
205         return mLogLevel;
206     }
207 #else
208     {
209         return static_cast<otLogLevel>(OPENTHREAD_CONFIG_LOG_LEVEL);
210     }
211 #endif
212 
213 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
214     /**
215      * This method sets the log level.
216      *
217      * @param[in] aLogLevel  A log level.
218      *
219      */
SetLogLevel(otLogLevel aLogLevel)220     void SetLogLevel(otLogLevel aLogLevel)
221     {
222         OT_ASSERT(aLogLevel <= OT_LOG_LEVEL_DEBG && aLogLevel >= OT_LOG_LEVEL_NONE);
223         mLogLevel = aLogLevel;
224     }
225 #endif
226 
227     /**
228      * This method finalizes the OpenThread instance.
229      *
230      * This method should be called when OpenThread instance is no longer in use.
231      *
232      */
233     void Finalize(void);
234 
235 #if OPENTHREAD_MTD || OPENTHREAD_FTD
236     /**
237      * This method deletes all the settings stored in non-volatile memory, and then triggers a platform reset.
238      *
239      */
240     void FactoryReset(void);
241 
242     /**
243      * This method erases all the OpenThread persistent info (network settings) stored in non-volatile memory.
244      *
245      * Erase is successful/allowed only if the device is in `disabled` state/role.
246      *
247      * @retval kErrorNone          All persistent info/state was erased successfully.
248      * @retval kErrorInvalidState  Device is not in `disabled` state/role.
249      *
250      */
251     Error ErasePersistentInfo(void);
252 
253 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
HeapFree(void * aPointer)254     static void  HeapFree(void *aPointer) { otPlatFree(aPointer); }
HeapCAlloc(size_t aCount,size_t aSize)255     static void *HeapCAlloc(size_t aCount, size_t aSize) { return otPlatCAlloc(aCount, aSize); }
256 #else
HeapFree(void * aPointer)257     static void  HeapFree(void *aPointer) { sHeap.Free(aPointer); }
HeapCAlloc(size_t aCount,size_t aSize)258     static void *HeapCAlloc(size_t aCount, size_t aSize) { return sHeap.CAlloc(aCount, aSize); }
259 
260     /**
261      * This method returns a reference to the Heap object.
262      *
263      * @returns A reference to the Heap object.
264      *
265      */
GetHeap(void)266     Utils::Heap &GetHeap(void) { return sHeap; }
267 #endif // OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
268 
269 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
270     /**
271      * This method returns a reference to application COAP object.
272      *
273      * @returns A reference to the application COAP object.
274      *
275      */
GetApplicationCoap(void)276     Coap::Coap &GetApplicationCoap(void) { return mApplicationCoap; }
277 #endif
278 
279 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
280     /**
281      * This method returns a reference to application COAP Secure object.
282      *
283      * @returns A reference to the application COAP Secure object.
284      *
285      */
GetApplicationCoapSecure(void)286     Coap::CoapSecure &GetApplicationCoapSecure(void) { return mApplicationCoapSecure; }
287 #endif
288 
289 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
290     /**
291      * This method enables/disables the "DNS name compressions" mode.
292      *
293      * By default DNS name compression is enabled. When disabled, DNS names are appended as full and never compressed.
294      * This is applicable to OpenThread's DNS and SRP client/server modules.
295      *
296      * This is intended for testing only and available under a `REFERENCE_DEVICE` config.
297      *
298      * @param[in] aEnabled   TRUE to enable the "DNS name compression" mode, FALSE to disable.
299      *
300      */
SetDnsNameCompressionEnabled(bool aEnabled)301     static void SetDnsNameCompressionEnabled(bool aEnabled) { sDnsNameCompressionEnabled = aEnabled; }
302 
303     /**
304      * This method indicates whether the "DNS name compression" mode is enabled or not.
305      *
306      * @returns TRUE if the "DNS name compressions" mode is enabled, FALSE otherwise.
307      *
308      */
IsDnsNameCompressionEnabled(void)309     static bool IsDnsNameCompressionEnabled(void) { return sDnsNameCompressionEnabled; }
310 #endif
311 
312 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
313 
314     /**
315      * This template method returns a reference to a given `Type` object belonging to the OpenThread instance.
316      *
317      * For example, `Get<MeshForwarder>()` returns a reference to the `MeshForwarder` object of the instance.
318      *
319      * Note that any `Type` for which the `Get<Type>` is defined MUST be uniquely accessible from the OpenThread
320      * `Instance` through the member variable property hierarchy.
321      *
322      * Specializations of the `Get<Type>()` method are defined in this file after the `Instance` class definition.
323      *
324      * @returns A reference to the `Type` object of the instance.
325      *
326      */
327     template <typename Type> inline Type &Get(void);
328 
329 private:
330     Instance(void);
331     void AfterInit(void);
332 
333     // Order of variables (their initialization in `Instance`)
334     // is important.
335     //
336     // Tasklet and Timer Schedulers are first to ensure other
337     // objects/classes can use them from their constructors.
338 
339     Tasklet::Scheduler    mTaskletScheduler;
340     TimerMilli::Scheduler mTimerMilliScheduler;
341 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
342     TimerMicro::Scheduler mTimerMicroScheduler;
343 #endif
344 
345 #if OPENTHREAD_MTD || OPENTHREAD_FTD
346     // RandomManager is initialized before other objects. Note that it
347     // requires MbedTls which itself may use Heap.
348 #if !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
349     static Utils::Heap sHeap;
350 #endif
351     Crypto::MbedTls mMbedTls;
352 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
353 
354     RandomManager mRandomManager;
355 
356     // Radio is initialized before other member variables
357     // (particularly, SubMac and Mac) to allow them to use its methods
358     // from their constructor.
359     Radio mRadio;
360 
361 #if OPENTHREAD_MTD || OPENTHREAD_FTD
362     // Notifier, TimeTicker, Settings, and MessagePool are initialized
363     // before other member variables since other classes/objects from
364     // their constructor may use them.
365     Notifier       mNotifier;
366     TimeTicker     mTimeTicker;
367     Settings       mSettings;
368     SettingsDriver mSettingsDriver;
369     MessagePool    mMessagePool;
370 
371     Ip6::Ip6    mIp6;
372     ThreadNetif mThreadNetif;
373 
374 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
375     Coap::Coap mApplicationCoap;
376 #endif
377 
378 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
379     Coap::CoapSecure mApplicationCoapSecure;
380 #endif
381 
382 #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
383     Utils::PingSender mPingSender;
384 #endif
385 
386 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
387     Utils::ChannelMonitor mChannelMonitor;
388 #endif
389 
390 #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && OPENTHREAD_FTD
391     Utils::ChannelManager mChannelManager;
392 #endif
393 
394 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
395     Utils::HistoryTracker mHistoryTracker;
396 #endif
397 
398 #if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
399     MeshCoP::DatasetUpdater mDatasetUpdater;
400 #endif
401 
402 #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
403     AnnounceSender mAnnounceSender;
404 #endif
405 
406 #if OPENTHREAD_CONFIG_OTNS_ENABLE
407     Utils::Otns mOtns;
408 #endif
409 
410 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
411     BorderRouter::RoutingManager mRoutingManager;
412 #endif
413 
414 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
415 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
416     Mac::LinkRaw mLinkRaw;
417 #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
418 
419 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
420     otLogLevel mLogLevel;
421 #endif
422 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
423     Extension::ExtensionBase &mExtension;
424 #endif
425 #if OPENTHREAD_CONFIG_DIAG_ENABLE
426     FactoryDiags::Diags mDiags;
427 #endif
428     bool mIsInitialized;
429 
430 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
431     static bool sDnsNameCompressionEnabled;
432 #endif
433 };
434 
435 // Specializations of the `Get<Type>()` method.
436 
Get(void)437 template <> inline Radio &Instance::Get(void)
438 {
439     return mRadio;
440 }
441 
Get(void)442 template <> inline Radio::Callbacks &Instance::Get(void)
443 {
444     return mRadio.mCallbacks;
445 }
446 
447 #if OPENTHREAD_MTD || OPENTHREAD_FTD
Get(void)448 template <> inline Notifier &Instance::Get(void)
449 {
450     return mNotifier;
451 }
452 
Get(void)453 template <> inline TimeTicker &Instance::Get(void)
454 {
455     return mTimeTicker;
456 }
457 
Get(void)458 template <> inline Settings &Instance::Get(void)
459 {
460     return mSettings;
461 }
462 
Get(void)463 template <> inline SettingsDriver &Instance::Get(void)
464 {
465     return mSettingsDriver;
466 }
467 
Get(void)468 template <> inline MeshForwarder &Instance::Get(void)
469 {
470     return mThreadNetif.mMeshForwarder;
471 }
472 
473 #if OPENTHREAD_CONFIG_MULTI_RADIO
Get(void)474 template <> inline RadioSelector &Instance::Get(void)
475 {
476     return mThreadNetif.mRadioSelector;
477 }
478 #endif
479 
Get(void)480 template <> inline Mle::Mle &Instance::Get(void)
481 {
482     return mThreadNetif.mMleRouter;
483 }
484 
Get(void)485 template <> inline Mle::MleRouter &Instance::Get(void)
486 {
487     return mThreadNetif.mMleRouter;
488 }
489 
Get(void)490 template <> inline Mle::DiscoverScanner &Instance::Get(void)
491 {
492     return mThreadNetif.mDiscoverScanner;
493 }
494 
Get(void)495 template <> inline NeighborTable &Instance::Get(void)
496 {
497     return mThreadNetif.mMleRouter.mNeighborTable;
498 }
499 
500 #if OPENTHREAD_FTD
Get(void)501 template <> inline ChildTable &Instance::Get(void)
502 {
503     return mThreadNetif.mMleRouter.mChildTable;
504 }
505 
Get(void)506 template <> inline RouterTable &Instance::Get(void)
507 {
508     return mThreadNetif.mMleRouter.mRouterTable;
509 }
510 #endif
511 
Get(void)512 template <> inline Ip6::Netif &Instance::Get(void)
513 {
514     return mThreadNetif;
515 }
516 
Get(void)517 template <> inline ThreadNetif &Instance::Get(void)
518 {
519     return mThreadNetif;
520 }
521 
Get(void)522 template <> inline Ip6::Ip6 &Instance::Get(void)
523 {
524     return mIp6;
525 }
526 
Get(void)527 template <> inline Mac::Mac &Instance::Get(void)
528 {
529     return mThreadNetif.mMac;
530 }
531 
Get(void)532 template <> inline Mac::SubMac &Instance::Get(void)
533 {
534     return mThreadNetif.mMac.mLinks.mSubMac;
535 }
536 
537 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
Get(void)538 template <> inline Trel::Link &Instance::Get(void)
539 {
540     return mThreadNetif.mMac.mLinks.mTrel;
541 }
542 
Get(void)543 template <> inline Trel::Interface &Instance::Get(void)
544 {
545     return mThreadNetif.mMac.mLinks.mTrel.mInterface;
546 }
547 #endif
548 
549 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
Get(void)550 template <> inline Mac::Filter &Instance::Get(void)
551 {
552     return mThreadNetif.mMac.mFilter;
553 }
554 #endif
555 
Get(void)556 template <> inline Lowpan::Lowpan &Instance::Get(void)
557 {
558     return mThreadNetif.mLowpan;
559 }
560 
Get(void)561 template <> inline KeyManager &Instance::Get(void)
562 {
563     return mThreadNetif.mKeyManager;
564 }
565 
Get(void)566 template <> inline Ip6::Filter &Instance::Get(void)
567 {
568     return mThreadNetif.mIp6Filter;
569 }
570 
571 #if OPENTHREAD_FTD
572 
Get(void)573 template <> inline IndirectSender &Instance::Get(void)
574 {
575     return mThreadNetif.mMeshForwarder.mIndirectSender;
576 }
577 
Get(void)578 template <> inline SourceMatchController &Instance::Get(void)
579 {
580     return mThreadNetif.mMeshForwarder.mIndirectSender.mSourceMatchController;
581 }
582 
Get(void)583 template <> inline DataPollHandler &Instance::Get(void)
584 {
585     return mThreadNetif.mMeshForwarder.mIndirectSender.mDataPollHandler;
586 }
587 
588 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
Get(void)589 template <> inline CslTxScheduler &Instance::Get(void)
590 {
591     return mThreadNetif.mMeshForwarder.mIndirectSender.mCslTxScheduler;
592 }
593 #endif
594 
Get(void)595 template <> inline AddressResolver &Instance::Get(void)
596 {
597     return mThreadNetif.mAddressResolver;
598 }
599 
Get(void)600 template <> inline MeshCoP::Leader &Instance::Get(void)
601 {
602     return mThreadNetif.mLeader;
603 }
604 
Get(void)605 template <> inline MeshCoP::JoinerRouter &Instance::Get(void)
606 {
607     return mThreadNetif.mJoinerRouter;
608 }
609 #endif // OPENTHREAD_FTD
610 
Get(void)611 template <> inline AnnounceBeginServer &Instance::Get(void)
612 {
613     return mThreadNetif.mAnnounceBegin;
614 }
615 
Get(void)616 template <> inline DataPollSender &Instance::Get(void)
617 {
618     return mThreadNetif.mMeshForwarder.mDataPollSender;
619 }
620 
Get(void)621 template <> inline EnergyScanServer &Instance::Get(void)
622 {
623     return mThreadNetif.mEnergyScan;
624 }
625 
Get(void)626 template <> inline PanIdQueryServer &Instance::Get(void)
627 {
628     return mThreadNetif.mPanIdQuery;
629 }
630 
631 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Get(void)632 template <> inline NetworkData::Local &Instance::Get(void)
633 {
634     return mThreadNetif.mNetworkDataLocal;
635 }
636 #endif
637 
Get(void)638 template <> inline NetworkData::Leader &Instance::Get(void)
639 {
640     return mThreadNetif.mNetworkDataLeader;
641 }
642 
643 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
Get(void)644 template <> inline NetworkData::Notifier &Instance::Get(void)
645 {
646     return mThreadNetif.mNetworkDataNotifier;
647 }
648 #endif
649 
650 #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
Get(void)651 template <> inline NetworkData::Publisher &Instance::Get(void)
652 {
653     return mThreadNetif.mNetworkDataPublisher;
654 }
655 #endif
656 
Get(void)657 template <> inline NetworkData::Service::Manager &Instance::Get(void)
658 {
659     return mThreadNetif.mNetworkDataServiceManager;
660 }
661 
662 #if OPENTHREAD_CONFIG_TCP_ENABLE
Get(void)663 template <> inline Ip6::Tcp &Instance::Get(void)
664 {
665     return mIp6.mTcp;
666 }
667 #endif
668 
Get(void)669 template <> inline Ip6::Udp &Instance::Get(void)
670 {
671     return mIp6.mUdp;
672 }
673 
Get(void)674 template <> inline Ip6::Icmp &Instance::Get(void)
675 {
676     return mIp6.mIcmp;
677 }
678 
Get(void)679 template <> inline Ip6::Mpl &Instance::Get(void)
680 {
681     return mIp6.mMpl;
682 }
683 
Get(void)684 template <> inline Tmf::Agent &Instance::Get(void)
685 {
686     return mThreadNetif.mTmfAgent;
687 }
688 
689 #if OPENTHREAD_CONFIG_DTLS_ENABLE
Get(void)690 template <> inline Coap::CoapSecure &Instance::Get(void)
691 {
692     return mThreadNetif.mCoapSecure;
693 }
694 #endif
695 
Get(void)696 template <> inline MeshCoP::ActiveDataset &Instance::Get(void)
697 {
698     return mThreadNetif.mActiveDataset;
699 }
700 
Get(void)701 template <> inline MeshCoP::PendingDataset &Instance::Get(void)
702 {
703     return mThreadNetif.mPendingDataset;
704 }
705 
706 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
Get(void)707 template <> inline TimeSync &Instance::Get(void)
708 {
709     return mThreadNetif.mTimeSync;
710 }
711 #endif
712 
713 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
Get(void)714 template <> inline MeshCoP::Commissioner &Instance::Get(void)
715 {
716     return mThreadNetif.mCommissioner;
717 }
718 #endif
719 
720 #if OPENTHREAD_CONFIG_JOINER_ENABLE
Get(void)721 template <> inline MeshCoP::Joiner &Instance::Get(void)
722 {
723     return mThreadNetif.mJoiner;
724 }
725 #endif
726 
727 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
Get(void)728 template <> inline Dns::Client &Instance::Get(void)
729 {
730     return mThreadNetif.mDnsClient;
731 }
732 #endif
733 
734 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
Get(void)735 template <> inline Srp::Client &Instance::Get(void)
736 {
737     return mThreadNetif.mSrpClient;
738 }
739 #endif
740 
741 #if OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE
Get(void)742 template <> inline Utils::SrpClientBuffers &Instance::Get(void)
743 {
744     return mThreadNetif.mSrpClientBuffers;
745 }
746 #endif
747 
748 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
Get(void)749 template <> inline Dns::ServiceDiscovery::Server &Instance::Get(void)
750 {
751     return mThreadNetif.mDnssdServer;
752 }
753 #endif
754 
755 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
Get(void)756 template <> inline NetworkDiagnostic::NetworkDiagnostic &Instance::Get(void)
757 {
758     return mThreadNetif.mNetworkDiagnostic;
759 }
760 #endif
761 
762 #if OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
Get(void)763 template <> inline Dhcp6::Client &Instance::Get(void)
764 {
765     return mThreadNetif.mDhcp6Client;
766 }
767 #endif
768 
769 #if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
Get(void)770 template <> inline Dhcp6::Server &Instance::Get(void)
771 {
772     return mThreadNetif.mDhcp6Server;
773 }
774 #endif
775 
776 #if OPENTHREAD_CONFIG_NEIGHBOR_DISCOVERY_AGENT_ENABLE
Get(void)777 template <> inline NeighborDiscovery::Agent &Instance::Get(void)
778 {
779     return mThreadNetif.mNeighborDiscoveryAgent;
780 }
781 #endif
782 
783 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
Get(void)784 template <> inline Utils::Slaac &Instance::Get(void)
785 {
786     return mThreadNetif.mSlaac;
787 }
788 #endif
789 
790 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
Get(void)791 template <> inline Utils::JamDetector &Instance::Get(void)
792 {
793     return mThreadNetif.mJamDetector;
794 }
795 #endif
796 
797 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
Get(void)798 template <> inline Sntp::Client &Instance::Get(void)
799 {
800     return mThreadNetif.mSntpClient;
801 }
802 #endif
803 
804 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
805 #if OPENTHREAD_FTD
Get(void)806 template <> inline Utils::ChildSupervisor &Instance::Get(void)
807 {
808     return mThreadNetif.mChildSupervisor;
809 }
810 #endif
Get(void)811 template <> inline Utils::SupervisionListener &Instance::Get(void)
812 {
813     return mThreadNetif.mSupervisionListener;
814 }
815 #endif
816 
817 #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
Get(void)818 template <> inline Utils::PingSender &Instance::Get(void)
819 {
820     return mPingSender;
821 }
822 #endif
823 
824 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
Get(void)825 template <> inline Utils::ChannelMonitor &Instance::Get(void)
826 {
827     return mChannelMonitor;
828 }
829 #endif
830 
831 #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && OPENTHREAD_FTD
Get(void)832 template <> inline Utils::ChannelManager &Instance::Get(void)
833 {
834     return mChannelManager;
835 }
836 #endif
837 
838 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
Get(void)839 template <> inline Utils::HistoryTracker &Instance::Get(void)
840 {
841     return mHistoryTracker;
842 }
843 #endif
844 
845 #if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
Get(void)846 template <> inline MeshCoP::DatasetUpdater &Instance::Get(void)
847 {
848     return mDatasetUpdater;
849 }
850 #endif
851 
852 #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
Get(void)853 template <> inline MeshCoP::BorderAgent &Instance::Get(void)
854 {
855     return mThreadNetif.mBorderAgent;
856 }
857 #endif
858 
859 #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
Get(void)860 template <> inline AnnounceSender &Instance::Get(void)
861 {
862     return mAnnounceSender;
863 }
864 #endif
865 
Get(void)866 template <> inline MessagePool &Instance::Get(void)
867 {
868     return mMessagePool;
869 }
870 
871 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
872 
Get(void)873 template <> inline BackboneRouter::Leader &Instance::Get(void)
874 {
875     return mThreadNetif.mBackboneRouterLeader;
876 }
877 
878 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
Get(void)879 template <> inline BackboneRouter::Local &Instance::Get(void)
880 {
881     return mThreadNetif.mBackboneRouterLocal;
882 }
Get(void)883 template <> inline BackboneRouter::Manager &Instance::Get(void)
884 {
885     return mThreadNetif.mBackboneRouterManager;
886 }
887 
888 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_MULTICAST_ROUTING_ENABLE
Get(void)889 template <> inline BackboneRouter::MulticastListenersTable &Instance::Get(void)
890 {
891     return mThreadNetif.mBackboneRouterManager.GetMulticastListenersTable();
892 }
893 #endif
894 
895 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_DUA_NDPROXYING_ENABLE
Get(void)896 template <> inline BackboneRouter::NdProxyTable &Instance::Get(void)
897 {
898     return mThreadNetif.mBackboneRouterManager.GetNdProxyTable();
899 }
900 #endif
901 
Get(void)902 template <> inline BackboneRouter::BackboneTmfAgent &Instance::Get(void)
903 {
904     return mThreadNetif.mBackboneRouterManager.GetBackboneTmfAgent();
905 }
906 #endif
907 
908 #if OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
Get(void)909 template <> inline MlrManager &Instance::Get(void)
910 {
911     return mThreadNetif.mMlrManager;
912 }
913 #endif
914 
915 #if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
Get(void)916 template <> inline DuaManager &Instance::Get(void)
917 {
918     return mThreadNetif.mDuaManager;
919 }
920 #endif
921 
922 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
Get(void)923 template <> inline LinkMetrics::LinkMetrics &Instance::Get(void)
924 {
925     return mThreadNetif.mLinkMetrics;
926 }
927 #endif
928 
929 #endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
930 
931 #if OPENTHREAD_CONFIG_OTNS_ENABLE
Get(void)932 template <> inline Utils::Otns &Instance::Get(void)
933 {
934     return mOtns;
935 }
936 #endif
937 
938 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
Get(void)939 template <> inline BorderRouter::RoutingManager &Instance::Get(void)
940 {
941     return mRoutingManager;
942 }
943 #endif
944 
945 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
Get(void)946 template <> inline Srp::Server &Instance::Get(void)
947 {
948     return mThreadNetif.mSrpServer;
949 }
950 #endif
951 
952 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
953 
954 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
Get(void)955 template <> inline Mac::LinkRaw &Instance::Get(void)
956 {
957     return mLinkRaw;
958 }
959 
960 #if OPENTHREAD_RADIO
Get(void)961 template <> inline Mac::SubMac &Instance::Get(void)
962 {
963     return mLinkRaw.mSubMac;
964 }
965 #endif
966 
967 #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
968 
Get(void)969 template <> inline Tasklet::Scheduler &Instance::Get(void)
970 {
971     return mTaskletScheduler;
972 }
973 
Get(void)974 template <> inline TimerMilli::Scheduler &Instance::Get(void)
975 {
976     return mTimerMilliScheduler;
977 }
978 
979 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
Get(void)980 template <> inline TimerMicro::Scheduler &Instance::Get(void)
981 {
982     return mTimerMicroScheduler;
983 }
984 #endif
985 
986 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
Get(void)987 template <> inline Extension::ExtensionBase &Instance::Get(void)
988 {
989     return mExtension;
990 }
991 #endif
992 
993 #if OPENTHREAD_CONFIG_DIAG_ENABLE
Get(void)994 template <> inline FactoryDiags::Diags &Instance::Get(void)
995 {
996     return mDiags;
997 }
998 #endif
999 
1000 /**
1001  * @}
1002  *
1003  */
1004 
1005 } // namespace ot
1006 
1007 #endif // INSTANCE_HPP_
1008