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