xref: /aosp_15_r20/external/openthread/src/core/instance/instance.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
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 implements the OpenThread Instance class.
32  */
33 
34 #include "instance.hpp"
35 
36 #include <openthread/platform/misc.h>
37 
38 #include "common/new.hpp"
39 #include "radio/trel_link.hpp"
40 #include "utils/heap.hpp"
41 
42 namespace ot {
43 
44 #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
45 
46 // Define the raw storage used for OpenThread instance (in single-instance case).
47 OT_DEFINE_ALIGNED_VAR(gInstanceRaw, sizeof(Instance), uint64_t);
48 
49 #endif
50 
51 #if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
52 
53 #define INSTANCE_SIZE_ALIGNED OT_ALIGNED_VAR_SIZE(sizeof(ot::Instance), uint64_t)
54 #define MULTI_INSTANCE_SIZE (OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM * INSTANCE_SIZE_ALIGNED)
55 
56 // Define the raw storage used for OpenThread instance (in multi-instance case).
57 static uint64_t gMultiInstanceRaw[MULTI_INSTANCE_SIZE];
58 
59 #endif
60 
61 #if OPENTHREAD_MTD || OPENTHREAD_FTD
62 #if !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
63 OT_DEFINE_ALIGNED_VAR(sHeapRaw, sizeof(Utils::Heap), uint64_t);
64 Utils::Heap *Instance::sHeap{nullptr};
65 #endif
66 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
67 bool Instance::sDnsNameCompressionEnabled = true;
68 #endif
69 #endif
70 
71 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
72 LogLevel Instance::sLogLevel = static_cast<LogLevel>(OPENTHREAD_CONFIG_LOG_LEVEL_INIT);
73 #endif
74 
Instance(void)75 Instance::Instance(void)
76     : mTimerMilliScheduler(*this)
77 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
78     , mTimerMicroScheduler(*this)
79 #endif
80     , mRadio(*this)
81 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
82     , mUptime(*this)
83 #endif
84 #if OPENTHREAD_MTD || OPENTHREAD_FTD
85     , mNotifier(*this)
86     , mTimeTicker(*this)
87     , mSettings(*this)
88     , mSettingsDriver(*this)
89     , mMessagePool(*this)
90 #if OPENTHREAD_CONFIG_PLATFORM_DNSSD_ENABLE || OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
91     // DNS-SD (mDNS) platform is initialized early to
92     // allow other modules to use it.
93     , mDnssd(*this)
94 #endif
95     , mIp6(*this)
96     , mThreadNetif(*this)
97     , mTmfAgent(*this)
98 #if OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
99     , mDhcp6Client(*this)
100 #endif
101 #if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
102     , mDhcp6Server(*this)
103 #endif
104 #if OPENTHREAD_CONFIG_NEIGHBOR_DISCOVERY_AGENT_ENABLE
105     , mNeighborDiscoveryAgent(*this)
106 #endif
107 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
108     , mSlaac(*this)
109 #endif
110 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
111     , mDnsClient(*this)
112 #endif
113 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
114     , mSrpClient(*this)
115 #endif
116 #if OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE
117     , mSrpClientBuffers(*this)
118 #endif
119 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
120     , mDnssdServer(*this)
121 #endif
122 #if OPENTHREAD_CONFIG_DNS_DSO_ENABLE
123     , mDnsDso(*this)
124 #endif
125 #if OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE
126     , mMdnsCore(*this)
127 #endif
128 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
129     , mSntpClient(*this)
130 #endif
131 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
132     , mBackboneRouterLocal(*this)
133 #endif
134     , mActiveDataset(*this)
135     , mPendingDataset(*this)
136     , mExtendedPanIdManager(*this)
137     , mNetworkNameManager(*this)
138     , mIp6Filter(*this)
139     , mKeyManager(*this)
140     , mLowpan(*this)
141     , mMac(*this)
142     , mMeshForwarder(*this)
143     , mMleRouter(*this)
144     , mDiscoverScanner(*this)
145     , mAddressResolver(*this)
146 #if OPENTHREAD_CONFIG_MULTI_RADIO
147     , mRadioSelector(*this)
148 #endif
149 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
150     , mNetworkDataLocal(*this)
151 #endif
152     , mNetworkDataLeader(*this)
153 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
154     , mNetworkDataNotifier(*this)
155 #endif
156 #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
157     , mNetworkDataPublisher(*this)
158 #endif
159     , mNetworkDataServiceManager(*this)
160     , mNetworkDiagnosticServer(*this)
161 #if OPENTHREAD_CONFIG_TMF_NETDIAG_CLIENT_ENABLE
162     , mNetworkDiagnosticClient(*this)
163 #endif
164 #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
165     , mBorderAgent(*this)
166 #endif
167 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
168     , mCommissioner(*this)
169 #endif
170 #if OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE
171     , mTmfSecureAgent(*this)
172 #endif
173 #if OPENTHREAD_CONFIG_JOINER_ENABLE
174     , mJoiner(*this)
175 #endif
176 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
177     , mJamDetector(*this)
178 #endif
179 #if OPENTHREAD_FTD
180     , mJoinerRouter(*this)
181     , mLeader(*this)
182 #endif
183 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
184     , mBackboneRouterLeader(*this)
185 #endif
186 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
187     , mBackboneRouterManager(*this)
188 #endif
189 #if OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
190     , mMlrManager(*this)
191 #endif
192 
193 #if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
194     , mDuaManager(*this)
195 #endif
196 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
197     , mSrpServer(*this)
198 #if OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE
199     , mSrpAdvertisingProxy(*this)
200 #endif
201 #endif
202 #if OPENTHREAD_FTD
203     , mChildSupervisor(*this)
204 #endif
205     , mSupervisionListener(*this)
206     , mAnnounceBegin(*this)
207     , mPanIdQuery(*this)
208     , mEnergyScan(*this)
209 #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
210     , mAnycastLocator(*this)
211 #endif
212 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
213     , mTimeSync(*this)
214 #endif
215 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
216     , mInitiator(*this)
217 #endif
218 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
219     , mSubject(*this)
220 #endif
221 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
222     , mApplicationCoap(*this)
223 #endif
224 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
225     , mApplicationCoapSecure(*this, /* aLayerTwoSecurity */ true)
226 #endif
227 #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE
228     , mApplicationBleSecure(*this)
229 #endif
230 #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
231     , mPingSender(*this)
232 #endif
233 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
234     , mChannelMonitor(*this)
235 #endif
236 #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && \
237     (OPENTHREAD_FTD || OPENTHREAD_CONFIG_CHANNEL_MANAGER_CSL_CHANNEL_SELECT_ENABLE)
238     , mChannelManager(*this)
239 #endif
240 #if OPENTHREAD_CONFIG_MESH_DIAG_ENABLE && OPENTHREAD_FTD
241     , mMeshDiag(*this)
242 #endif
243 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
244     , mHistoryTracker(*this)
245 #endif
246 #if OPENTHREAD_CONFIG_LINK_METRICS_MANAGER_ENABLE
247     , mLinkMetricsManager(*this)
248 #endif
249 #if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
250     , mDatasetUpdater(*this)
251 #endif
252 #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
253     , mAnnounceSender(*this)
254 #endif
255 #if OPENTHREAD_CONFIG_OTNS_ENABLE
256     , mOtns(*this)
257 #endif
258 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
259     , mRoutingManager(*this)
260 #endif
261 #if OPENTHREAD_CONFIG_NAT64_TRANSLATOR_ENABLE
262     , mNat64Translator(*this)
263 #endif
264 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
265 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
266     , mLinkRaw(*this)
267 #endif
268 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
269     , mExtension(Extension::ExtensionBase::Init(*this))
270 #endif
271 #if OPENTHREAD_CONFIG_DIAG_ENABLE
272     , mDiags(*this)
273 #endif
274 #if OPENTHREAD_CONFIG_POWER_CALIBRATION_ENABLE && OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
275     , mPowerCalibration(*this)
276 #endif
277     , mIsInitialized(false)
278     , mId(Random::NonCrypto::GetUint32())
279 {
280 }
281 
282 #if (OPENTHREAD_MTD || OPENTHREAD_FTD) && !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
GetHeap(void)283 Utils::Heap &Instance::GetHeap(void)
284 {
285     if (nullptr == sHeap)
286     {
287         sHeap = new (&sHeapRaw) Utils::Heap();
288     }
289 
290     return *sHeap;
291 }
292 #endif
293 
294 #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
295 
InitSingle(void)296 Instance &Instance::InitSingle(void)
297 {
298     Instance *instance = &Get();
299 
300     VerifyOrExit(!instance->mIsInitialized);
301 
302     instance = new (&gInstanceRaw) Instance();
303 
304     instance->AfterInit();
305 
306 exit:
307     return *instance;
308 }
309 
Get(void)310 Instance &Instance::Get(void)
311 {
312     void *instance = &gInstanceRaw;
313 
314     return *static_cast<Instance *>(instance);
315 }
316 
317 #else // #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
318 #if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
319 
InitMultiple(uint8_t aIdx)320 Instance *Instance::InitMultiple(uint8_t aIdx)
321 {
322     size_t    bufferSize;
323     uint64_t *instanceBuffer = gMultiInstanceRaw + aIdx * INSTANCE_SIZE_ALIGNED;
324     Instance *instance       = reinterpret_cast<Instance *>(instanceBuffer);
325 
326     VerifyOrExit(aIdx < OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_NUM);
327     VerifyOrExit(!instance->mIsInitialized);
328 
329     bufferSize = (&gMultiInstanceRaw[MULTI_INSTANCE_SIZE] - instanceBuffer) * sizeof(uint64_t);
330     instance   = Instance::Init(instanceBuffer, &bufferSize);
331 
332 exit:
333     return instance;
334 }
335 
Get(uint8_t aIdx)336 Instance &Instance::Get(uint8_t aIdx)
337 {
338     void *instance = gMultiInstanceRaw + aIdx * INSTANCE_SIZE_ALIGNED;
339     return *static_cast<Instance *>(instance);
340 }
341 
GetIdx(Instance * aInstance)342 uint8_t Instance::GetIdx(Instance *aInstance)
343 {
344     return static_cast<uint8_t>(
345         (reinterpret_cast<uint8_t *>(aInstance) - reinterpret_cast<uint8_t *>(gMultiInstanceRaw)) /
346         INSTANCE_SIZE_ALIGNED);
347 }
348 
349 #endif // #if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
350 
Init(void * aBuffer,size_t * aBufferSize)351 Instance *Instance::Init(void *aBuffer, size_t *aBufferSize)
352 {
353     Instance *instance = nullptr;
354 
355     VerifyOrExit(aBufferSize != nullptr);
356 
357     // Make sure the input buffer is big enough
358     VerifyOrExit(sizeof(Instance) <= *aBufferSize, *aBufferSize = sizeof(Instance));
359 
360     VerifyOrExit(aBuffer != nullptr);
361 
362     instance = new (aBuffer) Instance();
363 
364     instance->AfterInit();
365 
366 exit:
367     return instance;
368 }
369 
370 #endif // OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
371 
Reset(void)372 void Instance::Reset(void) { otPlatReset(this); }
373 
374 #if OPENTHREAD_CONFIG_PLATFORM_BOOTLOADER_MODE_ENABLE
ResetToBootloader(void)375 Error Instance::ResetToBootloader(void) { return otPlatResetToBootloader(this); }
376 #endif
377 
378 #if OPENTHREAD_RADIO
ResetRadioStack(void)379 void Instance::ResetRadioStack(void)
380 {
381     mRadio.Init();
382     mLinkRaw.Init();
383 }
384 #endif
385 
AfterInit(void)386 void Instance::AfterInit(void)
387 {
388     mIsInitialized = true;
389 #if OPENTHREAD_MTD || OPENTHREAD_FTD
390 
391     // Restore datasets and network information
392 
393     Get<Settings>().Init();
394     Get<Mle::MleRouter>().Restore();
395 
396 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
397     Get<Trel::Link>().AfterInit();
398 #endif
399 
400 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
401 
402 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
403     Get<Extension::ExtensionBase>().SignalInstanceInit();
404 #endif
405 }
406 
Finalize(void)407 void Instance::Finalize(void)
408 {
409     VerifyOrExit(mIsInitialized);
410 
411     mIsInitialized = false;
412 
413 #if OPENTHREAD_MTD || OPENTHREAD_FTD
414     IgnoreError(otThreadSetEnabled(this, false));
415     IgnoreError(otIp6SetEnabled(this, false));
416     IgnoreError(otLinkSetEnabled(this, false));
417 
418 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
419     Get<KeyManager>().DestroyTemporaryKeys();
420 #endif
421 
422     Get<Settings>().Deinit();
423 #endif
424 
425     IgnoreError(Get<Mac::SubMac>().Disable());
426 
427 #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
428 
429     /**
430      * Object was created on buffer, so instead of deleting
431      * the object we call destructor explicitly.
432      */
433     this->~Instance();
434 
435 #endif // !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
436 
437 exit:
438     return;
439 }
440 
441 #if OPENTHREAD_MTD || OPENTHREAD_FTD
442 
FactoryReset(void)443 void Instance::FactoryReset(void)
444 {
445     Get<Settings>().Wipe();
446 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
447     Get<KeyManager>().DestroyTemporaryKeys();
448     Get<KeyManager>().DestroyPersistentKeys();
449 #endif
450     otPlatReset(this);
451 }
452 
ErasePersistentInfo(void)453 Error Instance::ErasePersistentInfo(void)
454 {
455     Error error = kErrorNone;
456 
457     VerifyOrExit(Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
458     Get<Settings>().Wipe();
459 #if OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
460     Get<KeyManager>().DestroyTemporaryKeys();
461     Get<KeyManager>().DestroyPersistentKeys();
462 #endif
463 
464 exit:
465     return error;
466 }
467 
GetBufferInfo(BufferInfo & aInfo)468 void Instance::GetBufferInfo(BufferInfo &aInfo)
469 {
470     aInfo.Clear();
471 
472     aInfo.mTotalBuffers   = Get<MessagePool>().GetTotalBufferCount();
473     aInfo.mFreeBuffers    = Get<MessagePool>().GetFreeBufferCount();
474     aInfo.mMaxUsedBuffers = Get<MessagePool>().GetMaxUsedBufferCount();
475 
476     Get<MeshForwarder>().GetSendQueue().GetInfo(aInfo.m6loSendQueue);
477     Get<MeshForwarder>().GetReassemblyQueue().GetInfo(aInfo.m6loReassemblyQueue);
478     Get<Ip6::Ip6>().GetSendQueue().GetInfo(aInfo.mIp6Queue);
479 
480 #if OPENTHREAD_FTD
481     Get<Ip6::Mpl>().GetBufferedMessageSet().GetInfo(aInfo.mMplQueue);
482 #endif
483 
484     Get<Mle::MleRouter>().GetMessageQueue().GetInfo(aInfo.mMleQueue);
485 
486     Get<Tmf::Agent>().GetRequestMessages().GetInfo(aInfo.mCoapQueue);
487     Get<Tmf::Agent>().GetCachedResponses().GetInfo(aInfo.mCoapQueue);
488 
489 #if OPENTHREAD_CONFIG_SECURE_TRANSPORT_ENABLE
490     Get<Tmf::SecureAgent>().GetRequestMessages().GetInfo(aInfo.mCoapSecureQueue);
491     Get<Tmf::SecureAgent>().GetCachedResponses().GetInfo(aInfo.mCoapSecureQueue);
492 #endif
493 
494 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
495     GetApplicationCoap().GetRequestMessages().GetInfo(aInfo.mApplicationCoapQueue);
496     GetApplicationCoap().GetCachedResponses().GetInfo(aInfo.mApplicationCoapQueue);
497 #endif
498 }
499 
ResetBufferInfo(void)500 void Instance::ResetBufferInfo(void) { Get<MessagePool>().ResetMaxUsedBufferCount(); }
501 
502 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
503 
504 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
505 
SetLogLevel(LogLevel aLogLevel)506 void Instance::SetLogLevel(LogLevel aLogLevel)
507 {
508     if (aLogLevel != sLogLevel)
509     {
510         sLogLevel = aLogLevel;
511         otPlatLogHandleLevelChanged(sLogLevel);
512     }
513 }
514 
otPlatLogHandleLevelChanged(otLogLevel aLogLevel)515 extern "C" OT_TOOL_WEAK void otPlatLogHandleLevelChanged(otLogLevel aLogLevel) { OT_UNUSED_VARIABLE(aLogLevel); }
516 
517 #endif
518 
519 } // namespace ot
520