1 /*
2 * Copyright (c) 2023, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28 #include "android/otdaemon_telemetry.hpp"
29
30 #include <openthread/border_agent.h>
31 #include <openthread/nat64.h>
32 #include <openthread/openthread-system.h>
33 #include <openthread/thread.h>
34 #include <openthread/thread_ftd.h>
35 #include <openthread/trel.h>
36 #include <openthread/platform/radio.h>
37
38 #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
39 #include <openthread/dnssd_server.h>
40 #endif
41 #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
42 #include <openthread/srp_server.h>
43 #endif
44
45 #include "statslog_threadnetwork.h"
46 #include "common/code_utils.hpp"
47 #include "mdns/mdns.hpp"
48 #include "proto/threadnetwork_atoms.pb.h"
49
50 namespace otbr {
51 namespace Android {
52 using android::os::statsd::threadnetwork::ThreadnetworkDeviceInfoReported;
53 using android::os::statsd::threadnetwork::ThreadnetworkTelemetryDataReported;
54 using android::os::statsd::threadnetwork::ThreadnetworkTopoEntryRepeated;
55 using TelemetryData = android::os::statsd::threadnetwork::ThreadnetworkTelemetryDataReported;
56
TelemetryNodeTypeFromRoleAndLinkMode(const otDeviceRole & aRole,const otLinkModeConfig & aLinkModeCfg)57 static uint32_t TelemetryNodeTypeFromRoleAndLinkMode(const otDeviceRole &aRole, const otLinkModeConfig &aLinkModeCfg)
58 {
59 uint32_t nodeType;
60
61 switch (aRole)
62 {
63 case OT_DEVICE_ROLE_DISABLED:
64 nodeType = ThreadnetworkTelemetryDataReported::NODE_TYPE_DISABLED;
65 break;
66 case OT_DEVICE_ROLE_DETACHED:
67 nodeType = ThreadnetworkTelemetryDataReported::NODE_TYPE_DETACHED;
68 break;
69 case OT_DEVICE_ROLE_ROUTER:
70 nodeType = ThreadnetworkTelemetryDataReported::NODE_TYPE_ROUTER;
71 break;
72 case OT_DEVICE_ROLE_LEADER:
73 nodeType = ThreadnetworkTelemetryDataReported::NODE_TYPE_LEADER;
74 break;
75 case OT_DEVICE_ROLE_CHILD:
76 if (!aLinkModeCfg.mRxOnWhenIdle)
77 {
78 nodeType = ThreadnetworkTelemetryDataReported::NODE_TYPE_SLEEPY_END;
79 }
80 else if (!aLinkModeCfg.mDeviceType)
81 {
82 // If it's not an FTD, return as minimal end device.
83 nodeType = ThreadnetworkTelemetryDataReported::NODE_TYPE_MINIMAL_END;
84 }
85 else
86 {
87 nodeType = ThreadnetworkTelemetryDataReported::NODE_TYPE_END;
88 }
89 break;
90 default:
91 nodeType = ThreadnetworkTelemetryDataReported::NODE_TYPE_UNSPECIFIED;
92 }
93
94 return nodeType;
95 }
96
97 #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
SrpServerStateFromOtSrpServerState(otSrpServerState aSrpServerState)98 ThreadnetworkTelemetryDataReported::SrpServerState SrpServerStateFromOtSrpServerState(otSrpServerState aSrpServerState)
99 {
100 ThreadnetworkTelemetryDataReported::SrpServerState srpServerState;
101
102 switch (aSrpServerState)
103 {
104 case OT_SRP_SERVER_STATE_DISABLED:
105 srpServerState = ThreadnetworkTelemetryDataReported::SRP_SERVER_STATE_DISABLED;
106 break;
107 case OT_SRP_SERVER_STATE_RUNNING:
108 srpServerState = ThreadnetworkTelemetryDataReported::SRP_SERVER_STATE_RUNNING;
109 break;
110 case OT_SRP_SERVER_STATE_STOPPED:
111 srpServerState = ThreadnetworkTelemetryDataReported::SRP_SERVER_STATE_STOPPED;
112 break;
113 default:
114 srpServerState = ThreadnetworkTelemetryDataReported::SRP_SERVER_STATE_UNSPECIFIED;
115 }
116 return srpServerState;
117 }
118
SrpServerAddressModeFromOtSrpServerAddressMode(otSrpServerAddressMode aSrpServerAddressMode)119 ThreadnetworkTelemetryDataReported::SrpServerAddressMode SrpServerAddressModeFromOtSrpServerAddressMode(
120 otSrpServerAddressMode aSrpServerAddressMode)
121 {
122 ThreadnetworkTelemetryDataReported::SrpServerAddressMode srpServerAddressMode;
123
124 switch (aSrpServerAddressMode)
125 {
126 case OT_SRP_SERVER_ADDRESS_MODE_ANYCAST:
127 srpServerAddressMode = ThreadnetworkTelemetryDataReported::SRP_SERVER_ADDRESS_MODE_STATE_ANYCAST;
128 break;
129 case OT_SRP_SERVER_ADDRESS_MODE_UNICAST:
130 srpServerAddressMode = ThreadnetworkTelemetryDataReported::SRP_SERVER_ADDRESS_MODE_UNICAST;
131 break;
132 default:
133 srpServerAddressMode = ThreadnetworkTelemetryDataReported::SRP_SERVER_ADDRESS_MODE_UNSPECIFIED;
134 }
135 return srpServerAddressMode;
136 }
137 #endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY
138
CopyMdnsResponseCounters(const MdnsResponseCounters & from,ThreadnetworkTelemetryDataReported::MdnsResponseCounters * to)139 void CopyMdnsResponseCounters(const MdnsResponseCounters &from,
140 ThreadnetworkTelemetryDataReported::MdnsResponseCounters *to)
141 {
142 to->set_success_count(from.mSuccess);
143 to->set_not_found_count(from.mNotFound);
144 to->set_invalid_args_count(from.mInvalidArgs);
145 to->set_duplicated_count(from.mDuplicated);
146 to->set_not_implemented_count(from.mNotImplemented);
147 to->set_unknown_error_count(from.mUnknownError);
148 to->set_aborted_count(from.mAborted);
149 to->set_invalid_state_count(from.mInvalidState);
150 }
151
Nat64StateFromOtNat64State(otNat64State aNat64State)152 TelemetryData::Nat64State Nat64StateFromOtNat64State(otNat64State aNat64State)
153 {
154 TelemetryData::Nat64State nat64State;
155
156 switch (aNat64State)
157 {
158 case OT_NAT64_STATE_DISABLED:
159 nat64State = TelemetryData::NAT64_STATE_DISABLED;
160 break;
161 case OT_NAT64_STATE_NOT_RUNNING:
162 nat64State = TelemetryData::NAT64_STATE_NOT_RUNNING;
163 break;
164 case OT_NAT64_STATE_IDLE:
165 nat64State = TelemetryData::NAT64_STATE_IDLE;
166 break;
167 case OT_NAT64_STATE_ACTIVE:
168 nat64State = TelemetryData::NAT64_STATE_ACTIVE;
169 break;
170 default:
171 nat64State = TelemetryData::NAT64_STATE_UNSPECIFIED;
172 }
173
174 return nat64State;
175 }
176
RetrieveNat64State(otInstance * aInstance,TelemetryData::WpanBorderRouter * aWpanBorderRouter)177 void RetrieveNat64State(otInstance *aInstance, TelemetryData::WpanBorderRouter *aWpanBorderRouter)
178 {
179 auto nat64State = aWpanBorderRouter->mutable_nat64_state();
180
181 nat64State->set_prefix_manager_state(Nat64StateFromOtNat64State(otNat64GetPrefixManagerState(aInstance)));
182 nat64State->set_translator_state(Nat64StateFromOtNat64State(otNat64GetTranslatorState(aInstance)));
183 }
184
RetrieveNat64Counters(otInstance * aInstance,TelemetryData::BorderRoutingCounters * aBorderRoutingCounters)185 void RetrieveNat64Counters(otInstance *aInstance, TelemetryData::BorderRoutingCounters *aBorderRoutingCounters)
186 {
187 {
188 auto nat64IcmpCounters = aBorderRoutingCounters->mutable_nat64_protocol_counters()->mutable_icmp();
189 auto nat64UdpCounters = aBorderRoutingCounters->mutable_nat64_protocol_counters()->mutable_udp();
190 auto nat64TcpCounters = aBorderRoutingCounters->mutable_nat64_protocol_counters()->mutable_tcp();
191 otNat64ProtocolCounters otCounters;
192
193 otNat64GetCounters(aInstance, &otCounters);
194 nat64IcmpCounters->set_ipv4_to_ipv6_packets(otCounters.mIcmp.m4To6Packets);
195 nat64IcmpCounters->set_ipv4_to_ipv6_bytes(otCounters.mIcmp.m4To6Bytes);
196 nat64IcmpCounters->set_ipv6_to_ipv4_packets(otCounters.mIcmp.m6To4Packets);
197 nat64IcmpCounters->set_ipv6_to_ipv4_bytes(otCounters.mIcmp.m6To4Bytes);
198 nat64UdpCounters->set_ipv4_to_ipv6_packets(otCounters.mUdp.m4To6Packets);
199 nat64UdpCounters->set_ipv4_to_ipv6_bytes(otCounters.mUdp.m4To6Bytes);
200 nat64UdpCounters->set_ipv6_to_ipv4_packets(otCounters.mUdp.m6To4Packets);
201 nat64UdpCounters->set_ipv6_to_ipv4_bytes(otCounters.mUdp.m6To4Bytes);
202 nat64TcpCounters->set_ipv4_to_ipv6_packets(otCounters.mTcp.m4To6Packets);
203 nat64TcpCounters->set_ipv4_to_ipv6_bytes(otCounters.mTcp.m4To6Bytes);
204 nat64TcpCounters->set_ipv6_to_ipv4_packets(otCounters.mTcp.m6To4Packets);
205 nat64TcpCounters->set_ipv6_to_ipv4_bytes(otCounters.mTcp.m6To4Bytes);
206 }
207
208 {
209 auto errorCounters = aBorderRoutingCounters->mutable_nat64_error_counters();
210 otNat64ErrorCounters otCounters;
211 otNat64GetErrorCounters(aInstance, &otCounters);
212
213 errorCounters->mutable_unknown()->set_ipv4_to_ipv6_packets(otCounters.mCount4To6[OT_NAT64_DROP_REASON_UNKNOWN]);
214 errorCounters->mutable_unknown()->set_ipv6_to_ipv4_packets(otCounters.mCount6To4[OT_NAT64_DROP_REASON_UNKNOWN]);
215 errorCounters->mutable_illegal_packet()->set_ipv4_to_ipv6_packets(
216 otCounters.mCount4To6[OT_NAT64_DROP_REASON_ILLEGAL_PACKET]);
217 errorCounters->mutable_illegal_packet()->set_ipv6_to_ipv4_packets(
218 otCounters.mCount6To4[OT_NAT64_DROP_REASON_ILLEGAL_PACKET]);
219 errorCounters->mutable_unsupported_protocol()->set_ipv4_to_ipv6_packets(
220 otCounters.mCount4To6[OT_NAT64_DROP_REASON_UNSUPPORTED_PROTO]);
221 errorCounters->mutable_unsupported_protocol()->set_ipv6_to_ipv4_packets(
222 otCounters.mCount6To4[OT_NAT64_DROP_REASON_UNSUPPORTED_PROTO]);
223 errorCounters->mutable_no_mapping()->set_ipv4_to_ipv6_packets(
224 otCounters.mCount4To6[OT_NAT64_DROP_REASON_NO_MAPPING]);
225 errorCounters->mutable_no_mapping()->set_ipv6_to_ipv4_packets(
226 otCounters.mCount6To4[OT_NAT64_DROP_REASON_NO_MAPPING]);
227 }
228 }
229
RetrieveBorderAgentInfo(otInstance * aInstance,TelemetryData::BorderAgentInfo * aBorderAgentInfo)230 void RetrieveBorderAgentInfo(otInstance *aInstance, TelemetryData::BorderAgentInfo *aBorderAgentInfo)
231 {
232 auto baCounters = aBorderAgentInfo->mutable_border_agent_counters();
233 auto otBorderAgentCounters = *otBorderAgentGetCounters(aInstance);
234
235 baCounters->set_epskc_activations(otBorderAgentCounters.mEpskcActivations);
236 baCounters->set_epskc_deactivation_clears(otBorderAgentCounters.mEpskcDeactivationClears);
237 baCounters->set_epskc_deactivation_timeouts(otBorderAgentCounters.mEpskcDeactivationTimeouts);
238 baCounters->set_epskc_deactivation_max_attempts(otBorderAgentCounters.mEpskcDeactivationMaxAttempts);
239 baCounters->set_epskc_deactivation_disconnects(otBorderAgentCounters.mEpskcDeactivationDisconnects);
240 baCounters->set_epskc_invalid_ba_state_errors(otBorderAgentCounters.mEpskcInvalidBaStateErrors);
241 baCounters->set_epskc_invalid_args_errors(otBorderAgentCounters.mEpskcInvalidArgsErrors);
242 baCounters->set_epskc_start_secure_session_errors(otBorderAgentCounters.mEpskcStartSecureSessionErrors);
243 baCounters->set_epskc_secure_session_successes(otBorderAgentCounters.mEpskcSecureSessionSuccesses);
244 baCounters->set_epskc_secure_session_failures(otBorderAgentCounters.mEpskcSecureSessionFailures);
245 baCounters->set_epskc_commissioner_petitions(otBorderAgentCounters.mEpskcCommissionerPetitions);
246
247 baCounters->set_pskc_secure_session_successes(otBorderAgentCounters.mPskcSecureSessionSuccesses);
248 baCounters->set_pskc_secure_session_failures(otBorderAgentCounters.mPskcSecureSessionFailures);
249 baCounters->set_pskc_commissioner_petitions(otBorderAgentCounters.mPskcCommissionerPetitions);
250
251 baCounters->set_mgmt_active_get_reqs(otBorderAgentCounters.mMgmtActiveGets);
252 baCounters->set_mgmt_pending_get_reqs(otBorderAgentCounters.mMgmtPendingGets);
253 }
254
RetrieveTrelInfo(otInstance * aInstance,TelemetryData::TrelInfo * aTrelInfo)255 void RetrieveTrelInfo(otInstance *aInstance, TelemetryData::TrelInfo *aTrelInfo)
256 {
257 auto otTrelCounters = otTrelGetCounters(aInstance);
258 auto trelCounters = aTrelInfo->mutable_counters();
259
260 aTrelInfo->set_is_trel_enabled(otTrelIsEnabled(aInstance));
261 aTrelInfo->set_num_trel_peers(otTrelGetNumberOfPeers(aInstance));
262
263 trelCounters->set_trel_tx_packets(otTrelCounters->mTxPackets);
264 trelCounters->set_trel_tx_bytes(otTrelCounters->mTxBytes);
265 trelCounters->set_trel_tx_packets_failed(otTrelCounters->mTxFailure);
266 trelCounters->set_trel_rx_packets(otTrelCounters->mRxPackets);
267 trelCounters->set_trel_rx_bytes(otTrelCounters->mRxBytes);
268 }
269
RetrieveTelemetryAtom(otInstance * otInstance,Mdns::Publisher * aPublisher,ThreadnetworkTelemetryDataReported & telemetryDataReported,ThreadnetworkTopoEntryRepeated & topoEntryRepeated,ThreadnetworkDeviceInfoReported & deviceInfoReported)270 otError RetrieveTelemetryAtom(otInstance *otInstance,
271 Mdns::Publisher *aPublisher,
272 ThreadnetworkTelemetryDataReported &telemetryDataReported,
273 ThreadnetworkTopoEntryRepeated &topoEntryRepeated,
274 ThreadnetworkDeviceInfoReported &deviceInfoReported)
275 {
276 otError error = OT_ERROR_NONE;
277 std::vector<otNeighborInfo> neighborTable;
278
279 // Begin of ThreadnetworkDeviceInfoReported section.
280 deviceInfoReported.set_thread_version(otThreadGetVersion());
281 deviceInfoReported.set_ot_rcp_version(otGetRadioVersionString(otInstance));
282 // TODO: populate ot_host_version, thread_daemon_version.
283 // End of ThreadnetworkDeviceInfoReported section.
284
285 // Begin of WpanStats section.
286 auto wpanStats = telemetryDataReported.mutable_wpan_stats();
287
288 {
289 otDeviceRole role = otThreadGetDeviceRole(otInstance);
290 otLinkModeConfig otCfg = otThreadGetLinkMode(otInstance);
291
292 wpanStats->set_node_type(TelemetryNodeTypeFromRoleAndLinkMode(role, otCfg));
293 }
294
295 // Disable telemetry retrieval when Thread stack is disabled. DeviceInfo section above is
296 // always uploaded to understand the device count.
297 if (wpanStats->node_type() == ThreadnetworkTelemetryDataReported::NODE_TYPE_DISABLED)
298 {
299 otbrLogDebug("Skip telemetry retrieval since Thread stack is disabled.");
300 // Return error that only partial telemetries are populated.
301 // TODO: refine the error code name to mean: partial data are populated.
302 return OT_ERROR_FAILED;
303 }
304
305 wpanStats->set_channel(otLinkGetChannel(otInstance));
306
307 {
308 uint16_t ccaFailureRate = otLinkGetCcaFailureRate(otInstance);
309
310 wpanStats->set_mac_cca_fail_rate(static_cast<float>(ccaFailureRate) / 0xffff);
311 }
312
313 {
314 int8_t radioTxPower;
315
316 if (otPlatRadioGetTransmitPower(otInstance, &radioTxPower) == OT_ERROR_NONE)
317 {
318 wpanStats->set_radio_tx_power(radioTxPower);
319 }
320 else
321 {
322 error = OT_ERROR_FAILED;
323 }
324 }
325
326 {
327 const otMacCounters *linkCounters = otLinkGetCounters(otInstance);
328
329 wpanStats->set_phy_rx(linkCounters->mRxTotal);
330 wpanStats->set_phy_tx(linkCounters->mTxTotal);
331 wpanStats->set_mac_unicast_rx(linkCounters->mRxUnicast);
332 wpanStats->set_mac_unicast_tx(linkCounters->mTxUnicast);
333 wpanStats->set_mac_broadcast_rx(linkCounters->mRxBroadcast);
334 wpanStats->set_mac_broadcast_tx(linkCounters->mTxBroadcast);
335 wpanStats->set_mac_tx_ack_req(linkCounters->mTxAckRequested);
336 wpanStats->set_mac_tx_no_ack_req(linkCounters->mTxNoAckRequested);
337 wpanStats->set_mac_tx_acked(linkCounters->mTxAcked);
338 wpanStats->set_mac_tx_data(linkCounters->mTxData);
339 wpanStats->set_mac_tx_data_poll(linkCounters->mTxDataPoll);
340 wpanStats->set_mac_tx_beacon(linkCounters->mTxBeacon);
341 wpanStats->set_mac_tx_beacon_req(linkCounters->mTxBeaconRequest);
342 wpanStats->set_mac_tx_other_pkt(linkCounters->mTxOther);
343 wpanStats->set_mac_tx_retry(linkCounters->mTxRetry);
344 wpanStats->set_mac_rx_data(linkCounters->mRxData);
345 wpanStats->set_mac_rx_data_poll(linkCounters->mRxDataPoll);
346 wpanStats->set_mac_rx_beacon(linkCounters->mRxBeacon);
347 wpanStats->set_mac_rx_beacon_req(linkCounters->mRxBeaconRequest);
348 wpanStats->set_mac_rx_other_pkt(linkCounters->mRxOther);
349 wpanStats->set_mac_rx_filter_whitelist(linkCounters->mRxAddressFiltered);
350 wpanStats->set_mac_rx_filter_dest_addr(linkCounters->mRxDestAddrFiltered);
351 wpanStats->set_mac_tx_fail_cca(linkCounters->mTxErrCca);
352 wpanStats->set_mac_rx_fail_decrypt(linkCounters->mRxErrSec);
353 wpanStats->set_mac_rx_fail_no_frame(linkCounters->mRxErrNoFrame);
354 wpanStats->set_mac_rx_fail_unknown_neighbor(linkCounters->mRxErrUnknownNeighbor);
355 wpanStats->set_mac_rx_fail_invalid_src_addr(linkCounters->mRxErrInvalidSrcAddr);
356 wpanStats->set_mac_rx_fail_fcs(linkCounters->mRxErrFcs);
357 wpanStats->set_mac_rx_fail_other(linkCounters->mRxErrOther);
358 }
359
360 {
361 const otIpCounters *ipCounters = otThreadGetIp6Counters(otInstance);
362
363 wpanStats->set_ip_tx_success(ipCounters->mTxSuccess);
364 wpanStats->set_ip_rx_success(ipCounters->mRxSuccess);
365 wpanStats->set_ip_tx_failure(ipCounters->mTxFailure);
366 wpanStats->set_ip_rx_failure(ipCounters->mRxFailure);
367 }
368 // End of WpanStats section.
369
370 {
371 // Begin of WpanTopoFull section.
372 auto wpanTopoFull = telemetryDataReported.mutable_wpan_topo_full();
373 uint16_t rloc16 = otThreadGetRloc16(otInstance);
374
375 wpanTopoFull->set_rloc16(rloc16);
376
377 {
378 otRouterInfo info;
379
380 if (otThreadGetRouterInfo(otInstance, rloc16, &info) == OT_ERROR_NONE)
381 {
382 wpanTopoFull->set_router_id(info.mRouterId);
383 }
384 else
385 {
386 error = OT_ERROR_FAILED;
387 }
388 }
389
390 {
391 otNeighborInfoIterator iter = OT_NEIGHBOR_INFO_ITERATOR_INIT;
392 otNeighborInfo neighborInfo;
393
394 while (otThreadGetNextNeighborInfo(otInstance, &iter, &neighborInfo) == OT_ERROR_NONE)
395 {
396 neighborTable.push_back(neighborInfo);
397 }
398 }
399 wpanTopoFull->set_neighbor_table_size(neighborTable.size());
400
401 uint16_t childIndex = 0;
402 otChildInfo childInfo;
403 std::vector<otChildInfo> childTable;
404
405 while (otThreadGetChildInfoByIndex(otInstance, childIndex, &childInfo) == OT_ERROR_NONE)
406 {
407 childTable.push_back(childInfo);
408 childIndex++;
409 }
410 wpanTopoFull->set_child_table_size(childTable.size());
411
412 {
413 struct otLeaderData leaderData;
414
415 if (otThreadGetLeaderData(otInstance, &leaderData) == OT_ERROR_NONE)
416 {
417 wpanTopoFull->set_leader_router_id(leaderData.mLeaderRouterId);
418 wpanTopoFull->set_leader_weight(leaderData.mWeighting);
419 // Do not log network_data_version.
420 }
421 else
422 {
423 error = OT_ERROR_FAILED;
424 }
425 }
426
427 uint8_t weight = otThreadGetLocalLeaderWeight(otInstance);
428
429 wpanTopoFull->set_leader_local_weight(weight);
430
431 int8_t rssi = otPlatRadioGetRssi(otInstance);
432
433 wpanTopoFull->set_instant_rssi(rssi);
434
435 const otExtendedPanId *extPanId = otThreadGetExtendedPanId(otInstance);
436 uint64_t extPanIdVal;
437
438 extPanIdVal = ConvertOpenThreadUint64(extPanId->m8);
439 wpanTopoFull->set_has_extended_pan_id(extPanIdVal != 0);
440 // Note: Used leader_router_id instead of leader_rloc16.
441 // Note: Network level info (e.g., extended_pan_id, partition_id, is_active_br) is not logged.
442 // TODO: populate is_active_srp_server, sum_on_link_prefix_changes, preferred_router_id
443 // if needed.
444 // End of WpanTopoFull section.
445
446 // Begin of TopoEntry section.
447 std::map<uint16_t, const otChildInfo *> childMap;
448
449 for (const otChildInfo &childInfo : childTable)
450 {
451 auto pair = childMap.insert({childInfo.mRloc16, &childInfo});
452 if (!pair.second)
453 {
454 // This shouldn't happen, so log an error. It doesn't matter which
455 // duplicate is kept.
456 otbrLogErr("Children with duplicate RLOC16 found: 0x%04x", static_cast<int>(childInfo.mRloc16));
457 }
458 }
459
460 for (const otNeighborInfo &neighborInfo : neighborTable)
461 {
462 auto topoEntry = topoEntryRepeated.mutable_topo_entry_repeated()->add_topo_entries();
463
464 // 0~15: uint16_t rloc_16
465 // 16~31: uint16_t version Thread version of the neighbor
466 uint32_t comboTelemetry1 = 0;
467 comboTelemetry1 |= (((uint32_t)neighborInfo.mRloc16) & 0x0000FFFF);
468 comboTelemetry1 |= ((((uint32_t)neighborInfo.mVersion) & 0x0000FFFF) << 16);
469 topoEntry->set_combo_telemetry1(comboTelemetry1);
470
471 topoEntry->set_age_sec(neighborInfo.mAge);
472
473 // 0~7: uint8_t link_quality_in
474 // 8~15: int8_t average_rssi
475 // 16~23: int8_t last_rssi
476 // 24~31: uint8_t network_data_version
477 uint32_t comboTelemetry2 = 0;
478 comboTelemetry2 |= (((uint32_t)neighborInfo.mLinkQualityIn) & 0x000000FF);
479 comboTelemetry2 |= ((((uint32_t)neighborInfo.mAverageRssi) & 0x000000FF) << 8);
480 comboTelemetry2 |= ((((uint32_t)neighborInfo.mLastRssi) & 0x000000FF) << 16);
481 // network_data_version is populated in the next section.
482 topoEntry->set_combo_telemetry2(comboTelemetry2);
483
484 // Each bit on the flag represents a bool flag
485 // 0: rx_on_when_idle
486 // 1: full_function
487 // 2: secure_data_request
488 // 3: full_network_data
489 // 4: is_child
490 uint32_t topoEntryFlags = 0;
491 topoEntryFlags |= (neighborInfo.mRxOnWhenIdle ? 1 : 0);
492 topoEntryFlags |= ((neighborInfo.mFullThreadDevice ? 1 : 0) << 1);
493 topoEntryFlags |= ((/* secure_data_request */ true ? 1 : 0) << 2);
494 topoEntryFlags |= ((neighborInfo.mFullNetworkData ? 1 : 0) << 3);
495 topoEntry->set_topo_entry_flags(topoEntryFlags);
496
497 topoEntry->set_link_frame_counter(neighborInfo.mLinkFrameCounter);
498 topoEntry->set_mle_frame_counter(neighborInfo.mMleFrameCounter);
499
500 // 0~15: uint16_t mac_frame_error_rate. Frame error rate (0xffff->100%). Requires error tracking feature.
501 // 16~31: uint16_t ip_message_error_rate. (IPv6) msg error rate (0xffff->100%). Requires error tracking
502 // feature.
503 uint32_t comboTelemetry3 = 0;
504 comboTelemetry3 |= ((uint32_t)(neighborInfo.mFrameErrorRate) & 0x0000FFFF);
505 comboTelemetry3 |= ((((uint32_t)neighborInfo.mMessageErrorRate) & 0x0000FFFF) << 16);
506 topoEntry->set_combo_telemetry3(comboTelemetry3);
507
508 if (!neighborInfo.mIsChild)
509 {
510 continue;
511 }
512
513 auto it = childMap.find(neighborInfo.mRloc16);
514 if (it == childMap.end())
515 {
516 otbrLogErr("Neighbor 0x%04x not found in child table", static_cast<int>(neighborInfo.mRloc16));
517 continue;
518 }
519 const otChildInfo *childInfo = it->second;
520
521 comboTelemetry2 |= ((((uint32_t)childInfo->mNetworkDataVersion) & 0x000000FF) << 24);
522 topoEntry->set_combo_telemetry2(comboTelemetry2);
523
524 topoEntryFlags |= ((/* is_child */ true ? 1 : 0) << 4);
525 topoEntry->set_topo_entry_flags(topoEntryFlags);
526
527 topoEntry->set_timeout_sec(childInfo->mTimeout);
528 }
529 // End of TopoEntry section.
530 }
531
532 {
533 // Begin of WpanBorderRouter section.
534 auto wpanBorderRouter = telemetryDataReported.mutable_wpan_border_router();
535
536 // Begin of BorderRoutingCounters section.
537 {
538 auto borderRoutingCouters = wpanBorderRouter->mutable_border_routing_counters();
539 const otBorderRoutingCounters *otBorderRoutingCounters = otIp6GetBorderRoutingCounters(otInstance);
540
541 borderRoutingCouters->mutable_inbound_unicast()->set_packet_count(
542 otBorderRoutingCounters->mInboundUnicast.mPackets);
543 borderRoutingCouters->mutable_inbound_unicast()->set_byte_count(
544 otBorderRoutingCounters->mInboundUnicast.mBytes);
545 borderRoutingCouters->mutable_inbound_multicast()->set_packet_count(
546 otBorderRoutingCounters->mInboundMulticast.mPackets);
547 borderRoutingCouters->mutable_inbound_multicast()->set_byte_count(
548 otBorderRoutingCounters->mInboundMulticast.mBytes);
549 borderRoutingCouters->mutable_outbound_unicast()->set_packet_count(
550 otBorderRoutingCounters->mOutboundUnicast.mPackets);
551 borderRoutingCouters->mutable_outbound_unicast()->set_byte_count(
552 otBorderRoutingCounters->mOutboundUnicast.mBytes);
553 borderRoutingCouters->mutable_outbound_multicast()->set_packet_count(
554 otBorderRoutingCounters->mOutboundMulticast.mPackets);
555 borderRoutingCouters->mutable_outbound_multicast()->set_byte_count(
556 otBorderRoutingCounters->mOutboundMulticast.mBytes);
557 borderRoutingCouters->set_ra_rx(otBorderRoutingCounters->mRaRx);
558 borderRoutingCouters->set_ra_tx_success(otBorderRoutingCounters->mRaTxSuccess);
559 borderRoutingCouters->set_ra_tx_failure(otBorderRoutingCounters->mRaTxFailure);
560 borderRoutingCouters->set_rs_rx(otBorderRoutingCounters->mRsRx);
561 borderRoutingCouters->set_rs_tx_success(otBorderRoutingCounters->mRsTxSuccess);
562 borderRoutingCouters->set_rs_tx_failure(otBorderRoutingCounters->mRsTxFailure);
563
564 RetrieveNat64Counters(otInstance, borderRoutingCouters);
565 }
566
567 // End of BorderRoutingCounters section.
568
569 #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
570 // Begin of SrpServerInfo section.
571 {
572 auto srpServer = wpanBorderRouter->mutable_srp_server();
573 otSrpServerLeaseInfo leaseInfo;
574 const otSrpServerHost *host = nullptr;
575 const otSrpServerResponseCounters *responseCounters = otSrpServerGetResponseCounters(otInstance);
576
577 srpServer->set_state(SrpServerStateFromOtSrpServerState(otSrpServerGetState(otInstance)));
578 srpServer->set_port(otSrpServerGetPort(otInstance));
579 srpServer->set_address_mode(
580 SrpServerAddressModeFromOtSrpServerAddressMode(otSrpServerGetAddressMode(otInstance)));
581
582 auto srpServerHosts = srpServer->mutable_hosts();
583 auto srpServerServices = srpServer->mutable_services();
584 auto srpServerResponseCounters = srpServer->mutable_response_counters();
585
586 while ((host = otSrpServerGetNextHost(otInstance, host)))
587 {
588 const otSrpServerService *service = nullptr;
589
590 if (otSrpServerHostIsDeleted(host))
591 {
592 srpServerHosts->set_deleted_count(srpServerHosts->deleted_count() + 1);
593 }
594 else
595 {
596 srpServerHosts->set_fresh_count(srpServerHosts->fresh_count() + 1);
597 otSrpServerHostGetLeaseInfo(host, &leaseInfo);
598 srpServerHosts->set_lease_time_total_ms(srpServerHosts->lease_time_total_ms() + leaseInfo.mLease);
599 srpServerHosts->set_key_lease_time_total_ms(srpServerHosts->key_lease_time_total_ms() +
600 leaseInfo.mKeyLease);
601 srpServerHosts->set_remaining_lease_time_total_ms(srpServerHosts->remaining_lease_time_total_ms() +
602 leaseInfo.mRemainingLease);
603 srpServerHosts->set_remaining_key_lease_time_total_ms(
604 srpServerHosts->remaining_key_lease_time_total_ms() + leaseInfo.mRemainingKeyLease);
605 }
606
607 while ((service = otSrpServerHostGetNextService(host, service)))
608 {
609 if (otSrpServerServiceIsDeleted(service))
610 {
611 srpServerServices->set_deleted_count(srpServerServices->deleted_count() + 1);
612 }
613 else
614 {
615 srpServerServices->set_fresh_count(srpServerServices->fresh_count() + 1);
616 otSrpServerServiceGetLeaseInfo(service, &leaseInfo);
617 srpServerServices->set_lease_time_total_ms(srpServerServices->lease_time_total_ms() +
618 leaseInfo.mLease);
619 srpServerServices->set_key_lease_time_total_ms(srpServerServices->key_lease_time_total_ms() +
620 leaseInfo.mKeyLease);
621 srpServerServices->set_remaining_lease_time_total_ms(
622 srpServerServices->remaining_lease_time_total_ms() + leaseInfo.mRemainingLease);
623 srpServerServices->set_remaining_key_lease_time_total_ms(
624 srpServerServices->remaining_key_lease_time_total_ms() + leaseInfo.mRemainingKeyLease);
625 }
626 }
627 }
628
629 srpServerResponseCounters->set_success_count(responseCounters->mSuccess);
630 srpServerResponseCounters->set_server_failure_count(responseCounters->mServerFailure);
631 srpServerResponseCounters->set_format_error_count(responseCounters->mFormatError);
632 srpServerResponseCounters->set_name_exists_count(responseCounters->mNameExists);
633 srpServerResponseCounters->set_refused_count(responseCounters->mRefused);
634 srpServerResponseCounters->set_other_count(responseCounters->mOther);
635 }
636 // End of SrpServerInfo section.
637 #endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY
638
639 #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
640 // Begin of DnsServerInfo section.
641 {
642 auto dnsServer = wpanBorderRouter->mutable_dns_server();
643 auto dnsServerResponseCounters = dnsServer->mutable_response_counters();
644 otDnssdCounters otDnssdCounters = *otDnssdGetCounters(otInstance);
645
646 dnsServerResponseCounters->set_success_count(otDnssdCounters.mSuccessResponse);
647 dnsServerResponseCounters->set_server_failure_count(otDnssdCounters.mServerFailureResponse);
648 dnsServerResponseCounters->set_format_error_count(otDnssdCounters.mFormatErrorResponse);
649 dnsServerResponseCounters->set_name_error_count(otDnssdCounters.mNameErrorResponse);
650 dnsServerResponseCounters->set_not_implemented_count(otDnssdCounters.mNotImplementedResponse);
651 dnsServerResponseCounters->set_other_count(otDnssdCounters.mOtherResponse);
652 // The counters of queries, responses, failures handled by upstream DNS server.
653 dnsServerResponseCounters->set_upstream_dns_queries(otDnssdCounters.mUpstreamDnsCounters.mQueries);
654 dnsServerResponseCounters->set_upstream_dns_responses(otDnssdCounters.mUpstreamDnsCounters.mResponses);
655 dnsServerResponseCounters->set_upstream_dns_failures(otDnssdCounters.mUpstreamDnsCounters.mFailures);
656
657 dnsServer->set_resolved_by_local_srp_count(otDnssdCounters.mResolvedBySrp);
658
659 dnsServer->set_upstream_dns_query_state(
660 otDnssdUpstreamQueryIsEnabled(otInstance)
661 ? ThreadnetworkTelemetryDataReported::UPSTREAMDNS_QUERY_STATE_ENABLED
662 : ThreadnetworkTelemetryDataReported::UPSTREAMDNS_QUERY_STATE_DISABLED);
663 }
664 // End of DnsServerInfo section.
665 #endif // OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
666
667 // Start of MdnsInfo section.
668 if (aPublisher != nullptr)
669 {
670 auto mdns = wpanBorderRouter->mutable_mdns();
671 const MdnsTelemetryInfo &mdnsInfo = aPublisher->GetMdnsTelemetryInfo();
672
673 CopyMdnsResponseCounters(mdnsInfo.mHostRegistrations, mdns->mutable_host_registration_responses());
674 CopyMdnsResponseCounters(mdnsInfo.mServiceRegistrations, mdns->mutable_service_registration_responses());
675 CopyMdnsResponseCounters(mdnsInfo.mHostResolutions, mdns->mutable_host_resolution_responses());
676 CopyMdnsResponseCounters(mdnsInfo.mServiceResolutions, mdns->mutable_service_resolution_responses());
677
678 mdns->set_host_registration_ema_latency_ms(mdnsInfo.mHostRegistrationEmaLatency);
679 mdns->set_service_registration_ema_latency_ms(mdnsInfo.mServiceRegistrationEmaLatency);
680 mdns->set_host_resolution_ema_latency_ms(mdnsInfo.mHostResolutionEmaLatency);
681 mdns->set_service_resolution_ema_latency_ms(mdnsInfo.mServiceResolutionEmaLatency);
682 }
683 // End of MdnsInfo section.
684
685 // End of WpanBorderRouter section.
686
687 // Start of WpanRcp section.
688 {
689 auto wpanRcp = telemetryDataReported.mutable_wpan_rcp();
690 const otRadioSpinelMetrics *otRadioSpinelMetrics = otSysGetRadioSpinelMetrics();
691 auto rcpStabilityStatistics = wpanRcp->mutable_rcp_stability_statistics();
692
693 if (otRadioSpinelMetrics != nullptr)
694 {
695 rcpStabilityStatistics->set_rcp_timeout_count(otRadioSpinelMetrics->mRcpTimeoutCount);
696 rcpStabilityStatistics->set_rcp_reset_count(otRadioSpinelMetrics->mRcpUnexpectedResetCount);
697 rcpStabilityStatistics->set_rcp_restoration_count(otRadioSpinelMetrics->mRcpRestorationCount);
698 rcpStabilityStatistics->set_spinel_parse_error_count(otRadioSpinelMetrics->mSpinelParseErrorCount);
699 }
700
701 // TODO: provide rcp_firmware_update_count info.
702 rcpStabilityStatistics->set_thread_stack_uptime(otInstanceGetUptime(otInstance));
703
704 const otRcpInterfaceMetrics *otRcpInterfaceMetrics = otSysGetRcpInterfaceMetrics();
705
706 if (otRcpInterfaceMetrics != nullptr)
707 {
708 auto rcpInterfaceStatistics = wpanRcp->mutable_rcp_interface_statistics();
709
710 rcpInterfaceStatistics->set_rcp_interface_type(otRcpInterfaceMetrics->mRcpInterfaceType);
711 rcpInterfaceStatistics->set_transferred_frames_count(otRcpInterfaceMetrics->mTransferredFrameCount);
712 rcpInterfaceStatistics->set_transferred_valid_frames_count(
713 otRcpInterfaceMetrics->mTransferredValidFrameCount);
714 rcpInterfaceStatistics->set_transferred_garbage_frames_count(
715 otRcpInterfaceMetrics->mTransferredGarbageFrameCount);
716 rcpInterfaceStatistics->set_rx_frames_count(otRcpInterfaceMetrics->mRxFrameCount);
717 rcpInterfaceStatistics->set_rx_bytes_count(otRcpInterfaceMetrics->mRxFrameByteCount);
718 rcpInterfaceStatistics->set_tx_frames_count(otRcpInterfaceMetrics->mTxFrameCount);
719 rcpInterfaceStatistics->set_tx_bytes_count(otRcpInterfaceMetrics->mTxFrameByteCount);
720 }
721 }
722 // End of WpanRcp section.
723
724 // Start of CoexMetrics section.
725 {
726 auto coexMetrics = telemetryDataReported.mutable_coex_metrics();
727 otRadioCoexMetrics otRadioCoexMetrics;
728
729 if (otPlatRadioGetCoexMetrics(otInstance, &otRadioCoexMetrics) == OT_ERROR_NONE)
730 {
731 coexMetrics->set_count_tx_request(otRadioCoexMetrics.mNumTxRequest);
732 coexMetrics->set_count_tx_grant_immediate(otRadioCoexMetrics.mNumTxGrantImmediate);
733 coexMetrics->set_count_tx_grant_wait(otRadioCoexMetrics.mNumTxGrantWait);
734 coexMetrics->set_count_tx_grant_wait_activated(otRadioCoexMetrics.mNumTxGrantWaitActivated);
735 coexMetrics->set_count_tx_grant_wait_timeout(otRadioCoexMetrics.mNumTxGrantWaitTimeout);
736 coexMetrics->set_count_tx_grant_deactivated_during_request(
737 otRadioCoexMetrics.mNumTxGrantDeactivatedDuringRequest);
738 coexMetrics->set_tx_average_request_to_grant_time_us(otRadioCoexMetrics.mAvgTxRequestToGrantTime);
739 coexMetrics->set_count_rx_request(otRadioCoexMetrics.mNumRxRequest);
740 coexMetrics->set_count_rx_grant_immediate(otRadioCoexMetrics.mNumRxGrantImmediate);
741 coexMetrics->set_count_rx_grant_wait(otRadioCoexMetrics.mNumRxGrantWait);
742 coexMetrics->set_count_rx_grant_wait_activated(otRadioCoexMetrics.mNumRxGrantWaitActivated);
743 coexMetrics->set_count_rx_grant_wait_timeout(otRadioCoexMetrics.mNumRxGrantWaitTimeout);
744 coexMetrics->set_count_rx_grant_deactivated_during_request(
745 otRadioCoexMetrics.mNumRxGrantDeactivatedDuringRequest);
746 coexMetrics->set_count_rx_grant_none(otRadioCoexMetrics.mNumRxGrantNone);
747 coexMetrics->set_rx_average_request_to_grant_time_us(otRadioCoexMetrics.mAvgRxRequestToGrantTime);
748 }
749 else
750 {
751 error = OT_ERROR_FAILED;
752 }
753 }
754 // End of CoexMetrics section.
755
756 RetrieveNat64State(otInstance, wpanBorderRouter);
757 RetrieveBorderAgentInfo(otInstance, wpanBorderRouter->mutable_border_agent_info());
758 RetrieveTrelInfo(otInstance, wpanBorderRouter->mutable_trel_info());
759 }
760
761 return error;
762 }
763
PushAtom(const ThreadnetworkTelemetryDataReported & telemetryDataReported)764 int PushAtom(const ThreadnetworkTelemetryDataReported &telemetryDataReported)
765 {
766 const std::string &wpanStats = telemetryDataReported.wpan_stats().SerializeAsString();
767 const std::string &wpanTopoFull = telemetryDataReported.wpan_topo_full().SerializeAsString();
768 const std::string &wpanBorderRouter = telemetryDataReported.wpan_border_router().SerializeAsString();
769 const std::string &wpanRcp = telemetryDataReported.wpan_rcp().SerializeAsString();
770 const std::string &coexMetrics = telemetryDataReported.coex_metrics().SerializeAsString();
771 threadnetwork::BytesField wpanStatsBytesField{wpanStats.c_str(), wpanStats.size()};
772 threadnetwork::BytesField wpanTopoFullBytesField{wpanTopoFull.c_str(), wpanTopoFull.size()};
773 threadnetwork::BytesField wpanBorderRouterBytesField{wpanBorderRouter.c_str(), wpanBorderRouter.size()};
774 threadnetwork::BytesField wpanRcpBytesField{wpanRcp.c_str(), wpanRcp.size()};
775 threadnetwork::BytesField coexMetricsBytesField{coexMetrics.c_str(), coexMetrics.size()};
776 return threadnetwork::stats_write(threadnetwork::THREADNETWORK_TELEMETRY_DATA_REPORTED, wpanStatsBytesField,
777 wpanTopoFullBytesField, wpanBorderRouterBytesField, wpanRcpBytesField,
778 coexMetricsBytesField);
779 }
780
PushAtom(const ThreadnetworkTopoEntryRepeated & topoEntryRepeated)781 int PushAtom(const ThreadnetworkTopoEntryRepeated &topoEntryRepeated)
782 {
783 const std::string &topoEntryField = topoEntryRepeated.topo_entry_repeated().SerializeAsString();
784 threadnetwork::BytesField topoEntryFieldBytesField{topoEntryField.c_str(), topoEntryField.size()};
785 return threadnetwork::stats_write(threadnetwork::THREADNETWORK_TOPO_ENTRY_REPEATED, topoEntryFieldBytesField);
786 }
787
PushAtom(const ThreadnetworkDeviceInfoReported & deviceInfoReported)788 int PushAtom(const ThreadnetworkDeviceInfoReported &deviceInfoReported)
789 {
790 const std::string &otHostVersion = deviceInfoReported.ot_host_version();
791 const std::string &otRcpVersion = deviceInfoReported.ot_rcp_version();
792 const int32_t &threadVersion = deviceInfoReported.thread_version();
793 const std::string &threadDaemonVersion = deviceInfoReported.thread_daemon_version();
794 return threadnetwork::stats_write(threadnetwork::THREADNETWORK_DEVICE_INFO_REPORTED, otHostVersion.c_str(),
795 otRcpVersion.c_str(), threadVersion, threadDaemonVersion.c_str());
796 }
797
RetrieveAndPushAtoms(otInstance * otInstance)798 void RetrieveAndPushAtoms(otInstance *otInstance)
799 {
800 ThreadnetworkTelemetryDataReported telemetryDataReported;
801 ThreadnetworkTopoEntryRepeated topoEntryRepeated;
802 ThreadnetworkDeviceInfoReported deviceInfoReported;
803
804 otbrLogInfo("Try to push threadnetwork ATOMs.");
805 if (RetrieveTelemetryAtom(otInstance, nullptr, telemetryDataReported, topoEntryRepeated, deviceInfoReported) !=
806 OTBR_ERROR_NONE)
807 {
808 otbrLogWarning("Some telemetries are not populated");
809 }
810 if (PushAtom(telemetryDataReported) <= 0)
811 {
812 otbrLogWarning("Failed to push ThreadnetworkTelemetryDataReported");
813 }
814 if (PushAtom(topoEntryRepeated) <= 0)
815 {
816 otbrLogWarning("Failed to push ThreadnetworkTopoEntryRepeated");
817 }
818 if (PushAtom(deviceInfoReported) <= 0)
819 {
820 otbrLogWarning("Failed to push ThreadnetworkDeviceInfoReported");
821 }
822 otbrLogInfo("Pushed threadnetwork ATOMs.");
823 }
824 } // namespace Android
825 } // namespace otbr
826