xref: /aosp_15_r20/external/ot-br-posix/tests/dbus/test_dbus_client.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1 /*
2  *    Copyright (c) 2020, The OpenThread Authors.
3  *    All rights reserved.
4  *
5  *    Redistribution and use in source and binary forms, with or without
6  *    modification, are permitted provided that the following conditions are met:
7  *    1. Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *    2. Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *    3. Neither the name of the copyright holder nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *    POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <assert.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include <memory>
35 
36 #include <dbus/dbus.h>
37 #include <unistd.h>
38 
39 #include "common/code_utils.hpp"
40 #include "dbus/client/thread_api_dbus.hpp"
41 #include "dbus/common/constants.hpp"
42 #if OTBR_ENABLE_TELEMETRY_DATA_API
43 #include "proto/thread_telemetry.pb.h"
44 #endif
45 #include "proto/capabilities.pb.h"
46 
47 using otbr::DBus::ActiveScanResult;
48 using otbr::DBus::ClientError;
49 using otbr::DBus::DeviceRole;
50 using otbr::DBus::EnergyScanResult;
51 using otbr::DBus::ExternalRoute;
52 using otbr::DBus::Ip6Prefix;
53 using otbr::DBus::LinkModeConfig;
54 using otbr::DBus::OnMeshPrefix;
55 using otbr::DBus::SrpServerInfo;
56 using otbr::DBus::ThreadApiDBus;
57 using otbr::DBus::TxtEntry;
58 
59 #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
60 using otbr::DBus::DnssdCounters;
61 #endif
62 
63 #if OTBR_ENABLE_NAT64
64 using otbr::DBus::Nat64AddressMapping;
65 using otbr::DBus::Nat64ComponentState;
66 using otbr::DBus::Nat64ErrorCounters;
67 using otbr::DBus::Nat64ProtocolCounters;
68 #endif
69 
70 #define TEST_ASSERT(x)                                              \
71     do                                                              \
72     {                                                               \
73         if (!(x))                                                   \
74         {                                                           \
75             printf("Assert failed at %s:%d\n", __FILE__, __LINE__); \
76             exit(EXIT_FAILURE);                                     \
77         }                                                           \
78     } while (false)
79 
80 struct DBusConnectionDeleter
81 {
operator ()DBusConnectionDeleter82     void operator()(DBusConnection *aConnection) { dbus_connection_unref(aConnection); }
83 };
84 
85 using UniqueDBusConnection = std::unique_ptr<DBusConnection, DBusConnectionDeleter>;
86 
operator ==(const otbr::DBus::Ip6Prefix & aLhs,const otbr::DBus::Ip6Prefix & aRhs)87 static bool operator==(const otbr::DBus::Ip6Prefix &aLhs, const otbr::DBus::Ip6Prefix &aRhs)
88 {
89     bool prefixDataEquality = (aLhs.mPrefix.size() == aRhs.mPrefix.size()) &&
90                               (memcmp(&aLhs.mPrefix[0], &aRhs.mPrefix[0], aLhs.mPrefix.size()) == 0);
91 
92     return prefixDataEquality && aLhs.mLength == aRhs.mLength;
93 }
94 
CheckExternalRoute(ThreadApiDBus * aApi,const Ip6Prefix & aPrefix)95 static void CheckExternalRoute(ThreadApiDBus *aApi, const Ip6Prefix &aPrefix)
96 {
97     ExternalRoute              route = {};
98     std::vector<ExternalRoute> externalRouteTable;
99 
100     route.mPrefix     = aPrefix;
101     route.mStable     = true;
102     route.mPreference = 0;
103 
104     TEST_ASSERT(aApi->AddExternalRoute(route) == OTBR_ERROR_NONE);
105     sleep(10);
106     TEST_ASSERT(aApi->GetExternalRoutes(externalRouteTable) == OTBR_ERROR_NONE);
107     TEST_ASSERT(externalRouteTable.size() == 1);
108     TEST_ASSERT(externalRouteTable[0].mPrefix == aPrefix);
109     TEST_ASSERT(externalRouteTable[0].mPreference == 0);
110     TEST_ASSERT(externalRouteTable[0].mStable);
111     TEST_ASSERT(externalRouteTable[0].mNextHopIsThisDevice);
112 
113     TEST_ASSERT(aApi->RemoveExternalRoute(aPrefix) == OTBR_ERROR_NONE);
114     sleep(10);
115     TEST_ASSERT(aApi->GetExternalRoutes(externalRouteTable) == OTBR_ERROR_NONE);
116     TEST_ASSERT(externalRouteTable.empty());
117 }
118 
CheckOnMeshPrefix(ThreadApiDBus * aApi)119 static void CheckOnMeshPrefix(ThreadApiDBus *aApi)
120 {
121     OnMeshPrefix              prefix = {};
122     std::vector<OnMeshPrefix> onMeshPrefixes;
123 
124     prefix.mPrefix.mPrefix = {0xfd, 0xee, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
125     prefix.mPrefix.mLength = 64;
126 
127     prefix.mPreference = 0;
128     prefix.mStable     = true;
129 
130     TEST_ASSERT(aApi->AddOnMeshPrefix(prefix) == OTBR_ERROR_NONE);
131     sleep(10);
132     TEST_ASSERT(aApi->GetOnMeshPrefixes(onMeshPrefixes) == OTBR_ERROR_NONE);
133     TEST_ASSERT(onMeshPrefixes.size() == 1);
134     TEST_ASSERT(onMeshPrefixes[0].mPrefix == prefix.mPrefix);
135     TEST_ASSERT(onMeshPrefixes[0].mPreference == 0);
136     TEST_ASSERT(onMeshPrefixes[0].mStable);
137 
138     TEST_ASSERT(aApi->RemoveOnMeshPrefix(prefix.mPrefix) == OTBR_ERROR_NONE);
139     sleep(10);
140     TEST_ASSERT(aApi->GetOnMeshPrefixes(onMeshPrefixes) == OTBR_ERROR_NONE);
141     TEST_ASSERT(onMeshPrefixes.empty());
142 }
143 
CheckFeatureFlagUpdate(ThreadApiDBus * aApi)144 static void CheckFeatureFlagUpdate(ThreadApiDBus *aApi)
145 {
146     OTBR_UNUSED_VARIABLE(aApi);
147 #if OTBR_ENABLE_FEATURE_FLAGS
148     std::vector<uint8_t> responseFeatureFlagBytes;
149     // Serialized bytes of feature_flag proto, with enable_nat64=true.
150     uint8_t              requestRawBytes[] = {0x08, 0x01};
151     unsigned             byteArraySize     = sizeof(requestRawBytes) / sizeof(uint8_t);
152     std::vector<uint8_t> requestFeatureFlagBytes(&requestRawBytes[0], &requestRawBytes[byteArraySize]);
153     TEST_ASSERT(aApi->SetFeatureFlagListData(requestFeatureFlagBytes) == OTBR_ERROR_NONE);
154     TEST_ASSERT(aApi->GetFeatureFlagListData(responseFeatureFlagBytes) == OTBR_ERROR_NONE);
155 #endif
156 }
157 
CheckSrpServerInfo(ThreadApiDBus * aApi)158 void CheckSrpServerInfo(ThreadApiDBus *aApi)
159 {
160     SrpServerInfo srpServerInfo;
161 
162     TEST_ASSERT(aApi->GetSrpServerInfo(srpServerInfo) == OTBR_ERROR_NONE);
163     TEST_ASSERT(srpServerInfo.mState == otbr::DBus::OTBR_SRP_SERVER_STATE_RUNNING);
164     TEST_ASSERT(srpServerInfo.mPort != 0);
165     TEST_ASSERT(srpServerInfo.mHosts.mFreshCount == 0);
166     TEST_ASSERT(srpServerInfo.mHosts.mDeletedCount == 0);
167     TEST_ASSERT(srpServerInfo.mHosts.mLeaseTimeTotal == 0);
168     TEST_ASSERT(srpServerInfo.mHosts.mKeyLeaseTimeTotal == 0);
169     TEST_ASSERT(srpServerInfo.mHosts.mRemainingLeaseTimeTotal == 0);
170     TEST_ASSERT(srpServerInfo.mHosts.mRemainingKeyLeaseTimeTotal == 0);
171     TEST_ASSERT(srpServerInfo.mServices.mFreshCount == 0);
172     TEST_ASSERT(srpServerInfo.mServices.mDeletedCount == 0);
173     TEST_ASSERT(srpServerInfo.mServices.mLeaseTimeTotal == 0);
174     TEST_ASSERT(srpServerInfo.mServices.mKeyLeaseTimeTotal == 0);
175     TEST_ASSERT(srpServerInfo.mServices.mRemainingLeaseTimeTotal == 0);
176     TEST_ASSERT(srpServerInfo.mServices.mRemainingKeyLeaseTimeTotal == 0);
177     TEST_ASSERT(srpServerInfo.mResponseCounters.mSuccess == 0);
178     TEST_ASSERT(srpServerInfo.mResponseCounters.mServerFailure == 0);
179     TEST_ASSERT(srpServerInfo.mResponseCounters.mFormatError == 0);
180     TEST_ASSERT(srpServerInfo.mResponseCounters.mNameExists == 0);
181     TEST_ASSERT(srpServerInfo.mResponseCounters.mRefused == 0);
182     TEST_ASSERT(srpServerInfo.mResponseCounters.mOther == 0);
183 }
184 
CheckTrelInfo(ThreadApiDBus * aApi)185 void CheckTrelInfo(ThreadApiDBus *aApi)
186 {
187     OTBR_UNUSED_VARIABLE(aApi);
188 
189 #if OTBR_ENABLE_TREL
190     otbr::DBus::TrelInfo trelInfo;
191 
192     TEST_ASSERT(aApi->GetTrelInfo(trelInfo) == OTBR_ERROR_NONE);
193     TEST_ASSERT(trelInfo.mEnabled);
194     TEST_ASSERT(trelInfo.mNumTrelPeers == 0);
195     TEST_ASSERT(trelInfo.mTrelCounters.mTxPackets == 0);
196     TEST_ASSERT(trelInfo.mTrelCounters.mTxBytes == 0);
197     TEST_ASSERT(trelInfo.mTrelCounters.mTxFailure == 0);
198     TEST_ASSERT(trelInfo.mTrelCounters.mRxPackets == 0);
199     TEST_ASSERT(trelInfo.mTrelCounters.mRxBytes == 0);
200 #endif
201 }
202 
CheckDnssdCounters(ThreadApiDBus * aApi)203 void CheckDnssdCounters(ThreadApiDBus *aApi)
204 {
205     OTBR_UNUSED_VARIABLE(aApi);
206 #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
207     otbr::DBus::DnssdCounters dnssdCounters;
208 
209     TEST_ASSERT(aApi->GetDnssdCounters(dnssdCounters) == OTBR_ERROR_NONE);
210     TEST_ASSERT(dnssdCounters.mSuccessResponse == 0);
211     TEST_ASSERT(dnssdCounters.mServerFailureResponse == 0);
212     TEST_ASSERT(dnssdCounters.mFormatErrorResponse == 0);
213     TEST_ASSERT(dnssdCounters.mNameErrorResponse == 0);
214     TEST_ASSERT(dnssdCounters.mNotImplementedResponse == 0);
215     TEST_ASSERT(dnssdCounters.mOtherResponse == 0);
216     TEST_ASSERT(dnssdCounters.mResolvedBySrp == 0);
217 #endif
218 }
219 
CheckMdnsInfo(ThreadApiDBus * aApi)220 void CheckMdnsInfo(ThreadApiDBus *aApi)
221 {
222     otbr::MdnsTelemetryInfo mdnsInfo;
223 
224     TEST_ASSERT(aApi->GetMdnsTelemetryInfo(mdnsInfo) == OTBR_ERROR_NONE);
225 
226     TEST_ASSERT(mdnsInfo.mServiceRegistrations.mSuccess > 0);
227     TEST_ASSERT(mdnsInfo.mServiceRegistrationEmaLatency > 0);
228 }
229 
CheckNat64(ThreadApiDBus * aApi)230 void CheckNat64(ThreadApiDBus *aApi)
231 {
232     OTBR_UNUSED_VARIABLE(aApi);
233 #if OTBR_ENABLE_NAT64
234     {
235         Nat64ComponentState aState;
236         TEST_ASSERT(aApi->SetNat64Enabled(false) == OTBR_ERROR_NONE);
237         TEST_ASSERT(aApi->GetNat64State(aState) == OTBR_ERROR_NONE);
238         TEST_ASSERT(aState.mPrefixManagerState == OTBR_NAT64_STATE_NAME_DISABLED);
239         TEST_ASSERT(aState.mTranslatorState == OTBR_NAT64_STATE_NAME_DISABLED);
240 
241         TEST_ASSERT(aApi->SetNat64Enabled(true) == OTBR_ERROR_NONE);
242         TEST_ASSERT(aApi->GetNat64State(aState) == OTBR_ERROR_NONE);
243         TEST_ASSERT(aState.mPrefixManagerState != OTBR_NAT64_STATE_NAME_DISABLED);
244         TEST_ASSERT(aState.mTranslatorState != OTBR_NAT64_STATE_NAME_DISABLED);
245     }
246 
247     {
248         std::vector<Nat64AddressMapping> aMappings;
249         TEST_ASSERT(aApi->GetNat64Mappings(aMappings) == OTBR_ERROR_NONE);
250     }
251 
252     {
253         Nat64ProtocolCounters aCounters;
254         TEST_ASSERT(aApi->GetNat64ProtocolCounters(aCounters) == OTBR_ERROR_NONE);
255     }
256 
257     {
258         Nat64ErrorCounters aCounters;
259         TEST_ASSERT(aApi->GetNat64ErrorCounters(aCounters) == OTBR_ERROR_NONE);
260     }
261 #endif
262 }
263 
CheckEphemeralKey(ThreadApiDBus * aApi)264 void CheckEphemeralKey(ThreadApiDBus *aApi)
265 {
266     bool enabled;
267 
268     TEST_ASSERT(aApi->SetEphemeralKeyEnabled(false) == OTBR_ERROR_NONE);
269     TEST_ASSERT(aApi->GetEphemeralKeyEnabled(enabled) == OTBR_ERROR_NONE);
270     TEST_ASSERT(enabled == false);
271     TEST_ASSERT(aApi->SetEphemeralKeyEnabled(true) == OTBR_ERROR_NONE);
272     TEST_ASSERT(aApi->GetEphemeralKeyEnabled(enabled) == OTBR_ERROR_NONE);
273     TEST_ASSERT(enabled == true);
274 }
275 
CheckBorderAgentInfo(const threadnetwork::TelemetryData_BorderAgentInfo & aBorderAgentInfo)276 void CheckBorderAgentInfo(const threadnetwork::TelemetryData_BorderAgentInfo &aBorderAgentInfo)
277 {
278     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_activations() == 0);
279     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_deactivation_clears() == 0);
280     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_deactivation_timeouts() == 0);
281     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_deactivation_max_attempts() == 0);
282     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_deactivation_disconnects() == 0);
283     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_invalid_ba_state_errors() == 0);
284     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_invalid_args_errors() == 0);
285     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_start_secure_session_errors() == 0);
286     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_secure_session_successes() == 0);
287     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_secure_session_failures() == 0);
288     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().epskc_commissioner_petitions() == 0);
289     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().pskc_secure_session_successes() == 0);
290     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().pskc_secure_session_failures() == 0);
291     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().pskc_commissioner_petitions() == 0);
292     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().mgmt_active_get_reqs() == 0);
293     TEST_ASSERT(aBorderAgentInfo.border_agent_counters().mgmt_pending_get_reqs() == 0);
294 }
295 
296 #if OTBR_ENABLE_TELEMETRY_DATA_API
CheckTelemetryData(ThreadApiDBus * aApi)297 void CheckTelemetryData(ThreadApiDBus *aApi)
298 {
299     std::vector<uint8_t>         responseTelemetryDataBytes;
300     threadnetwork::TelemetryData telemetryData;
301 
302     TEST_ASSERT(aApi->GetTelemetryData(responseTelemetryDataBytes) == OTBR_ERROR_NONE);
303     // Print TelemetryData proto in hex format.
304     printf("TelemetryData bytes in hex: ");
305     for (uint8_t byte : responseTelemetryDataBytes)
306     {
307         printf("%02x ", byte);
308     }
309     printf("\n");
310 
311     TEST_ASSERT(telemetryData.ParseFromString(
312         std::string(responseTelemetryDataBytes.begin(), responseTelemetryDataBytes.end())));
313     TEST_ASSERT(telemetryData.wpan_stats().node_type() == threadnetwork::TelemetryData::NODE_TYPE_LEADER);
314     TEST_ASSERT(telemetryData.wpan_stats().channel() == 11);
315     TEST_ASSERT(telemetryData.wpan_stats().radio_tx_power() == 0);
316     TEST_ASSERT(telemetryData.wpan_stats().mac_cca_fail_rate() < 1e-6);
317     TEST_ASSERT(telemetryData.wpan_stats().phy_tx() > 0);
318     TEST_ASSERT(telemetryData.wpan_stats().phy_rx() > 0);
319     TEST_ASSERT(telemetryData.wpan_stats().ip_tx_success() > 0);
320     TEST_ASSERT(telemetryData.wpan_topo_full().rloc16() < 0xffff);
321     TEST_ASSERT(telemetryData.wpan_topo_full().network_data().size() > 0);
322     TEST_ASSERT(telemetryData.wpan_topo_full().partition_id() > 0);
323     TEST_ASSERT(telemetryData.wpan_topo_full().extended_pan_id() > 0);
324     TEST_ASSERT(telemetryData.wpan_topo_full().peer_br_count() == 0);
325     TEST_ASSERT(telemetryData.topo_entries_size() == 1);
326     TEST_ASSERT(telemetryData.topo_entries(0).rloc16() < 0xffff);
327     TEST_ASSERT(telemetryData.wpan_border_router().border_routing_counters().rs_tx_failure() == 0);
328 #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
329     TEST_ASSERT(telemetryData.wpan_border_router().srp_server().state() ==
330                 threadnetwork::TelemetryData::SRP_SERVER_STATE_RUNNING);
331 #endif
332 #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
333     TEST_ASSERT(telemetryData.wpan_border_router().dns_server().response_counters().server_failure_count() == 0);
334 #endif
335 #if OTBR_ENABLE_TREL
336     TEST_ASSERT(telemetryData.wpan_border_router().trel_info().is_trel_enabled());
337     TEST_ASSERT(telemetryData.wpan_border_router().trel_info().has_counters());
338     TEST_ASSERT(telemetryData.wpan_border_router().trel_info().counters().trel_tx_packets() == 0);
339     TEST_ASSERT(telemetryData.wpan_border_router().trel_info().counters().trel_tx_bytes() == 0);
340 #endif
341 #if OTBR_ENABLE_BORDER_ROUTING
342     TEST_ASSERT(telemetryData.wpan_border_router().infra_link_info().name() == "lo");
343     TEST_ASSERT(telemetryData.wpan_border_router().infra_link_info().is_up());
344     TEST_ASSERT(telemetryData.wpan_border_router().infra_link_info().is_running());
345     TEST_ASSERT(!telemetryData.wpan_border_router().infra_link_info().is_multicast());
346     TEST_ASSERT(telemetryData.wpan_border_router().infra_link_info().link_local_address_count() == 0);
347     TEST_ASSERT(telemetryData.wpan_border_router().infra_link_info().unique_local_address_count() == 0);
348     TEST_ASSERT(telemetryData.wpan_border_router().infra_link_info().global_unicast_address_count() == 0);
349     TEST_ASSERT(telemetryData.wpan_border_router().infra_link_info().peer_br_count() == 0);
350     TEST_ASSERT(telemetryData.wpan_border_router().external_route_info().has_default_route_added() == false);
351     TEST_ASSERT(telemetryData.wpan_border_router().external_route_info().has_ula_route_added() == false);
352     TEST_ASSERT(telemetryData.wpan_border_router().external_route_info().has_others_route_added() == false);
353 #endif
354     TEST_ASSERT(telemetryData.wpan_border_router().mdns().service_registration_responses().success_count() > 0);
355 #if OTBR_ENABLE_NAT64
356     TEST_ASSERT(telemetryData.wpan_border_router().nat64_state().prefix_manager_state() ==
357                 threadnetwork::TelemetryData::NAT64_STATE_NOT_RUNNING);
358 #endif
359 #if OTBR_ENABLE_DHCP6_PD
360     TEST_ASSERT(telemetryData.wpan_border_router().dhcp6_pd_state() ==
361                 threadnetwork::TelemetryData::DHCP6_PD_STATE_DISABLED);
362     TEST_ASSERT(telemetryData.wpan_border_router().hashed_pd_prefix().empty());
363     TEST_ASSERT(telemetryData.wpan_border_router().pd_processed_ra_info().num_platform_ra_received() == 0);
364     TEST_ASSERT(telemetryData.wpan_border_router().pd_processed_ra_info().num_platform_pio_processed() == 0);
365     TEST_ASSERT(telemetryData.wpan_border_router().pd_processed_ra_info().last_platform_ra_msec() == 0);
366 #endif
367     TEST_ASSERT(telemetryData.wpan_rcp().rcp_interface_statistics().transferred_frames_count() > 0);
368     TEST_ASSERT(telemetryData.coex_metrics().count_tx_request() > 0);
369 #if OTBR_ENABLE_LINK_METRICS_TELEMETRY
370     TEST_ASSERT(telemetryData.low_power_metrics().link_metrics_entries_size() >= 0);
371 #endif
372 #if OTBR_ENABLE_BORDER_AGENT
373     CheckBorderAgentInfo(telemetryData.wpan_border_router().border_agent_info());
374 #endif
375 }
376 #endif
377 
CheckCapabilities(ThreadApiDBus * aApi)378 void CheckCapabilities(ThreadApiDBus *aApi)
379 {
380     std::vector<uint8_t> responseCapabilitiesBytes;
381     otbr::Capabilities   capabilities;
382 
383     TEST_ASSERT(aApi->GetCapabilities(responseCapabilitiesBytes) == OTBR_ERROR_NONE);
384     // Print TelemetryData proto in hex format.
385     printf("TelemetryData bytes in hex: ");
386     for (uint8_t byte : responseCapabilitiesBytes)
387     {
388         printf("%02x ", byte);
389     }
390     printf("\n");
391 
392     TEST_ASSERT(
393         capabilities.ParseFromString(std::string(responseCapabilitiesBytes.begin(), responseCapabilitiesBytes.end())));
394     TEST_ASSERT(capabilities.nat64() == OTBR_ENABLE_NAT64);
395 }
396 
main()397 int main()
398 {
399     DBusError                      error;
400     UniqueDBusConnection           connection;
401     std::unique_ptr<ThreadApiDBus> api;
402     uint64_t                       extpanid = 0xdead00beaf00cafe;
403     std::string                    region;
404     uint32_t                       scanDuration         = 1000; // 1s for each channel
405     bool                           stepDone             = false;
406     uint32_t                       preferredChannelMask = 0;
407 
408     dbus_error_init(&error);
409     connection = UniqueDBusConnection(dbus_bus_get(DBUS_BUS_SYSTEM, &error));
410 
411     VerifyOrExit(connection != nullptr);
412 
413     VerifyOrExit(dbus_bus_register(connection.get(), &error) == true);
414 
415     api = std::unique_ptr<ThreadApiDBus>(new ThreadApiDBus(connection.get()));
416 
417     api->AddDeviceRoleHandler(
418         [](DeviceRole aRole) { printf("Device role changed to %d\n", static_cast<uint8_t>(aRole)); });
419 
420     TEST_ASSERT(api->SetRadioRegion("US") == ClientError::ERROR_NONE);
421     TEST_ASSERT(api->GetRadioRegion(region) == ClientError::ERROR_NONE);
422     TEST_ASSERT(region == "US");
423 
424     TEST_ASSERT(api->GetPreferredChannelMask(preferredChannelMask) == ClientError::ERROR_NONE);
425 
426     api->EnergyScan(scanDuration, [&stepDone](const std::vector<EnergyScanResult> &aResult) {
427         TEST_ASSERT(!aResult.empty());
428         printf("Energy Scan:\n");
429         for (auto &result : aResult)
430         {
431             printf("channel %d rssi %d\n", result.mChannel, result.mMaxRssi);
432         }
433 
434         stepDone = true;
435     });
436 
437     CheckFeatureFlagUpdate(api.get());
438 
439     while (!stepDone)
440     {
441         dbus_connection_read_write_dispatch(connection.get(), 0);
442     }
443 
444     stepDone = false;
445 
446     api->Scan([&api, extpanid, &stepDone](const std::vector<ActiveScanResult> &aResult) {
447         LinkModeConfig       cfg        = {true, false, true};
448         std::vector<uint8_t> networkKey = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
449                                            0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
450         uint16_t             channel    = 11;
451 
452         for (auto &&result : aResult)
453         {
454             printf("channel %d rssi %d\n", result.mChannel, result.mRssi);
455         }
456 
457         api->SetLinkMode(cfg);
458         api->GetLinkMode(cfg);
459         printf("LinkMode %d %d %d\n", cfg.mRxOnWhenIdle, cfg.mDeviceType, cfg.mNetworkData);
460 
461         cfg.mDeviceType = true;
462         api->SetLinkMode(cfg);
463 
464         api->Attach("Test", 0x3456, extpanid, networkKey, {}, 1 << channel,
465                     [&api, channel, extpanid, &stepDone](ClientError aError) {
466                         printf("Attach result %d\n", static_cast<int>(aError));
467                         sleep(20);
468                         uint64_t             extpanidCheck;
469                         std::vector<uint8_t> activeDataset;
470 
471                         if (aError == OTBR_ERROR_NONE)
472                         {
473                             std::string                           name;
474                             uint64_t                              extAddress = 0;
475                             uint16_t                              rloc16     = 0xffff;
476                             std::vector<uint8_t>                  networkData;
477                             std::vector<uint8_t>                  stableNetworkData;
478                             int8_t                                rssi;
479                             int8_t                                txPower;
480                             std::vector<otbr::DBus::ChildInfo>    childTable;
481                             std::vector<otbr::DBus::NeighborInfo> neighborTable;
482                             uint32_t                              partitionId;
483                             uint16_t                              channelResult;
484 
485                             TEST_ASSERT(api->GetChannel(channelResult) == OTBR_ERROR_NONE);
486                             TEST_ASSERT(channelResult == channel);
487                             TEST_ASSERT(api->GetNetworkName(name) == OTBR_ERROR_NONE);
488                             TEST_ASSERT(api->GetExtPanId(extpanidCheck) == OTBR_ERROR_NONE);
489                             TEST_ASSERT(api->GetRloc16(rloc16) == OTBR_ERROR_NONE);
490                             TEST_ASSERT(api->GetExtendedAddress(extAddress) == OTBR_ERROR_NONE);
491                             TEST_ASSERT(api->GetNetworkData(networkData) == OTBR_ERROR_NONE);
492                             TEST_ASSERT(api->GetStableNetworkData(stableNetworkData) == OTBR_ERROR_NONE);
493                             TEST_ASSERT(api->GetChildTable(childTable) == OTBR_ERROR_NONE);
494                             TEST_ASSERT(api->GetNeighborTable(neighborTable) == OTBR_ERROR_NONE);
495                             printf("neighborTable size %zu\n", neighborTable.size());
496                             printf("childTable size %zu\n", childTable.size());
497                             TEST_ASSERT(neighborTable.size() == 1);
498                             TEST_ASSERT(childTable.size() == 1);
499                             TEST_ASSERT(api->GetPartitionId(partitionId) == OTBR_ERROR_NONE);
500                             TEST_ASSERT(api->GetInstantRssi(rssi) == OTBR_ERROR_NONE);
501                             TEST_ASSERT(api->GetRadioTxPower(txPower) == OTBR_ERROR_NONE);
502                             TEST_ASSERT(api->GetActiveDatasetTlvs(activeDataset) == OTBR_ERROR_NONE);
503                             CheckSrpServerInfo(api.get());
504                             CheckTrelInfo(api.get());
505                             CheckMdnsInfo(api.get());
506                             CheckDnssdCounters(api.get());
507                             CheckNat64(api.get());
508                             CheckEphemeralKey(api.get());
509 #if OTBR_ENABLE_TELEMETRY_DATA_API
510                             CheckTelemetryData(api.get());
511 #endif
512                             CheckCapabilities(api.get());
513                             api->FactoryReset(nullptr);
514                             TEST_ASSERT(api->GetNetworkName(name) == OTBR_ERROR_NONE);
515                             TEST_ASSERT(rloc16 != 0xffff);
516                             TEST_ASSERT(extAddress != 0);
517                             TEST_ASSERT(!networkData.empty());
518                             TEST_ASSERT(api->GetNeighborTable(neighborTable) == OTBR_ERROR_NONE);
519                             TEST_ASSERT(neighborTable.empty());
520                         }
521                         if (aError != OTBR_ERROR_NONE || extpanidCheck != extpanid)
522                         {
523                             exit(-1);
524                         }
525                         TEST_ASSERT(api->SetActiveDatasetTlvs(activeDataset) == OTBR_ERROR_NONE);
526                         api->Attach([&api, channel, extpanid, &stepDone](ClientError aErr) {
527                             uint8_t                routerId;
528                             otbr::DBus::LeaderData leaderData;
529                             uint8_t                leaderWeight;
530                             uint16_t               channelResult;
531                             uint64_t               extpanidCheck;
532                             Ip6Prefix              prefix;
533                             std::vector<TxtEntry>  updatedTxtEntries{TxtEntry{"B", {97, 98, 99}}};
534 
535                             prefix.mPrefix = {0xfd, 0xcd, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
536                             prefix.mLength = 64;
537 
538                             TEST_ASSERT(aErr == ClientError::ERROR_NONE);
539                             TEST_ASSERT(api->GetChannel(channelResult) == OTBR_ERROR_NONE);
540                             TEST_ASSERT(channelResult == channel);
541                             TEST_ASSERT(api->GetExtPanId(extpanidCheck) == OTBR_ERROR_NONE);
542                             TEST_ASSERT(extpanidCheck == extpanid);
543 
544                             TEST_ASSERT(api->GetLocalLeaderWeight(leaderWeight) == OTBR_ERROR_NONE);
545                             TEST_ASSERT(api->GetLeaderData(leaderData) == OTBR_ERROR_NONE);
546                             TEST_ASSERT(api->GetRouterId(routerId) == OTBR_ERROR_NONE);
547                             TEST_ASSERT(routerId == leaderData.mLeaderRouterId);
548 
549                             TEST_ASSERT(api->UpdateVendorMeshCopTxtEntries(updatedTxtEntries) == OTBR_ERROR_NONE);
550 
551                             CheckExternalRoute(api.get(), prefix);
552                             CheckOnMeshPrefix(api.get());
553 
554                             api->FactoryReset(nullptr);
555                             TEST_ASSERT(api->JoinerStart("ABCDEF", "", "", "", "", "", nullptr) ==
556                                         ClientError::OT_ERROR_NOT_FOUND);
557                             TEST_ASSERT(api->JoinerStart(
558                                             "ABCDEF", "", "", "", "", "", [&api, &stepDone](ClientError aJoinError) {
559                                                 DeviceRole deviceRole;
560 
561                                                 TEST_ASSERT(aJoinError == ClientError::OT_ERROR_NOT_FOUND);
562 
563                                                 api->FactoryReset(nullptr);
564                                                 api->GetDeviceRole(deviceRole);
565                                                 TEST_ASSERT(deviceRole == otbr::DBus::OTBR_DEVICE_ROLE_DISABLED);
566 
567                                                 stepDone = true;
568                                             }) == ClientError::ERROR_NONE);
569                         });
570                     });
571     });
572 
573     while (!stepDone)
574     {
575         dbus_connection_read_write_dispatch(connection.get(), 0);
576     }
577 
578 exit:
579     dbus_error_free(&error);
580     return 0;
581 };
582