• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string.h>
31 
32 #include <openthread/border_router.h>
33 #include <openthread/channel_monitor.h>
34 #include <openthread/dnssd_server.h>
35 #include <openthread/instance.h>
36 #include <openthread/joiner.h>
37 #include <openthread/link_raw.h>
38 #include <openthread/ncp.h>
39 #include <openthread/netdata.h>
40 #include <openthread/srp_server.h>
41 #include <openthread/thread_ftd.h>
42 #include <openthread/platform/radio.h>
43 
44 #include "common/byteswap.hpp"
45 #include "dbus/common/constants.hpp"
46 #include "dbus/server/dbus_agent.hpp"
47 #include "dbus/server/dbus_thread_object.hpp"
48 
49 #if OTBR_ENABLE_LEGACY
50 #include <ot-legacy-pairing-ext.h>
51 #endif
52 
53 using std::placeholders::_1;
54 using std::placeholders::_2;
55 
GetDeviceRoleName(otDeviceRole aRole)56 static std::string GetDeviceRoleName(otDeviceRole aRole)
57 {
58     std::string roleName;
59 
60     switch (aRole)
61     {
62     case OT_DEVICE_ROLE_DISABLED:
63         roleName = OTBR_ROLE_NAME_DISABLED;
64         break;
65     case OT_DEVICE_ROLE_DETACHED:
66         roleName = OTBR_ROLE_NAME_DETACHED;
67         break;
68     case OT_DEVICE_ROLE_CHILD:
69         roleName = OTBR_ROLE_NAME_CHILD;
70         break;
71     case OT_DEVICE_ROLE_ROUTER:
72         roleName = OTBR_ROLE_NAME_ROUTER;
73         break;
74     case OT_DEVICE_ROLE_LEADER:
75         roleName = OTBR_ROLE_NAME_LEADER;
76         break;
77     }
78 
79     return roleName;
80 }
81 
ConvertOpenThreadUint64(const uint8_t * aValue)82 static uint64_t ConvertOpenThreadUint64(const uint8_t *aValue)
83 {
84     uint64_t val = 0;
85 
86     for (size_t i = 0; i < sizeof(uint64_t); i++)
87     {
88         val = (val << 8) | aValue[i];
89     }
90     return val;
91 }
92 
93 namespace otbr {
94 namespace DBus {
95 
DBusThreadObject(DBusConnection * aConnection,const std::string & aInterfaceName,otbr::Ncp::ControllerOpenThread * aNcp,Mdns::Publisher * aPublisher)96 DBusThreadObject::DBusThreadObject(DBusConnection *                 aConnection,
97                                    const std::string &              aInterfaceName,
98                                    otbr::Ncp::ControllerOpenThread *aNcp,
99                                    Mdns::Publisher *                aPublisher)
100     : DBusObject(aConnection, OTBR_DBUS_OBJECT_PREFIX + aInterfaceName)
101     , mNcp(aNcp)
102     , mPublisher(aPublisher)
103 {
104 }
105 
Init(void)106 otbrError DBusThreadObject::Init(void)
107 {
108     otbrError error        = OTBR_ERROR_NONE;
109     auto      threadHelper = mNcp->GetThreadHelper();
110 
111     SuccessOrExit(error = DBusObject::Init());
112 
113     threadHelper->AddDeviceRoleHandler(std::bind(&DBusThreadObject::DeviceRoleHandler, this, _1));
114     threadHelper->AddActiveDatasetChangeHandler(std::bind(&DBusThreadObject::ActiveDatasetChangeHandler, this, _1));
115     mNcp->RegisterResetHandler(std::bind(&DBusThreadObject::NcpResetHandler, this));
116 
117     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_SCAN_METHOD,
118                    std::bind(&DBusThreadObject::ScanHandler, this, _1));
119     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ENERGY_SCAN_METHOD,
120                    std::bind(&DBusThreadObject::EnergyScanHandler, this, _1));
121     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ATTACH_METHOD,
122                    std::bind(&DBusThreadObject::AttachHandler, this, _1));
123     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_DETACH_METHOD,
124                    std::bind(&DBusThreadObject::DetachHandler, this, _1));
125     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_FACTORY_RESET_METHOD,
126                    std::bind(&DBusThreadObject::FactoryResetHandler, this, _1));
127     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_RESET_METHOD,
128                    std::bind(&DBusThreadObject::ResetHandler, this, _1));
129     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_JOINER_START_METHOD,
130                    std::bind(&DBusThreadObject::JoinerStartHandler, this, _1));
131     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_JOINER_STOP_METHOD,
132                    std::bind(&DBusThreadObject::JoinerStopHandler, this, _1));
133     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PERMIT_UNSECURE_JOIN_METHOD,
134                    std::bind(&DBusThreadObject::PermitUnsecureJoinHandler, this, _1));
135     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ADD_ON_MESH_PREFIX_METHOD,
136                    std::bind(&DBusThreadObject::AddOnMeshPrefixHandler, this, _1));
137     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_REMOVE_ON_MESH_PREFIX_METHOD,
138                    std::bind(&DBusThreadObject::RemoveOnMeshPrefixHandler, this, _1));
139     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ADD_EXTERNAL_ROUTE_METHOD,
140                    std::bind(&DBusThreadObject::AddExternalRouteHandler, this, _1));
141     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_REMOVE_EXTERNAL_ROUTE_METHOD,
142                    std::bind(&DBusThreadObject::RemoveExternalRouteHandler, this, _1));
143     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ATTACH_ALL_NODES_TO_METHOD,
144                    std::bind(&DBusThreadObject::AttachAllNodesToHandler, this, _1));
145     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_UPDATE_VENDOR_MESHCOP_TXT_METHOD,
146                    std::bind(&DBusThreadObject::UpdateMeshCopTxtHandler, this, _1));
147     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_GET_PROPERTIES_METHOD,
148                    std::bind(&DBusThreadObject::GetPropertiesHandler, this, _1));
149 
150     RegisterMethod(DBUS_INTERFACE_INTROSPECTABLE, DBUS_INTROSPECT_METHOD,
151                    std::bind(&DBusThreadObject::IntrospectHandler, this, _1));
152 
153     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_MESH_LOCAL_PREFIX,
154                                std::bind(&DBusThreadObject::SetMeshLocalPrefixHandler, this, _1));
155     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LEGACY_ULA_PREFIX,
156                                std::bind(&DBusThreadObject::SetLegacyUlaPrefixHandler, this, _1));
157     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LINK_MODE,
158                                std::bind(&DBusThreadObject::SetLinkModeHandler, this, _1));
159     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_ACTIVE_DATASET_TLVS,
160                                std::bind(&DBusThreadObject::SetActiveDatasetTlvsHandler, this, _1));
161     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RADIO_REGION,
162                                std::bind(&DBusThreadObject::SetRadioRegionHandler, this, _1));
163 
164     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LINK_MODE,
165                                std::bind(&DBusThreadObject::GetLinkModeHandler, this, _1));
166     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DEVICE_ROLE,
167                                std::bind(&DBusThreadObject::GetDeviceRoleHandler, this, _1));
168     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_NETWORK_NAME,
169                                std::bind(&DBusThreadObject::GetNetworkNameHandler, this, _1));
170 
171     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_PANID,
172                                std::bind(&DBusThreadObject::GetPanIdHandler, this, _1));
173     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_EXTPANID,
174                                std::bind(&DBusThreadObject::GetExtPanIdHandler, this, _1));
175     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_EUI64,
176                                std::bind(&DBusThreadObject::GetEui64Handler, this, _1));
177     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CHANNEL,
178                                std::bind(&DBusThreadObject::GetChannelHandler, this, _1));
179     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_NETWORK_KEY,
180                                std::bind(&DBusThreadObject::GetNetworkKeyHandler, this, _1));
181     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CCA_FAILURE_RATE,
182                                std::bind(&DBusThreadObject::GetCcaFailureRateHandler, this, _1));
183     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LINK_COUNTERS,
184                                std::bind(&DBusThreadObject::GetLinkCountersHandler, this, _1));
185     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_IP6_COUNTERS,
186                                std::bind(&DBusThreadObject::GetIp6CountersHandler, this, _1));
187     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_SUPPORTED_CHANNEL_MASK,
188                                std::bind(&DBusThreadObject::GetSupportedChannelMaskHandler, this, _1));
189     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RLOC16,
190                                std::bind(&DBusThreadObject::GetRloc16Handler, this, _1));
191     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_EXTENDED_ADDRESS,
192                                std::bind(&DBusThreadObject::GetExtendedAddressHandler, this, _1));
193     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_ROUTER_ID,
194                                std::bind(&DBusThreadObject::GetRouterIdHandler, this, _1));
195     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LEADER_DATA,
196                                std::bind(&DBusThreadObject::GetLeaderDataHandler, this, _1));
197     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_NETWORK_DATA_PRPOERTY,
198                                std::bind(&DBusThreadObject::GetNetworkDataHandler, this, _1));
199     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_STABLE_NETWORK_DATA_PRPOERTY,
200                                std::bind(&DBusThreadObject::GetStableNetworkDataHandler, this, _1));
201     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LOCAL_LEADER_WEIGHT,
202                                std::bind(&DBusThreadObject::GetLocalLeaderWeightHandler, this, _1));
203 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
204     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CHANNEL_MONITOR_SAMPLE_COUNT,
205                                std::bind(&DBusThreadObject::GetChannelMonitorSampleCountHandler, this, _1));
206     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CHANNEL_MONITOR_ALL_CHANNEL_QUALITIES,
207                                std::bind(&DBusThreadObject::GetChannelMonitorAllChannelQualities, this, _1));
208 #endif
209     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CHILD_TABLE,
210                                std::bind(&DBusThreadObject::GetChildTableHandler, this, _1));
211     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_NEIGHBOR_TABLE_PROEPRTY,
212                                std::bind(&DBusThreadObject::GetNeighborTableHandler, this, _1));
213     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_PARTITION_ID_PROEPRTY,
214                                std::bind(&DBusThreadObject::GetPartitionIDHandler, this, _1));
215     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_INSTANT_RSSI,
216                                std::bind(&DBusThreadObject::GetInstantRssiHandler, this, _1));
217     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RADIO_TX_POWER,
218                                std::bind(&DBusThreadObject::GetRadioTxPowerHandler, this, _1));
219     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_EXTERNAL_ROUTES,
220                                std::bind(&DBusThreadObject::GetExternalRoutesHandler, this, _1));
221     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_ON_MESH_PREFIXES,
222                                std::bind(&DBusThreadObject::GetOnMeshPrefixesHandler, this, _1));
223     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_ACTIVE_DATASET_TLVS,
224                                std::bind(&DBusThreadObject::GetActiveDatasetTlvsHandler, this, _1));
225     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RADIO_REGION,
226                                std::bind(&DBusThreadObject::GetRadioRegionHandler, this, _1));
227     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_SRP_SERVER_INFO,
228                                std::bind(&DBusThreadObject::GetSrpServerInfoHandler, this, _1));
229     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_MDNS_TELEMETRY_INFO,
230                                std::bind(&DBusThreadObject::GetMdnsTelemetryInfoHandler, this, _1));
231     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DNSSD_COUNTERS,
232                                std::bind(&DBusThreadObject::GetDnssdCountersHandler, this, _1));
233     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_OT_HOST_VERSION,
234                                std::bind(&DBusThreadObject::GetOtHostVersionHandler, this, _1));
235     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_OT_RCP_VERSION,
236                                std::bind(&DBusThreadObject::GetOtRcpVersionHandler, this, _1));
237     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_THREAD_VERSION,
238                                std::bind(&DBusThreadObject::GetThreadVersionHandler, this, _1));
239     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RADIO_SPINEL_METRICS,
240                                std::bind(&DBusThreadObject::GetRadioSpinelMetricsHandler, this, _1));
241     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RCP_INTERFACE_METRICS,
242                                std::bind(&DBusThreadObject::GetRcpInterfaceMetricsHandler, this, _1));
243     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_UPTIME,
244                                std::bind(&DBusThreadObject::GetUptimeHandler, this, _1));
245     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RADIO_COEX_METRICS,
246                                std::bind(&DBusThreadObject::GetRadioCoexMetrics, this, _1));
247 
248     SuccessOrExit(error = Signal(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_SIGNAL_READY, std::make_tuple()));
249 
250 exit:
251     return error;
252 }
253 
DeviceRoleHandler(otDeviceRole aDeviceRole)254 void DBusThreadObject::DeviceRoleHandler(otDeviceRole aDeviceRole)
255 {
256     SignalPropertyChanged(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DEVICE_ROLE, GetDeviceRoleName(aDeviceRole));
257 }
258 
NcpResetHandler(void)259 void DBusThreadObject::NcpResetHandler(void)
260 {
261     mNcp->GetThreadHelper()->AddDeviceRoleHandler(std::bind(&DBusThreadObject::DeviceRoleHandler, this, _1));
262     mNcp->GetThreadHelper()->AddActiveDatasetChangeHandler(
263         std::bind(&DBusThreadObject::ActiveDatasetChangeHandler, this, _1));
264     SignalPropertyChanged(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DEVICE_ROLE,
265                           GetDeviceRoleName(OT_DEVICE_ROLE_DISABLED));
266 }
267 
ScanHandler(DBusRequest & aRequest)268 void DBusThreadObject::ScanHandler(DBusRequest &aRequest)
269 {
270     auto threadHelper = mNcp->GetThreadHelper();
271     threadHelper->Scan(std::bind(&DBusThreadObject::ReplyScanResult, this, aRequest, _1, _2));
272 }
273 
ReplyScanResult(DBusRequest & aRequest,otError aError,const std::vector<otActiveScanResult> & aResult)274 void DBusThreadObject::ReplyScanResult(DBusRequest &                          aRequest,
275                                        otError                                aError,
276                                        const std::vector<otActiveScanResult> &aResult)
277 {
278     std::vector<ActiveScanResult> results;
279 
280     if (aError != OT_ERROR_NONE)
281     {
282         aRequest.ReplyOtResult(aError);
283     }
284     else
285     {
286         for (const auto &r : aResult)
287         {
288             ActiveScanResult result;
289 
290             result.mExtAddress = ConvertOpenThreadUint64(r.mExtAddress.m8);
291             result.mPanId      = r.mPanId;
292             result.mChannel    = r.mChannel;
293             result.mRssi       = r.mRssi;
294             result.mLqi        = r.mLqi;
295 
296             results.emplace_back(result);
297         }
298 
299         aRequest.Reply(std::tie(results));
300     }
301 }
302 
EnergyScanHandler(DBusRequest & aRequest)303 void DBusThreadObject::EnergyScanHandler(DBusRequest &aRequest)
304 {
305     otError  error        = OT_ERROR_NONE;
306     auto     threadHelper = mNcp->GetThreadHelper();
307     uint32_t scanDuration;
308 
309     auto args = std::tie(scanDuration);
310 
311     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
312     threadHelper->EnergyScan(scanDuration, std::bind(&DBusThreadObject::ReplyEnergyScanResult, this, aRequest, _1, _2));
313 
314 exit:
315     if (error != OT_ERROR_NONE)
316     {
317         aRequest.ReplyOtResult(error);
318     }
319 }
320 
ReplyEnergyScanResult(DBusRequest & aRequest,otError aError,const std::vector<otEnergyScanResult> & aResult)321 void DBusThreadObject::ReplyEnergyScanResult(DBusRequest &                          aRequest,
322                                              otError                                aError,
323                                              const std::vector<otEnergyScanResult> &aResult)
324 {
325     std::vector<EnergyScanResult> results;
326 
327     if (aError != OT_ERROR_NONE)
328     {
329         aRequest.ReplyOtResult(aError);
330     }
331     else
332     {
333         for (const auto &r : aResult)
334         {
335             EnergyScanResult result;
336 
337             result.mChannel = r.mChannel;
338             result.mMaxRssi = r.mMaxRssi;
339 
340             results.emplace_back(result);
341         }
342 
343         aRequest.Reply(std::tie(results));
344     }
345 }
346 
AttachHandler(DBusRequest & aRequest)347 void DBusThreadObject::AttachHandler(DBusRequest &aRequest)
348 {
349     auto                 threadHelper = mNcp->GetThreadHelper();
350     std::string          name;
351     uint16_t             panid;
352     uint64_t             extPanId;
353     std::vector<uint8_t> networkKey;
354     std::vector<uint8_t> pskc;
355     uint32_t             channelMask;
356 
357     auto args = std::tie(networkKey, panid, name, extPanId, pskc, channelMask);
358 
359     if (IsDBusMessageEmpty(*aRequest.GetMessage()))
360     {
361         threadHelper->Attach([aRequest](otError aError, int64_t aAttachDelayMs) mutable {
362             OT_UNUSED_VARIABLE(aAttachDelayMs);
363 
364             aRequest.ReplyOtResult(aError);
365         });
366     }
367     else if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
368     {
369         aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
370     }
371     else
372     {
373         threadHelper->Attach(name, panid, extPanId, networkKey, pskc, channelMask,
374                              [aRequest](otError aError, int64_t aAttachDelayMs) mutable {
375                                  OT_UNUSED_VARIABLE(aAttachDelayMs);
376 
377                                  aRequest.ReplyOtResult(aError);
378                              });
379     }
380 }
381 
AttachAllNodesToHandler(DBusRequest & aRequest)382 void DBusThreadObject::AttachAllNodesToHandler(DBusRequest &aRequest)
383 {
384     std::vector<uint8_t> dataset;
385     otError              error = OT_ERROR_NONE;
386 
387     auto args = std::tie(dataset);
388 
389     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
390 
391     mNcp->GetThreadHelper()->AttachAllNodesTo(dataset, [aRequest](otError error, int64_t aAttachDelayMs) mutable {
392         aRequest.ReplyOtResult<int64_t>(error, aAttachDelayMs);
393     });
394 
395 exit:
396     if (error != OT_ERROR_NONE)
397     {
398         aRequest.ReplyOtResult(error);
399     }
400 }
401 
DetachHandler(DBusRequest & aRequest)402 void DBusThreadObject::DetachHandler(DBusRequest &aRequest)
403 {
404     aRequest.ReplyOtResult(mNcp->GetThreadHelper()->Detach());
405 }
406 
FactoryResetHandler(DBusRequest & aRequest)407 void DBusThreadObject::FactoryResetHandler(DBusRequest &aRequest)
408 {
409     otError error = OT_ERROR_NONE;
410 
411     SuccessOrExit(error = mNcp->GetThreadHelper()->Detach());
412     SuccessOrExit(otInstanceErasePersistentInfo(mNcp->GetThreadHelper()->GetInstance()));
413     mNcp->Reset();
414 
415 exit:
416     aRequest.ReplyOtResult(error);
417 }
418 
ResetHandler(DBusRequest & aRequest)419 void DBusThreadObject::ResetHandler(DBusRequest &aRequest)
420 {
421     mNcp->Reset();
422     aRequest.ReplyOtResult(OT_ERROR_NONE);
423 }
424 
JoinerStartHandler(DBusRequest & aRequest)425 void DBusThreadObject::JoinerStartHandler(DBusRequest &aRequest)
426 {
427     auto        threadHelper = mNcp->GetThreadHelper();
428     std::string pskd, provisionUrl, vendorName, vendorModel, vendorSwVersion, vendorData;
429     auto        args = std::tie(pskd, provisionUrl, vendorName, vendorModel, vendorSwVersion, vendorData);
430 
431     if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
432     {
433         aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
434     }
435     else
436     {
437         threadHelper->JoinerStart(pskd, provisionUrl, vendorName, vendorModel, vendorSwVersion, vendorData,
438                                   [aRequest](otError aError) mutable { aRequest.ReplyOtResult(aError); });
439     }
440 }
441 
JoinerStopHandler(DBusRequest & aRequest)442 void DBusThreadObject::JoinerStopHandler(DBusRequest &aRequest)
443 {
444     auto threadHelper = mNcp->GetThreadHelper();
445 
446     otJoinerStop(threadHelper->GetInstance());
447     aRequest.ReplyOtResult(OT_ERROR_NONE);
448 }
449 
PermitUnsecureJoinHandler(DBusRequest & aRequest)450 void DBusThreadObject::PermitUnsecureJoinHandler(DBusRequest &aRequest)
451 {
452 #ifdef OTBR_ENABLE_UNSECURE_JOIN
453     auto     threadHelper = mNcp->GetThreadHelper();
454     uint16_t port;
455     uint32_t timeout;
456     auto     args = std::tie(port, timeout);
457 
458     if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
459     {
460         aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
461     }
462     else
463     {
464         aRequest.ReplyOtResult(threadHelper->PermitUnsecureJoin(port, timeout));
465     }
466 #else
467     aRequest.ReplyOtResult(OT_ERROR_NOT_IMPLEMENTED);
468 #endif
469 }
470 
AddOnMeshPrefixHandler(DBusRequest & aRequest)471 void DBusThreadObject::AddOnMeshPrefixHandler(DBusRequest &aRequest)
472 {
473     auto                 threadHelper = mNcp->GetThreadHelper();
474     OnMeshPrefix         onMeshPrefix;
475     auto                 args  = std::tie(onMeshPrefix);
476     otError              error = OT_ERROR_NONE;
477     otBorderRouterConfig config;
478 
479     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
480 
481     // size is guaranteed by parsing
482     std::copy(onMeshPrefix.mPrefix.mPrefix.begin(), onMeshPrefix.mPrefix.mPrefix.end(),
483               &config.mPrefix.mPrefix.mFields.m8[0]);
484     config.mPrefix.mLength = onMeshPrefix.mPrefix.mLength;
485     config.mPreference     = onMeshPrefix.mPreference;
486     config.mSlaac          = onMeshPrefix.mSlaac;
487     config.mDhcp           = onMeshPrefix.mDhcp;
488     config.mConfigure      = onMeshPrefix.mConfigure;
489     config.mDefaultRoute   = onMeshPrefix.mDefaultRoute;
490     config.mOnMesh         = onMeshPrefix.mOnMesh;
491     config.mStable         = onMeshPrefix.mStable;
492 
493     SuccessOrExit(error = otBorderRouterAddOnMeshPrefix(threadHelper->GetInstance(), &config));
494     SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
495 
496 exit:
497     aRequest.ReplyOtResult(error);
498 }
499 
RemoveOnMeshPrefixHandler(DBusRequest & aRequest)500 void DBusThreadObject::RemoveOnMeshPrefixHandler(DBusRequest &aRequest)
501 {
502     auto        threadHelper = mNcp->GetThreadHelper();
503     Ip6Prefix   onMeshPrefix;
504     auto        args  = std::tie(onMeshPrefix);
505     otError     error = OT_ERROR_NONE;
506     otIp6Prefix prefix;
507 
508     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
509     // size is guaranteed by parsing
510     std::copy(onMeshPrefix.mPrefix.begin(), onMeshPrefix.mPrefix.end(), &prefix.mPrefix.mFields.m8[0]);
511     prefix.mLength = onMeshPrefix.mLength;
512 
513     SuccessOrExit(error = otBorderRouterRemoveOnMeshPrefix(threadHelper->GetInstance(), &prefix));
514     SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
515 
516 exit:
517     aRequest.ReplyOtResult(error);
518 }
519 
AddExternalRouteHandler(DBusRequest & aRequest)520 void DBusThreadObject::AddExternalRouteHandler(DBusRequest &aRequest)
521 {
522     auto                  threadHelper = mNcp->GetThreadHelper();
523     ExternalRoute         route;
524     auto                  args  = std::tie(route);
525     otError               error = OT_ERROR_NONE;
526     otExternalRouteConfig otRoute;
527     otIp6Prefix &         prefix = otRoute.mPrefix;
528 
529     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
530 
531     // size is guaranteed by parsing
532     std::copy(route.mPrefix.mPrefix.begin(), route.mPrefix.mPrefix.end(), &prefix.mPrefix.mFields.m8[0]);
533     prefix.mLength      = route.mPrefix.mLength;
534     otRoute.mPreference = route.mPreference;
535     otRoute.mStable     = route.mStable;
536 
537     SuccessOrExit(error = otBorderRouterAddRoute(threadHelper->GetInstance(), &otRoute));
538     if (route.mStable)
539     {
540         SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
541     }
542 
543 exit:
544     aRequest.ReplyOtResult(error);
545 }
546 
RemoveExternalRouteHandler(DBusRequest & aRequest)547 void DBusThreadObject::RemoveExternalRouteHandler(DBusRequest &aRequest)
548 {
549     auto        threadHelper = mNcp->GetThreadHelper();
550     Ip6Prefix   routePrefix;
551     auto        args  = std::tie(routePrefix);
552     otError     error = OT_ERROR_NONE;
553     otIp6Prefix prefix;
554 
555     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
556 
557     // size is guaranteed by parsing
558     std::copy(routePrefix.mPrefix.begin(), routePrefix.mPrefix.end(), &prefix.mPrefix.mFields.m8[0]);
559     prefix.mLength = routePrefix.mLength;
560 
561     SuccessOrExit(error = otBorderRouterRemoveRoute(threadHelper->GetInstance(), &prefix));
562     SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
563 
564 exit:
565     aRequest.ReplyOtResult(error);
566 }
567 
IntrospectHandler(DBusRequest & aRequest)568 void DBusThreadObject::IntrospectHandler(DBusRequest &aRequest)
569 {
570     std::string xmlString(
571 #include "dbus/server/introspect.hpp"
572     );
573 
574     aRequest.Reply(std::tie(xmlString));
575 }
576 
SetMeshLocalPrefixHandler(DBusMessageIter & aIter)577 otError DBusThreadObject::SetMeshLocalPrefixHandler(DBusMessageIter &aIter)
578 {
579     auto                                      threadHelper = mNcp->GetThreadHelper();
580     otMeshLocalPrefix                         prefix;
581     std::array<uint8_t, OTBR_IP6_PREFIX_SIZE> data{};
582     otError                                   error = OT_ERROR_NONE;
583 
584     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
585     memcpy(&prefix.m8, &data.front(), sizeof(prefix.m8));
586     error = otThreadSetMeshLocalPrefix(threadHelper->GetInstance(), &prefix);
587 
588 exit:
589     return error;
590 }
591 
SetLegacyUlaPrefixHandler(DBusMessageIter & aIter)592 otError DBusThreadObject::SetLegacyUlaPrefixHandler(DBusMessageIter &aIter)
593 {
594 #if OTBR_ENABLE_LEGACY
595     std::array<uint8_t, OTBR_IP6_PREFIX_SIZE> data;
596     otError                                   error = OT_ERROR_NONE;
597 
598     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
599     otSetLegacyUlaPrefix(&data[0]);
600 
601 exit:
602     return error;
603 #else
604     OTBR_UNUSED_VARIABLE(aIter);
605 
606     return OT_ERROR_NOT_IMPLEMENTED;
607 #endif // OTBR_ENABLE_LEGACY
608 }
609 
SetLinkModeHandler(DBusMessageIter & aIter)610 otError DBusThreadObject::SetLinkModeHandler(DBusMessageIter &aIter)
611 {
612     auto             threadHelper = mNcp->GetThreadHelper();
613     LinkModeConfig   cfg;
614     otLinkModeConfig otCfg;
615     otError          error = OT_ERROR_NONE;
616 
617     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, cfg) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
618     otCfg.mDeviceType   = cfg.mDeviceType;
619     otCfg.mNetworkData  = cfg.mNetworkData;
620     otCfg.mRxOnWhenIdle = cfg.mRxOnWhenIdle;
621     error               = otThreadSetLinkMode(threadHelper->GetInstance(), otCfg);
622 
623 exit:
624     return error;
625 }
626 
GetLinkModeHandler(DBusMessageIter & aIter)627 otError DBusThreadObject::GetLinkModeHandler(DBusMessageIter &aIter)
628 {
629     auto             threadHelper = mNcp->GetThreadHelper();
630     otLinkModeConfig otCfg        = otThreadGetLinkMode(threadHelper->GetInstance());
631     LinkModeConfig   cfg;
632     otError          error = OT_ERROR_NONE;
633 
634     cfg.mDeviceType   = otCfg.mDeviceType;
635     cfg.mNetworkData  = otCfg.mNetworkData;
636     cfg.mRxOnWhenIdle = otCfg.mRxOnWhenIdle;
637 
638     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, cfg) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
639 
640 exit:
641     return error;
642 }
643 
GetDeviceRoleHandler(DBusMessageIter & aIter)644 otError DBusThreadObject::GetDeviceRoleHandler(DBusMessageIter &aIter)
645 {
646     auto         threadHelper = mNcp->GetThreadHelper();
647     otDeviceRole role         = otThreadGetDeviceRole(threadHelper->GetInstance());
648     std::string  roleName     = GetDeviceRoleName(role);
649     otError      error        = OT_ERROR_NONE;
650 
651     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, roleName) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
652 
653 exit:
654     return error;
655 }
656 
GetNetworkNameHandler(DBusMessageIter & aIter)657 otError DBusThreadObject::GetNetworkNameHandler(DBusMessageIter &aIter)
658 {
659     auto        threadHelper = mNcp->GetThreadHelper();
660     std::string networkName  = otThreadGetNetworkName(threadHelper->GetInstance());
661     otError     error        = OT_ERROR_NONE;
662 
663     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, networkName) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
664 
665 exit:
666     return error;
667 }
668 
GetPanIdHandler(DBusMessageIter & aIter)669 otError DBusThreadObject::GetPanIdHandler(DBusMessageIter &aIter)
670 {
671     auto     threadHelper = mNcp->GetThreadHelper();
672     uint16_t panId        = otLinkGetPanId(threadHelper->GetInstance());
673     otError  error        = OT_ERROR_NONE;
674 
675     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, panId) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
676 
677 exit:
678     return error;
679 }
680 
GetExtPanIdHandler(DBusMessageIter & aIter)681 otError DBusThreadObject::GetExtPanIdHandler(DBusMessageIter &aIter)
682 {
683     auto                   threadHelper = mNcp->GetThreadHelper();
684     const otExtendedPanId *extPanId     = otThreadGetExtendedPanId(threadHelper->GetInstance());
685     uint64_t               extPanIdVal;
686     otError                error = OT_ERROR_NONE;
687 
688     extPanIdVal = ConvertOpenThreadUint64(extPanId->m8);
689 
690     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, extPanIdVal) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
691 
692 exit:
693     return error;
694 }
695 
GetChannelHandler(DBusMessageIter & aIter)696 otError DBusThreadObject::GetChannelHandler(DBusMessageIter &aIter)
697 {
698     auto     threadHelper = mNcp->GetThreadHelper();
699     uint16_t channel      = otLinkGetChannel(threadHelper->GetInstance());
700     otError  error        = OT_ERROR_NONE;
701 
702     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, channel) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
703 
704 exit:
705     return error;
706 }
707 
GetNetworkKeyHandler(DBusMessageIter & aIter)708 otError DBusThreadObject::GetNetworkKeyHandler(DBusMessageIter &aIter)
709 {
710     auto         threadHelper = mNcp->GetThreadHelper();
711     otNetworkKey networkKey;
712     otError      error = OT_ERROR_NONE;
713 
714     otThreadGetNetworkKey(threadHelper->GetInstance(), &networkKey);
715     std::vector<uint8_t> keyVal(networkKey.m8, networkKey.m8 + sizeof(networkKey.m8));
716     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, keyVal) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
717 
718 exit:
719     return error;
720 }
721 
GetCcaFailureRateHandler(DBusMessageIter & aIter)722 otError DBusThreadObject::GetCcaFailureRateHandler(DBusMessageIter &aIter)
723 {
724     auto     threadHelper = mNcp->GetThreadHelper();
725     uint16_t failureRate  = otLinkGetCcaFailureRate(threadHelper->GetInstance());
726     otError  error        = OT_ERROR_NONE;
727 
728     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, failureRate) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
729 
730 exit:
731     return error;
732 }
733 
GetLinkCountersHandler(DBusMessageIter & aIter)734 otError DBusThreadObject::GetLinkCountersHandler(DBusMessageIter &aIter)
735 {
736     auto                 threadHelper = mNcp->GetThreadHelper();
737     const otMacCounters *otCounters   = otLinkGetCounters(threadHelper->GetInstance());
738     MacCounters          counters;
739     otError              error = OT_ERROR_NONE;
740 
741     counters.mTxTotal              = otCounters->mTxTotal;
742     counters.mTxUnicast            = otCounters->mTxUnicast;
743     counters.mTxBroadcast          = otCounters->mTxBroadcast;
744     counters.mTxAckRequested       = otCounters->mTxAckRequested;
745     counters.mTxAcked              = otCounters->mTxAcked;
746     counters.mTxNoAckRequested     = otCounters->mTxNoAckRequested;
747     counters.mTxData               = otCounters->mTxData;
748     counters.mTxDataPoll           = otCounters->mTxDataPoll;
749     counters.mTxBeacon             = otCounters->mTxBeacon;
750     counters.mTxBeaconRequest      = otCounters->mTxBeaconRequest;
751     counters.mTxOther              = otCounters->mTxOther;
752     counters.mTxRetry              = otCounters->mTxRetry;
753     counters.mTxErrCca             = otCounters->mTxErrCca;
754     counters.mTxErrAbort           = otCounters->mTxErrAbort;
755     counters.mTxErrBusyChannel     = otCounters->mTxErrBusyChannel;
756     counters.mRxTotal              = otCounters->mRxTotal;
757     counters.mRxUnicast            = otCounters->mTxUnicast;
758     counters.mRxBroadcast          = otCounters->mRxBroadcast;
759     counters.mRxData               = otCounters->mRxData;
760     counters.mRxDataPoll           = otCounters->mTxDataPoll;
761     counters.mRxBeacon             = otCounters->mRxBeacon;
762     counters.mRxBeaconRequest      = otCounters->mRxBeaconRequest;
763     counters.mRxOther              = otCounters->mRxOther;
764     counters.mRxAddressFiltered    = otCounters->mRxAddressFiltered;
765     counters.mRxDestAddrFiltered   = otCounters->mRxDestAddrFiltered;
766     counters.mRxDuplicated         = otCounters->mRxDuplicated;
767     counters.mRxErrNoFrame         = otCounters->mRxErrNoFrame;
768     counters.mRxErrUnknownNeighbor = otCounters->mRxErrUnknownNeighbor;
769     counters.mRxErrInvalidSrcAddr  = otCounters->mRxErrInvalidSrcAddr;
770     counters.mRxErrSec             = otCounters->mRxErrSec;
771     counters.mRxErrFcs             = otCounters->mRxErrFcs;
772     counters.mRxErrOther           = otCounters->mRxErrOther;
773 
774     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, counters) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
775 
776 exit:
777     return error;
778 }
779 
GetIp6CountersHandler(DBusMessageIter & aIter)780 otError DBusThreadObject::GetIp6CountersHandler(DBusMessageIter &aIter)
781 {
782     auto                threadHelper = mNcp->GetThreadHelper();
783     const otIpCounters *otCounters   = otThreadGetIp6Counters(threadHelper->GetInstance());
784     IpCounters          counters;
785     otError             error = OT_ERROR_NONE;
786 
787     counters.mTxSuccess = otCounters->mTxSuccess;
788     counters.mTxFailure = otCounters->mTxFailure;
789     counters.mRxSuccess = otCounters->mRxSuccess;
790     counters.mRxFailure = otCounters->mRxFailure;
791 
792     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, counters) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
793 
794 exit:
795     return error;
796 }
797 
GetSupportedChannelMaskHandler(DBusMessageIter & aIter)798 otError DBusThreadObject::GetSupportedChannelMaskHandler(DBusMessageIter &aIter)
799 {
800     auto     threadHelper = mNcp->GetThreadHelper();
801     uint32_t channelMask  = otLinkGetSupportedChannelMask(threadHelper->GetInstance());
802     otError  error        = OT_ERROR_NONE;
803 
804     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, channelMask) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
805 
806 exit:
807     return error;
808 }
809 
GetRloc16Handler(DBusMessageIter & aIter)810 otError DBusThreadObject::GetRloc16Handler(DBusMessageIter &aIter)
811 {
812     auto     threadHelper = mNcp->GetThreadHelper();
813     otError  error        = OT_ERROR_NONE;
814     uint16_t rloc16       = otThreadGetRloc16(threadHelper->GetInstance());
815 
816     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, rloc16) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
817 
818 exit:
819     return error;
820 }
821 
GetExtendedAddressHandler(DBusMessageIter & aIter)822 otError DBusThreadObject::GetExtendedAddressHandler(DBusMessageIter &aIter)
823 {
824     auto                threadHelper    = mNcp->GetThreadHelper();
825     otError             error           = OT_ERROR_NONE;
826     const otExtAddress *addr            = otLinkGetExtendedAddress(threadHelper->GetInstance());
827     uint64_t            extendedAddress = ConvertOpenThreadUint64(addr->m8);
828 
829     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, extendedAddress) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
830 
831 exit:
832     return error;
833 }
834 
GetRouterIdHandler(DBusMessageIter & aIter)835 otError DBusThreadObject::GetRouterIdHandler(DBusMessageIter &aIter)
836 {
837     auto         threadHelper = mNcp->GetThreadHelper();
838     otError      error        = OT_ERROR_NONE;
839     uint16_t     rloc16       = otThreadGetRloc16(threadHelper->GetInstance());
840     otRouterInfo info;
841 
842     VerifyOrExit(otThreadGetRouterInfo(threadHelper->GetInstance(), rloc16, &info) == OT_ERROR_NONE,
843                  error = OT_ERROR_INVALID_STATE);
844     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, info.mRouterId) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
845 
846 exit:
847     return error;
848 }
849 
GetLeaderDataHandler(DBusMessageIter & aIter)850 otError DBusThreadObject::GetLeaderDataHandler(DBusMessageIter &aIter)
851 {
852     auto                threadHelper = mNcp->GetThreadHelper();
853     otError             error        = OT_ERROR_NONE;
854     struct otLeaderData data;
855     LeaderData          leaderData;
856 
857     SuccessOrExit(error = otThreadGetLeaderData(threadHelper->GetInstance(), &data));
858     leaderData.mPartitionId       = data.mPartitionId;
859     leaderData.mWeighting         = data.mWeighting;
860     leaderData.mDataVersion       = data.mDataVersion;
861     leaderData.mStableDataVersion = data.mStableDataVersion;
862     leaderData.mLeaderRouterId    = data.mLeaderRouterId;
863     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, leaderData) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
864 
865 exit:
866     return error;
867 }
868 
GetNetworkDataHandler(DBusMessageIter & aIter)869 otError DBusThreadObject::GetNetworkDataHandler(DBusMessageIter &aIter)
870 {
871     static constexpr size_t kNetworkDataMaxSize = 255;
872     auto                    threadHelper        = mNcp->GetThreadHelper();
873     otError                 error               = OT_ERROR_NONE;
874     uint8_t                 data[kNetworkDataMaxSize];
875     uint8_t                 len = sizeof(data);
876     std::vector<uint8_t>    networkData;
877 
878     SuccessOrExit(error = otNetDataGet(threadHelper->GetInstance(), /*stable=*/false, data, &len));
879     networkData = std::vector<uint8_t>(&data[0], &data[len]);
880     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, networkData) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
881 
882 exit:
883     return error;
884 }
885 
GetStableNetworkDataHandler(DBusMessageIter & aIter)886 otError DBusThreadObject::GetStableNetworkDataHandler(DBusMessageIter &aIter)
887 {
888     static constexpr size_t kNetworkDataMaxSize = 255;
889     auto                    threadHelper        = mNcp->GetThreadHelper();
890     otError                 error               = OT_ERROR_NONE;
891     uint8_t                 data[kNetworkDataMaxSize];
892     uint8_t                 len = sizeof(data);
893     std::vector<uint8_t>    networkData;
894 
895     SuccessOrExit(error = otNetDataGet(threadHelper->GetInstance(), /*stable=*/true, data, &len));
896     networkData = std::vector<uint8_t>(&data[0], &data[len]);
897     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, networkData) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
898 
899 exit:
900     return error;
901 }
902 
GetLocalLeaderWeightHandler(DBusMessageIter & aIter)903 otError DBusThreadObject::GetLocalLeaderWeightHandler(DBusMessageIter &aIter)
904 {
905     auto    threadHelper = mNcp->GetThreadHelper();
906     otError error        = OT_ERROR_NONE;
907     uint8_t weight       = otThreadGetLocalLeaderWeight(threadHelper->GetInstance());
908 
909     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, weight) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
910 
911 exit:
912     return error;
913 }
914 
GetChannelMonitorSampleCountHandler(DBusMessageIter & aIter)915 otError DBusThreadObject::GetChannelMonitorSampleCountHandler(DBusMessageIter &aIter)
916 {
917 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
918     auto     threadHelper = mNcp->GetThreadHelper();
919     otError  error        = OT_ERROR_NONE;
920     uint32_t cnt          = otChannelMonitorGetSampleCount(threadHelper->GetInstance());
921 
922     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, cnt) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
923 
924 exit:
925     return error;
926 #else  // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
927     OTBR_UNUSED_VARIABLE(aIter);
928     return OT_ERROR_NOT_IMPLEMENTED;
929 #endif // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
930 }
931 
GetChannelMonitorAllChannelQualities(DBusMessageIter & aIter)932 otError DBusThreadObject::GetChannelMonitorAllChannelQualities(DBusMessageIter &aIter)
933 {
934 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
935     auto                        threadHelper = mNcp->GetThreadHelper();
936     otError                     error        = OT_ERROR_NONE;
937     uint32_t                    channelMask  = otLinkGetSupportedChannelMask(threadHelper->GetInstance());
938     constexpr uint8_t           kNumChannels = sizeof(channelMask) * 8; // 8 bit per byte
939     std::vector<ChannelQuality> quality;
940 
941     for (uint8_t i = 0; i < kNumChannels; i++)
942     {
943         if (channelMask & (1U << i))
944         {
945             uint16_t occupancy = otChannelMonitorGetChannelOccupancy(threadHelper->GetInstance(), i);
946 
947             quality.emplace_back(ChannelQuality{i, occupancy});
948         }
949     }
950 
951     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, quality) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
952 
953 exit:
954     return error;
955 #else  // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
956     OTBR_UNUSED_VARIABLE(aIter);
957     return OT_ERROR_NOT_IMPLEMENTED;
958 #endif // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
959 }
960 
GetChildTableHandler(DBusMessageIter & aIter)961 otError DBusThreadObject::GetChildTableHandler(DBusMessageIter &aIter)
962 {
963     auto                   threadHelper = mNcp->GetThreadHelper();
964     otError                error        = OT_ERROR_NONE;
965     uint16_t               childIndex   = 0;
966     otChildInfo            childInfo;
967     std::vector<ChildInfo> childTable;
968 
969     while (otThreadGetChildInfoByIndex(threadHelper->GetInstance(), childIndex, &childInfo) == OT_ERROR_NONE)
970     {
971         ChildInfo info;
972 
973         info.mExtAddress         = ConvertOpenThreadUint64(childInfo.mExtAddress.m8);
974         info.mTimeout            = childInfo.mTimeout;
975         info.mAge                = childInfo.mAge;
976         info.mChildId            = childInfo.mChildId;
977         info.mNetworkDataVersion = childInfo.mNetworkDataVersion;
978         info.mLinkQualityIn      = childInfo.mLinkQualityIn;
979         info.mAverageRssi        = childInfo.mAverageRssi;
980         info.mLastRssi           = childInfo.mLastRssi;
981         info.mFrameErrorRate     = childInfo.mFrameErrorRate;
982         info.mMessageErrorRate   = childInfo.mMessageErrorRate;
983         info.mRxOnWhenIdle       = childInfo.mRxOnWhenIdle;
984         info.mFullThreadDevice   = childInfo.mFullThreadDevice;
985         info.mFullNetworkData    = childInfo.mFullNetworkData;
986         info.mIsStateRestoring   = childInfo.mIsStateRestoring;
987         childTable.push_back(info);
988         childIndex++;
989     }
990 
991     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, childTable) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
992 
993 exit:
994     return error;
995 }
996 
GetNeighborTableHandler(DBusMessageIter & aIter)997 otError DBusThreadObject::GetNeighborTableHandler(DBusMessageIter &aIter)
998 {
999     auto                      threadHelper = mNcp->GetThreadHelper();
1000     otError                   error        = OT_ERROR_NONE;
1001     otNeighborInfoIterator    iter         = OT_NEIGHBOR_INFO_ITERATOR_INIT;
1002     otNeighborInfo            neighborInfo;
1003     std::vector<NeighborInfo> neighborTable;
1004 
1005     while (otThreadGetNextNeighborInfo(threadHelper->GetInstance(), &iter, &neighborInfo) == OT_ERROR_NONE)
1006     {
1007         NeighborInfo info;
1008 
1009         info.mExtAddress       = ConvertOpenThreadUint64(neighborInfo.mExtAddress.m8);
1010         info.mAge              = neighborInfo.mAge;
1011         info.mRloc16           = neighborInfo.mRloc16;
1012         info.mLinkFrameCounter = neighborInfo.mLinkFrameCounter;
1013         info.mMleFrameCounter  = neighborInfo.mMleFrameCounter;
1014         info.mLinkQualityIn    = neighborInfo.mLinkQualityIn;
1015         info.mAverageRssi      = neighborInfo.mAverageRssi;
1016         info.mLastRssi         = neighborInfo.mLastRssi;
1017         info.mFrameErrorRate   = neighborInfo.mFrameErrorRate;
1018         info.mMessageErrorRate = neighborInfo.mMessageErrorRate;
1019         info.mRxOnWhenIdle     = neighborInfo.mRxOnWhenIdle;
1020         info.mFullThreadDevice = neighborInfo.mFullThreadDevice;
1021         info.mFullNetworkData  = neighborInfo.mFullNetworkData;
1022         info.mIsChild          = neighborInfo.mIsChild;
1023         neighborTable.push_back(info);
1024     }
1025 
1026     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, neighborTable) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1027 
1028 exit:
1029     return error;
1030 }
1031 
GetPartitionIDHandler(DBusMessageIter & aIter)1032 otError DBusThreadObject::GetPartitionIDHandler(DBusMessageIter &aIter)
1033 {
1034     auto     threadHelper = mNcp->GetThreadHelper();
1035     otError  error        = OT_ERROR_NONE;
1036     uint32_t partitionId  = otThreadGetPartitionId(threadHelper->GetInstance());
1037 
1038     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, partitionId) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1039 
1040 exit:
1041     return error;
1042 }
1043 
GetInstantRssiHandler(DBusMessageIter & aIter)1044 otError DBusThreadObject::GetInstantRssiHandler(DBusMessageIter &aIter)
1045 {
1046     auto    threadHelper = mNcp->GetThreadHelper();
1047     otError error        = OT_ERROR_NONE;
1048     int8_t  rssi         = otPlatRadioGetRssi(threadHelper->GetInstance());
1049 
1050     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, rssi) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1051 
1052 exit:
1053     return error;
1054 }
1055 
GetRadioTxPowerHandler(DBusMessageIter & aIter)1056 otError DBusThreadObject::GetRadioTxPowerHandler(DBusMessageIter &aIter)
1057 {
1058     auto    threadHelper = mNcp->GetThreadHelper();
1059     otError error        = OT_ERROR_NONE;
1060     int8_t  txPower;
1061 
1062     SuccessOrExit(error = otPlatRadioGetTransmitPower(threadHelper->GetInstance(), &txPower));
1063 
1064     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, txPower) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1065 
1066 exit:
1067     return error;
1068 }
1069 
GetExternalRoutesHandler(DBusMessageIter & aIter)1070 otError DBusThreadObject::GetExternalRoutesHandler(DBusMessageIter &aIter)
1071 {
1072     auto                       threadHelper = mNcp->GetThreadHelper();
1073     otError                    error        = OT_ERROR_NONE;
1074     otNetworkDataIterator      iter         = OT_NETWORK_DATA_ITERATOR_INIT;
1075     otExternalRouteConfig      config;
1076     std::vector<ExternalRoute> externalRouteTable;
1077 
1078     while (otNetDataGetNextRoute(threadHelper->GetInstance(), &iter, &config) == OT_ERROR_NONE)
1079     {
1080         ExternalRoute route;
1081 
1082         route.mPrefix.mPrefix      = std::vector<uint8_t>(&config.mPrefix.mPrefix.mFields.m8[0],
1083                                                      &config.mPrefix.mPrefix.mFields.m8[OTBR_IP6_PREFIX_SIZE]);
1084         route.mPrefix.mLength      = config.mPrefix.mLength;
1085         route.mRloc16              = config.mRloc16;
1086         route.mPreference          = config.mPreference;
1087         route.mStable              = config.mStable;
1088         route.mNextHopIsThisDevice = config.mNextHopIsThisDevice;
1089         externalRouteTable.push_back(route);
1090     }
1091 
1092     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, externalRouteTable) == OTBR_ERROR_NONE,
1093                  error = OT_ERROR_INVALID_ARGS);
1094 
1095 exit:
1096     return error;
1097 }
1098 
GetOnMeshPrefixesHandler(DBusMessageIter & aIter)1099 otError DBusThreadObject::GetOnMeshPrefixesHandler(DBusMessageIter &aIter)
1100 {
1101     auto                      threadHelper = mNcp->GetThreadHelper();
1102     otError                   error        = OT_ERROR_NONE;
1103     otNetworkDataIterator     iter         = OT_NETWORK_DATA_ITERATOR_INIT;
1104     otBorderRouterConfig      config;
1105     std::vector<OnMeshPrefix> onMeshPrefixes;
1106 
1107     while (otNetDataGetNextOnMeshPrefix(threadHelper->GetInstance(), &iter, &config) == OT_ERROR_NONE)
1108     {
1109         OnMeshPrefix prefix;
1110 
1111         prefix.mPrefix.mPrefix = std::vector<uint8_t>(&config.mPrefix.mPrefix.mFields.m8[0],
1112                                                       &config.mPrefix.mPrefix.mFields.m8[OTBR_IP6_PREFIX_SIZE]);
1113         prefix.mPrefix.mLength = config.mPrefix.mLength;
1114         prefix.mRloc16         = config.mRloc16;
1115         prefix.mPreference     = config.mPreference;
1116         prefix.mPreferred      = config.mPreferred;
1117         prefix.mSlaac          = config.mSlaac;
1118         prefix.mDhcp           = config.mDhcp;
1119         prefix.mConfigure      = config.mConfigure;
1120         prefix.mDefaultRoute   = config.mDefaultRoute;
1121         prefix.mOnMesh         = config.mOnMesh;
1122         prefix.mStable         = config.mStable;
1123         prefix.mNdDns          = config.mNdDns;
1124         prefix.mDp             = config.mDp;
1125         onMeshPrefixes.push_back(prefix);
1126     }
1127     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, onMeshPrefixes) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1128 
1129 exit:
1130     return error;
1131 }
1132 
SetActiveDatasetTlvsHandler(DBusMessageIter & aIter)1133 otError DBusThreadObject::SetActiveDatasetTlvsHandler(DBusMessageIter &aIter)
1134 {
1135     auto                     threadHelper = mNcp->GetThreadHelper();
1136     std::vector<uint8_t>     data;
1137     otOperationalDatasetTlvs datasetTlvs;
1138     otError                  error = OT_ERROR_NONE;
1139 
1140     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1141     VerifyOrExit(data.size() <= sizeof(datasetTlvs.mTlvs));
1142     std::copy(std::begin(data), std::end(data), std::begin(datasetTlvs.mTlvs));
1143     datasetTlvs.mLength = data.size();
1144     error               = otDatasetSetActiveTlvs(threadHelper->GetInstance(), &datasetTlvs);
1145 
1146 exit:
1147     return error;
1148 }
1149 
GetActiveDatasetTlvsHandler(DBusMessageIter & aIter)1150 otError DBusThreadObject::GetActiveDatasetTlvsHandler(DBusMessageIter &aIter)
1151 {
1152     auto                     threadHelper = mNcp->GetThreadHelper();
1153     otError                  error        = OT_ERROR_NONE;
1154     std::vector<uint8_t>     data;
1155     otOperationalDatasetTlvs datasetTlvs;
1156 
1157     SuccessOrExit(error = otDatasetGetActiveTlvs(threadHelper->GetInstance(), &datasetTlvs));
1158     data = std::vector<uint8_t>{std::begin(datasetTlvs.mTlvs), std::begin(datasetTlvs.mTlvs) + datasetTlvs.mLength};
1159 
1160     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1161 
1162 exit:
1163     return error;
1164 }
1165 
SetRadioRegionHandler(DBusMessageIter & aIter)1166 otError DBusThreadObject::SetRadioRegionHandler(DBusMessageIter &aIter)
1167 {
1168     auto        threadHelper = mNcp->GetThreadHelper();
1169     std::string radioRegion;
1170     uint16_t    regionCode;
1171     otError     error = OT_ERROR_NONE;
1172 
1173     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, radioRegion) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1174     VerifyOrExit(radioRegion.size() == sizeof(uint16_t), error = OT_ERROR_INVALID_ARGS);
1175     regionCode = radioRegion[0] << 8 | radioRegion[1];
1176 
1177     error = otPlatRadioSetRegion(threadHelper->GetInstance(), regionCode);
1178 
1179 exit:
1180     return error;
1181 }
1182 
UpdateMeshCopTxtHandler(DBusRequest & aRequest)1183 void DBusThreadObject::UpdateMeshCopTxtHandler(DBusRequest &aRequest)
1184 {
1185     auto                                        threadHelper = mNcp->GetThreadHelper();
1186     otError                                     error        = OT_ERROR_NONE;
1187     std::map<std::string, std::vector<uint8_t>> update;
1188     std::vector<TxtEntry>                       updatedTxtEntries;
1189     auto                                        args = std::tie(updatedTxtEntries);
1190 
1191     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1192     for (const auto &entry : updatedTxtEntries)
1193     {
1194         update[entry.mKey] = entry.mValue;
1195     }
1196     for (const auto reservedKey : {"rv", "tv", "sb", "nn", "xp", "at", "pt", "dn", "sq", "bb", "omr"})
1197     {
1198         VerifyOrExit(!update.count(reservedKey), error = OT_ERROR_INVALID_ARGS);
1199     }
1200     threadHelper->OnUpdateMeshCopTxt(std::move(update));
1201 
1202 exit:
1203     aRequest.ReplyOtResult(error);
1204 }
1205 
GetRadioRegionHandler(DBusMessageIter & aIter)1206 otError DBusThreadObject::GetRadioRegionHandler(DBusMessageIter &aIter)
1207 {
1208     auto        threadHelper = mNcp->GetThreadHelper();
1209     otError     error        = OT_ERROR_NONE;
1210     std::string radioRegion;
1211     uint16_t    regionCode;
1212 
1213     SuccessOrExit(error = otPlatRadioGetRegion(threadHelper->GetInstance(), &regionCode));
1214     radioRegion.resize(sizeof(uint16_t), '\0');
1215     radioRegion[0] = static_cast<char>((regionCode >> 8) & 0xff);
1216     radioRegion[1] = static_cast<char>(regionCode & 0xff);
1217 
1218     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, radioRegion) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1219 
1220 exit:
1221     return error;
1222 }
1223 
GetSrpServerInfoHandler(DBusMessageIter & aIter)1224 otError DBusThreadObject::GetSrpServerInfoHandler(DBusMessageIter &aIter)
1225 {
1226 #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
1227     auto                               threadHelper = mNcp->GetThreadHelper();
1228     auto                               instance     = threadHelper->GetInstance();
1229     otError                            error        = OT_ERROR_NONE;
1230     SrpServerInfo                      srpServerInfo{};
1231     otSrpServerLeaseInfo               leaseInfo;
1232     const otSrpServerHost *            host             = nullptr;
1233     const otSrpServerResponseCounters *responseCounters = otSrpServerGetResponseCounters(instance);
1234 
1235     srpServerInfo.mState       = SrpServerState(static_cast<uint8_t>(otSrpServerGetState(instance)));
1236     srpServerInfo.mPort        = otSrpServerGetPort(instance);
1237     srpServerInfo.mAddressMode = SrpServerAddressMode(static_cast<uint8_t>(otSrpServerGetAddressMode(instance)));
1238 
1239     while ((host = otSrpServerGetNextHost(instance, host)))
1240     {
1241         const otSrpServerService *service = nullptr;
1242 
1243         if (otSrpServerHostIsDeleted(host))
1244         {
1245             ++srpServerInfo.mHosts.mDeletedCount;
1246         }
1247         else
1248         {
1249             ++srpServerInfo.mHosts.mFreshCount;
1250             otSrpServerHostGetLeaseInfo(host, &leaseInfo);
1251             srpServerInfo.mHosts.mLeaseTimeTotal += leaseInfo.mLease;
1252             srpServerInfo.mHosts.mKeyLeaseTimeTotal += leaseInfo.mKeyLease;
1253             srpServerInfo.mHosts.mRemainingLeaseTimeTotal += leaseInfo.mRemainingLease;
1254             srpServerInfo.mHosts.mRemainingKeyLeaseTimeTotal += leaseInfo.mRemainingKeyLease;
1255         }
1256 
1257         while ((service = otSrpServerHostGetNextService(host, service)))
1258         {
1259             if (otSrpServerServiceIsDeleted(service))
1260             {
1261                 ++srpServerInfo.mServices.mDeletedCount;
1262             }
1263             else
1264             {
1265                 ++srpServerInfo.mServices.mFreshCount;
1266                 otSrpServerServiceGetLeaseInfo(service, &leaseInfo);
1267                 srpServerInfo.mServices.mLeaseTimeTotal += leaseInfo.mLease;
1268                 srpServerInfo.mServices.mKeyLeaseTimeTotal += leaseInfo.mKeyLease;
1269                 srpServerInfo.mServices.mRemainingLeaseTimeTotal += leaseInfo.mRemainingLease;
1270                 srpServerInfo.mServices.mRemainingKeyLeaseTimeTotal += leaseInfo.mRemainingKeyLease;
1271             }
1272         }
1273     }
1274 
1275     srpServerInfo.mResponseCounters.mSuccess       = responseCounters->mSuccess;
1276     srpServerInfo.mResponseCounters.mServerFailure = responseCounters->mServerFailure;
1277     srpServerInfo.mResponseCounters.mFormatError   = responseCounters->mFormatError;
1278     srpServerInfo.mResponseCounters.mNameExists    = responseCounters->mNameExists;
1279     srpServerInfo.mResponseCounters.mRefused       = responseCounters->mRefused;
1280     srpServerInfo.mResponseCounters.mOther         = responseCounters->mOther;
1281 
1282     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, srpServerInfo) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1283 
1284 exit:
1285     return error;
1286 #else  // OTBR_ENABLE_SRP_ADVERTISING_PROXY
1287     OTBR_UNUSED_VARIABLE(aIter);
1288 
1289     return OT_ERROR_NOT_IMPLEMENTED;
1290 #endif // OTBR_ENABLE_SRP_ADVERTISING_PROXY
1291 }
1292 
GetMdnsTelemetryInfoHandler(DBusMessageIter & aIter)1293 otError DBusThreadObject::GetMdnsTelemetryInfoHandler(DBusMessageIter &aIter)
1294 {
1295     otError error = OT_ERROR_NONE;
1296 
1297     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, mPublisher->GetMdnsTelemetryInfo()) == OTBR_ERROR_NONE,
1298                  error = OT_ERROR_INVALID_ARGS);
1299 exit:
1300     return error;
1301 }
1302 
GetDnssdCountersHandler(DBusMessageIter & aIter)1303 otError DBusThreadObject::GetDnssdCountersHandler(DBusMessageIter &aIter)
1304 {
1305 #if OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
1306     auto            threadHelper = mNcp->GetThreadHelper();
1307     auto            instance     = threadHelper->GetInstance();
1308     otError         error        = OT_ERROR_NONE;
1309     DnssdCounters   dnssdCounters;
1310     otDnssdCounters otDnssdCounters = *otDnssdGetCounters(instance);
1311 
1312     dnssdCounters.mSuccessResponse        = otDnssdCounters.mSuccessResponse;
1313     dnssdCounters.mServerFailureResponse  = otDnssdCounters.mServerFailureResponse;
1314     dnssdCounters.mFormatErrorResponse    = otDnssdCounters.mFormatErrorResponse;
1315     dnssdCounters.mNameErrorResponse      = otDnssdCounters.mNameErrorResponse;
1316     dnssdCounters.mNotImplementedResponse = otDnssdCounters.mNotImplementedResponse;
1317     dnssdCounters.mOtherResponse          = otDnssdCounters.mOtherResponse;
1318 
1319     dnssdCounters.mResolvedBySrp = otDnssdCounters.mResolvedBySrp;
1320 
1321     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, dnssdCounters) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1322 
1323 exit:
1324     return error;
1325 #else  // OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
1326     OTBR_UNUSED_VARIABLE(aIter);
1327 
1328     return OT_ERROR_NOT_IMPLEMENTED;
1329 #endif // OTBR_ENABLE_DNSSD_DISCOVERY_PROXY
1330 }
1331 
GetPropertiesHandler(DBusRequest & aRequest)1332 void DBusThreadObject::GetPropertiesHandler(DBusRequest &aRequest)
1333 {
1334     UniqueDBusMessage        reply(dbus_message_new_method_return(aRequest.GetMessage()));
1335     DBusMessageIter          iter;
1336     DBusMessageIter          replyIter;
1337     DBusMessageIter          replySubIter;
1338     std::vector<std::string> propertyNames;
1339     otError                  error = OT_ERROR_NONE;
1340 
1341     VerifyOrExit(reply != nullptr, error = OT_ERROR_NO_BUFS);
1342     VerifyOrExit(dbus_message_iter_init(aRequest.GetMessage(), &iter), error = OT_ERROR_FAILED);
1343     VerifyOrExit(DBusMessageExtract(&iter, propertyNames) == OTBR_ERROR_NONE, error = OT_ERROR_PARSE);
1344 
1345     dbus_message_iter_init_append(reply.get(), &replyIter);
1346     VerifyOrExit(
1347         dbus_message_iter_open_container(&replyIter, DBUS_TYPE_ARRAY, DBUS_TYPE_VARIANT_AS_STRING, &replySubIter),
1348         error = OT_ERROR_NO_BUFS);
1349 
1350     for (const std::string &propertyName : propertyNames)
1351     {
1352         auto handlerIter = mGetPropertyHandlers.find(propertyName);
1353 
1354         otbrLogInfo("GetPropertiesHandler getting property: %s", propertyName.c_str());
1355         VerifyOrExit(handlerIter != mGetPropertyHandlers.end(), error = OT_ERROR_NOT_FOUND);
1356 
1357         SuccessOrExit(error = handlerIter->second(replySubIter));
1358     }
1359 
1360     VerifyOrExit(dbus_message_iter_close_container(&replyIter, &replySubIter), error = OT_ERROR_NO_BUFS);
1361 
1362 exit:
1363     if (error == OT_ERROR_NONE)
1364     {
1365         dbus_connection_send(aRequest.GetConnection(), reply.get(), nullptr);
1366     }
1367     else
1368     {
1369         aRequest.ReplyOtResult(error);
1370     }
1371 }
1372 
RegisterGetPropertyHandler(const std::string & aInterfaceName,const std::string & aPropertyName,const PropertyHandlerType & aHandler)1373 void DBusThreadObject::RegisterGetPropertyHandler(const std::string &        aInterfaceName,
1374                                                   const std::string &        aPropertyName,
1375                                                   const PropertyHandlerType &aHandler)
1376 {
1377     DBusObject::RegisterGetPropertyHandler(aInterfaceName, aPropertyName, aHandler);
1378     mGetPropertyHandlers[aPropertyName] = aHandler;
1379 }
1380 
GetOtHostVersionHandler(DBusMessageIter & aIter)1381 otError DBusThreadObject::GetOtHostVersionHandler(DBusMessageIter &aIter)
1382 {
1383     otError     error   = OT_ERROR_NONE;
1384     std::string version = otGetVersionString();
1385 
1386     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, version) == OTBR_ERROR_NONE, error = OT_ERROR_FAILED);
1387 
1388 exit:
1389     return error;
1390 }
1391 
GetEui64Handler(DBusMessageIter & aIter)1392 otError DBusThreadObject::GetEui64Handler(DBusMessageIter &aIter)
1393 {
1394     auto         threadHelper = mNcp->GetThreadHelper();
1395     otError      error        = OT_ERROR_NONE;
1396     otExtAddress extAddr;
1397     uint64_t     eui64;
1398 
1399     otLinkGetFactoryAssignedIeeeEui64(threadHelper->GetInstance(), &extAddr);
1400 
1401     eui64 = ConvertOpenThreadUint64(extAddr.m8);
1402 
1403     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, eui64) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1404 
1405 exit:
1406     return error;
1407 }
1408 
GetOtRcpVersionHandler(DBusMessageIter & aIter)1409 otError DBusThreadObject::GetOtRcpVersionHandler(DBusMessageIter &aIter)
1410 {
1411     auto        threadHelper = mNcp->GetThreadHelper();
1412     otError     error        = OT_ERROR_NONE;
1413     std::string version      = otGetRadioVersionString(threadHelper->GetInstance());
1414 
1415     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, version) == OTBR_ERROR_NONE, error = OT_ERROR_FAILED);
1416 
1417 exit:
1418     return error;
1419 }
1420 
GetThreadVersionHandler(DBusMessageIter & aIter)1421 otError DBusThreadObject::GetThreadVersionHandler(DBusMessageIter &aIter)
1422 {
1423     otError error = OT_ERROR_NONE;
1424 
1425     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, otThreadGetVersion()) == OTBR_ERROR_NONE, error = OT_ERROR_FAILED);
1426 
1427 exit:
1428     return error;
1429 }
1430 
GetRadioSpinelMetricsHandler(DBusMessageIter & aIter)1431 otError DBusThreadObject::GetRadioSpinelMetricsHandler(DBusMessageIter &aIter)
1432 {
1433     otError              error = OT_ERROR_NONE;
1434     RadioSpinelMetrics   radioSpinelMetrics;
1435     otRadioSpinelMetrics otRadioSpinelMetrics = *otSysGetRadioSpinelMetrics();
1436 
1437     radioSpinelMetrics.mRcpTimeoutCount         = otRadioSpinelMetrics.mRcpTimeoutCount;
1438     radioSpinelMetrics.mRcpUnexpectedResetCount = otRadioSpinelMetrics.mRcpUnexpectedResetCount;
1439     radioSpinelMetrics.mRcpRestorationCount     = otRadioSpinelMetrics.mRcpRestorationCount;
1440     radioSpinelMetrics.mSpinelParseErrorCount   = otRadioSpinelMetrics.mSpinelParseErrorCount;
1441 
1442     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, radioSpinelMetrics) == OTBR_ERROR_NONE,
1443                  error = OT_ERROR_INVALID_ARGS);
1444 
1445 exit:
1446     return error;
1447 }
1448 
GetRcpInterfaceMetricsHandler(DBusMessageIter & aIter)1449 otError DBusThreadObject::GetRcpInterfaceMetricsHandler(DBusMessageIter &aIter)
1450 {
1451     otError               error = OT_ERROR_NONE;
1452     RcpInterfaceMetrics   rcpInterfaceMetrics;
1453     otRcpInterfaceMetrics otRcpInterfaceMetrics = *otSysGetRcpInterfaceMetrics();
1454 
1455     rcpInterfaceMetrics.mRcpInterfaceType             = otRcpInterfaceMetrics.mRcpInterfaceType;
1456     rcpInterfaceMetrics.mTransferredFrameCount        = otRcpInterfaceMetrics.mTransferredFrameCount;
1457     rcpInterfaceMetrics.mTransferredValidFrameCount   = otRcpInterfaceMetrics.mTransferredValidFrameCount;
1458     rcpInterfaceMetrics.mTransferredGarbageFrameCount = otRcpInterfaceMetrics.mTransferredGarbageFrameCount;
1459     rcpInterfaceMetrics.mRxFrameCount                 = otRcpInterfaceMetrics.mRxFrameCount;
1460     rcpInterfaceMetrics.mRxFrameByteCount             = otRcpInterfaceMetrics.mRxFrameByteCount;
1461     rcpInterfaceMetrics.mTxFrameCount                 = otRcpInterfaceMetrics.mTxFrameCount;
1462     rcpInterfaceMetrics.mTxFrameByteCount             = otRcpInterfaceMetrics.mTxFrameByteCount;
1463 
1464     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, rcpInterfaceMetrics) == OTBR_ERROR_NONE,
1465                  error = OT_ERROR_INVALID_ARGS);
1466 
1467 exit:
1468     return error;
1469 }
1470 
GetUptimeHandler(DBusMessageIter & aIter)1471 otError DBusThreadObject::GetUptimeHandler(DBusMessageIter &aIter)
1472 {
1473     otError error = OT_ERROR_NONE;
1474 
1475     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, otInstanceGetUptime(mNcp->GetThreadHelper()->GetInstance())) ==
1476                      OTBR_ERROR_NONE,
1477                  error = OT_ERROR_INVALID_ARGS);
1478 
1479 exit:
1480     return error;
1481 }
1482 
GetRadioCoexMetrics(DBusMessageIter & aIter)1483 otError DBusThreadObject::GetRadioCoexMetrics(DBusMessageIter &aIter)
1484 {
1485     otError            error = OT_ERROR_NONE;
1486     otRadioCoexMetrics otRadioCoexMetrics;
1487     RadioCoexMetrics   radioCoexMetrics;
1488 
1489     SuccessOrExit(error = otPlatRadioGetCoexMetrics(mNcp->GetInstance(), &otRadioCoexMetrics));
1490 
1491     radioCoexMetrics.mNumGrantGlitch                     = otRadioCoexMetrics.mNumGrantGlitch;
1492     radioCoexMetrics.mNumTxRequest                       = otRadioCoexMetrics.mNumTxRequest;
1493     radioCoexMetrics.mNumTxGrantImmediate                = otRadioCoexMetrics.mNumTxGrantImmediate;
1494     radioCoexMetrics.mNumTxGrantWait                     = otRadioCoexMetrics.mNumTxGrantWait;
1495     radioCoexMetrics.mNumTxGrantWaitActivated            = otRadioCoexMetrics.mNumTxGrantWaitActivated;
1496     radioCoexMetrics.mNumTxGrantWaitTimeout              = otRadioCoexMetrics.mNumTxGrantWaitTimeout;
1497     radioCoexMetrics.mNumTxGrantDeactivatedDuringRequest = otRadioCoexMetrics.mNumTxGrantDeactivatedDuringRequest;
1498     radioCoexMetrics.mNumTxDelayedGrant                  = otRadioCoexMetrics.mNumTxDelayedGrant;
1499     radioCoexMetrics.mAvgTxRequestToGrantTime            = otRadioCoexMetrics.mAvgTxRequestToGrantTime;
1500     radioCoexMetrics.mNumRxRequest                       = otRadioCoexMetrics.mNumRxRequest;
1501     radioCoexMetrics.mNumRxGrantImmediate                = otRadioCoexMetrics.mNumRxGrantImmediate;
1502     radioCoexMetrics.mNumRxGrantWait                     = otRadioCoexMetrics.mNumRxGrantWait;
1503     radioCoexMetrics.mNumRxGrantWaitActivated            = otRadioCoexMetrics.mNumRxGrantWaitActivated;
1504     radioCoexMetrics.mNumRxGrantWaitTimeout              = otRadioCoexMetrics.mNumRxGrantWaitTimeout;
1505     radioCoexMetrics.mNumRxGrantDeactivatedDuringRequest = otRadioCoexMetrics.mNumRxGrantDeactivatedDuringRequest;
1506     radioCoexMetrics.mNumRxDelayedGrant                  = otRadioCoexMetrics.mNumRxDelayedGrant;
1507     radioCoexMetrics.mAvgRxRequestToGrantTime            = otRadioCoexMetrics.mAvgRxRequestToGrantTime;
1508     radioCoexMetrics.mNumRxGrantNone                     = otRadioCoexMetrics.mNumRxGrantNone;
1509     radioCoexMetrics.mStopped                            = otRadioCoexMetrics.mStopped;
1510 
1511     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, radioCoexMetrics) == OTBR_ERROR_NONE,
1512                  error = OT_ERROR_INVALID_ARGS);
1513 
1514 exit:
1515     return error;
1516 }
1517 
ActiveDatasetChangeHandler(const otOperationalDatasetTlvs & aDatasetTlvs)1518 void DBusThreadObject::ActiveDatasetChangeHandler(const otOperationalDatasetTlvs &aDatasetTlvs)
1519 {
1520     std::vector<uint8_t> value(aDatasetTlvs.mLength);
1521     std::copy(aDatasetTlvs.mTlvs, aDatasetTlvs.mTlvs + aDatasetTlvs.mLength, value.begin());
1522     SignalPropertyChanged(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_ACTIVE_DATASET_TLVS, value);
1523 }
1524 
1525 static_assert(OTBR_SRP_SERVER_STATE_DISABLED == static_cast<uint8_t>(OT_SRP_SERVER_STATE_DISABLED),
1526               "OTBR_SRP_SERVER_STATE_DISABLED value is incorrect");
1527 static_assert(OTBR_SRP_SERVER_STATE_RUNNING == static_cast<uint8_t>(OT_SRP_SERVER_STATE_RUNNING),
1528               "OTBR_SRP_SERVER_STATE_RUNNING value is incorrect");
1529 static_assert(OTBR_SRP_SERVER_STATE_STOPPED == static_cast<uint8_t>(OT_SRP_SERVER_STATE_STOPPED),
1530               "OTBR_SRP_SERVER_STATE_STOPPED value is incorrect");
1531 
1532 static_assert(OTBR_SRP_SERVER_ADDRESS_MODE_UNICAST == static_cast<uint8_t>(OT_SRP_SERVER_ADDRESS_MODE_UNICAST),
1533               "OTBR_SRP_SERVER_ADDRESS_MODE_UNICAST value is incorrect");
1534 static_assert(OTBR_SRP_SERVER_ADDRESS_MODE_ANYCAST == static_cast<uint8_t>(OT_SRP_SERVER_ADDRESS_MODE_ANYCAST),
1535               "OTBR_SRP_SERVER_ADDRESS_MODE_ANYCAST value is incorrect");
1536 
1537 } // namespace DBus
1538 } // namespace otbr
1539