• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_MTD || OPENTHREAD_FTD
52 #if !OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
53 Utils::Heap Instance::sHeap;
54 #endif
55 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
56 bool Instance::sDnsNameCompressionEnabled = true;
57 #endif
58 #endif
59 
60 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
61 LogLevel Instance::sLogLevel = static_cast<LogLevel>(OPENTHREAD_CONFIG_LOG_LEVEL_INIT);
62 #endif
63 
Instance(void)64 Instance::Instance(void)
65     : mTimerMilliScheduler(*this)
66 #if OPENTHREAD_CONFIG_PLATFORM_USEC_TIMER_ENABLE
67     , mTimerMicroScheduler(*this)
68 #endif
69     , mRadio(*this)
70 #if OPENTHREAD_CONFIG_UPTIME_ENABLE
71     , mUptime(*this)
72 #endif
73 #if OPENTHREAD_MTD || OPENTHREAD_FTD
74     , mNotifier(*this)
75     , mTimeTicker(*this)
76     , mSettings(*this)
77     , mSettingsDriver(*this)
78     , mMessagePool(*this)
79     , mIp6(*this)
80     , mThreadNetif(*this)
81     , mTmfAgent(*this)
82 #if OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE
83     , mDhcp6Client(*this)
84 #endif
85 #if OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE
86     , mDhcp6Server(*this)
87 #endif
88 #if OPENTHREAD_CONFIG_NEIGHBOR_DISCOVERY_AGENT_ENABLE
89     , mNeighborDiscoveryAgent(*this)
90 #endif
91 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
92     , mSlaac(*this)
93 #endif
94 #if OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE
95     , mDnsClient(*this)
96 #endif
97 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
98     , mSrpClient(*this)
99 #endif
100 #if OPENTHREAD_CONFIG_SRP_CLIENT_BUFFERS_ENABLE
101     , mSrpClientBuffers(*this)
102 #endif
103 #if OPENTHREAD_CONFIG_DNSSD_SERVER_ENABLE
104     , mDnssdServer(*this)
105 #endif
106 #if OPENTHREAD_CONFIG_DNS_DSO_ENABLE
107     , mDnsDso(*this)
108 #endif
109 #if OPENTHREAD_CONFIG_SNTP_CLIENT_ENABLE
110     , mSntpClient(*this)
111 #endif
112     , mActiveDataset(*this)
113     , mPendingDataset(*this)
114     , mExtendedPanIdManager(*this)
115     , mNetworkNameManager(*this)
116     , mIp6Filter(*this)
117     , mKeyManager(*this)
118     , mLowpan(*this)
119     , mMac(*this)
120     , mMeshForwarder(*this)
121     , mMleRouter(*this)
122     , mDiscoverScanner(*this)
123     , mAddressResolver(*this)
124 #if OPENTHREAD_CONFIG_MULTI_RADIO
125     , mRadioSelector(*this)
126 #endif
127 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
128     , mNetworkDataLocal(*this)
129 #endif
130     , mNetworkDataLeader(*this)
131 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE || OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
132     , mNetworkDataNotifier(*this)
133 #endif
134 #if OPENTHREAD_CONFIG_NETDATA_PUBLISHER_ENABLE
135     , mNetworkDataPublisher(*this)
136 #endif
137     , mNetworkDataServiceManager(*this)
138 #if OPENTHREAD_FTD || OPENTHREAD_CONFIG_TMF_NETWORK_DIAG_MTD_ENABLE
139     , mNetworkDiagnostic(*this)
140 #endif
141 #if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE
142     , mBorderAgent(*this)
143 #endif
144 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE && OPENTHREAD_FTD
145     , mCommissioner(*this)
146 #endif
147 #if OPENTHREAD_CONFIG_DTLS_ENABLE
148     , mCoapSecure(*this)
149 #endif
150 #if OPENTHREAD_CONFIG_JOINER_ENABLE
151     , mJoiner(*this)
152 #endif
153 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
154     , mJamDetector(*this)
155 #endif
156 #if OPENTHREAD_FTD
157     , mJoinerRouter(*this)
158     , mLeader(*this)
159 #endif
160 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
161     , mBackboneRouterLeader(*this)
162 #endif
163 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
164     , mBackboneRouterLocal(*this)
165     , mBackboneRouterManager(*this)
166 #endif
167 #if OPENTHREAD_CONFIG_MLR_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE)
168     , mMlrManager(*this)
169 #endif
170 
171 #if OPENTHREAD_CONFIG_DUA_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_DUA_ENABLE)
172     , mDuaManager(*this)
173 #endif
174 #if OPENTHREAD_CONFIG_SRP_SERVER_ENABLE
175     , mSrpServer(*this)
176 #endif
177 
178 #if OPENTHREAD_CONFIG_CHILD_SUPERVISION_ENABLE
179 #if OPENTHREAD_FTD
180     , mChildSupervisor(*this)
181 #endif
182     , mSupervisionListener(*this)
183 #endif
184     , mAnnounceBegin(*this)
185     , mPanIdQuery(*this)
186     , mEnergyScan(*this)
187 #if OPENTHREAD_CONFIG_TMF_ANYCAST_LOCATOR_ENABLE
188     , mAnycastLocator(*this)
189 #endif
190 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
191     , mTimeSync(*this)
192 #endif
193 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE || OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
194     , mLinkMetrics(*this)
195 #endif
196 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
197     , mApplicationCoap(*this)
198 #endif
199 #if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE
200     , mApplicationCoapSecure(*this, /* aLayerTwoSecurity */ true)
201 #endif
202 #if OPENTHREAD_CONFIG_PING_SENDER_ENABLE
203     , mPingSender(*this)
204 #endif
205 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
206     , mChannelMonitor(*this)
207 #endif
208 #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE && OPENTHREAD_FTD
209     , mChannelManager(*this)
210 #endif
211 #if OPENTHREAD_CONFIG_HISTORY_TRACKER_ENABLE
212     , mHistoryTracker(*this)
213 #endif
214 #if (OPENTHREAD_CONFIG_DATASET_UPDATER_ENABLE || OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE) && OPENTHREAD_FTD
215     , mDatasetUpdater(*this)
216 #endif
217 #if OPENTHREAD_CONFIG_ANNOUNCE_SENDER_ENABLE
218     , mAnnounceSender(*this)
219 #endif
220 #if OPENTHREAD_CONFIG_OTNS_ENABLE
221     , mOtns(*this)
222 #endif
223 #if OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE
224     , mRoutingManager(*this)
225 #endif
226 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
227 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
228     , mLinkRaw(*this)
229 #endif
230 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
231     , mExtension(Extension::ExtensionBase::Init(*this))
232 #endif
233 #if OPENTHREAD_CONFIG_DIAG_ENABLE
234     , mDiags(*this)
235 #endif
236     , mIsInitialized(false)
237 {
238 }
239 
240 #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
241 
InitSingle(void)242 Instance &Instance::InitSingle(void)
243 {
244     Instance *instance = &Get();
245 
246     VerifyOrExit(!instance->mIsInitialized);
247 
248     instance = new (&gInstanceRaw) Instance();
249 
250     instance->AfterInit();
251 
252 exit:
253     return *instance;
254 }
255 
Get(void)256 Instance &Instance::Get(void)
257 {
258     void *instance = &gInstanceRaw;
259 
260     return *static_cast<Instance *>(instance);
261 }
262 
263 #else // #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
264 
Init(void * aBuffer,size_t * aBufferSize)265 Instance *Instance::Init(void *aBuffer, size_t *aBufferSize)
266 {
267     Instance *instance = nullptr;
268 
269     VerifyOrExit(aBufferSize != nullptr);
270 
271     // Make sure the input buffer is big enough
272     VerifyOrExit(sizeof(Instance) <= *aBufferSize, *aBufferSize = sizeof(Instance));
273 
274     VerifyOrExit(aBuffer != nullptr);
275 
276     instance = new (aBuffer) Instance();
277 
278     instance->AfterInit();
279 
280 exit:
281     return instance;
282 }
283 
284 #endif // OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
285 
Reset(void)286 void Instance::Reset(void)
287 {
288     otPlatReset(this);
289 }
290 
291 #if OPENTHREAD_RADIO
ResetRadioStack(void)292 void Instance::ResetRadioStack(void)
293 {
294     mRadio.Init();
295     mLinkRaw.Init();
296 }
297 #endif
298 
AfterInit(void)299 void Instance::AfterInit(void)
300 {
301     mIsInitialized = true;
302 #if OPENTHREAD_MTD || OPENTHREAD_FTD
303 
304     // Restore datasets and network information
305 
306     Get<Settings>().Init();
307     Get<Mle::MleRouter>().Restore();
308 
309 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
310     Get<Trel::Link>().AfterInit();
311 #endif
312 
313 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
314 
315 #if OPENTHREAD_ENABLE_VENDOR_EXTENSION
316     Get<Extension::ExtensionBase>().SignalInstanceInit();
317 #endif
318 }
319 
Finalize(void)320 void Instance::Finalize(void)
321 {
322     VerifyOrExit(mIsInitialized);
323 
324     mIsInitialized = false;
325 
326 #if OPENTHREAD_MTD || OPENTHREAD_FTD
327     IgnoreError(otThreadSetEnabled(this, false));
328     IgnoreError(otIp6SetEnabled(this, false));
329     IgnoreError(otLinkSetEnabled(this, false));
330 
331     Get<Settings>().Deinit();
332 #endif
333 
334     IgnoreError(Get<Mac::SubMac>().Disable());
335 
336 #if !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
337 
338     /**
339      * Object was created on buffer, so instead of deleting
340      * the object we call destructor explicitly.
341      */
342     this->~Instance();
343 
344 #endif // !OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
345 
346 exit:
347     return;
348 }
349 
350 #if OPENTHREAD_MTD || OPENTHREAD_FTD
351 
FactoryReset(void)352 void Instance::FactoryReset(void)
353 {
354     Get<Settings>().Wipe();
355     otPlatReset(this);
356 }
357 
ErasePersistentInfo(void)358 Error Instance::ErasePersistentInfo(void)
359 {
360     Error error = kErrorNone;
361 
362     VerifyOrExit(Get<Mle::MleRouter>().IsDisabled(), error = kErrorInvalidState);
363     Get<Settings>().Wipe();
364 
365 exit:
366     return error;
367 }
368 
GetBufferInfo(BufferInfo & aInfo)369 void Instance::GetBufferInfo(BufferInfo &aInfo)
370 {
371     aInfo.Clear();
372 
373     aInfo.mTotalBuffers = Get<MessagePool>().GetTotalBufferCount();
374     aInfo.mFreeBuffers  = Get<MessagePool>().GetFreeBufferCount();
375 
376     Get<MeshForwarder>().GetSendQueue().GetInfo(aInfo.m6loSendQueue);
377     Get<MeshForwarder>().GetReassemblyQueue().GetInfo(aInfo.m6loReassemblyQueue);
378     Get<Ip6::Ip6>().GetSendQueue().GetInfo(aInfo.mIp6Queue);
379 
380 #if OPENTHREAD_FTD
381     Get<Ip6::Mpl>().GetBufferedMessageSet().GetInfo(aInfo.mMplQueue);
382 #endif
383 
384     Get<Mle::MleRouter>().GetMessageQueue().GetInfo(aInfo.mMleQueue);
385 
386     Get<Tmf::Agent>().GetRequestMessages().GetInfo(aInfo.mCoapQueue);
387     Get<Tmf::Agent>().GetCachedResponses().GetInfo(aInfo.mCoapQueue);
388 
389 #if OPENTHREAD_CONFIG_DTLS_ENABLE
390     Get<Coap::CoapSecure>().GetRequestMessages().GetInfo(aInfo.mCoapSecureQueue);
391     Get<Coap::CoapSecure>().GetCachedResponses().GetInfo(aInfo.mCoapSecureQueue);
392 #endif
393 
394 #if OPENTHREAD_CONFIG_COAP_API_ENABLE
395     GetApplicationCoap().GetRequestMessages().GetInfo(aInfo.mApplicationCoapQueue);
396     GetApplicationCoap().GetCachedResponses().GetInfo(aInfo.mApplicationCoapQueue);
397 #endif
398 }
399 
400 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
401 
402 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
403 
SetLogLevel(LogLevel aLogLevel)404 void Instance::SetLogLevel(LogLevel aLogLevel)
405 {
406     if (aLogLevel != sLogLevel)
407     {
408         sLogLevel = aLogLevel;
409         otPlatLogHandleLevelChanged(sLogLevel);
410     }
411 }
412 
otPlatLogHandleLevelChanged(otLogLevel aLogLevel)413 extern "C" OT_TOOL_WEAK void otPlatLogHandleLevelChanged(otLogLevel aLogLevel)
414 {
415     OT_UNUSED_VARIABLE(aLogLevel);
416 }
417 
418 #endif
419 
420 } // namespace ot
421