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, ¤tTime);
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