xref: /aosp_15_r20/external/ot-br-posix/src/utils/thread_helper.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1 /*
2  *    Copyright (c) 2020, 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 #define OTBR_LOG_TAG "UTILS"
30 
31 #include "utils/thread_helper.hpp"
32 
33 #include <assert.h>
34 #include <limits.h>
35 #include <string.h>
36 #include <time.h>
37 
38 #include <openthread/border_agent.h>
39 #include <openthread/border_router.h>
40 #include <openthread/channel_manager.h>
41 #include <openthread/dataset_ftd.h>
42 #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
43 #include <openthread/dnssd_server.h>
44 #endif
45 #include <openthread/jam_detection.h>
46 #include <openthread/joiner.h>
47 #if OTBR_ENABLE_NAT64
48 #include <openthread/crypto.h>
49 #include <openthread/nat64.h>
50 #include "utils/sha256.hpp"
51 #endif
52 #if OTBR_ENABLE_DHCP6_PD
53 #include "utils/sha256.hpp"
54 #endif
55 #if OTBR_ENABLE_LINK_METRICS_TELEMETRY
56 #include <openthread/link_metrics.h>
57 #endif
58 #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
59 #include <openthread/srp_server.h>
60 #endif
61 #include <openthread/thread_ftd.h>
62 #if OTBR_ENABLE_TREL
63 #include <openthread/trel.h>
64 #endif
65 #include <net/if.h>
66 #include <openthread/platform/radio.h>
67 
68 #include "common/byteswap.hpp"
69 #include "common/code_utils.hpp"
70 #include "common/logging.hpp"
71 #include "common/tlv.hpp"
72 #include "ncp/rcp_host.hpp"
73 
74 namespace otbr {
75 namespace agent {
76 namespace {
FindTlv(uint8_t aTlvType,const uint8_t * aTlvs,int aTlvsSize)77 const Tlv *FindTlv(uint8_t aTlvType, const uint8_t *aTlvs, int aTlvsSize)
78 {
79     const Tlv *result = nullptr;
80 
81     for (const Tlv *tlv = reinterpret_cast<const Tlv *>(aTlvs);
82          reinterpret_cast<const uint8_t *>(tlv) + sizeof(Tlv) < aTlvs + aTlvsSize; tlv = tlv->GetNext())
83     {
84         if (tlv->GetType() == aTlvType)
85         {
86             ExitNow(result = tlv);
87         }
88     }
89 
90 exit:
91     return result;
92 }
93 
94 #if OTBR_ENABLE_TELEMETRY_DATA_API
TelemetryNodeTypeFromRoleAndLinkMode(const otDeviceRole & aRole,const otLinkModeConfig & aLinkModeCfg)95 static uint32_t TelemetryNodeTypeFromRoleAndLinkMode(const otDeviceRole &aRole, const otLinkModeConfig &aLinkModeCfg)
96 {
97     uint32_t nodeType;
98 
99     switch (aRole)
100     {
101     case OT_DEVICE_ROLE_DISABLED:
102         nodeType = threadnetwork::TelemetryData::NODE_TYPE_DISABLED;
103         break;
104     case OT_DEVICE_ROLE_DETACHED:
105         nodeType = threadnetwork::TelemetryData::NODE_TYPE_DETACHED;
106         break;
107     case OT_DEVICE_ROLE_ROUTER:
108         nodeType = threadnetwork::TelemetryData::NODE_TYPE_ROUTER;
109         break;
110     case OT_DEVICE_ROLE_LEADER:
111         nodeType = threadnetwork::TelemetryData::NODE_TYPE_LEADER;
112         break;
113     case OT_DEVICE_ROLE_CHILD:
114         if (!aLinkModeCfg.mRxOnWhenIdle)
115         {
116             nodeType = threadnetwork::TelemetryData::NODE_TYPE_SLEEPY_END;
117         }
118         else if (!aLinkModeCfg.mDeviceType)
119         {
120             // If it's not an FTD, return as minimal end device.
121             nodeType = threadnetwork::TelemetryData::NODE_TYPE_MINIMAL_END;
122         }
123         else
124         {
125             nodeType = threadnetwork::TelemetryData::NODE_TYPE_END;
126         }
127         break;
128     default:
129         nodeType = threadnetwork::TelemetryData::NODE_TYPE_UNSPECIFIED;
130     }
131 
132     return nodeType;
133 }
134 
135 #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
SrpServerStateFromOtSrpServerState(otSrpServerState srpServerState)136 threadnetwork::TelemetryData_SrpServerState SrpServerStateFromOtSrpServerState(otSrpServerState srpServerState)
137 {
138     switch (srpServerState)
139     {
140     case OT_SRP_SERVER_STATE_DISABLED:
141         return threadnetwork::TelemetryData::SRP_SERVER_STATE_DISABLED;
142     case OT_SRP_SERVER_STATE_RUNNING:
143         return threadnetwork::TelemetryData::SRP_SERVER_STATE_RUNNING;
144     case OT_SRP_SERVER_STATE_STOPPED:
145         return threadnetwork::TelemetryData::SRP_SERVER_STATE_STOPPED;
146     default:
147         return threadnetwork::TelemetryData::SRP_SERVER_STATE_UNSPECIFIED;
148     }
149 }
150 
SrpServerAddressModeFromOtSrpServerAddressMode(otSrpServerAddressMode srpServerAddressMode)151 threadnetwork::TelemetryData_SrpServerAddressMode SrpServerAddressModeFromOtSrpServerAddressMode(
152     otSrpServerAddressMode srpServerAddressMode)
153 {
154     switch (srpServerAddressMode)
155     {
156     case OT_SRP_SERVER_ADDRESS_MODE_ANYCAST:
157         return threadnetwork::TelemetryData::SRP_SERVER_ADDRESS_MODE_STATE_ANYCAST;
158     case OT_SRP_SERVER_ADDRESS_MODE_UNICAST:
159         return threadnetwork::TelemetryData::SRP_SERVER_ADDRESS_MODE_UNICAST;
160     default:
161         return threadnetwork::TelemetryData::SRP_SERVER_ADDRESS_MODE_UNSPECIFIED;
162     }
163 }
164 #endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY
165 
166 #if OTBR_ENABLE_NAT64
Nat64StateFromOtNat64State(otNat64State nat64State)167 threadnetwork::TelemetryData_Nat64State Nat64StateFromOtNat64State(otNat64State nat64State)
168 {
169     switch (nat64State)
170     {
171     case OT_NAT64_STATE_DISABLED:
172         return threadnetwork::TelemetryData::NAT64_STATE_DISABLED;
173     case OT_NAT64_STATE_NOT_RUNNING:
174         return threadnetwork::TelemetryData::NAT64_STATE_NOT_RUNNING;
175     case OT_NAT64_STATE_IDLE:
176         return threadnetwork::TelemetryData::NAT64_STATE_IDLE;
177     case OT_NAT64_STATE_ACTIVE:
178         return threadnetwork::TelemetryData::NAT64_STATE_ACTIVE;
179     default:
180         return threadnetwork::TelemetryData::NAT64_STATE_UNSPECIFIED;
181     }
182 }
183 
CopyNat64TrafficCounters(const otNat64Counters & from,threadnetwork::TelemetryData_Nat64TrafficCounters * to)184 void CopyNat64TrafficCounters(const otNat64Counters &from, threadnetwork::TelemetryData_Nat64TrafficCounters *to)
185 {
186     to->set_ipv4_to_ipv6_packets(from.m4To6Packets);
187     to->set_ipv4_to_ipv6_bytes(from.m4To6Bytes);
188     to->set_ipv6_to_ipv4_packets(from.m6To4Packets);
189     to->set_ipv6_to_ipv4_bytes(from.m6To4Bytes);
190 }
191 #endif // OTBR_ENABLE_NAT64
192 
193 #if OTBR_ENABLE_DHCP6_PD
Dhcp6PdStateFromOtDhcp6PdState(otBorderRoutingDhcp6PdState dhcp6PdState)194 threadnetwork::TelemetryData_Dhcp6PdState Dhcp6PdStateFromOtDhcp6PdState(otBorderRoutingDhcp6PdState dhcp6PdState)
195 {
196     threadnetwork::TelemetryData_Dhcp6PdState pdState = threadnetwork::TelemetryData::DHCP6_PD_STATE_UNSPECIFIED;
197 
198     switch (dhcp6PdState)
199     {
200     case OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED:
201         pdState = threadnetwork::TelemetryData::DHCP6_PD_STATE_DISABLED;
202         break;
203     case OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED:
204         pdState = threadnetwork::TelemetryData::DHCP6_PD_STATE_STOPPED;
205         break;
206     case OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING:
207         pdState = threadnetwork::TelemetryData::DHCP6_PD_STATE_RUNNING;
208         break;
209     default:
210         break;
211     }
212 
213     return pdState;
214 }
215 #endif // OTBR_ENABLE_DHCP6_PD
216 
CopyMdnsResponseCounters(const MdnsResponseCounters & from,threadnetwork::TelemetryData_MdnsResponseCounters * to)217 void CopyMdnsResponseCounters(const MdnsResponseCounters &from, threadnetwork::TelemetryData_MdnsResponseCounters *to)
218 {
219     to->set_success_count(from.mSuccess);
220     to->set_not_found_count(from.mNotFound);
221     to->set_invalid_args_count(from.mInvalidArgs);
222     to->set_duplicated_count(from.mDuplicated);
223     to->set_not_implemented_count(from.mNotImplemented);
224     to->set_unknown_error_count(from.mUnknownError);
225     to->set_aborted_count(from.mAborted);
226     to->set_invalid_state_count(from.mInvalidState);
227 }
228 #endif // OTBR_ENABLE_TELEMETRY_DATA_API
229 } // namespace
230 
ThreadHelper(otInstance * aInstance,otbr::Ncp::RcpHost * aHost)231 ThreadHelper::ThreadHelper(otInstance *aInstance, otbr::Ncp::RcpHost *aHost)
232     : mInstance(aInstance)
233     , mHost(aHost)
234 {
235 #if OTBR_ENABLE_TELEMETRY_DATA_API && (OTBR_ENABLE_NAT64 || OTBR_ENABLE_DHCP6_PD)
236     otError error;
237 
238     SuccessOrExit(error = otPlatCryptoRandomGet(mNat64PdCommonSalt, sizeof(mNat64PdCommonSalt)));
239 
240 exit:
241     if (error != OT_ERROR_NONE)
242     {
243         otbrLogWarning("Error otPlatCryptoRandomGet: %s", otThreadErrorToString(error));
244     }
245 #endif
246 }
247 
StateChangedCallback(otChangedFlags aFlags)248 void ThreadHelper::StateChangedCallback(otChangedFlags aFlags)
249 {
250     if (aFlags & OT_CHANGED_THREAD_ROLE)
251     {
252         otDeviceRole role = mHost->GetDeviceRole();
253 
254         for (const auto &handler : mDeviceRoleHandlers)
255         {
256             handler(role);
257         }
258 
259         if (role != OT_DEVICE_ROLE_DISABLED && role != OT_DEVICE_ROLE_DETACHED)
260         {
261             if (mAttachHandler != nullptr)
262             {
263                 if (mWaitingMgmtSetResponse)
264                 {
265                     otbrLogInfo("StateChangedCallback is called during waiting for Mgmt Set Response");
266                     ExitNow();
267                 }
268                 if (mAttachPendingDatasetTlvs.mLength == 0)
269                 {
270                     AttachHandler handler = mAttachHandler;
271 
272                     mAttachHandler = nullptr;
273                     handler(OT_ERROR_NONE, mAttachDelayMs);
274                 }
275                 else
276                 {
277                     otOperationalDataset emptyDataset = {};
278                     otError              error =
279                         otDatasetSendMgmtPendingSet(mInstance, &emptyDataset, mAttachPendingDatasetTlvs.mTlvs,
280                                                     mAttachPendingDatasetTlvs.mLength, MgmtSetResponseHandler, this);
281                     if (error != OT_ERROR_NONE)
282                     {
283                         AttachHandler handler = mAttachHandler;
284 
285                         mAttachHandler            = nullptr;
286                         mAttachPendingDatasetTlvs = {};
287                         mWaitingMgmtSetResponse   = false;
288                         handler(error, 0);
289                     }
290                     else
291                     {
292                         mWaitingMgmtSetResponse = true;
293                     }
294                 }
295             }
296             else if (mJoinerHandler != nullptr)
297             {
298                 mJoinerHandler(OT_ERROR_NONE);
299                 mJoinerHandler = nullptr;
300             }
301         }
302     }
303 
304     if (aFlags & OT_CHANGED_ACTIVE_DATASET)
305     {
306         ActiveDatasetChangedCallback();
307     }
308 
309 exit:
310     return;
311 }
312 
ActiveDatasetChangedCallback()313 void ThreadHelper::ActiveDatasetChangedCallback()
314 {
315     otError                  error;
316     otOperationalDatasetTlvs datasetTlvs;
317 
318     SuccessOrExit(error = otDatasetGetActiveTlvs(mInstance, &datasetTlvs));
319 
320     for (const auto &handler : mActiveDatasetChangeHandlers)
321     {
322         handler(datasetTlvs);
323     }
324 
325 exit:
326     if (error != OT_ERROR_NONE)
327     {
328         otbrLogWarning("Error handling active dataset change: %s", otThreadErrorToString(error));
329     }
330 }
331 
332 #if OTBR_ENABLE_DBUS_SERVER
OnUpdateMeshCopTxt(std::map<std::string,std::vector<uint8_t>> aUpdate)333 void ThreadHelper::OnUpdateMeshCopTxt(std::map<std::string, std::vector<uint8_t>> aUpdate)
334 {
335     if (mUpdateMeshCopTxtHandler)
336     {
337         mUpdateMeshCopTxtHandler(std::move(aUpdate));
338     }
339     else
340     {
341         otbrLogErr("No UpdateMeshCopTxtHandler");
342     }
343 }
344 #endif
345 
AddDeviceRoleHandler(DeviceRoleHandler aHandler)346 void ThreadHelper::AddDeviceRoleHandler(DeviceRoleHandler aHandler)
347 {
348     mDeviceRoleHandlers.emplace_back(aHandler);
349 }
350 
Scan(ScanHandler aHandler)351 void ThreadHelper::Scan(ScanHandler aHandler)
352 {
353     otError error = OT_ERROR_NONE;
354 
355     VerifyOrExit(aHandler != nullptr);
356     mScanHandler = aHandler;
357     mScanResults.clear();
358 
359     error =
360         otLinkActiveScan(mInstance, /*scanChannels =*/0, /*scanDuration=*/0, &ThreadHelper::ActiveScanHandler, this);
361 
362 exit:
363     if (error != OT_ERROR_NONE)
364     {
365         if (aHandler)
366         {
367             mScanHandler(error, {});
368         }
369         mScanHandler = nullptr;
370     }
371 }
372 
EnergyScan(uint32_t aScanDuration,EnergyScanHandler aHandler)373 void ThreadHelper::EnergyScan(uint32_t aScanDuration, EnergyScanHandler aHandler)
374 {
375     otError  error             = OT_ERROR_NONE;
376     uint32_t preferredChannels = otPlatRadioGetPreferredChannelMask(mInstance);
377 
378     VerifyOrExit(aHandler != nullptr, error = OT_ERROR_BUSY);
379     VerifyOrExit(aScanDuration < UINT16_MAX, error = OT_ERROR_INVALID_ARGS);
380     mEnergyScanHandler = aHandler;
381     mEnergyScanResults.clear();
382 
383     error = otLinkEnergyScan(mInstance, preferredChannels, static_cast<uint16_t>(aScanDuration),
384                              &ThreadHelper::EnergyScanCallback, this);
385 
386 exit:
387     if (error != OT_ERROR_NONE)
388     {
389         if (aHandler)
390         {
391             mEnergyScanHandler(error, {});
392         }
393         mEnergyScanHandler = nullptr;
394     }
395 }
396 
RandomFill(void * aBuf,size_t size)397 void ThreadHelper::RandomFill(void *aBuf, size_t size)
398 {
399     std::uniform_int_distribution<> dist(0, UINT8_MAX);
400     uint8_t                        *buf = static_cast<uint8_t *>(aBuf);
401 
402     for (size_t i = 0; i < size; i++)
403     {
404         buf[i] = static_cast<uint8_t>(dist(mRandomDevice));
405     }
406 }
407 
ActiveScanHandler(otActiveScanResult * aResult,void * aThreadHelper)408 void ThreadHelper::ActiveScanHandler(otActiveScanResult *aResult, void *aThreadHelper)
409 {
410     ThreadHelper *helper = static_cast<ThreadHelper *>(aThreadHelper);
411 
412     helper->ActiveScanHandler(aResult);
413 }
414 
ActiveScanHandler(otActiveScanResult * aResult)415 void ThreadHelper::ActiveScanHandler(otActiveScanResult *aResult)
416 {
417     if (aResult == nullptr)
418     {
419         if (mScanHandler != nullptr)
420         {
421             mScanHandler(OT_ERROR_NONE, mScanResults);
422         }
423     }
424     else
425     {
426         mScanResults.push_back(*aResult);
427     }
428 }
429 
430 #if OTBR_ENABLE_DHCP6_PD
SetDhcp6PdStateCallback(Dhcp6PdStateCallback aCallback)431 void ThreadHelper::SetDhcp6PdStateCallback(Dhcp6PdStateCallback aCallback)
432 {
433     mDhcp6PdCallback = std::move(aCallback);
434     otBorderRoutingDhcp6PdSetRequestCallback(mInstance, &ThreadHelper::BorderRoutingDhcp6PdCallback, this);
435 }
436 
BorderRoutingDhcp6PdCallback(otBorderRoutingDhcp6PdState aState,void * aThreadHelper)437 void ThreadHelper::BorderRoutingDhcp6PdCallback(otBorderRoutingDhcp6PdState aState, void *aThreadHelper)
438 {
439     ThreadHelper *helper = static_cast<ThreadHelper *>(aThreadHelper);
440 
441     helper->BorderRoutingDhcp6PdCallback(aState);
442 }
443 
BorderRoutingDhcp6PdCallback(otBorderRoutingDhcp6PdState aState)444 void ThreadHelper::BorderRoutingDhcp6PdCallback(otBorderRoutingDhcp6PdState aState)
445 {
446     if (mDhcp6PdCallback != nullptr)
447     {
448         mDhcp6PdCallback(aState);
449     }
450 }
451 #endif // OTBR_ENABLE_DHCP6_PD
452 
EnergyScanCallback(otEnergyScanResult * aResult,void * aThreadHelper)453 void ThreadHelper::EnergyScanCallback(otEnergyScanResult *aResult, void *aThreadHelper)
454 {
455     ThreadHelper *helper = static_cast<ThreadHelper *>(aThreadHelper);
456 
457     helper->EnergyScanCallback(aResult);
458 }
459 
EnergyScanCallback(otEnergyScanResult * aResult)460 void ThreadHelper::EnergyScanCallback(otEnergyScanResult *aResult)
461 {
462     if (aResult == nullptr)
463     {
464         if (mEnergyScanHandler != nullptr)
465         {
466             mEnergyScanHandler(OT_ERROR_NONE, mEnergyScanResults);
467         }
468     }
469     else
470     {
471         mEnergyScanResults.push_back(*aResult);
472     }
473 }
474 
RandomChannelFromChannelMask(uint32_t aChannelMask)475 uint8_t ThreadHelper::RandomChannelFromChannelMask(uint32_t aChannelMask)
476 {
477     // 8 bit per byte
478     constexpr uint8_t kNumChannels = sizeof(aChannelMask) * 8;
479     uint8_t           channels[kNumChannels];
480     uint8_t           numValidChannels = 0;
481 
482     for (uint8_t i = 0; i < kNumChannels; i++)
483     {
484         if (aChannelMask & (1 << i))
485         {
486             channels[numValidChannels++] = i;
487         }
488     }
489 
490     return channels[std::uniform_int_distribution<unsigned int>(0, numValidChannels - 1)(mRandomDevice)];
491 }
492 
ToOtExtendedPanId(uint64_t aExtPanId)493 static otExtendedPanId ToOtExtendedPanId(uint64_t aExtPanId)
494 {
495     otExtendedPanId extPanId;
496     uint64_t        mask = UINT8_MAX;
497 
498     for (size_t i = 0; i < sizeof(uint64_t); i++)
499     {
500         extPanId.m8[i] = static_cast<uint8_t>((aExtPanId >> ((sizeof(uint64_t) - i - 1) * 8)) & mask);
501     }
502 
503     return extPanId;
504 }
505 
Attach(const std::string & aNetworkName,uint16_t aPanId,uint64_t aExtPanId,const std::vector<uint8_t> & aNetworkKey,const std::vector<uint8_t> & aPSKc,uint32_t aChannelMask,AttachHandler aHandler)506 void ThreadHelper::Attach(const std::string          &aNetworkName,
507                           uint16_t                    aPanId,
508                           uint64_t                    aExtPanId,
509                           const std::vector<uint8_t> &aNetworkKey,
510                           const std::vector<uint8_t> &aPSKc,
511                           uint32_t                    aChannelMask,
512                           AttachHandler               aHandler)
513 
514 {
515     otError              error   = OT_ERROR_NONE;
516     otOperationalDataset dataset = {};
517 
518     VerifyOrExit(aHandler != nullptr, error = OT_ERROR_INVALID_ARGS);
519     VerifyOrExit(mAttachHandler == nullptr && mJoinerHandler == nullptr, error = OT_ERROR_INVALID_STATE);
520     VerifyOrExit(aNetworkKey.empty() || aNetworkKey.size() == sizeof(dataset.mNetworkKey.m8),
521                  error = OT_ERROR_INVALID_ARGS);
522     VerifyOrExit(aPSKc.empty() || aPSKc.size() == sizeof(dataset.mPskc.m8), error = OT_ERROR_INVALID_ARGS);
523     VerifyOrExit(aChannelMask != 0, error = OT_ERROR_INVALID_ARGS);
524 
525     SuccessOrExit(error = otDatasetCreateNewNetwork(mInstance, &dataset));
526 
527     if (aExtPanId != UINT64_MAX)
528     {
529         dataset.mExtendedPanId = ToOtExtendedPanId(aExtPanId);
530     }
531 
532     if (!aNetworkKey.empty())
533     {
534         memcpy(dataset.mNetworkKey.m8, &aNetworkKey[0], sizeof(dataset.mNetworkKey.m8));
535     }
536 
537     if (aPanId != UINT16_MAX)
538     {
539         dataset.mPanId = aPanId;
540     }
541 
542     if (!aPSKc.empty())
543     {
544         memcpy(dataset.mPskc.m8, &aPSKc[0], sizeof(dataset.mPskc.m8));
545     }
546 
547     SuccessOrExit(error = otNetworkNameFromString(&dataset.mNetworkName, aNetworkName.c_str()));
548 
549     dataset.mChannelMask &= aChannelMask;
550     VerifyOrExit(dataset.mChannelMask != 0, otbrLogWarning("Invalid channel mask"), error = OT_ERROR_INVALID_ARGS);
551 
552     dataset.mChannel = RandomChannelFromChannelMask(dataset.mChannelMask);
553 
554     SuccessOrExit(error = otDatasetSetActive(mInstance, &dataset));
555 
556     if (!otIp6IsEnabled(mInstance))
557     {
558         SuccessOrExit(error = otIp6SetEnabled(mInstance, true));
559     }
560 
561     SuccessOrExit(error = otThreadSetEnabled(mInstance, true));
562     mAttachDelayMs = 0;
563     mAttachHandler = aHandler;
564 
565 exit:
566     if (error != OT_ERROR_NONE)
567     {
568         if (aHandler)
569         {
570             aHandler(error, 0);
571         }
572     }
573 }
574 
Attach(AttachHandler aHandler)575 void ThreadHelper::Attach(AttachHandler aHandler)
576 {
577     otError error = OT_ERROR_NONE;
578 
579     VerifyOrExit(mAttachHandler == nullptr && mJoinerHandler == nullptr, error = OT_ERROR_INVALID_STATE);
580 
581     if (!otIp6IsEnabled(mInstance))
582     {
583         SuccessOrExit(error = otIp6SetEnabled(mInstance, true));
584     }
585     SuccessOrExit(error = otThreadSetEnabled(mInstance, true));
586     mAttachHandler = aHandler;
587 
588 exit:
589     if (error != OT_ERROR_NONE)
590     {
591         if (aHandler)
592         {
593             aHandler(error, 0);
594         }
595     }
596 }
597 
Detach(void)598 otError ThreadHelper::Detach(void)
599 {
600     otError error = OT_ERROR_NONE;
601 
602     SuccessOrExit(error = otThreadSetEnabled(mInstance, false));
603     SuccessOrExit(error = otIp6SetEnabled(mInstance, false));
604 
605 exit:
606     return error;
607 }
608 
Reset(void)609 otError ThreadHelper::Reset(void)
610 {
611     mDeviceRoleHandlers.clear();
612     otInstanceReset(mInstance);
613 
614     return OT_ERROR_NONE;
615 }
616 
JoinerStart(const std::string & aPskd,const std::string & aProvisioningUrl,const std::string & aVendorName,const std::string & aVendorModel,const std::string & aVendorSwVersion,const std::string & aVendorData,ResultHandler aHandler)617 void ThreadHelper::JoinerStart(const std::string &aPskd,
618                                const std::string &aProvisioningUrl,
619                                const std::string &aVendorName,
620                                const std::string &aVendorModel,
621                                const std::string &aVendorSwVersion,
622                                const std::string &aVendorData,
623                                ResultHandler      aHandler)
624 {
625     otError error = OT_ERROR_NONE;
626 
627     VerifyOrExit(aHandler != nullptr, error = OT_ERROR_INVALID_ARGS);
628     VerifyOrExit(mAttachHandler == nullptr && mJoinerHandler == nullptr, error = OT_ERROR_INVALID_STATE);
629 
630     if (!otIp6IsEnabled(mInstance))
631     {
632         SuccessOrExit(error = otIp6SetEnabled(mInstance, true));
633     }
634     SuccessOrExit(error = otJoinerStart(mInstance, aPskd.c_str(), aProvisioningUrl.c_str(), aVendorName.c_str(),
635                                         aVendorModel.c_str(), aVendorSwVersion.c_str(), aVendorData.c_str(),
636                                         JoinerCallback, this));
637     mJoinerHandler = aHandler;
638 
639 exit:
640     if (error != OT_ERROR_NONE)
641     {
642         if (aHandler)
643         {
644             aHandler(error);
645         }
646     }
647 }
648 
JoinerCallback(otError aError,void * aThreadHelper)649 void ThreadHelper::JoinerCallback(otError aError, void *aThreadHelper)
650 {
651     ThreadHelper *helper = static_cast<ThreadHelper *>(aThreadHelper);
652 
653     helper->JoinerCallback(aError);
654 }
655 
JoinerCallback(otError aError)656 void ThreadHelper::JoinerCallback(otError aError)
657 {
658     if (aError != OT_ERROR_NONE)
659     {
660         otbrLogWarning("Failed to join Thread network: %s", otThreadErrorToString(aError));
661         mJoinerHandler(aError);
662         mJoinerHandler = nullptr;
663     }
664     else
665     {
666         LogOpenThreadResult("Start Thread network", otThreadSetEnabled(mInstance, true));
667     }
668 }
669 
TryResumeNetwork(void)670 otError ThreadHelper::TryResumeNetwork(void)
671 {
672     otError error = OT_ERROR_NONE;
673 
674     if (otLinkGetPanId(mInstance) != UINT16_MAX && mHost->GetDeviceRole() == OT_DEVICE_ROLE_DISABLED)
675     {
676         if (!otIp6IsEnabled(mInstance))
677         {
678             SuccessOrExit(error = otIp6SetEnabled(mInstance, true));
679             SuccessOrExit(error = otThreadSetEnabled(mInstance, true));
680         }
681     }
682 
683 exit:
684     if (error != OT_ERROR_NONE)
685     {
686         (void)otIp6SetEnabled(mInstance, false);
687     }
688 
689     return error;
690 }
691 
LogOpenThreadResult(const char * aAction,otError aError)692 void ThreadHelper::LogOpenThreadResult(const char *aAction, otError aError)
693 {
694     if (aError == OT_ERROR_NONE)
695     {
696         otbrLogInfo("%s: %s", aAction, otThreadErrorToString(aError));
697     }
698     else
699     {
700         otbrLogWarning("%s: %s", aAction, otThreadErrorToString(aError));
701     }
702 }
703 
AttachAllNodesTo(const std::vector<uint8_t> & aDatasetTlvs,AttachHandler aHandler)704 void ThreadHelper::AttachAllNodesTo(const std::vector<uint8_t> &aDatasetTlvs, AttachHandler aHandler)
705 {
706     constexpr uint32_t kDelayTimerMilliseconds = 300 * 1000;
707 
708     otError                  error = OT_ERROR_NONE;
709     otOperationalDatasetTlvs datasetTlvs;
710     otOperationalDataset     dataset;
711     otOperationalDataset     emptyDataset{};
712     otDeviceRole             role = mHost->GetDeviceRole();
713 
714     if (aHandler == nullptr)
715     {
716         otbrLogWarning("Attach Handler is nullptr");
717         ExitNow(error = OT_ERROR_INVALID_ARGS);
718     }
719     VerifyOrExit(mAttachHandler == nullptr && mJoinerHandler == nullptr, error = OT_ERROR_BUSY);
720 
721     VerifyOrExit(aDatasetTlvs.size() <= sizeof(datasetTlvs.mTlvs), error = OT_ERROR_INVALID_ARGS);
722     std::copy(aDatasetTlvs.begin(), aDatasetTlvs.end(), datasetTlvs.mTlvs);
723     datasetTlvs.mLength = aDatasetTlvs.size();
724 
725     SuccessOrExit(error = otDatasetParseTlvs(&datasetTlvs, &dataset));
726     VerifyOrExit(dataset.mComponents.mIsActiveTimestampPresent, error = OT_ERROR_INVALID_ARGS);
727     VerifyOrExit(dataset.mComponents.mIsNetworkKeyPresent, error = OT_ERROR_INVALID_ARGS);
728     VerifyOrExit(dataset.mComponents.mIsNetworkNamePresent, error = OT_ERROR_INVALID_ARGS);
729     VerifyOrExit(dataset.mComponents.mIsExtendedPanIdPresent, error = OT_ERROR_INVALID_ARGS);
730     VerifyOrExit(dataset.mComponents.mIsMeshLocalPrefixPresent, error = OT_ERROR_INVALID_ARGS);
731     VerifyOrExit(dataset.mComponents.mIsPanIdPresent, error = OT_ERROR_INVALID_ARGS);
732     VerifyOrExit(dataset.mComponents.mIsChannelPresent, error = OT_ERROR_INVALID_ARGS);
733     VerifyOrExit(dataset.mComponents.mIsPskcPresent, error = OT_ERROR_INVALID_ARGS);
734     VerifyOrExit(dataset.mComponents.mIsSecurityPolicyPresent, error = OT_ERROR_INVALID_ARGS);
735     VerifyOrExit(dataset.mComponents.mIsChannelMaskPresent, error = OT_ERROR_INVALID_ARGS);
736 
737     SuccessOrExit(error = ProcessDatasetForMigration(datasetTlvs, kDelayTimerMilliseconds));
738 
739     assert(datasetTlvs.mLength > 0);
740 
741     if (role == OT_DEVICE_ROLE_DISABLED || role == OT_DEVICE_ROLE_DETACHED)
742     {
743         otOperationalDataset existingDataset;
744         bool                 hasActiveDataset;
745 
746         error = otDatasetGetActive(mInstance, &existingDataset);
747         VerifyOrExit(error == OT_ERROR_NONE || error == OT_ERROR_NOT_FOUND);
748 
749         hasActiveDataset = (error == OT_ERROR_NONE);
750 
751         if (!hasActiveDataset)
752         {
753             SuccessOrExit(error = otDatasetSetActiveTlvs(mInstance, &datasetTlvs));
754         }
755 
756         if (!otIp6IsEnabled(mInstance))
757         {
758             SuccessOrExit(error = otIp6SetEnabled(mInstance, true));
759         }
760         SuccessOrExit(error = otThreadSetEnabled(mInstance, true));
761 
762         if (hasActiveDataset)
763         {
764             mAttachDelayMs            = kDelayTimerMilliseconds;
765             mAttachPendingDatasetTlvs = datasetTlvs;
766         }
767         else
768         {
769             mAttachDelayMs            = 0;
770             mAttachPendingDatasetTlvs = {};
771         }
772         mWaitingMgmtSetResponse = false;
773         mAttachHandler          = aHandler;
774         ExitNow();
775     }
776 
777     SuccessOrExit(error = otDatasetSendMgmtPendingSet(mInstance, &emptyDataset, datasetTlvs.mTlvs, datasetTlvs.mLength,
778                                                       MgmtSetResponseHandler, this));
779     mAttachDelayMs          = kDelayTimerMilliseconds;
780     mAttachHandler          = aHandler;
781     mWaitingMgmtSetResponse = true;
782 
783 exit:
784     if (error != OT_ERROR_NONE)
785     {
786         aHandler(error, 0);
787     }
788 }
789 
MgmtSetResponseHandler(otError aResult,void * aContext)790 void ThreadHelper::MgmtSetResponseHandler(otError aResult, void *aContext)
791 {
792     static_cast<ThreadHelper *>(aContext)->MgmtSetResponseHandler(aResult);
793 }
794 
MgmtSetResponseHandler(otError aResult)795 void ThreadHelper::MgmtSetResponseHandler(otError aResult)
796 {
797     AttachHandler handler;
798     int64_t       attachDelayMs;
799 
800     LogOpenThreadResult("MgmtSetResponseHandler()", aResult);
801     mWaitingMgmtSetResponse = false;
802 
803     if (mAttachHandler == nullptr)
804     {
805         otbrLogWarning("mAttachHandler is nullptr");
806         mAttachDelayMs            = 0;
807         mAttachPendingDatasetTlvs = {};
808         ExitNow();
809     }
810 
811     switch (aResult)
812     {
813     case OT_ERROR_NONE:
814     case OT_ERROR_REJECTED:
815         break;
816     default:
817         aResult = OT_ERROR_FAILED;
818         break;
819     }
820 
821     attachDelayMs             = mAttachDelayMs;
822     handler                   = mAttachHandler;
823     mAttachDelayMs            = 0;
824     mAttachHandler            = nullptr;
825     mAttachPendingDatasetTlvs = {};
826     if (aResult == OT_ERROR_NONE)
827     {
828         handler(aResult, attachDelayMs);
829     }
830     else
831     {
832         handler(aResult, 0);
833     }
834 
835 exit:
836     return;
837 }
838 
839 #if OTBR_ENABLE_UNSECURE_JOIN
PermitUnsecureJoin(uint16_t aPort,uint32_t aSeconds)840 otError ThreadHelper::PermitUnsecureJoin(uint16_t aPort, uint32_t aSeconds)
841 {
842     otError      error = OT_ERROR_NONE;
843     otExtAddress steeringData;
844 
845     // 0xff to allow all devices to join
846     memset(&steeringData.m8, 0xff, sizeof(steeringData.m8));
847     SuccessOrExit(error = otIp6AddUnsecurePort(mInstance, aPort));
848     otThreadSetSteeringData(mInstance, &steeringData);
849 
850     if (aSeconds > 0)
851     {
852         auto delay = Milliseconds(aSeconds * 1000);
853 
854         ++mUnsecurePortRefCounter[aPort];
855 
856         mHost->PostTimerTask(delay, [this, aPort]() {
857             assert(mUnsecurePortRefCounter.find(aPort) != mUnsecurePortRefCounter.end());
858             assert(mUnsecurePortRefCounter[aPort] > 0);
859 
860             if (--mUnsecurePortRefCounter[aPort] == 0)
861             {
862                 otExtAddress noneAddress;
863 
864                 // 0 to clean steering data
865                 memset(&noneAddress.m8, 0, sizeof(noneAddress.m8));
866                 (void)otIp6RemoveUnsecurePort(mInstance, aPort);
867                 otThreadSetSteeringData(mInstance, &noneAddress);
868                 mUnsecurePortRefCounter.erase(aPort);
869             }
870         });
871     }
872     else
873     {
874         otExtAddress noneAddress;
875 
876         memset(&noneAddress.m8, 0, sizeof(noneAddress.m8));
877         (void)otIp6RemoveUnsecurePort(mInstance, aPort);
878         otThreadSetSteeringData(mInstance, &noneAddress);
879     }
880 
881 exit:
882     return error;
883 }
884 #endif
885 
AddActiveDatasetChangeHandler(DatasetChangeHandler aHandler)886 void ThreadHelper::AddActiveDatasetChangeHandler(DatasetChangeHandler aHandler)
887 {
888     mActiveDatasetChangeHandlers.push_back(std::move(aHandler));
889 }
890 
DetachGracefully(ResultHandler aHandler)891 void ThreadHelper::DetachGracefully(ResultHandler aHandler)
892 {
893     otError error = OT_ERROR_NONE;
894 
895     VerifyOrExit(mDetachGracefullyHandler == nullptr, error = OT_ERROR_BUSY);
896 
897     SuccessOrExit(error = otThreadDetachGracefully(mInstance, &ThreadHelper::DetachGracefullyCallback, this));
898     mDetachGracefullyHandler = aHandler;
899 
900 exit:
901     if (error != OT_ERROR_NONE)
902     {
903         aHandler(error);
904     }
905 }
906 
DetachGracefullyCallback(void * aContext)907 void ThreadHelper::DetachGracefullyCallback(void *aContext)
908 {
909     static_cast<ThreadHelper *>(aContext)->DetachGracefullyCallback();
910 }
911 
DetachGracefullyCallback(void)912 void ThreadHelper::DetachGracefullyCallback(void)
913 {
914     if (mDetachGracefullyHandler != nullptr)
915     {
916         mDetachGracefullyHandler(OT_ERROR_NONE);
917     }
918 }
919 
920 #if OTBR_ENABLE_TELEMETRY_DATA_API
921 #if OTBR_ENABLE_BORDER_ROUTING
RetrieveInfraLinkInfo(threadnetwork::TelemetryData::InfraLinkInfo & aInfraLinkInfo)922 void ThreadHelper::RetrieveInfraLinkInfo(threadnetwork::TelemetryData::InfraLinkInfo &aInfraLinkInfo)
923 {
924     {
925         otSysInfraNetIfAddressCounters addressCounters;
926         uint32_t                       ifrFlags = otSysGetInfraNetifFlags();
927 
928         otSysCountInfraNetifAddresses(&addressCounters);
929 
930         aInfraLinkInfo.set_name(otSysGetInfraNetifName());
931         aInfraLinkInfo.set_is_up((ifrFlags & IFF_UP) != 0);
932         aInfraLinkInfo.set_is_running((ifrFlags & IFF_RUNNING) != 0);
933         aInfraLinkInfo.set_is_multicast((ifrFlags & IFF_MULTICAST) != 0);
934         aInfraLinkInfo.set_link_local_address_count(addressCounters.mLinkLocalAddresses);
935         aInfraLinkInfo.set_unique_local_address_count(addressCounters.mUniqueLocalAddresses);
936         aInfraLinkInfo.set_global_unicast_address_count(addressCounters.mGlobalUnicastAddresses);
937     }
938 
939     //---- peer_br_count
940     {
941         uint32_t                           count = 0;
942         otBorderRoutingPrefixTableIterator iterator;
943         otBorderRoutingRouterEntry         entry;
944 
945         otBorderRoutingPrefixTableInitIterator(mInstance, &iterator);
946 
947         while (otBorderRoutingGetNextRouterEntry(mInstance, &iterator, &entry) == OT_ERROR_NONE)
948         {
949             if (entry.mIsPeerBr)
950             {
951                 count++;
952             }
953         }
954 
955         aInfraLinkInfo.set_peer_br_count(count);
956     }
957 }
958 
RetrieveExternalRouteInfo(threadnetwork::TelemetryData::ExternalRoutes & aExternalRouteInfo)959 void ThreadHelper::RetrieveExternalRouteInfo(threadnetwork::TelemetryData::ExternalRoutes &aExternalRouteInfo)
960 {
961     bool      isDefaultRouteAdded = false;
962     bool      isUlaRouteAdded     = false;
963     bool      isOthersRouteAdded  = false;
964     Ip6Prefix prefix;
965     uint16_t  rloc16 = otThreadGetRloc16(mInstance);
966 
967     otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
968     otExternalRouteConfig config;
969 
970     while (otNetDataGetNextRoute(mInstance, &iterator, &config) == OT_ERROR_NONE)
971     {
972         if (!config.mStable || config.mRloc16 != rloc16)
973         {
974             continue;
975         }
976 
977         prefix.Set(config.mPrefix);
978         if (prefix.IsDefaultRoutePrefix())
979         {
980             isDefaultRouteAdded = true;
981         }
982         else if (prefix.IsUlaPrefix())
983         {
984             isUlaRouteAdded = true;
985         }
986         else
987         {
988             isOthersRouteAdded = true;
989         }
990     }
991 
992     aExternalRouteInfo.set_has_default_route_added(isDefaultRouteAdded);
993     aExternalRouteInfo.set_has_ula_route_added(isUlaRouteAdded);
994     aExternalRouteInfo.set_has_others_route_added(isOthersRouteAdded);
995 }
996 #endif // OTBR_ENABLE_BORDER_ROUTING
997 
998 #if OTBR_ENABLE_DHCP6_PD
RetrievePdInfo(threadnetwork::TelemetryData::WpanBorderRouter * aWpanBorderRouter)999 void ThreadHelper::RetrievePdInfo(threadnetwork::TelemetryData::WpanBorderRouter *aWpanBorderRouter)
1000 {
1001     aWpanBorderRouter->set_dhcp6_pd_state(Dhcp6PdStateFromOtDhcp6PdState(otBorderRoutingDhcp6PdGetState(mInstance)));
1002     RetrieveHashedPdPrefix(aWpanBorderRouter->mutable_hashed_pd_prefix());
1003     RetrievePdProcessedRaInfo(aWpanBorderRouter->mutable_pd_processed_ra_info());
1004 }
1005 
RetrieveHashedPdPrefix(std::string * aHashedPdPrefix)1006 void ThreadHelper::RetrieveHashedPdPrefix(std::string *aHashedPdPrefix)
1007 {
1008     otBorderRoutingPrefixTableEntry aPrefixInfo;
1009     const uint8_t                  *prefixAddr          = nullptr;
1010     const uint8_t                  *truncatedHash       = nullptr;
1011     constexpr size_t                kHashPrefixLength   = 6;
1012     constexpr size_t                kHashedPrefixLength = 2;
1013     std::vector<uint8_t>            hashedPdHeader      = {0x20, 0x01, 0x0d, 0xb8};
1014     std::vector<uint8_t>            hashedPdTailer      = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1015     std::vector<uint8_t>            hashedPdPrefix;
1016     hashedPdPrefix.reserve(16);
1017     Sha256       sha256;
1018     Sha256::Hash hash;
1019 
1020     SuccessOrExit(otBorderRoutingGetPdOmrPrefix(mInstance, &aPrefixInfo));
1021     prefixAddr = aPrefixInfo.mPrefix.mPrefix.mFields.m8;
1022 
1023     // TODO: Put below steps into a reusable function.
1024     sha256.Start();
1025     sha256.Update(prefixAddr, kHashPrefixLength);
1026     sha256.Update(mNat64PdCommonSalt, kNat64PdCommonHashSaltLength);
1027     sha256.Finish(hash);
1028 
1029     // Append hashedPdHeader
1030     hashedPdPrefix.insert(hashedPdPrefix.end(), hashedPdHeader.begin(), hashedPdHeader.end());
1031 
1032     // Append the first 2 bytes of the hashed prefix
1033     truncatedHash = hash.GetBytes();
1034     hashedPdPrefix.insert(hashedPdPrefix.end(), truncatedHash, truncatedHash + kHashedPrefixLength);
1035 
1036     // Append ip[6] and ip[7]
1037     hashedPdPrefix.push_back(prefixAddr[6]);
1038     hashedPdPrefix.push_back(prefixAddr[7]);
1039 
1040     // Append hashedPdTailer
1041     hashedPdPrefix.insert(hashedPdPrefix.end(), hashedPdTailer.begin(), hashedPdTailer.end());
1042 
1043     aHashedPdPrefix->append(reinterpret_cast<const char *>(hashedPdPrefix.data()), hashedPdPrefix.size());
1044 
1045 exit:
1046     return;
1047 }
1048 
RetrievePdProcessedRaInfo(threadnetwork::TelemetryData::PdProcessedRaInfo * aPdProcessedRaInfo)1049 void ThreadHelper::RetrievePdProcessedRaInfo(threadnetwork::TelemetryData::PdProcessedRaInfo *aPdProcessedRaInfo)
1050 {
1051     otPdProcessedRaInfo raInfo;
1052 
1053     SuccessOrExit(otBorderRoutingGetPdProcessedRaInfo(mInstance, &raInfo));
1054     aPdProcessedRaInfo->set_num_platform_ra_received(raInfo.mNumPlatformRaReceived);
1055     aPdProcessedRaInfo->set_num_platform_pio_processed(raInfo.mNumPlatformPioProcessed);
1056     aPdProcessedRaInfo->set_last_platform_ra_msec(raInfo.mLastPlatformRaMsec);
1057 
1058 exit:
1059     return;
1060 }
1061 #endif // OTBR_ENABLE_DHCP6_PD
1062 
1063 #if OTBR_ENABLE_BORDER_AGENT
RetrieveBorderAgentInfo(threadnetwork::TelemetryData::BorderAgentInfo * aBorderAgentInfo)1064 void ThreadHelper::RetrieveBorderAgentInfo(threadnetwork::TelemetryData::BorderAgentInfo *aBorderAgentInfo)
1065 {
1066     auto baCounters            = aBorderAgentInfo->mutable_border_agent_counters();
1067     auto otBorderAgentCounters = *otBorderAgentGetCounters(mInstance);
1068 
1069     baCounters->set_epskc_activations(otBorderAgentCounters.mEpskcActivations);
1070     baCounters->set_epskc_deactivation_clears(otBorderAgentCounters.mEpskcDeactivationClears);
1071     baCounters->set_epskc_deactivation_timeouts(otBorderAgentCounters.mEpskcDeactivationTimeouts);
1072     baCounters->set_epskc_deactivation_max_attempts(otBorderAgentCounters.mEpskcDeactivationMaxAttempts);
1073     baCounters->set_epskc_deactivation_disconnects(otBorderAgentCounters.mEpskcDeactivationDisconnects);
1074     baCounters->set_epskc_invalid_ba_state_errors(otBorderAgentCounters.mEpskcInvalidBaStateErrors);
1075     baCounters->set_epskc_invalid_args_errors(otBorderAgentCounters.mEpskcInvalidArgsErrors);
1076     baCounters->set_epskc_start_secure_session_errors(otBorderAgentCounters.mEpskcStartSecureSessionErrors);
1077     baCounters->set_epskc_secure_session_successes(otBorderAgentCounters.mEpskcSecureSessionSuccesses);
1078     baCounters->set_epskc_secure_session_failures(otBorderAgentCounters.mEpskcSecureSessionFailures);
1079     baCounters->set_epskc_commissioner_petitions(otBorderAgentCounters.mEpskcCommissionerPetitions);
1080 
1081     baCounters->set_pskc_secure_session_successes(otBorderAgentCounters.mPskcSecureSessionSuccesses);
1082     baCounters->set_pskc_secure_session_failures(otBorderAgentCounters.mPskcSecureSessionFailures);
1083     baCounters->set_pskc_commissioner_petitions(otBorderAgentCounters.mPskcCommissionerPetitions);
1084 
1085     baCounters->set_mgmt_active_get_reqs(otBorderAgentCounters.mMgmtActiveGets);
1086     baCounters->set_mgmt_pending_get_reqs(otBorderAgentCounters.mMgmtPendingGets);
1087 }
1088 #endif
1089 
RetrieveTelemetryData(Mdns::Publisher * aPublisher,threadnetwork::TelemetryData & telemetryData)1090 otError ThreadHelper::RetrieveTelemetryData(Mdns::Publisher *aPublisher, threadnetwork::TelemetryData &telemetryData)
1091 {
1092     otError                     error = OT_ERROR_NONE;
1093     std::vector<otNeighborInfo> neighborTable;
1094 
1095     // Begin of WpanStats section.
1096     auto wpanStats = telemetryData.mutable_wpan_stats();
1097 
1098     {
1099         otDeviceRole     role  = mHost->GetDeviceRole();
1100         otLinkModeConfig otCfg = otThreadGetLinkMode(mInstance);
1101 
1102         wpanStats->set_node_type(TelemetryNodeTypeFromRoleAndLinkMode(role, otCfg));
1103     }
1104 
1105     wpanStats->set_channel(otLinkGetChannel(mInstance));
1106 
1107     {
1108         uint16_t ccaFailureRate = otLinkGetCcaFailureRate(mInstance);
1109 
1110         wpanStats->set_mac_cca_fail_rate(static_cast<float>(ccaFailureRate) / 0xffff);
1111     }
1112 
1113     {
1114         int8_t radioTxPower;
1115 
1116         if (otPlatRadioGetTransmitPower(mInstance, &radioTxPower) == OT_ERROR_NONE)
1117         {
1118             wpanStats->set_radio_tx_power(radioTxPower);
1119         }
1120         else
1121         {
1122             error = OT_ERROR_FAILED;
1123         }
1124     }
1125 
1126     {
1127         const otMacCounters *linkCounters = otLinkGetCounters(mInstance);
1128 
1129         wpanStats->set_phy_rx(linkCounters->mRxTotal);
1130         wpanStats->set_phy_tx(linkCounters->mTxTotal);
1131         wpanStats->set_mac_unicast_rx(linkCounters->mRxUnicast);
1132         wpanStats->set_mac_unicast_tx(linkCounters->mTxUnicast);
1133         wpanStats->set_mac_broadcast_rx(linkCounters->mRxBroadcast);
1134         wpanStats->set_mac_broadcast_tx(linkCounters->mTxBroadcast);
1135         wpanStats->set_mac_tx_ack_req(linkCounters->mTxAckRequested);
1136         wpanStats->set_mac_tx_no_ack_req(linkCounters->mTxNoAckRequested);
1137         wpanStats->set_mac_tx_acked(linkCounters->mTxAcked);
1138         wpanStats->set_mac_tx_data(linkCounters->mTxData);
1139         wpanStats->set_mac_tx_data_poll(linkCounters->mTxDataPoll);
1140         wpanStats->set_mac_tx_beacon(linkCounters->mTxBeacon);
1141         wpanStats->set_mac_tx_beacon_req(linkCounters->mTxBeaconRequest);
1142         wpanStats->set_mac_tx_other_pkt(linkCounters->mTxOther);
1143         wpanStats->set_mac_tx_retry(linkCounters->mTxRetry);
1144         wpanStats->set_mac_rx_data(linkCounters->mRxData);
1145         wpanStats->set_mac_rx_data_poll(linkCounters->mRxDataPoll);
1146         wpanStats->set_mac_rx_beacon(linkCounters->mRxBeacon);
1147         wpanStats->set_mac_rx_beacon_req(linkCounters->mRxBeaconRequest);
1148         wpanStats->set_mac_rx_other_pkt(linkCounters->mRxOther);
1149         wpanStats->set_mac_rx_filter_whitelist(linkCounters->mRxAddressFiltered);
1150         wpanStats->set_mac_rx_filter_dest_addr(linkCounters->mRxDestAddrFiltered);
1151         wpanStats->set_mac_tx_fail_cca(linkCounters->mTxErrCca);
1152         wpanStats->set_mac_rx_fail_decrypt(linkCounters->mRxErrSec);
1153         wpanStats->set_mac_rx_fail_no_frame(linkCounters->mRxErrNoFrame);
1154         wpanStats->set_mac_rx_fail_unknown_neighbor(linkCounters->mRxErrUnknownNeighbor);
1155         wpanStats->set_mac_rx_fail_invalid_src_addr(linkCounters->mRxErrInvalidSrcAddr);
1156         wpanStats->set_mac_rx_fail_fcs(linkCounters->mRxErrFcs);
1157         wpanStats->set_mac_rx_fail_other(linkCounters->mRxErrOther);
1158     }
1159 
1160     {
1161         const otIpCounters *ipCounters = otThreadGetIp6Counters(mInstance);
1162 
1163         wpanStats->set_ip_tx_success(ipCounters->mTxSuccess);
1164         wpanStats->set_ip_rx_success(ipCounters->mRxSuccess);
1165         wpanStats->set_ip_tx_failure(ipCounters->mTxFailure);
1166         wpanStats->set_ip_rx_failure(ipCounters->mRxFailure);
1167     }
1168     // End of WpanStats section.
1169 
1170     {
1171         // Begin of WpanTopoFull section.
1172         auto     wpanTopoFull = telemetryData.mutable_wpan_topo_full();
1173         uint16_t rloc16       = otThreadGetRloc16(mInstance);
1174 
1175         wpanTopoFull->set_rloc16(rloc16);
1176 
1177         {
1178             otRouterInfo info;
1179 
1180             if (otThreadGetRouterInfo(mInstance, rloc16, &info) == OT_ERROR_NONE)
1181             {
1182                 wpanTopoFull->set_router_id(info.mRouterId);
1183             }
1184             else
1185             {
1186                 error = OT_ERROR_FAILED;
1187             }
1188         }
1189 
1190         otNeighborInfoIterator iter = OT_NEIGHBOR_INFO_ITERATOR_INIT;
1191         otNeighborInfo         neighborInfo;
1192 
1193         while (otThreadGetNextNeighborInfo(mInstance, &iter, &neighborInfo) == OT_ERROR_NONE)
1194         {
1195             neighborTable.push_back(neighborInfo);
1196         }
1197         wpanTopoFull->set_neighbor_table_size(neighborTable.size());
1198 
1199         uint16_t                 childIndex = 0;
1200         otChildInfo              childInfo;
1201         std::vector<otChildInfo> childTable;
1202 
1203         while (otThreadGetChildInfoByIndex(mInstance, childIndex, &childInfo) == OT_ERROR_NONE)
1204         {
1205             childTable.push_back(childInfo);
1206             childIndex++;
1207         }
1208         wpanTopoFull->set_child_table_size(childTable.size());
1209 
1210         {
1211             struct otLeaderData leaderData;
1212 
1213             if (otThreadGetLeaderData(mInstance, &leaderData) == OT_ERROR_NONE)
1214             {
1215                 wpanTopoFull->set_leader_router_id(leaderData.mLeaderRouterId);
1216                 wpanTopoFull->set_leader_weight(leaderData.mWeighting);
1217                 wpanTopoFull->set_network_data_version(leaderData.mDataVersion);
1218                 wpanTopoFull->set_stable_network_data_version(leaderData.mStableDataVersion);
1219             }
1220             else
1221             {
1222                 error = OT_ERROR_FAILED;
1223             }
1224         }
1225 
1226         uint8_t weight = otThreadGetLocalLeaderWeight(mInstance);
1227 
1228         wpanTopoFull->set_leader_local_weight(weight);
1229 
1230         uint32_t partitionId = otThreadGetPartitionId(mInstance);
1231 
1232         wpanTopoFull->set_partition_id(partitionId);
1233 
1234         static constexpr size_t kNetworkDataMaxSize = 255;
1235         {
1236             uint8_t              data[kNetworkDataMaxSize];
1237             uint8_t              len = sizeof(data);
1238             std::vector<uint8_t> networkData;
1239 
1240             if (otNetDataGet(mInstance, /*stable=*/false, data, &len) == OT_ERROR_NONE)
1241             {
1242                 networkData = std::vector<uint8_t>(&data[0], &data[len]);
1243                 wpanTopoFull->set_network_data(std::string(networkData.begin(), networkData.end()));
1244             }
1245             else
1246             {
1247                 error = OT_ERROR_FAILED;
1248             }
1249         }
1250 
1251         {
1252             uint8_t              data[kNetworkDataMaxSize];
1253             uint8_t              len = sizeof(data);
1254             std::vector<uint8_t> networkData;
1255 
1256             if (otNetDataGet(mInstance, /*stable=*/true, data, &len) == OT_ERROR_NONE)
1257             {
1258                 networkData = std::vector<uint8_t>(&data[0], &data[len]);
1259                 wpanTopoFull->set_stable_network_data(std::string(networkData.begin(), networkData.end()));
1260             }
1261             else
1262             {
1263                 error = OT_ERROR_FAILED;
1264             }
1265         }
1266 
1267         int8_t rssi = otPlatRadioGetRssi(mInstance);
1268 
1269         wpanTopoFull->set_instant_rssi(rssi);
1270 
1271         const otExtendedPanId *extPanId = otThreadGetExtendedPanId(mInstance);
1272         uint64_t               extPanIdVal;
1273 
1274         extPanIdVal = ConvertOpenThreadUint64(extPanId->m8);
1275         wpanTopoFull->set_extended_pan_id(extPanIdVal);
1276 #if OTBR_ENABLE_BORDER_ROUTING
1277         wpanTopoFull->set_peer_br_count(otBorderRoutingCountPeerBrs(mInstance, /*minAge=*/nullptr));
1278 #endif
1279         // End of WpanTopoFull section.
1280 
1281         // Begin of TopoEntry section.
1282         std::map<uint16_t, const otChildInfo *> childMap;
1283 
1284         for (const otChildInfo &childInfo : childTable)
1285         {
1286             auto pair = childMap.insert({childInfo.mRloc16, &childInfo});
1287             if (!pair.second)
1288             {
1289                 // This shouldn't happen, so log an error. It doesn't matter which
1290                 // duplicate is kept.
1291                 otbrLogErr("Children with duplicate RLOC16 found: 0x%04x", static_cast<int>(childInfo.mRloc16));
1292             }
1293         }
1294 
1295         for (const otNeighborInfo &neighborInfo : neighborTable)
1296         {
1297             auto topoEntry = telemetryData.add_topo_entries();
1298             topoEntry->set_rloc16(neighborInfo.mRloc16);
1299             topoEntry->mutable_age()->set_seconds(neighborInfo.mAge);
1300             topoEntry->set_link_quality_in(neighborInfo.mLinkQualityIn);
1301             topoEntry->set_average_rssi(neighborInfo.mAverageRssi);
1302             topoEntry->set_last_rssi(neighborInfo.mLastRssi);
1303             topoEntry->set_link_frame_counter(neighborInfo.mLinkFrameCounter);
1304             topoEntry->set_mle_frame_counter(neighborInfo.mMleFrameCounter);
1305             topoEntry->set_rx_on_when_idle(neighborInfo.mRxOnWhenIdle);
1306             topoEntry->set_secure_data_request(true);
1307             topoEntry->set_full_function(neighborInfo.mFullThreadDevice);
1308             topoEntry->set_full_network_data(neighborInfo.mFullNetworkData);
1309             topoEntry->set_mac_frame_error_rate(static_cast<float>(neighborInfo.mFrameErrorRate) / 0xffff);
1310             topoEntry->set_ip_message_error_rate(static_cast<float>(neighborInfo.mMessageErrorRate) / 0xffff);
1311             topoEntry->set_version(neighborInfo.mVersion);
1312 
1313             if (!neighborInfo.mIsChild)
1314             {
1315                 continue;
1316             }
1317 
1318             auto it = childMap.find(neighborInfo.mRloc16);
1319             if (it == childMap.end())
1320             {
1321                 otbrLogErr("Neighbor 0x%04x not found in child table", static_cast<int>(neighborInfo.mRloc16));
1322                 continue;
1323             }
1324             const otChildInfo *childInfo = it->second;
1325             topoEntry->set_is_child(true);
1326             topoEntry->mutable_timeout()->set_seconds(childInfo->mTimeout);
1327             topoEntry->set_network_data_version(childInfo->mNetworkDataVersion);
1328         }
1329         // End of TopoEntry section.
1330     }
1331 
1332     {
1333         // Begin of WpanBorderRouter section.
1334         auto wpanBorderRouter = telemetryData.mutable_wpan_border_router();
1335         // Begin of BorderRoutingCounters section.
1336         auto                           borderRoutingCouters    = wpanBorderRouter->mutable_border_routing_counters();
1337         const otBorderRoutingCounters *otBorderRoutingCounters = otIp6GetBorderRoutingCounters(mInstance);
1338 
1339         borderRoutingCouters->mutable_inbound_unicast()->set_packet_count(
1340             otBorderRoutingCounters->mInboundUnicast.mPackets);
1341         borderRoutingCouters->mutable_inbound_unicast()->set_byte_count(
1342             otBorderRoutingCounters->mInboundUnicast.mBytes);
1343         borderRoutingCouters->mutable_inbound_multicast()->set_packet_count(
1344             otBorderRoutingCounters->mInboundMulticast.mPackets);
1345         borderRoutingCouters->mutable_inbound_multicast()->set_byte_count(
1346             otBorderRoutingCounters->mInboundMulticast.mBytes);
1347         borderRoutingCouters->mutable_outbound_unicast()->set_packet_count(
1348             otBorderRoutingCounters->mOutboundUnicast.mPackets);
1349         borderRoutingCouters->mutable_outbound_unicast()->set_byte_count(
1350             otBorderRoutingCounters->mOutboundUnicast.mBytes);
1351         borderRoutingCouters->mutable_outbound_multicast()->set_packet_count(
1352             otBorderRoutingCounters->mOutboundMulticast.mPackets);
1353         borderRoutingCouters->mutable_outbound_multicast()->set_byte_count(
1354             otBorderRoutingCounters->mOutboundMulticast.mBytes);
1355         borderRoutingCouters->set_ra_rx(otBorderRoutingCounters->mRaRx);
1356         borderRoutingCouters->set_ra_tx_success(otBorderRoutingCounters->mRaTxSuccess);
1357         borderRoutingCouters->set_ra_tx_failure(otBorderRoutingCounters->mRaTxFailure);
1358         borderRoutingCouters->set_rs_rx(otBorderRoutingCounters->mRsRx);
1359         borderRoutingCouters->set_rs_tx_success(otBorderRoutingCounters->mRsTxSuccess);
1360         borderRoutingCouters->set_rs_tx_failure(otBorderRoutingCounters->mRsTxFailure);
1361         borderRoutingCouters->mutable_inbound_internet()->set_packet_count(
1362             otBorderRoutingCounters->mInboundInternet.mPackets);
1363         borderRoutingCouters->mutable_inbound_internet()->set_byte_count(
1364             otBorderRoutingCounters->mInboundInternet.mBytes);
1365         borderRoutingCouters->mutable_outbound_internet()->set_packet_count(
1366             otBorderRoutingCounters->mOutboundInternet.mPackets);
1367         borderRoutingCouters->mutable_outbound_internet()->set_byte_count(
1368             otBorderRoutingCounters->mOutboundInternet.mBytes);
1369 
1370 #if OTBR_ENABLE_NAT64
1371         {
1372             auto nat64IcmpCounters = borderRoutingCouters->mutable_nat64_protocol_counters()->mutable_icmp();
1373             auto nat64UdpCounters  = borderRoutingCouters->mutable_nat64_protocol_counters()->mutable_udp();
1374             auto nat64TcpCounters  = borderRoutingCouters->mutable_nat64_protocol_counters()->mutable_tcp();
1375             otNat64ProtocolCounters otCounters;
1376 
1377             otNat64GetCounters(mInstance, &otCounters);
1378             nat64IcmpCounters->set_ipv4_to_ipv6_packets(otCounters.mIcmp.m4To6Packets);
1379             nat64IcmpCounters->set_ipv4_to_ipv6_bytes(otCounters.mIcmp.m4To6Bytes);
1380             nat64IcmpCounters->set_ipv6_to_ipv4_packets(otCounters.mIcmp.m6To4Packets);
1381             nat64IcmpCounters->set_ipv6_to_ipv4_bytes(otCounters.mIcmp.m6To4Bytes);
1382             nat64UdpCounters->set_ipv4_to_ipv6_packets(otCounters.mUdp.m4To6Packets);
1383             nat64UdpCounters->set_ipv4_to_ipv6_bytes(otCounters.mUdp.m4To6Bytes);
1384             nat64UdpCounters->set_ipv6_to_ipv4_packets(otCounters.mUdp.m6To4Packets);
1385             nat64UdpCounters->set_ipv6_to_ipv4_bytes(otCounters.mUdp.m6To4Bytes);
1386             nat64TcpCounters->set_ipv4_to_ipv6_packets(otCounters.mTcp.m4To6Packets);
1387             nat64TcpCounters->set_ipv4_to_ipv6_bytes(otCounters.mTcp.m4To6Bytes);
1388             nat64TcpCounters->set_ipv6_to_ipv4_packets(otCounters.mTcp.m6To4Packets);
1389             nat64TcpCounters->set_ipv6_to_ipv4_bytes(otCounters.mTcp.m6To4Bytes);
1390         }
1391 
1392         {
1393             auto                 errorCounters = borderRoutingCouters->mutable_nat64_error_counters();
1394             otNat64ErrorCounters otCounters;
1395             otNat64GetErrorCounters(mInstance, &otCounters);
1396 
1397             errorCounters->mutable_unknown()->set_ipv4_to_ipv6_packets(
1398                 otCounters.mCount4To6[OT_NAT64_DROP_REASON_UNKNOWN]);
1399             errorCounters->mutable_unknown()->set_ipv6_to_ipv4_packets(
1400                 otCounters.mCount6To4[OT_NAT64_DROP_REASON_UNKNOWN]);
1401             errorCounters->mutable_illegal_packet()->set_ipv4_to_ipv6_packets(
1402                 otCounters.mCount4To6[OT_NAT64_DROP_REASON_ILLEGAL_PACKET]);
1403             errorCounters->mutable_illegal_packet()->set_ipv6_to_ipv4_packets(
1404                 otCounters.mCount6To4[OT_NAT64_DROP_REASON_ILLEGAL_PACKET]);
1405             errorCounters->mutable_unsupported_protocol()->set_ipv4_to_ipv6_packets(
1406                 otCounters.mCount4To6[OT_NAT64_DROP_REASON_UNSUPPORTED_PROTO]);
1407             errorCounters->mutable_unsupported_protocol()->set_ipv6_to_ipv4_packets(
1408                 otCounters.mCount6To4[OT_NAT64_DROP_REASON_UNSUPPORTED_PROTO]);
1409             errorCounters->mutable_no_mapping()->set_ipv4_to_ipv6_packets(
1410                 otCounters.mCount4To6[OT_NAT64_DROP_REASON_NO_MAPPING]);
1411             errorCounters->mutable_no_mapping()->set_ipv6_to_ipv4_packets(
1412                 otCounters.mCount6To4[OT_NAT64_DROP_REASON_NO_MAPPING]);
1413         }
1414 #endif // OTBR_ENABLE_NAT64
1415        // End of BorderRoutingCounters section.
1416 
1417 #if OTBR_ENABLE_TREL
1418         // Begin of TrelInfo section.
1419         {
1420             auto trelInfo       = wpanBorderRouter->mutable_trel_info();
1421             auto otTrelCounters = otTrelGetCounters(mInstance);
1422             auto trelCounters   = trelInfo->mutable_counters();
1423 
1424             trelInfo->set_is_trel_enabled(otTrelIsEnabled(mInstance));
1425             trelInfo->set_num_trel_peers(otTrelGetNumberOfPeers(mInstance));
1426 
1427             trelCounters->set_trel_tx_packets(otTrelCounters->mTxPackets);
1428             trelCounters->set_trel_tx_bytes(otTrelCounters->mTxBytes);
1429             trelCounters->set_trel_tx_packets_failed(otTrelCounters->mTxFailure);
1430             trelCounters->set_tre_rx_packets(otTrelCounters->mRxPackets);
1431             trelCounters->set_trel_rx_bytes(otTrelCounters->mRxBytes);
1432         }
1433         // End of TrelInfo section.
1434 #endif // OTBR_ENABLE_TREL
1435 
1436 #if OTBR_ENABLE_BORDER_ROUTING
1437         RetrieveInfraLinkInfo(*wpanBorderRouter->mutable_infra_link_info());
1438         RetrieveExternalRouteInfo(*wpanBorderRouter->mutable_external_route_info());
1439 #endif
1440 
1441 #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
1442         // Begin of SrpServerInfo section.
1443         {
1444             auto                               srpServer = wpanBorderRouter->mutable_srp_server();
1445             otSrpServerLeaseInfo               leaseInfo;
1446             const otSrpServerHost             *host             = nullptr;
1447             const otSrpServerResponseCounters *responseCounters = otSrpServerGetResponseCounters(mInstance);
1448 
1449             srpServer->set_state(SrpServerStateFromOtSrpServerState(otSrpServerGetState(mInstance)));
1450             srpServer->set_port(otSrpServerGetPort(mInstance));
1451             srpServer->set_address_mode(
1452                 SrpServerAddressModeFromOtSrpServerAddressMode(otSrpServerGetAddressMode(mInstance)));
1453 
1454             auto srpServerHosts            = srpServer->mutable_hosts();
1455             auto srpServerServices         = srpServer->mutable_services();
1456             auto srpServerResponseCounters = srpServer->mutable_response_counters();
1457 
1458             while ((host = otSrpServerGetNextHost(mInstance, host)))
1459             {
1460                 const otSrpServerService *service = nullptr;
1461 
1462                 if (otSrpServerHostIsDeleted(host))
1463                 {
1464                     srpServerHosts->set_deleted_count(srpServerHosts->deleted_count() + 1);
1465                 }
1466                 else
1467                 {
1468                     srpServerHosts->set_fresh_count(srpServerHosts->fresh_count() + 1);
1469                     otSrpServerHostGetLeaseInfo(host, &leaseInfo);
1470                     srpServerHosts->set_lease_time_total_ms(srpServerHosts->lease_time_total_ms() + leaseInfo.mLease);
1471                     srpServerHosts->set_key_lease_time_total_ms(srpServerHosts->key_lease_time_total_ms() +
1472                                                                 leaseInfo.mKeyLease);
1473                     srpServerHosts->set_remaining_lease_time_total_ms(srpServerHosts->remaining_lease_time_total_ms() +
1474                                                                       leaseInfo.mRemainingLease);
1475                     srpServerHosts->set_remaining_key_lease_time_total_ms(
1476                         srpServerHosts->remaining_key_lease_time_total_ms() + leaseInfo.mRemainingKeyLease);
1477                 }
1478 
1479                 while ((service = otSrpServerHostGetNextService(host, service)))
1480                 {
1481                     if (otSrpServerServiceIsDeleted(service))
1482                     {
1483                         srpServerServices->set_deleted_count(srpServerServices->deleted_count() + 1);
1484                     }
1485                     else
1486                     {
1487                         srpServerServices->set_fresh_count(srpServerServices->fresh_count() + 1);
1488                         otSrpServerServiceGetLeaseInfo(service, &leaseInfo);
1489                         srpServerServices->set_lease_time_total_ms(srpServerServices->lease_time_total_ms() +
1490                                                                    leaseInfo.mLease);
1491                         srpServerServices->set_key_lease_time_total_ms(srpServerServices->key_lease_time_total_ms() +
1492                                                                        leaseInfo.mKeyLease);
1493                         srpServerServices->set_remaining_lease_time_total_ms(
1494                             srpServerServices->remaining_lease_time_total_ms() + leaseInfo.mRemainingLease);
1495                         srpServerServices->set_remaining_key_lease_time_total_ms(
1496                             srpServerServices->remaining_key_lease_time_total_ms() + leaseInfo.mRemainingKeyLease);
1497                     }
1498                 }
1499             }
1500 
1501             srpServerResponseCounters->set_success_count(responseCounters->mSuccess);
1502             srpServerResponseCounters->set_server_failure_count(responseCounters->mServerFailure);
1503             srpServerResponseCounters->set_format_error_count(responseCounters->mFormatError);
1504             srpServerResponseCounters->set_name_exists_count(responseCounters->mNameExists);
1505             srpServerResponseCounters->set_refused_count(responseCounters->mRefused);
1506             srpServerResponseCounters->set_other_count(responseCounters->mOther);
1507         }
1508         // End of SrpServerInfo section.
1509 #endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY
1510 
1511 #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
1512         // Begin of DnsServerInfo section.
1513         {
1514             auto            dnsServer                 = wpanBorderRouter->mutable_dns_server();
1515             auto            dnsServerResponseCounters = dnsServer->mutable_response_counters();
1516             otDnssdCounters otDnssdCounters           = *otDnssdGetCounters(mInstance);
1517 
1518             dnsServerResponseCounters->set_success_count(otDnssdCounters.mSuccessResponse);
1519             dnsServerResponseCounters->set_server_failure_count(otDnssdCounters.mServerFailureResponse);
1520             dnsServerResponseCounters->set_format_error_count(otDnssdCounters.mFormatErrorResponse);
1521             dnsServerResponseCounters->set_name_error_count(otDnssdCounters.mNameErrorResponse);
1522             dnsServerResponseCounters->set_not_implemented_count(otDnssdCounters.mNotImplementedResponse);
1523             dnsServerResponseCounters->set_other_count(otDnssdCounters.mOtherResponse);
1524             // The counters of queries, responses, failures handled by upstream DNS server.
1525             dnsServerResponseCounters->set_upstream_dns_queries(otDnssdCounters.mUpstreamDnsCounters.mQueries);
1526             dnsServerResponseCounters->set_upstream_dns_responses(otDnssdCounters.mUpstreamDnsCounters.mResponses);
1527             dnsServerResponseCounters->set_upstream_dns_failures(otDnssdCounters.mUpstreamDnsCounters.mFailures);
1528 
1529             dnsServer->set_resolved_by_local_srp_count(otDnssdCounters.mResolvedBySrp);
1530 
1531 #if OTBR_ENABLE_DNS_UPSTREAM_QUERY
1532             dnsServer->set_upstream_dns_query_state(
1533                 otDnssdUpstreamQueryIsEnabled(mInstance)
1534                     ? threadnetwork::TelemetryData::UPSTREAMDNS_QUERY_STATE_ENABLED
1535                     : threadnetwork::TelemetryData::UPSTREAMDNS_QUERY_STATE_DISABLED);
1536 #endif // OTBR_ENABLE_DNS_UPSTREAM_QUERY
1537         }
1538         // End of DnsServerInfo section.
1539 #endif // OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
1540 
1541         // Start of MdnsInfo section.
1542         if (aPublisher != nullptr)
1543         {
1544             auto                     mdns     = wpanBorderRouter->mutable_mdns();
1545             const MdnsTelemetryInfo &mdnsInfo = aPublisher->GetMdnsTelemetryInfo();
1546 
1547             CopyMdnsResponseCounters(mdnsInfo.mHostRegistrations, mdns->mutable_host_registration_responses());
1548             CopyMdnsResponseCounters(mdnsInfo.mServiceRegistrations, mdns->mutable_service_registration_responses());
1549             CopyMdnsResponseCounters(mdnsInfo.mHostResolutions, mdns->mutable_host_resolution_responses());
1550             CopyMdnsResponseCounters(mdnsInfo.mServiceResolutions, mdns->mutable_service_resolution_responses());
1551 
1552             mdns->set_host_registration_ema_latency_ms(mdnsInfo.mHostRegistrationEmaLatency);
1553             mdns->set_service_registration_ema_latency_ms(mdnsInfo.mServiceRegistrationEmaLatency);
1554             mdns->set_host_resolution_ema_latency_ms(mdnsInfo.mHostResolutionEmaLatency);
1555             mdns->set_service_resolution_ema_latency_ms(mdnsInfo.mServiceResolutionEmaLatency);
1556         }
1557         // End of MdnsInfo section.
1558 
1559 #if OTBR_ENABLE_NAT64
1560         // Start of BorderRoutingNat64State section.
1561         {
1562             auto nat64State = wpanBorderRouter->mutable_nat64_state();
1563 
1564             nat64State->set_prefix_manager_state(Nat64StateFromOtNat64State(otNat64GetPrefixManagerState(mInstance)));
1565             nat64State->set_translator_state(Nat64StateFromOtNat64State(otNat64GetTranslatorState(mInstance)));
1566         }
1567         // End of BorderRoutingNat64State section.
1568 
1569         // Start of Nat64Mapping section.
1570         {
1571             otNat64AddressMappingIterator iterator;
1572             otNat64AddressMapping         otMapping;
1573             Sha256::Hash                  hash;
1574             Sha256                        sha256;
1575 
1576             otNat64InitAddressMappingIterator(mInstance, &iterator);
1577             while (otNat64GetNextAddressMapping(mInstance, &iterator, &otMapping) == OT_ERROR_NONE)
1578             {
1579                 auto nat64Mapping         = wpanBorderRouter->add_nat64_mappings();
1580                 auto nat64MappingCounters = nat64Mapping->mutable_counters();
1581 
1582                 nat64Mapping->set_mapping_id(otMapping.mId);
1583                 CopyNat64TrafficCounters(otMapping.mCounters.mTcp, nat64MappingCounters->mutable_tcp());
1584                 CopyNat64TrafficCounters(otMapping.mCounters.mUdp, nat64MappingCounters->mutable_udp());
1585                 CopyNat64TrafficCounters(otMapping.mCounters.mIcmp, nat64MappingCounters->mutable_icmp());
1586 
1587                 sha256.Start();
1588                 sha256.Update(otMapping.mIp6.mFields.m8, sizeof(otMapping.mIp6.mFields.m8));
1589                 sha256.Update(mNat64PdCommonSalt, sizeof(mNat64PdCommonSalt));
1590                 sha256.Finish(hash);
1591 
1592                 nat64Mapping->mutable_hashed_ipv6_address()->append(reinterpret_cast<const char *>(hash.GetBytes()),
1593                                                                     Sha256::Hash::kSize);
1594                 // Remaining time is not included in the telemetry
1595             }
1596         }
1597         // End of Nat64Mapping section.
1598 #endif // OTBR_ENABLE_NAT64
1599 #if OTBR_ENABLE_DHCP6_PD
1600         RetrievePdInfo(wpanBorderRouter);
1601 #endif // OTBR_ENABLE_DHCP6_PD
1602 #if OTBR_ENABLE_BORDER_AGENT
1603         RetrieveBorderAgentInfo(wpanBorderRouter->mutable_border_agent_info());
1604 #endif // OTBR_ENABLE_BORDER_AGENT
1605        // End of WpanBorderRouter section.
1606 
1607         // Start of WpanRcp section.
1608         {
1609             auto                        wpanRcp                = telemetryData.mutable_wpan_rcp();
1610             const otRadioSpinelMetrics *otRadioSpinelMetrics   = otSysGetRadioSpinelMetrics();
1611             auto                        rcpStabilityStatistics = wpanRcp->mutable_rcp_stability_statistics();
1612 
1613             if (otRadioSpinelMetrics != nullptr)
1614             {
1615                 rcpStabilityStatistics->set_rcp_timeout_count(otRadioSpinelMetrics->mRcpTimeoutCount);
1616                 rcpStabilityStatistics->set_rcp_reset_count(otRadioSpinelMetrics->mRcpUnexpectedResetCount);
1617                 rcpStabilityStatistics->set_rcp_restoration_count(otRadioSpinelMetrics->mRcpRestorationCount);
1618                 rcpStabilityStatistics->set_spinel_parse_error_count(otRadioSpinelMetrics->mSpinelParseErrorCount);
1619             }
1620 
1621             // TODO: provide rcp_firmware_update_count info.
1622             rcpStabilityStatistics->set_thread_stack_uptime(otInstanceGetUptime(mInstance));
1623 
1624             const otRcpInterfaceMetrics *otRcpInterfaceMetrics = otSysGetRcpInterfaceMetrics();
1625 
1626             if (otRcpInterfaceMetrics != nullptr)
1627             {
1628                 auto rcpInterfaceStatistics = wpanRcp->mutable_rcp_interface_statistics();
1629 
1630                 rcpInterfaceStatistics->set_rcp_interface_type(otRcpInterfaceMetrics->mRcpInterfaceType);
1631                 rcpInterfaceStatistics->set_transferred_frames_count(otRcpInterfaceMetrics->mTransferredFrameCount);
1632                 rcpInterfaceStatistics->set_transferred_valid_frames_count(
1633                     otRcpInterfaceMetrics->mTransferredValidFrameCount);
1634                 rcpInterfaceStatistics->set_transferred_garbage_frames_count(
1635                     otRcpInterfaceMetrics->mTransferredGarbageFrameCount);
1636                 rcpInterfaceStatistics->set_rx_frames_count(otRcpInterfaceMetrics->mRxFrameCount);
1637                 rcpInterfaceStatistics->set_rx_bytes_count(otRcpInterfaceMetrics->mRxFrameByteCount);
1638                 rcpInterfaceStatistics->set_tx_frames_count(otRcpInterfaceMetrics->mTxFrameCount);
1639                 rcpInterfaceStatistics->set_tx_bytes_count(otRcpInterfaceMetrics->mTxFrameByteCount);
1640             }
1641         }
1642         // End of WpanRcp section.
1643 
1644         // Start of CoexMetrics section.
1645         {
1646             auto               coexMetrics = telemetryData.mutable_coex_metrics();
1647             otRadioCoexMetrics otRadioCoexMetrics;
1648 
1649             if (otPlatRadioGetCoexMetrics(mInstance, &otRadioCoexMetrics) == OT_ERROR_NONE)
1650             {
1651                 coexMetrics->set_count_tx_request(otRadioCoexMetrics.mNumTxRequest);
1652                 coexMetrics->set_count_tx_grant_immediate(otRadioCoexMetrics.mNumTxGrantImmediate);
1653                 coexMetrics->set_count_tx_grant_wait(otRadioCoexMetrics.mNumTxGrantWait);
1654                 coexMetrics->set_count_tx_grant_wait_activated(otRadioCoexMetrics.mNumTxGrantWaitActivated);
1655                 coexMetrics->set_count_tx_grant_wait_timeout(otRadioCoexMetrics.mNumTxGrantWaitTimeout);
1656                 coexMetrics->set_count_tx_grant_deactivated_during_request(
1657                     otRadioCoexMetrics.mNumTxGrantDeactivatedDuringRequest);
1658                 coexMetrics->set_tx_average_request_to_grant_time_us(otRadioCoexMetrics.mAvgTxRequestToGrantTime);
1659                 coexMetrics->set_count_rx_request(otRadioCoexMetrics.mNumRxRequest);
1660                 coexMetrics->set_count_rx_grant_immediate(otRadioCoexMetrics.mNumRxGrantImmediate);
1661                 coexMetrics->set_count_rx_grant_wait(otRadioCoexMetrics.mNumRxGrantWait);
1662                 coexMetrics->set_count_rx_grant_wait_activated(otRadioCoexMetrics.mNumRxGrantWaitActivated);
1663                 coexMetrics->set_count_rx_grant_wait_timeout(otRadioCoexMetrics.mNumRxGrantWaitTimeout);
1664                 coexMetrics->set_count_rx_grant_deactivated_during_request(
1665                     otRadioCoexMetrics.mNumRxGrantDeactivatedDuringRequest);
1666                 coexMetrics->set_count_rx_grant_none(otRadioCoexMetrics.mNumRxGrantNone);
1667                 coexMetrics->set_rx_average_request_to_grant_time_us(otRadioCoexMetrics.mAvgRxRequestToGrantTime);
1668             }
1669             else
1670             {
1671                 error = OT_ERROR_FAILED;
1672             }
1673         }
1674         // End of CoexMetrics section.
1675     }
1676 
1677 #if OTBR_ENABLE_LINK_METRICS_TELEMETRY
1678     {
1679         auto lowPowerMetrics = telemetryData.mutable_low_power_metrics();
1680         // Begin of Link Metrics section.
1681         for (const otNeighborInfo &neighborInfo : neighborTable)
1682         {
1683             otError             query_error;
1684             otLinkMetricsValues values;
1685 
1686             query_error = otLinkMetricsManagerGetMetricsValueByExtAddr(mInstance, &neighborInfo.mExtAddress, &values);
1687             // Some neighbors don't support Link Metrics Subject feature. So it's expected that some other errors
1688             // are returned.
1689             if (query_error == OT_ERROR_NONE)
1690             {
1691                 auto linkMetricsStats = lowPowerMetrics->add_link_metrics_entries();
1692                 linkMetricsStats->set_link_margin(values.mLinkMarginValue);
1693                 linkMetricsStats->set_rssi(values.mRssiValue);
1694             }
1695         }
1696     }
1697 #endif // OTBR_ENABLE_LINK_METRICS_TELEMETRY
1698 
1699     return error;
1700 }
1701 #endif // OTBR_ENABLE_TELEMETRY_DATA_API
1702 
ProcessDatasetForMigration(otOperationalDatasetTlvs & aDatasetTlvs,uint32_t aDelayMilli)1703 otError ThreadHelper::ProcessDatasetForMigration(otOperationalDatasetTlvs &aDatasetTlvs, uint32_t aDelayMilli)
1704 {
1705     otError  error = OT_ERROR_NONE;
1706     Tlv     *tlv;
1707     timespec currentTime;
1708     uint64_t pendingTimestamp = 0;
1709 
1710     VerifyOrExit(FindTlv(OT_MESHCOP_TLV_PENDINGTIMESTAMP, aDatasetTlvs.mTlvs, aDatasetTlvs.mLength) == nullptr,
1711                  error = OT_ERROR_INVALID_ARGS);
1712     VerifyOrExit(FindTlv(OT_MESHCOP_TLV_DELAYTIMER, aDatasetTlvs.mTlvs, aDatasetTlvs.mLength) == nullptr,
1713                  error = OT_ERROR_INVALID_ARGS);
1714 
1715     // There must be sufficient space for a Pending Timestamp TLV and a Delay Timer TLV.
1716     VerifyOrExit(
1717         static_cast<int>(aDatasetTlvs.mLength +
1718                          (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint64_t))    // Pending Timestamp TLV (10 bytes)
1719                          + (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t))) // Delay Timer TLV (6 bytes)
1720             <= int{sizeof(aDatasetTlvs.mTlvs)},
1721         error = OT_ERROR_INVALID_ARGS);
1722 
1723     tlv = reinterpret_cast<Tlv *>(aDatasetTlvs.mTlvs + aDatasetTlvs.mLength);
1724     /*
1725      * Pending Timestamp TLV
1726      *
1727      * | Type | Value | Timestamp Seconds | Timestamp Ticks | U bit |
1728      * |  8   |   8   |         48        |         15      |   1   |
1729      */
1730     tlv->SetType(OT_MESHCOP_TLV_PENDINGTIMESTAMP);
1731     clock_gettime(CLOCK_REALTIME, &currentTime);
1732     pendingTimestamp |= (static_cast<uint64_t>(currentTime.tv_sec) << 16); // Set the 48 bits of Timestamp seconds.
1733     pendingTimestamp |= (((static_cast<uint64_t>(currentTime.tv_nsec) * 32768 / 1000000000) & 0x7fff)
1734                          << 1); // Set the 15 bits of Timestamp ticks, the fractional Unix Time value in 32.768 kHz
1735                                 // resolution. Leave the U-bit unset.
1736     tlv->SetValue(pendingTimestamp);
1737 
1738     tlv = tlv->GetNext();
1739     tlv->SetType(OT_MESHCOP_TLV_DELAYTIMER);
1740     tlv->SetValue(aDelayMilli);
1741 
1742     aDatasetTlvs.mLength = reinterpret_cast<uint8_t *>(tlv->GetNext()) - aDatasetTlvs.mTlvs;
1743 
1744 exit:
1745     return error;
1746 }
1747 
1748 } // namespace agent
1749 } // namespace otbr
1750