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