forked from project-chip/connectedhomeip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGenericThreadStackManagerImpl_OpenThread.h
303 lines (254 loc) · 13.2 KB
/
GenericThreadStackManagerImpl_OpenThread.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2019 Nest Labs, Inc.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file
* Provides a generic implementation of ThreadStackManager features
* for use on platforms that use OpenThread.
*/
#pragma once
#include <openthread/instance.h>
#include <openthread/link.h>
#include <openthread/netdata.h>
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
#include <openthread/srp_client.h>
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
#include <openthread/dns_client.h>
#endif
#include <app/icd/server/ICDServerConfig.h>
#include <lib/dnssd/Advertiser.h>
#include <lib/dnssd/platform/Dnssd.h>
#include <platform/GeneralFaults.h>
#include <platform/NetworkCommissioning.h>
namespace chip {
namespace DeviceLayer {
class ThreadStackManagerImpl;
namespace Internal {
/**
* Provides a generic implementation of ThreadStackManager features that works in conjunction
* with OpenThread.
*
* This class contains implementations of select features from the ThreadStackManager abstract
* interface that are suitable for use on devices that employ OpenThread. It is intended to
* be inherited, directly or indirectly, by the ThreadStackManagerImpl class, which also appears
* as the template's ImplClass parameter.
*
* The class is designed to be independent of the choice of host OS (e.g. RTOS or posix) and
* network stack (e.g. LwIP or other IP stack).
*/
template <class ImplClass>
class GenericThreadStackManagerImpl_OpenThread
{
public:
// ===== Platform-specific methods directly callable by the application.
otInstance * OTInstance() const;
static void OnOpenThreadStateChange(uint32_t flags, void * context);
inline void OverrunErrorTally(void);
void
SetNetworkStatusChangeCallback(NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * statusChangeCallback)
{
mpStatusChangeCallback = statusChangeCallback;
}
protected:
// ===== Methods that implement the ThreadStackManager abstract interface.
void _ProcessThreadActivity(void);
bool _HaveRouteToAddress(const Inet::IPAddress & destAddr);
void _OnPlatformEvent(const ChipDeviceEvent * event);
bool _IsThreadEnabled(void);
CHIP_ERROR _SetThreadEnabled(bool val);
bool _IsThreadProvisioned(void);
bool _IsThreadAttached(void);
CHIP_ERROR _GetThreadProvision(Thread::OperationalDataset & dataset);
CHIP_ERROR _SetThreadProvision(ByteSpan netInfo);
CHIP_ERROR _AttachToThreadNetwork(const Thread::OperationalDataset & dataset,
NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * callback);
void _OnThreadAttachFinished(void);
void _ErasePersistentInfo(void);
ConnectivityManager::ThreadDeviceType _GetThreadDeviceType(void);
CHIP_ERROR _SetThreadDeviceType(ConnectivityManager::ThreadDeviceType deviceType);
CHIP_ERROR _StartThreadScan(NetworkCommissioning::ThreadDriver::ScanCallback * callback);
static void _OnNetworkScanFinished(otActiveScanResult * aResult, void * aContext);
void _OnNetworkScanFinished(otActiveScanResult * aResult);
void _UpdateNetworkStatus();
#if CHIP_CONFIG_ENABLE_ICD_SERVER
CHIP_ERROR _SetPollingInterval(System::Clock::Milliseconds32 pollingInterval);
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
bool _HaveMeshConnectivity(void);
CHIP_ERROR _GetAndLogThreadStatsCounters(void);
CHIP_ERROR _GetAndLogThreadTopologyMinimal(void);
CHIP_ERROR _GetAndLogThreadTopologyFull(void);
CHIP_ERROR _GetPrimary802154MACAddress(uint8_t * buf);
CHIP_ERROR _GetExternalIPv6Address(chip::Inet::IPAddress & addr);
void _ResetThreadNetworkDiagnosticsCounts(void);
CHIP_ERROR _GetPollPeriod(uint32_t & buf);
void _OnWoBLEAdvertisingStart(void);
void _OnWoBLEAdvertisingStop(void);
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
CHIP_ERROR _AddSrpService(const char * aInstanceName, const char * aName, uint16_t aPort,
const Span<const char * const> & aSubTypes, const Span<const Dnssd::TextEntry> & aTxtEntries,
uint32_t aLeaseInterval, uint32_t aKeyLeaseInterval);
CHIP_ERROR _RemoveSrpService(const char * aInstanceName, const char * aName);
CHIP_ERROR _InvalidateAllSrpServices();
CHIP_ERROR _RemoveInvalidSrpServices();
CHIP_ERROR _ClearAllSrpHostAndServices();
CHIP_ERROR _SetupSrpHost(const char * aHostName);
CHIP_ERROR _ClearSrpHost(const char * aHostName);
CHIP_ERROR _SetSrpDnsCallbacks(DnsAsyncReturnCallback aInitCallback, DnsAsyncReturnCallback aErrorCallback, void * aContext);
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
CHIP_ERROR _DnsBrowse(const char * aServiceName, DnsBrowseCallback aCallback, void * aContext);
CHIP_ERROR _DnsResolve(const char * aServiceName, const char * aInstanceName, DnsResolveCallback aCallback, void * aContext);
static void DispatchResolve(intptr_t context);
static void DispatchResolveNoMemory(intptr_t context);
static void DispatchAddressResolve(intptr_t context);
static void DispatchBrowseEmpty(intptr_t context);
static void DispatchBrowse(intptr_t context);
static void DispatchBrowseNoMemory(intptr_t context);
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
// ===== Members available to the implementation subclass.
CHIP_ERROR DoInit(otInstance * otInst);
bool IsThreadAttachedNoLock(void);
bool IsThreadInterfaceUpNoLock(void);
private:
// ===== Private members for use by this class only.
otInstance * mOTInst;
uint64_t mOverrunCount = 0;
bool mIsAttached = false;
bool mTemporaryRxOnWhenIdle = false;
NetworkCommissioning::ThreadDriver::ScanCallback * mpScanCallback;
NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * mpConnectCallback;
NetworkCommissioning::Internal::BaseDriver::NetworkStatusChangeCallback * mpStatusChangeCallback = nullptr;
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
struct SrpClient
{
static constexpr uint8_t kMaxServicesNumber = CHIP_DEVICE_CONFIG_THREAD_SRP_MAX_SERVICES;
static constexpr char kDefaultDomainName[] = "default.service.arpa";
static constexpr uint8_t kDefaultDomainNameSize = 20;
static constexpr uint8_t kMaxDomainNameSize = 32;
// SRP is used for both operational and commissionable services, so buffers sizes must be worst case.
static constexpr size_t kSubTypeMaxNumber = Dnssd::Common::kSubTypeMaxNumber;
static constexpr size_t kSubTypeTotalLength = Dnssd::Common::kSubTypeTotalLength;
static constexpr size_t kTxtMaxNumber =
std::max(Dnssd::CommissionAdvertisingParameters::kTxtMaxNumber, Dnssd::OperationalAdvertisingParameters::kTxtMaxNumber);
static constexpr size_t kTxtTotalValueLength = std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalValueSize,
Dnssd::OperationalAdvertisingParameters::kTxtTotalValueSize);
static constexpr size_t kServiceBufferSize = Dnssd::Common::kInstanceNameMaxLength + 1 + // add null-terminator
Dnssd::kDnssdTypeAndProtocolMaxSize + 1 + // add null-terminator
kSubTypeTotalLength + kSubTypeMaxNumber + // add null-terminator for each subtype
kTxtTotalValueLength;
struct Service
{
otSrpClientService mService;
bool mIsInvalid;
uint8_t mServiceBuffer[kServiceBufferSize];
const char * mSubTypes[kSubTypeMaxNumber + 1]; // extra entry for null terminator
otDnsTxtEntry mTxtEntries[kTxtMaxNumber];
bool IsUsed() const { return mService.mInstanceName != nullptr; }
bool Matches(const char * instanceName, const char * name) const;
bool Matches(const char * instanceName, const char * name, uint16_t port, const Span<const char * const> & subTypes,
const Span<const Dnssd::TextEntry> & txtEntries) const;
};
char mHostName[Dnssd::kHostNameMaxLength + 1];
otIp6Address mHostAddress;
Service mServices[kMaxServicesNumber];
bool mIsInitialized;
DnsAsyncReturnCallback mInitializedCallback;
void * mCallbackContext;
};
SrpClient mSrpClient;
bool mIsSrpClearAllRequested = false;
static void OnSrpClientNotification(otError aError, const otSrpClientHostInfo * aHostInfo, const otSrpClientService * aServices,
const otSrpClientService * aRemovedServices, void * aContext);
static void OnSrpClientStateChange(const otSockAddr * aServerSockAddr, void * aContext);
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_COMMISSIONABLE_DISCOVERY
// Thread supports both operational and commissionable discovery, so buffers sizes must be worst case.
static constexpr uint8_t kMaxDnsServiceTxtEntriesNumber =
std::max(Dnssd::CommissionAdvertisingParameters::kTxtMaxNumber, Dnssd::OperationalAdvertisingParameters::kTxtMaxNumber);
static constexpr size_t kTotalDnsServiceTxtValueSize = std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalValueSize,
Dnssd::OperationalAdvertisingParameters::kTxtTotalValueSize);
static constexpr size_t kTotalDnsServiceTxtKeySize = std::max(Dnssd::CommissionAdvertisingParameters::kTxtTotalKeySize,
Dnssd::OperationalAdvertisingParameters::kTxtTotalKeySize);
#else
// Thread only supports operational discovery.
static constexpr uint8_t kMaxDnsServiceTxtEntriesNumber = Dnssd::OperationalAdvertisingParameters::kTxtMaxNumber;
static constexpr size_t kTotalDnsServiceTxtValueSize = Dnssd::OperationalAdvertisingParameters::kTxtTotalValueSize;
static constexpr size_t kTotalDnsServiceTxtKeySize = Dnssd::OperationalAdvertisingParameters::kTxtTotalKeySize;
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_COMMISSIONABLE_DISCOVERY
static constexpr size_t kTotalDnsServiceTxtBufferSize =
kTotalDnsServiceTxtKeySize + kMaxDnsServiceTxtEntriesNumber + kTotalDnsServiceTxtValueSize;
DnsBrowseCallback mDnsBrowseCallback;
DnsResolveCallback mDnsResolveCallback;
struct DnsServiceTxtEntries
{
uint8_t mBuffer[kTotalDnsServiceTxtBufferSize];
Dnssd::TextEntry mTxtEntries[kMaxDnsServiceTxtEntriesNumber];
};
struct DnsResult
{
void * context;
chip::Dnssd::DnssdService mMdnsService;
DnsServiceTxtEntries mServiceTxtEntry;
CHIP_ERROR error;
DnsResult(void * cbContext, CHIP_ERROR aError)
{
context = cbContext;
error = aError;
}
};
static void OnDnsBrowseResult(otError aError, const otDnsBrowseResponse * aResponse, void * aContext);
static void OnDnsResolveResult(otError aError, const otDnsServiceResponse * aResponse, void * aContext);
static void OnDnsAddressResolveResult(otError aError, const otDnsAddressResponse * aResponse, void * aContext);
static CHIP_ERROR ResolveAddress(intptr_t context, otDnsAddressCallback callback);
static CHIP_ERROR FromOtDnsResponseToMdnsData(otDnsServiceInfo & serviceInfo, const char * serviceType,
chip::Dnssd::DnssdService & mdnsService, DnsServiceTxtEntries & serviceTxtEntries,
otError error);
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT
GeneralFaults<kMaxNetworkFaults> mNetworkFaults;
inline ImplClass * Impl() { return static_cast<ImplClass *>(this); }
};
// Instruct the compiler to instantiate the template only when explicitly told to do so.
extern template class GenericThreadStackManagerImpl_OpenThread<ThreadStackManagerImpl>;
/**
* Returns the underlying OpenThread instance object.
*/
template <class ImplClass>
inline otInstance * GenericThreadStackManagerImpl_OpenThread<ImplClass>::OTInstance() const
{
return mOTInst;
}
template <class ImplClass>
inline void GenericThreadStackManagerImpl_OpenThread<ImplClass>::OverrunErrorTally(void)
{
mOverrunCount++;
}
template <class ImplClass>
inline void GenericThreadStackManagerImpl_OpenThread<ImplClass>::_OnWoBLEAdvertisingStart(void)
{
// Do nothing by default.
}
template <class ImplClass>
inline void GenericThreadStackManagerImpl_OpenThread<ImplClass>::_OnWoBLEAdvertisingStop(void)
{
// Do nothing by default.
}
} // namespace Internal
} // namespace DeviceLayer
} // namespace chip