Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2020 Project CHIP Authors
4 : * Copyright (c) 2019 Nest Labs, Inc.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : /**
20 : * @file
21 : * Defines the public interface for the Device Layer ThreadStackManager object.
22 : */
23 :
24 : #pragma once
25 :
26 : #include <app/icd/server/ICDServerConfig.h>
27 :
28 : #include <app/util/basic-types.h>
29 : #include <inet/IPAddress.h>
30 : #include <lib/support/Span.h>
31 : #include <platform/NetworkCommissioning.h>
32 :
33 : namespace chip {
34 :
35 : namespace Dnssd {
36 : struct TextEntry;
37 : struct DnssdService;
38 : class CommissionAdvertisingParameters;
39 : } // namespace Dnssd
40 :
41 : namespace Thread {
42 : class OperationalDataset;
43 : } // namespace Thread
44 :
45 : namespace Transport {
46 : class PeerAddress;
47 : } // namespace Transport
48 :
49 : namespace DeviceLayer {
50 :
51 : class PlatformManagerImpl;
52 : class ThreadStackManagerImpl;
53 : class ConfigurationManagerImpl;
54 : class DeviceControlServer;
55 :
56 : /**
57 : * Provides a callback to send a Rendezvous announcement to a peer.
58 : *
59 : * @param[in] context A pointer to a context provided by the caller.
60 : * @param[in] peerAddr The address of the peer to send the announcement to.
61 : */
62 : typedef CHIP_ERROR (*RendezvousAnnouncementRequestCallback)(void * context, const Transport::PeerAddress & peerAddr);
63 :
64 : namespace Internal {
65 : class NFCCommissioningManagerImpl;
66 : class BLEManagerImpl;
67 : template <class>
68 : class GenericPlatformManagerImpl;
69 : template <class>
70 : class GenericConfigurationManagerImpl;
71 : template <class>
72 : class GenericPlatformManagerImpl_CMSISOS;
73 : template <class>
74 : class GenericPlatformManagerImpl_FreeRTOS;
75 : template <class>
76 : class GenericConnectivityManagerImpl_Thread;
77 : template <class>
78 : class GenericThreadStackManagerImpl_OpenThread;
79 : template <class>
80 : class GenericThreadStackManagerImpl_OpenThread_LwIP;
81 : template <class>
82 : class GenericThreadStackManagerImpl_FreeRTOS;
83 : } // namespace Internal
84 :
85 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
86 : // Declaration of callback types corresponding to DnssdResolveCallback and DnssdBrowseCallback to avoid circular including.
87 : using DnsResolveCallback = void (*)(void * context, chip::Dnssd::DnssdService * result, const Span<Inet::IPAddress> & addresses,
88 : CHIP_ERROR error);
89 : using DnsBrowseCallback = void (*)(void * context, chip::Dnssd::DnssdService * services, size_t servicesSize, bool finalBrowse,
90 : CHIP_ERROR error);
91 : #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
92 :
93 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
94 : using DnsAsyncReturnCallback = void (*)(void * context, CHIP_ERROR error);
95 : #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
96 :
97 : /**
98 : * Provides features for initializing and interacting with the Thread stack on
99 : * a chip-enabled device.
100 : */
101 : class ThreadStackManager
102 : {
103 : using ImplClass = ThreadStackManagerImpl;
104 :
105 : public:
106 : // ===== Members that define the public interface of the ThreadStackManager
107 :
108 : CHIP_ERROR InitThreadStack();
109 : void ProcessThreadActivity();
110 : CHIP_ERROR StartThreadTask();
111 : void LockThreadStack();
112 : bool TryLockThreadStack();
113 : void UnlockThreadStack();
114 : bool HaveRouteToAddress(const chip::Inet::IPAddress & destAddr);
115 : bool IsThreadEnabled();
116 : bool IsThreadProvisioned();
117 : bool IsThreadAttached();
118 : CHIP_ERROR GetThreadProvision(Thread::OperationalDataset & dataset);
119 : CHIP_ERROR GetPrimary802154MACAddress(uint8_t * buf);
120 : CHIP_ERROR GetThreadVersion(uint16_t & version);
121 :
122 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_MESHCOP
123 : CHIP_ERROR RendezvousStart(RendezvousAnnouncementRequestCallback announcementRequest, void * context);
124 : void RendezvousStop();
125 : void CancelRendezvousAnnouncement();
126 : #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_MESHCOP
127 :
128 : CHIP_ERROR SetThreadProvision(ByteSpan aDataset);
129 : CHIP_ERROR SetThreadEnabled(bool val);
130 : CHIP_ERROR AttachToThreadNetwork(const Thread::OperationalDataset & dataset,
131 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * callback);
132 : CHIP_ERROR StartThreadScan(NetworkCommissioning::ThreadDriver::ScanCallback * callback);
133 : void OnThreadAttachFinished(void);
134 :
135 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
136 : CHIP_ERROR AddSrpService(const char * aInstanceName, const char * aName, uint16_t aPort,
137 : const Span<const char * const> & aSubTypes, const Span<const Dnssd::TextEntry> & aTxtEntries,
138 : uint32_t aLeaseInterval, uint32_t aKeyLeaseInterval);
139 : CHIP_ERROR RemoveSrpService(const char * aInstanceName, const char * aName);
140 : CHIP_ERROR InvalidateAllSrpServices(); ///< Mark all SRP services as invalid
141 : CHIP_ERROR RemoveInvalidSrpServices(); ///< Remove SRP services marked as invalid
142 :
143 : /*
144 : * @brief Utility function to clear all thread SRP host and services established between the SRP server and client.
145 : * It is expected that a transaction is done between the SRP server and client so the clear request is applied on both ends
146 : *
147 : * A generic implementation is provided in `GenericThreadStackManagerImpl_OpenThread` with the SoC OT stack
148 : */
149 : CHIP_ERROR ClearAllSrpHostAndServices();
150 :
151 : /*
152 : * @brief Used to synchronize on the SRP server response confirming the clearing of the host and service entries
153 : * Should be called in ClearAllSrpHostAndServices once the request is sent.
154 : */
155 : void WaitOnSrpClearAllComplete();
156 :
157 : /*
158 : * @brief Notify that the SRP server confirmed the clearing of the host and service entries
159 : * Should be called in the SRP Client set callback in the removal confirmation.
160 : */
161 : void NotifySrpClearAllComplete();
162 : CHIP_ERROR SetupSrpHost(const char * aHostName);
163 : CHIP_ERROR ClearSrpHost(const char * aHostName);
164 : CHIP_ERROR SetSrpDnsCallbacks(DnsAsyncReturnCallback aInitCallback, DnsAsyncReturnCallback aErrorCallback, void * aContext);
165 :
166 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
167 : CHIP_ERROR DnsBrowse(const char * aServiceName, DnsBrowseCallback aCallback, void * aContext);
168 : CHIP_ERROR DnsResolve(const char * aServiceName, const char * aInstanceName, DnsResolveCallback aCallback, void * aContext);
169 : #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
170 : #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
171 :
172 : void ResetThreadNetworkDiagnosticsCounts(void);
173 :
174 : private:
175 : // ===== Members for internal use by the following friends.
176 :
177 : friend class PlatformManagerImpl;
178 : friend class ConfigurationManagerImpl;
179 : friend class DeviceControlServer;
180 : #if CHIP_DEVICE_CONFIG_ENABLE_NFC_BASED_COMMISSIONING
181 : friend class Internal::NFCCommissioningManagerImpl;
182 : #endif
183 : #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
184 : friend class Internal::BLEManagerImpl;
185 : #endif
186 : template <class>
187 : friend class Internal::GenericPlatformManagerImpl;
188 : template <class>
189 : friend class Internal::GenericConfigurationManagerImpl;
190 : template <class>
191 : friend class Internal::GenericPlatformManagerImpl_CMSISOS;
192 : template <class>
193 : friend class Internal::GenericPlatformManagerImpl_FreeRTOS;
194 : template <class>
195 : friend class Internal::GenericConnectivityManagerImpl_Thread;
196 : template <class>
197 : friend class Internal::GenericThreadStackManagerImpl_OpenThread;
198 : template <class>
199 : friend class Internal::GenericThreadStackManagerImpl_OpenThread_LwIP;
200 : template <class>
201 : friend class Internal::GenericThreadStackManagerImpl_FreeRTOS;
202 :
203 : void OnPlatformEvent(const ChipDeviceEvent * event);
204 : void ErasePersistentInfo();
205 : ConnectivityManager::ThreadDeviceType GetThreadDeviceType();
206 : CHIP_ERROR SetThreadDeviceType(ConnectivityManager::ThreadDeviceType threadRole);
207 :
208 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
209 : CHIP_ERROR SetPollingInterval(System::Clock::Milliseconds32 pollingInterval);
210 : #endif
211 :
212 : protected:
213 : // Construction/destruction limited to subclasses.
214 : ThreadStackManager() = default;
215 : ~ThreadStackManager() = default;
216 :
217 : // No copy, move or assignment.
218 : ThreadStackManager(const ThreadStackManager &) = delete;
219 : ThreadStackManager(const ThreadStackManager &&) = delete;
220 : ThreadStackManager & operator=(const ThreadStackManager &) = delete;
221 : };
222 :
223 : /**
224 : * Returns the public interface of the ThreadStackManager singleton object.
225 : *
226 : * chip applications should use this to access features of the ThreadStackManager object
227 : * that are common to all platforms.
228 : */
229 : extern ThreadStackManager & ThreadStackMgr();
230 :
231 : /**
232 : * Returns the platform-specific implementation of the ThreadStackManager singleton object.
233 : *
234 : * chip applications can use this to gain access to features of the ThreadStackManager
235 : * that are specific to the selected platform.
236 : */
237 : extern ThreadStackManagerImpl & ThreadStackMgrImpl();
238 :
239 : } // namespace DeviceLayer
240 : } // namespace chip
241 :
242 : /* Include a header file containing the implementation of the ThreadStackManager
243 : * object for the selected platform.
244 : */
245 : #ifdef EXTERNAL_THREADSTACKMANAGERIMPL_HEADER
246 : #include EXTERNAL_THREADSTACKMANAGERIMPL_HEADER
247 : #elif defined(CHIP_DEVICE_LAYER_TARGET)
248 : #define THREADSTACKMANAGERIMPL_HEADER <platform/CHIP_DEVICE_LAYER_TARGET/ThreadStackManagerImpl.h>
249 : #include THREADSTACKMANAGERIMPL_HEADER
250 : #endif // defined(CHIP_DEVICE_LAYER_TARGET)
251 :
252 : namespace chip {
253 : namespace DeviceLayer {
254 :
255 : inline CHIP_ERROR ThreadStackManager::InitThreadStack()
256 : {
257 : return static_cast<ImplClass *>(this)->_InitThreadStack();
258 : }
259 :
260 : inline void ThreadStackManager::ProcessThreadActivity()
261 : {
262 : static_cast<ImplClass *>(this)->_ProcessThreadActivity();
263 : }
264 :
265 : inline CHIP_ERROR ThreadStackManager::StartThreadTask()
266 : {
267 : return static_cast<ImplClass *>(this)->_StartThreadTask();
268 : }
269 :
270 : inline void ThreadStackManager::LockThreadStack()
271 : {
272 : static_cast<ImplClass *>(this)->_LockThreadStack();
273 : }
274 :
275 : inline bool ThreadStackManager::TryLockThreadStack()
276 : {
277 : return static_cast<ImplClass *>(this)->_TryLockThreadStack();
278 : }
279 :
280 : inline void ThreadStackManager::UnlockThreadStack()
281 : {
282 : static_cast<ImplClass *>(this)->_UnlockThreadStack();
283 : }
284 :
285 : /**
286 : * Determines whether a route exists via the Thread interface to the specified destination address.
287 : */
288 : inline bool ThreadStackManager::HaveRouteToAddress(const chip::Inet::IPAddress & destAddr)
289 : {
290 : return static_cast<ImplClass *>(this)->_HaveRouteToAddress(destAddr);
291 : }
292 :
293 25 : inline void ThreadStackManager::OnPlatformEvent(const ChipDeviceEvent * event)
294 : {
295 25 : static_cast<ImplClass *>(this)->_OnPlatformEvent(event);
296 25 : }
297 :
298 0 : inline bool ThreadStackManager::IsThreadEnabled()
299 : {
300 0 : return static_cast<ImplClass *>(this)->_IsThreadEnabled();
301 : }
302 :
303 0 : inline CHIP_ERROR ThreadStackManager::SetThreadEnabled(bool val)
304 : {
305 0 : return static_cast<ImplClass *>(this)->_SetThreadEnabled(val);
306 : }
307 :
308 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
309 : inline CHIP_ERROR ThreadStackManager::AddSrpService(const char * aInstanceName, const char * aName, uint16_t aPort,
310 : const Span<const char * const> & aSubTypes,
311 : const Span<const Dnssd::TextEntry> & aTxtEntries, uint32_t aLeaseInterval = 0,
312 : uint32_t aKeyLeaseInterval = 0)
313 : {
314 : return static_cast<ImplClass *>(this)->_AddSrpService(aInstanceName, aName, aPort, aSubTypes, aTxtEntries, aLeaseInterval,
315 : aKeyLeaseInterval);
316 : }
317 :
318 : inline CHIP_ERROR ThreadStackManager::RemoveSrpService(const char * aInstanceName, const char * aName)
319 : {
320 : return static_cast<ImplClass *>(this)->_RemoveSrpService(aInstanceName, aName);
321 : }
322 :
323 : inline CHIP_ERROR ThreadStackManager::InvalidateAllSrpServices()
324 : {
325 : return static_cast<ImplClass *>(this)->_InvalidateAllSrpServices();
326 : }
327 :
328 : inline CHIP_ERROR ThreadStackManager::RemoveInvalidSrpServices()
329 : {
330 : return static_cast<ImplClass *>(this)->_RemoveInvalidSrpServices();
331 : }
332 :
333 : inline CHIP_ERROR ThreadStackManager::ClearAllSrpHostAndServices()
334 : {
335 : return static_cast<ImplClass *>(this)->_ClearAllSrpHostAndServices();
336 : }
337 :
338 : inline void ThreadStackManager::WaitOnSrpClearAllComplete()
339 : {
340 : return static_cast<ImplClass *>(this)->_WaitOnSrpClearAllComplete();
341 : }
342 :
343 : inline void ThreadStackManager::NotifySrpClearAllComplete()
344 : {
345 : return static_cast<ImplClass *>(this)->_NotifySrpClearAllComplete();
346 : }
347 :
348 : inline CHIP_ERROR ThreadStackManager::SetupSrpHost(const char * aHostName)
349 : {
350 : return static_cast<ImplClass *>(this)->_SetupSrpHost(aHostName);
351 : }
352 :
353 : inline CHIP_ERROR ThreadStackManager::ClearSrpHost(const char * aHostName)
354 : {
355 : return static_cast<ImplClass *>(this)->_ClearSrpHost(aHostName);
356 : }
357 :
358 : inline CHIP_ERROR ThreadStackManager::SetSrpDnsCallbacks(DnsAsyncReturnCallback aInitCallback,
359 : DnsAsyncReturnCallback aErrorCallback, void * aContext)
360 : {
361 : return static_cast<ImplClass *>(this)->_SetSrpDnsCallbacks(aInitCallback, aErrorCallback, aContext);
362 : }
363 :
364 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
365 : inline CHIP_ERROR ThreadStackManager::DnsBrowse(const char * aServiceName, DnsBrowseCallback aCallback, void * aContext)
366 : {
367 : return static_cast<ImplClass *>(this)->_DnsBrowse(aServiceName, aCallback, aContext);
368 : }
369 :
370 : inline CHIP_ERROR ThreadStackManager::DnsResolve(const char * aServiceName, const char * aInstanceName,
371 : DnsResolveCallback aCallback, void * aContext)
372 : {
373 : return static_cast<ImplClass *>(this)->_DnsResolve(aServiceName, aInstanceName, aCallback, aContext);
374 : }
375 :
376 : #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
377 : #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
378 :
379 0 : inline bool ThreadStackManager::IsThreadProvisioned()
380 : {
381 0 : return static_cast<ImplClass *>(this)->_IsThreadProvisioned();
382 : }
383 :
384 0 : inline bool ThreadStackManager::IsThreadAttached()
385 : {
386 0 : return static_cast<ImplClass *>(this)->_IsThreadAttached();
387 : }
388 :
389 0 : inline CHIP_ERROR ThreadStackManager::GetThreadProvision(Thread::OperationalDataset & dataset)
390 : {
391 0 : return static_cast<ImplClass *>(this)->_GetThreadProvision(dataset);
392 : }
393 :
394 0 : inline CHIP_ERROR ThreadStackManager::SetThreadProvision(ByteSpan netInfo)
395 : {
396 0 : return static_cast<ImplClass *>(this)->_SetThreadProvision(netInfo);
397 : }
398 :
399 : inline CHIP_ERROR
400 0 : ThreadStackManager::AttachToThreadNetwork(const Thread::OperationalDataset & dataset,
401 : NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * callback)
402 : {
403 0 : return static_cast<ImplClass *>(this)->_AttachToThreadNetwork(dataset, callback);
404 : }
405 :
406 0 : inline void ThreadStackManager::OnThreadAttachFinished(void)
407 : {
408 0 : static_cast<ImplClass *>(this)->_OnThreadAttachFinished();
409 0 : }
410 :
411 0 : inline CHIP_ERROR ThreadStackManager::StartThreadScan(NetworkCommissioning::ThreadDriver::ScanCallback * callback)
412 : {
413 0 : return static_cast<ImplClass *>(this)->_StartThreadScan(callback);
414 : }
415 :
416 1 : inline void ThreadStackManager::ErasePersistentInfo()
417 : {
418 1 : static_cast<ImplClass *>(this)->_ErasePersistentInfo();
419 1 : }
420 :
421 : inline ConnectivityManager::ThreadDeviceType ThreadStackManager::GetThreadDeviceType()
422 : {
423 : return static_cast<ImplClass *>(this)->_GetThreadDeviceType();
424 : }
425 :
426 : inline CHIP_ERROR ThreadStackManager::SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType)
427 : {
428 : return static_cast<ImplClass *>(this)->_SetThreadDeviceType(deviceType);
429 : }
430 :
431 : #if CHIP_CONFIG_ENABLE_ICD_SERVER
432 : inline CHIP_ERROR ThreadStackManager::SetPollingInterval(System::Clock::Milliseconds32 pollingInterval)
433 : {
434 : return static_cast<ImplClass *>(this)->_SetPollingInterval(pollingInterval);
435 : }
436 : #endif // CHIP_CONFIG_ENABLE_ICD_SERVER
437 :
438 11 : inline CHIP_ERROR ThreadStackManager::GetPrimary802154MACAddress(uint8_t * buf)
439 : {
440 11 : return static_cast<ImplClass *>(this)->_GetPrimary802154MACAddress(buf);
441 : }
442 :
443 0 : inline CHIP_ERROR ThreadStackManager::GetThreadVersion(uint16_t & version)
444 : {
445 0 : return static_cast<ImplClass *>(this)->_GetThreadVersion(version);
446 : }
447 :
448 : #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_MESHCOP
449 : inline CHIP_ERROR ThreadStackManager::RendezvousStart(RendezvousAnnouncementRequestCallback announcementRequest, void * context)
450 : {
451 : return static_cast<ImplClass *>(this)->_RendezvousStart(announcementRequest, context);
452 : }
453 :
454 : inline void ThreadStackManager::RendezvousStop()
455 : {
456 : static_cast<ImplClass *>(this)->_RendezvousStop();
457 : }
458 :
459 : inline void ThreadStackManager::CancelRendezvousAnnouncement()
460 : {
461 : static_cast<ImplClass *>(this)->_CancelRendezvousAnnouncement();
462 : }
463 : #endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_MESHCOP
464 :
465 0 : inline void ThreadStackManager::ResetThreadNetworkDiagnosticsCounts()
466 : {
467 0 : static_cast<ImplClass *>(this)->_ResetThreadNetworkDiagnosticsCounts();
468 0 : }
469 :
470 : } // namespace DeviceLayer
471 : } // namespace chip
|