Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / src / dbus / server / dbus_thread_object.cpp
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/instance.h>
35 #include <openthread/joiner.h>
36 #include <openthread/link_raw.h>
37 #include <openthread/ncp.h>
38 #include <openthread/netdata.h>
39 #include <openthread/thread_ftd.h>
40 #include <openthread/platform/radio.h>
41
42 #include "common/byteswap.hpp"
43 #include "dbus/common/constants.hpp"
44 #include "dbus/server/dbus_agent.hpp"
45 #include "dbus/server/dbus_thread_object.hpp"
46
47 #if OTBR_ENABLE_LEGACY
48 #include <ot-legacy-pairing-ext.h>
49 #endif
50
51 using std::placeholders::_1;
52 using std::placeholders::_2;
53
54 static std::string GetDeviceRoleName(otDeviceRole aRole)
55 {
56     std::string roleName;
57
58     switch (aRole)
59     {
60     case OT_DEVICE_ROLE_DISABLED:
61         roleName = OTBR_ROLE_NAME_DISABLED;
62         break;
63     case OT_DEVICE_ROLE_DETACHED:
64         roleName = OTBR_ROLE_NAME_DETACHED;
65         break;
66     case OT_DEVICE_ROLE_CHILD:
67         roleName = OTBR_ROLE_NAME_CHILD;
68         break;
69     case OT_DEVICE_ROLE_ROUTER:
70         roleName = OTBR_ROLE_NAME_ROUTER;
71         break;
72     case OT_DEVICE_ROLE_LEADER:
73         roleName = OTBR_ROLE_NAME_LEADER;
74         break;
75     }
76
77     return roleName;
78 }
79
80 static uint64_t ConvertOpenThreadUint64(const uint8_t *aValue)
81 {
82     uint64_t val = 0;
83
84     for (size_t i = 0; i < sizeof(uint64_t); i++)
85     {
86         val = (val << 8) | aValue[i];
87     }
88     return val;
89 }
90
91 namespace otbr {
92 namespace DBus {
93
94 DBusThreadObject::DBusThreadObject(DBusConnection *                 aConnection,
95                                    const std::string &              aInterfaceName,
96                                    otbr::Ncp::ControllerOpenThread *aNcp)
97     : DBusObject(aConnection, OTBR_DBUS_OBJECT_PREFIX + aInterfaceName)
98     , mNcp(aNcp)
99 {
100 }
101
102 otbrError DBusThreadObject::Init(void)
103 {
104     otbrError error        = DBusObject::Init();
105     auto      threadHelper = mNcp->GetThreadHelper();
106
107     threadHelper->AddDeviceRoleHandler(std::bind(&DBusThreadObject::DeviceRoleHandler, this, _1));
108     mNcp->RegisterResetHandler(std::bind(&DBusThreadObject::NcpResetHandler, this));
109
110     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_SCAN_METHOD,
111                    std::bind(&DBusThreadObject::ScanHandler, this, _1));
112     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ATTACH_METHOD,
113                    std::bind(&DBusThreadObject::AttachHandler, this, _1));
114     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_FACTORY_RESET_METHOD,
115                    std::bind(&DBusThreadObject::FactoryResetHandler, this, _1));
116     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_RESET_METHOD,
117                    std::bind(&DBusThreadObject::ResetHandler, this, _1));
118     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_JOINER_START_METHOD,
119                    std::bind(&DBusThreadObject::JoinerStartHandler, this, _1));
120     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_JOINER_STOP_METHOD,
121                    std::bind(&DBusThreadObject::JoinerStopHandler, this, _1));
122     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PERMIT_UNSECURE_JOIN_METHOD,
123                    std::bind(&DBusThreadObject::PermitUnsecureJoinHandler, this, _1));
124     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ADD_ON_MESH_PREFIX_METHOD,
125                    std::bind(&DBusThreadObject::AddOnMeshPrefixHandler, this, _1));
126     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_REMOVE_ON_MESH_PREFIX_METHOD,
127                    std::bind(&DBusThreadObject::RemoveOnMeshPrefixHandler, this, _1));
128     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_ADD_EXTERNAL_ROUTE_METHOD,
129                    std::bind(&DBusThreadObject::AddExternalRouteHandler, this, _1));
130     RegisterMethod(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_REMOVE_EXTERNAL_ROUTE_METHOD,
131                    std::bind(&DBusThreadObject::RemoveExternalRouteHandler, this, _1));
132
133     RegisterMethod(DBUS_INTERFACE_INTROSPECTABLE, DBUS_INTROSPECT_METHOD,
134                    std::bind(&DBusThreadObject::IntrospectHandler, this, _1));
135
136     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_MESH_LOCAL_PREFIX,
137                                std::bind(&DBusThreadObject::SetMeshLocalPrefixHandler, this, _1));
138     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LEGACY_ULA_PREFIX,
139                                std::bind(&DBusThreadObject::SetLegacyUlaPrefixHandler, this, _1));
140     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LINK_MODE,
141                                std::bind(&DBusThreadObject::SetLinkModeHandler, this, _1));
142     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_ACTIVE_DATASET_TLVS,
143                                std::bind(&DBusThreadObject::SetActiveDatasetTlvsHandler, this, _1));
144     RegisterSetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RADIO_REGION,
145                                std::bind(&DBusThreadObject::SetRadioRegionHandler, this, _1));
146
147     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LINK_MODE,
148                                std::bind(&DBusThreadObject::GetLinkModeHandler, this, _1));
149     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DEVICE_ROLE,
150                                std::bind(&DBusThreadObject::GetDeviceRoleHandler, this, _1));
151     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_NETWORK_NAME,
152                                std::bind(&DBusThreadObject::GetNetworkNameHandler, this, _1));
153
154     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_PANID,
155                                std::bind(&DBusThreadObject::GetPanIdHandler, this, _1));
156     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_EXTPANID,
157                                std::bind(&DBusThreadObject::GetExtPanIdHandler, this, _1));
158     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CHANNEL,
159                                std::bind(&DBusThreadObject::GetChannelHandler, this, _1));
160     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_MASTER_KEY,
161                                std::bind(&DBusThreadObject::GetMasterKeyHandler, this, _1));
162     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CCA_FAILURE_RATE,
163                                std::bind(&DBusThreadObject::GetCcaFailureRateHandler, this, _1));
164     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LINK_COUNTERS,
165                                std::bind(&DBusThreadObject::GetLinkCountersHandler, this, _1));
166     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_IP6_COUNTERS,
167                                std::bind(&DBusThreadObject::GetIp6CountersHandler, this, _1));
168     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_SUPPORTED_CHANNEL_MASK,
169                                std::bind(&DBusThreadObject::GetSupportedChannelMaskHandler, this, _1));
170     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RLOC16,
171                                std::bind(&DBusThreadObject::GetRloc16Handler, this, _1));
172     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_EXTENDED_ADDRESS,
173                                std::bind(&DBusThreadObject::GetExtendedAddressHandler, this, _1));
174     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_ROUTER_ID,
175                                std::bind(&DBusThreadObject::GetRouterIdHandler, this, _1));
176     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LEADER_DATA,
177                                std::bind(&DBusThreadObject::GetLeaderDataHandler, this, _1));
178     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_NETWORK_DATA_PRPOERTY,
179                                std::bind(&DBusThreadObject::GetNetworkDataHandler, this, _1));
180     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_STABLE_NETWORK_DATA_PRPOERTY,
181                                std::bind(&DBusThreadObject::GetStableNetworkDataHandler, this, _1));
182     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_LOCAL_LEADER_WEIGHT,
183                                std::bind(&DBusThreadObject::GetLocalLeaderWeightHandler, this, _1));
184     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CHANNEL_MONITOR_SAMPLE_COUNT,
185                                std::bind(&DBusThreadObject::GetChannelMonitorSampleCountHandler, this, _1));
186     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CHANNEL_MONITOR_ALL_CHANNEL_QUALITIES,
187                                std::bind(&DBusThreadObject::GetChannelMonitorAllChannelQualities, this, _1));
188     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_CHILD_TABLE,
189                                std::bind(&DBusThreadObject::GetChildTableHandler, this, _1));
190     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_NEIGHBOR_TABLE_PROEPRTY,
191                                std::bind(&DBusThreadObject::GetNeighborTableHandler, this, _1));
192     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_PARTITION_ID_PROEPRTY,
193                                std::bind(&DBusThreadObject::GetPartitionIDHandler, this, _1));
194     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_INSTANT_RSSI,
195                                std::bind(&DBusThreadObject::GetInstantRssiHandler, this, _1));
196     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RADIO_TX_POWER,
197                                std::bind(&DBusThreadObject::GetRadioTxPowerHandler, this, _1));
198     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_EXTERNAL_ROUTES,
199                                std::bind(&DBusThreadObject::GetExternalRoutesHandler, this, _1));
200     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_ACTIVE_DATASET_TLVS,
201                                std::bind(&DBusThreadObject::GetActiveDatasetTlvsHandler, this, _1));
202     RegisterGetPropertyHandler(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_RADIO_REGION,
203                                std::bind(&DBusThreadObject::GetRadioRegionHandler, this, _1));
204
205     return error;
206 }
207
208 void DBusThreadObject::DeviceRoleHandler(otDeviceRole aDeviceRole)
209 {
210     SignalPropertyChanged(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DEVICE_ROLE, GetDeviceRoleName(aDeviceRole));
211 }
212
213 void DBusThreadObject::NcpResetHandler(void)
214 {
215     mNcp->GetThreadHelper()->AddDeviceRoleHandler(std::bind(&DBusThreadObject::DeviceRoleHandler, this, _1));
216     SignalPropertyChanged(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DEVICE_ROLE,
217                           GetDeviceRoleName(OT_DEVICE_ROLE_DISABLED));
218 }
219
220 void DBusThreadObject::ScanHandler(DBusRequest &aRequest)
221 {
222     auto threadHelper = mNcp->GetThreadHelper();
223     threadHelper->Scan(std::bind(&DBusThreadObject::ReplyScanResult, this, aRequest, _1, _2));
224 }
225
226 void DBusThreadObject::ReplyScanResult(DBusRequest &                          aRequest,
227                                        otError                                aError,
228                                        const std::vector<otActiveScanResult> &aResult)
229 {
230     std::vector<ActiveScanResult> results;
231
232     if (aError != OT_ERROR_NONE)
233     {
234         aRequest.ReplyOtResult(aError);
235     }
236     else
237     {
238         for (const auto &r : aResult)
239         {
240             ActiveScanResult result;
241
242             result.mExtAddress    = ConvertOpenThreadUint64(r.mExtAddress.m8);
243             result.mExtendedPanId = ConvertOpenThreadUint64(r.mExtendedPanId.m8);
244             result.mNetworkName   = r.mNetworkName.m8;
245             result.mSteeringData =
246                 std::vector<uint8_t>(r.mSteeringData.m8, r.mSteeringData.m8 + r.mSteeringData.mLength);
247             result.mPanId         = r.mPanId;
248             result.mJoinerUdpPort = r.mJoinerUdpPort;
249             result.mChannel       = r.mChannel;
250             result.mRssi          = r.mRssi;
251             result.mLqi           = r.mLqi;
252             result.mVersion       = r.mVersion;
253             result.mIsNative      = r.mIsNative;
254             result.mIsJoinable    = r.mIsJoinable;
255
256             results.emplace_back(result);
257         }
258
259         aRequest.Reply(std::tie(results));
260     }
261 }
262
263 void DBusThreadObject::AttachHandler(DBusRequest &aRequest)
264 {
265     auto                 threadHelper = mNcp->GetThreadHelper();
266     std::string          name;
267     uint16_t             panid;
268     uint64_t             extPanId;
269     std::vector<uint8_t> masterKey;
270     std::vector<uint8_t> pskc;
271     uint32_t             channelMask;
272
273     auto args = std::tie(masterKey, panid, name, extPanId, pskc, channelMask);
274
275     if (IsDBusMessageEmpty(*aRequest.GetMessage()))
276     {
277         threadHelper->Attach([aRequest](otError aError) mutable { aRequest.ReplyOtResult(aError); });
278     }
279     else if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
280     {
281         aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
282     }
283     else
284     {
285         threadHelper->Attach(name, panid, extPanId, masterKey, pskc, channelMask,
286                              [aRequest](otError aError) mutable { aRequest.ReplyOtResult(aError); });
287     }
288 }
289
290 void DBusThreadObject::FactoryResetHandler(DBusRequest &aRequest)
291 {
292     aRequest.ReplyOtResult(OT_ERROR_NONE);
293     otInstanceFactoryReset(mNcp->GetThreadHelper()->GetInstance());
294 }
295
296 void DBusThreadObject::ResetHandler(DBusRequest &aRequest)
297 {
298     aRequest.ReplyOtResult(OT_ERROR_NONE);
299     otInstanceReset(mNcp->GetThreadHelper()->GetInstance());
300 }
301
302 void DBusThreadObject::JoinerStartHandler(DBusRequest &aRequest)
303 {
304     auto        threadHelper = mNcp->GetThreadHelper();
305     std::string pskd, provisionUrl, vendorName, vendorModel, vendorSwVersion, vendorData;
306     auto        args = std::tie(pskd, provisionUrl, vendorName, vendorModel, vendorSwVersion, vendorData);
307
308     if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
309     {
310         aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
311     }
312     else
313     {
314         threadHelper->JoinerStart(pskd, provisionUrl, vendorName, vendorModel, vendorSwVersion, vendorData,
315                                   [aRequest](otError aError) mutable { aRequest.ReplyOtResult(aError); });
316     }
317 }
318
319 void DBusThreadObject::JoinerStopHandler(DBusRequest &aRequest)
320 {
321     auto threadHelper = mNcp->GetThreadHelper();
322
323     otJoinerStop(threadHelper->GetInstance());
324     aRequest.ReplyOtResult(OT_ERROR_NONE);
325 }
326
327 void DBusThreadObject::PermitUnsecureJoinHandler(DBusRequest &aRequest)
328 {
329 #ifdef OTBR_ENABLE_UNSECURE_JOIN
330     auto     threadHelper = mNcp->GetThreadHelper();
331     uint16_t port;
332     uint32_t timeout;
333     auto     args = std::tie(port, timeout);
334
335     if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
336     {
337         aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
338     }
339     else
340     {
341         aRequest.ReplyOtResult(threadHelper->PermitUnsecureJoin(port, timeout));
342     }
343 #else
344     aRequest.ReplyOtResult(OT_ERROR_NOT_IMPLEMENTED);
345 #endif
346 }
347
348 void DBusThreadObject::AddOnMeshPrefixHandler(DBusRequest &aRequest)
349 {
350     auto                 threadHelper = mNcp->GetThreadHelper();
351     OnMeshPrefix         onMeshPrefix;
352     auto                 args  = std::tie(onMeshPrefix);
353     otError              error = OT_ERROR_NONE;
354     otBorderRouterConfig config;
355
356     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
357
358     // size is guaranteed by parsing
359     std::copy(onMeshPrefix.mPrefix.mPrefix.begin(), onMeshPrefix.mPrefix.mPrefix.end(),
360               &config.mPrefix.mPrefix.mFields.m8[0]);
361     config.mPrefix.mLength = onMeshPrefix.mPrefix.mLength;
362     config.mPreference     = onMeshPrefix.mPreference;
363     config.mSlaac          = onMeshPrefix.mSlaac;
364     config.mDhcp           = onMeshPrefix.mDhcp;
365     config.mConfigure      = onMeshPrefix.mConfigure;
366     config.mDefaultRoute   = onMeshPrefix.mDefaultRoute;
367     config.mOnMesh         = onMeshPrefix.mOnMesh;
368     config.mStable         = onMeshPrefix.mStable;
369
370     SuccessOrExit(error = otBorderRouterAddOnMeshPrefix(threadHelper->GetInstance(), &config));
371     SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
372
373 exit:
374     aRequest.ReplyOtResult(error);
375 }
376
377 void DBusThreadObject::RemoveOnMeshPrefixHandler(DBusRequest &aRequest)
378 {
379     auto        threadHelper = mNcp->GetThreadHelper();
380     Ip6Prefix   onMeshPrefix;
381     auto        args  = std::tie(onMeshPrefix);
382     otError     error = OT_ERROR_NONE;
383     otIp6Prefix prefix;
384
385     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
386     // size is guaranteed by parsing
387     std::copy(onMeshPrefix.mPrefix.begin(), onMeshPrefix.mPrefix.end(), &prefix.mPrefix.mFields.m8[0]);
388     prefix.mLength = onMeshPrefix.mLength;
389
390     SuccessOrExit(error = otBorderRouterRemoveOnMeshPrefix(threadHelper->GetInstance(), &prefix));
391     SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
392
393 exit:
394     aRequest.ReplyOtResult(error);
395 }
396
397 void DBusThreadObject::AddExternalRouteHandler(DBusRequest &aRequest)
398 {
399     auto                  threadHelper = mNcp->GetThreadHelper();
400     ExternalRoute         route;
401     auto                  args  = std::tie(route);
402     otError               error = OT_ERROR_NONE;
403     otExternalRouteConfig otRoute;
404     otIp6Prefix &         prefix = otRoute.mPrefix;
405
406     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
407
408     // size is guaranteed by parsing
409     std::copy(route.mPrefix.mPrefix.begin(), route.mPrefix.mPrefix.end(), &prefix.mPrefix.mFields.m8[0]);
410     prefix.mLength      = route.mPrefix.mLength;
411     otRoute.mPreference = route.mPreference;
412     otRoute.mStable     = route.mStable;
413
414     SuccessOrExit(error = otBorderRouterAddRoute(threadHelper->GetInstance(), &otRoute));
415     if (route.mStable)
416     {
417         SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
418     }
419
420 exit:
421     aRequest.ReplyOtResult(error);
422 }
423
424 void DBusThreadObject::RemoveExternalRouteHandler(DBusRequest &aRequest)
425 {
426     auto        threadHelper = mNcp->GetThreadHelper();
427     Ip6Prefix   routePrefix;
428     auto        args  = std::tie(routePrefix);
429     otError     error = OT_ERROR_NONE;
430     otIp6Prefix prefix;
431
432     VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
433
434     // size is guaranteed by parsing
435     std::copy(routePrefix.mPrefix.begin(), routePrefix.mPrefix.end(), &prefix.mPrefix.mFields.m8[0]);
436     prefix.mLength = routePrefix.mLength;
437
438     SuccessOrExit(error = otBorderRouterRemoveRoute(threadHelper->GetInstance(), &prefix));
439     SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
440
441 exit:
442     aRequest.ReplyOtResult(error);
443 }
444
445 void DBusThreadObject::IntrospectHandler(DBusRequest &aRequest)
446 {
447     std::string xmlString(
448 #include "dbus/server/introspect.hpp"
449     );
450
451     aRequest.Reply(std::tie(xmlString));
452 }
453
454 otError DBusThreadObject::SetMeshLocalPrefixHandler(DBusMessageIter &aIter)
455 {
456     auto                                      threadHelper = mNcp->GetThreadHelper();
457     otMeshLocalPrefix                         prefix;
458     std::array<uint8_t, OTBR_IP6_PREFIX_SIZE> data{};
459     otError                                   error = OT_ERROR_NONE;
460
461     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
462     memcpy(&prefix.m8, &data.front(), sizeof(prefix.m8));
463     error = otThreadSetMeshLocalPrefix(threadHelper->GetInstance(), &prefix);
464
465 exit:
466     return error;
467 }
468
469 otError DBusThreadObject::SetLegacyUlaPrefixHandler(DBusMessageIter &aIter)
470 {
471 #if OTBR_ENABLE_LEGACY
472     std::array<uint8_t, OTBR_IP6_PREFIX_SIZE> data;
473     otError                                   error = OT_ERROR_NONE;
474
475     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
476     otSetLegacyUlaPrefix(&data[0]);
477
478 exit:
479     return error;
480 #else
481     OTBR_UNUSED_VARIABLE(aIter);
482
483     return OT_ERROR_NOT_IMPLEMENTED;
484 #endif // OTBR_ENABLE_LEGACY
485 }
486
487 otError DBusThreadObject::SetLinkModeHandler(DBusMessageIter &aIter)
488 {
489     auto             threadHelper = mNcp->GetThreadHelper();
490     LinkModeConfig   cfg;
491     otLinkModeConfig otCfg;
492     otError          error = OT_ERROR_NONE;
493
494     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, cfg) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
495     otCfg.mDeviceType   = cfg.mDeviceType;
496     otCfg.mNetworkData  = cfg.mNetworkData;
497     otCfg.mRxOnWhenIdle = cfg.mRxOnWhenIdle;
498     error               = otThreadSetLinkMode(threadHelper->GetInstance(), otCfg);
499
500 exit:
501     return error;
502 }
503
504 otError DBusThreadObject::GetLinkModeHandler(DBusMessageIter &aIter)
505 {
506     auto             threadHelper = mNcp->GetThreadHelper();
507     otLinkModeConfig otCfg        = otThreadGetLinkMode(threadHelper->GetInstance());
508     LinkModeConfig   cfg;
509     otError          error = OT_ERROR_NONE;
510
511     cfg.mDeviceType   = otCfg.mDeviceType;
512     cfg.mNetworkData  = otCfg.mNetworkData;
513     cfg.mRxOnWhenIdle = otCfg.mRxOnWhenIdle;
514
515     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, cfg) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
516
517 exit:
518     return error;
519 }
520
521 otError DBusThreadObject::GetDeviceRoleHandler(DBusMessageIter &aIter)
522 {
523     auto         threadHelper = mNcp->GetThreadHelper();
524     otDeviceRole role         = otThreadGetDeviceRole(threadHelper->GetInstance());
525     std::string  roleName     = GetDeviceRoleName(role);
526     otError      error        = OT_ERROR_NONE;
527
528     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, roleName) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
529
530 exit:
531     return error;
532 }
533
534 otError DBusThreadObject::GetNetworkNameHandler(DBusMessageIter &aIter)
535 {
536     auto        threadHelper = mNcp->GetThreadHelper();
537     std::string networkName  = otThreadGetNetworkName(threadHelper->GetInstance());
538     otError     error        = OT_ERROR_NONE;
539
540     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, networkName) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
541
542 exit:
543     return error;
544 }
545
546 otError DBusThreadObject::GetPanIdHandler(DBusMessageIter &aIter)
547 {
548     auto     threadHelper = mNcp->GetThreadHelper();
549     uint16_t panId        = otLinkGetPanId(threadHelper->GetInstance());
550     otError  error        = OT_ERROR_NONE;
551
552     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, panId) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
553
554 exit:
555     return error;
556 }
557
558 otError DBusThreadObject::GetExtPanIdHandler(DBusMessageIter &aIter)
559 {
560     auto                   threadHelper = mNcp->GetThreadHelper();
561     const otExtendedPanId *extPanId     = otThreadGetExtendedPanId(threadHelper->GetInstance());
562     uint64_t               extPanIdVal;
563     otError                error = OT_ERROR_NONE;
564
565     extPanIdVal = ConvertOpenThreadUint64(extPanId->m8);
566
567     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, extPanIdVal) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
568
569 exit:
570     return error;
571 }
572
573 otError DBusThreadObject::GetChannelHandler(DBusMessageIter &aIter)
574 {
575     auto     threadHelper = mNcp->GetThreadHelper();
576     uint16_t channel      = otLinkGetChannel(threadHelper->GetInstance());
577     otError  error        = OT_ERROR_NONE;
578
579     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, channel) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
580
581 exit:
582     return error;
583 }
584
585 otError DBusThreadObject::GetMasterKeyHandler(DBusMessageIter &aIter)
586 {
587     auto                 threadHelper = mNcp->GetThreadHelper();
588     const otMasterKey *  masterKey    = otThreadGetMasterKey(threadHelper->GetInstance());
589     std::vector<uint8_t> keyVal(masterKey->m8, masterKey->m8 + sizeof(masterKey->m8));
590     otError              error = OT_ERROR_NONE;
591
592     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, keyVal) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
593
594 exit:
595     return error;
596 }
597
598 otError DBusThreadObject::GetCcaFailureRateHandler(DBusMessageIter &aIter)
599 {
600     auto     threadHelper = mNcp->GetThreadHelper();
601     uint16_t failureRate  = otLinkGetCcaFailureRate(threadHelper->GetInstance());
602     otError  error        = OT_ERROR_NONE;
603
604     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, failureRate) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
605
606 exit:
607     return error;
608 }
609
610 otError DBusThreadObject::GetLinkCountersHandler(DBusMessageIter &aIter)
611 {
612     auto                 threadHelper = mNcp->GetThreadHelper();
613     const otMacCounters *otCounters   = otLinkGetCounters(threadHelper->GetInstance());
614     MacCounters          counters;
615     otError              error = OT_ERROR_NONE;
616
617     counters.mTxTotal              = otCounters->mTxTotal;
618     counters.mTxUnicast            = otCounters->mTxUnicast;
619     counters.mTxBroadcast          = otCounters->mTxBroadcast;
620     counters.mTxAckRequested       = otCounters->mTxAckRequested;
621     counters.mTxAcked              = otCounters->mTxAcked;
622     counters.mTxNoAckRequested     = otCounters->mTxNoAckRequested;
623     counters.mTxData               = otCounters->mTxData;
624     counters.mTxDataPoll           = otCounters->mTxDataPoll;
625     counters.mTxBeacon             = otCounters->mTxBeacon;
626     counters.mTxBeaconRequest      = otCounters->mTxBeaconRequest;
627     counters.mTxOther              = otCounters->mTxOther;
628     counters.mTxRetry              = otCounters->mTxRetry;
629     counters.mTxErrCca             = otCounters->mTxErrCca;
630     counters.mTxErrAbort           = otCounters->mTxErrAbort;
631     counters.mTxErrBusyChannel     = otCounters->mTxErrBusyChannel;
632     counters.mRxTotal              = otCounters->mRxTotal;
633     counters.mRxUnicast            = otCounters->mTxUnicast;
634     counters.mRxBroadcast          = otCounters->mRxBroadcast;
635     counters.mRxData               = otCounters->mRxData;
636     counters.mRxDataPoll           = otCounters->mTxDataPoll;
637     counters.mRxBeacon             = otCounters->mRxBeacon;
638     counters.mRxBeaconRequest      = otCounters->mRxBeaconRequest;
639     counters.mRxOther              = otCounters->mRxOther;
640     counters.mRxAddressFiltered    = otCounters->mRxAddressFiltered;
641     counters.mRxDestAddrFiltered   = otCounters->mRxDestAddrFiltered;
642     counters.mRxDuplicated         = otCounters->mRxDuplicated;
643     counters.mRxErrNoFrame         = otCounters->mRxErrNoFrame;
644     counters.mRxErrUnknownNeighbor = otCounters->mRxErrUnknownNeighbor;
645     counters.mRxErrInvalidSrcAddr  = otCounters->mRxErrInvalidSrcAddr;
646     counters.mRxErrSec             = otCounters->mRxErrSec;
647     counters.mRxErrFcs             = otCounters->mRxErrFcs;
648     counters.mRxErrOther           = otCounters->mRxErrOther;
649
650     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, counters) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
651
652 exit:
653     return error;
654 }
655
656 otError DBusThreadObject::GetIp6CountersHandler(DBusMessageIter &aIter)
657 {
658     auto                threadHelper = mNcp->GetThreadHelper();
659     const otIpCounters *otCounters   = otThreadGetIp6Counters(threadHelper->GetInstance());
660     IpCounters          counters;
661     otError             error = OT_ERROR_NONE;
662
663     counters.mTxSuccess = otCounters->mTxSuccess;
664     counters.mTxFailure = otCounters->mTxFailure;
665     counters.mRxSuccess = otCounters->mRxSuccess;
666     counters.mRxFailure = otCounters->mRxFailure;
667
668     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, counters) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
669
670 exit:
671     return error;
672 }
673
674 otError DBusThreadObject::GetSupportedChannelMaskHandler(DBusMessageIter &aIter)
675 {
676     auto     threadHelper = mNcp->GetThreadHelper();
677     uint32_t channelMask  = otLinkGetSupportedChannelMask(threadHelper->GetInstance());
678     otError  error        = OT_ERROR_NONE;
679
680     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, channelMask) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
681
682 exit:
683     return error;
684 }
685
686 otError DBusThreadObject::GetRloc16Handler(DBusMessageIter &aIter)
687 {
688     auto     threadHelper = mNcp->GetThreadHelper();
689     otError  error        = OT_ERROR_NONE;
690     uint16_t rloc16       = otThreadGetRloc16(threadHelper->GetInstance());
691
692     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, rloc16) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
693
694 exit:
695     return error;
696 }
697
698 otError DBusThreadObject::GetExtendedAddressHandler(DBusMessageIter &aIter)
699 {
700     auto                threadHelper    = mNcp->GetThreadHelper();
701     otError             error           = OT_ERROR_NONE;
702     const otExtAddress *addr            = otLinkGetExtendedAddress(threadHelper->GetInstance());
703     uint64_t            extendedAddress = ConvertOpenThreadUint64(addr->m8);
704
705     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, extendedAddress) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
706
707 exit:
708     return error;
709 }
710
711 otError DBusThreadObject::GetRouterIdHandler(DBusMessageIter &aIter)
712 {
713     auto         threadHelper = mNcp->GetThreadHelper();
714     otError      error        = OT_ERROR_NONE;
715     uint16_t     rloc16       = otThreadGetRloc16(threadHelper->GetInstance());
716     otRouterInfo info;
717
718     VerifyOrExit(otThreadGetRouterInfo(threadHelper->GetInstance(), rloc16, &info) == OT_ERROR_NONE,
719                  error = OT_ERROR_INVALID_STATE);
720     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, info.mRouterId) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
721
722 exit:
723     return error;
724 }
725
726 otError DBusThreadObject::GetLeaderDataHandler(DBusMessageIter &aIter)
727 {
728     auto                threadHelper = mNcp->GetThreadHelper();
729     otError             error        = OT_ERROR_NONE;
730     struct otLeaderData data;
731     LeaderData          leaderData;
732
733     SuccessOrExit(error = otThreadGetLeaderData(threadHelper->GetInstance(), &data));
734     leaderData.mPartitionId       = data.mPartitionId;
735     leaderData.mWeighting         = data.mWeighting;
736     leaderData.mDataVersion       = data.mDataVersion;
737     leaderData.mStableDataVersion = data.mStableDataVersion;
738     leaderData.mLeaderRouterId    = data.mLeaderRouterId;
739     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, leaderData) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
740
741 exit:
742     return error;
743 }
744
745 otError DBusThreadObject::GetNetworkDataHandler(DBusMessageIter &aIter)
746 {
747     static constexpr size_t kNetworkDataMaxSize = 255;
748     auto                    threadHelper        = mNcp->GetThreadHelper();
749     otError                 error               = OT_ERROR_NONE;
750     uint8_t                 data[kNetworkDataMaxSize];
751     uint8_t                 len = sizeof(data);
752     std::vector<uint8_t>    networkData;
753
754     SuccessOrExit(error = otNetDataGet(threadHelper->GetInstance(), /*stable=*/false, data, &len));
755     networkData = std::vector<uint8_t>(&data[0], &data[len]);
756     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, networkData) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
757
758 exit:
759     return error;
760 }
761
762 otError DBusThreadObject::GetStableNetworkDataHandler(DBusMessageIter &aIter)
763 {
764     static constexpr size_t kNetworkDataMaxSize = 255;
765     auto                    threadHelper        = mNcp->GetThreadHelper();
766     otError                 error               = OT_ERROR_NONE;
767     uint8_t                 data[kNetworkDataMaxSize];
768     uint8_t                 len = sizeof(data);
769     std::vector<uint8_t>    networkData;
770
771     SuccessOrExit(error = otNetDataGet(threadHelper->GetInstance(), /*stable=*/true, data, &len));
772     networkData = std::vector<uint8_t>(&data[0], &data[len]);
773     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, networkData) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
774
775 exit:
776     return error;
777 }
778
779 otError DBusThreadObject::GetLocalLeaderWeightHandler(DBusMessageIter &aIter)
780 {
781     auto    threadHelper = mNcp->GetThreadHelper();
782     otError error        = OT_ERROR_NONE;
783     uint8_t weight       = otThreadGetLocalLeaderWeight(threadHelper->GetInstance());
784
785     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, weight) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
786
787 exit:
788     return error;
789 }
790
791 otError DBusThreadObject::GetChannelMonitorSampleCountHandler(DBusMessageIter &aIter)
792 {
793 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
794     auto     threadHelper = mNcp->GetThreadHelper();
795     otError  error        = OT_ERROR_NONE;
796     uint32_t cnt          = otChannelMonitorGetSampleCount(threadHelper->GetInstance());
797
798     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, cnt) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
799
800 exit:
801     return error;
802 #else  // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
803     OTBR_UNUSED_VARIABLE(aIter);
804     return OT_ERROR_NOT_IMPLEMENTED;
805 #endif // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
806 }
807
808 otError DBusThreadObject::GetChannelMonitorAllChannelQualities(DBusMessageIter &aIter)
809 {
810 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
811     auto                        threadHelper = mNcp->GetThreadHelper();
812     otError                     error        = OT_ERROR_NONE;
813     uint32_t                    channelMask  = otLinkGetSupportedChannelMask(threadHelper->GetInstance());
814     constexpr uint8_t           kNumChannels = sizeof(channelMask) * 8; // 8 bit per byte
815     std::vector<ChannelQuality> quality;
816
817     for (uint8_t i = 0; i < kNumChannels; i++)
818     {
819         if (channelMask & (1U << i))
820         {
821             uint16_t occupancy = otChannelMonitorGetChannelOccupancy(threadHelper->GetInstance(), i);
822
823             quality.emplace_back(ChannelQuality{i, occupancy});
824         }
825     }
826
827     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, quality) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
828
829 exit:
830     return error;
831 #else  // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
832     OTBR_UNUSED_VARIABLE(aIter);
833     return OT_ERROR_NOT_IMPLEMENTED;
834 #endif // OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
835 }
836
837 otError DBusThreadObject::GetChildTableHandler(DBusMessageIter &aIter)
838 {
839     auto                   threadHelper = mNcp->GetThreadHelper();
840     otError                error        = OT_ERROR_NONE;
841     uint16_t               childIndex   = 0;
842     otChildInfo            childInfo;
843     std::vector<ChildInfo> childTable;
844
845     while (otThreadGetChildInfoByIndex(threadHelper->GetInstance(), childIndex, &childInfo) == OT_ERROR_NONE)
846     {
847         ChildInfo info;
848
849         info.mExtAddress         = ConvertOpenThreadUint64(childInfo.mExtAddress.m8);
850         info.mTimeout            = childInfo.mTimeout;
851         info.mAge                = childInfo.mAge;
852         info.mChildId            = childInfo.mChildId;
853         info.mNetworkDataVersion = childInfo.mNetworkDataVersion;
854         info.mLinkQualityIn      = childInfo.mLinkQualityIn;
855         info.mAverageRssi        = childInfo.mAverageRssi;
856         info.mLastRssi           = childInfo.mLastRssi;
857         info.mFrameErrorRate     = childInfo.mFrameErrorRate;
858         info.mMessageErrorRate   = childInfo.mMessageErrorRate;
859         info.mRxOnWhenIdle       = childInfo.mRxOnWhenIdle;
860         info.mFullThreadDevice   = childInfo.mFullThreadDevice;
861         info.mFullNetworkData    = childInfo.mFullNetworkData;
862         info.mIsStateRestoring   = childInfo.mIsStateRestoring;
863         childTable.push_back(info);
864         childIndex++;
865     }
866
867     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, childTable) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
868
869 exit:
870     return error;
871 }
872
873 otError DBusThreadObject::GetNeighborTableHandler(DBusMessageIter &aIter)
874 {
875     auto                      threadHelper = mNcp->GetThreadHelper();
876     otError                   error        = OT_ERROR_NONE;
877     otNeighborInfoIterator    iter         = OT_NEIGHBOR_INFO_ITERATOR_INIT;
878     otNeighborInfo            neighborInfo;
879     std::vector<NeighborInfo> neighborTable;
880
881     while (otThreadGetNextNeighborInfo(threadHelper->GetInstance(), &iter, &neighborInfo) == OT_ERROR_NONE)
882     {
883         NeighborInfo info;
884
885         info.mExtAddress       = ConvertOpenThreadUint64(neighborInfo.mExtAddress.m8);
886         info.mAge              = neighborInfo.mAge;
887         info.mRloc16           = neighborInfo.mRloc16;
888         info.mLinkFrameCounter = neighborInfo.mLinkFrameCounter;
889         info.mMleFrameCounter  = neighborInfo.mMleFrameCounter;
890         info.mLinkQualityIn    = neighborInfo.mLinkQualityIn;
891         info.mAverageRssi      = neighborInfo.mAverageRssi;
892         info.mLastRssi         = neighborInfo.mLastRssi;
893         info.mFrameErrorRate   = neighborInfo.mFrameErrorRate;
894         info.mMessageErrorRate = neighborInfo.mMessageErrorRate;
895         info.mRxOnWhenIdle     = neighborInfo.mRxOnWhenIdle;
896         info.mFullThreadDevice = neighborInfo.mFullThreadDevice;
897         info.mFullNetworkData  = neighborInfo.mFullNetworkData;
898         info.mIsChild          = neighborInfo.mIsChild;
899         neighborTable.push_back(info);
900     }
901
902     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, neighborTable) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
903
904 exit:
905     return error;
906 }
907
908 otError DBusThreadObject::GetPartitionIDHandler(DBusMessageIter &aIter)
909 {
910     auto     threadHelper = mNcp->GetThreadHelper();
911     otError  error        = OT_ERROR_NONE;
912     uint32_t partitionId  = otThreadGetPartitionId(threadHelper->GetInstance());
913
914     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, partitionId) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
915
916 exit:
917     return error;
918 }
919
920 otError DBusThreadObject::GetInstantRssiHandler(DBusMessageIter &aIter)
921 {
922     auto    threadHelper = mNcp->GetThreadHelper();
923     otError error        = OT_ERROR_NONE;
924     int8_t  rssi         = otPlatRadioGetRssi(threadHelper->GetInstance());
925
926     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, rssi) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
927
928 exit:
929     return error;
930 }
931
932 otError DBusThreadObject::GetRadioTxPowerHandler(DBusMessageIter &aIter)
933 {
934     auto    threadHelper = mNcp->GetThreadHelper();
935     otError error        = OT_ERROR_NONE;
936     int8_t  txPower;
937
938     SuccessOrExit(error = otPlatRadioGetTransmitPower(threadHelper->GetInstance(), &txPower));
939
940     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, txPower) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
941
942 exit:
943     return error;
944 }
945
946 otError DBusThreadObject::GetExternalRoutesHandler(DBusMessageIter &aIter)
947 {
948     auto                       threadHelper = mNcp->GetThreadHelper();
949     otError                    error        = OT_ERROR_NONE;
950     otNetworkDataIterator      iter         = OT_NETWORK_DATA_ITERATOR_INIT;
951     otExternalRouteConfig      config;
952     std::vector<ExternalRoute> externalRouteTable;
953
954     while (otNetDataGetNextRoute(threadHelper->GetInstance(), &iter, &config) == OT_ERROR_NONE)
955     {
956         ExternalRoute route;
957
958         route.mPrefix.mPrefix      = std::vector<uint8_t>(&config.mPrefix.mPrefix.mFields.m8[0],
959                                                      &config.mPrefix.mPrefix.mFields.m8[OTBR_IP6_PREFIX_SIZE]);
960         route.mPrefix.mLength      = config.mPrefix.mLength;
961         route.mRloc16              = config.mRloc16;
962         route.mPreference          = config.mPreference;
963         route.mStable              = config.mStable;
964         route.mNextHopIsThisDevice = config.mNextHopIsThisDevice;
965         externalRouteTable.push_back(route);
966     }
967
968     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, externalRouteTable) == OTBR_ERROR_NONE,
969                  error = OT_ERROR_INVALID_ARGS);
970
971 exit:
972     return error;
973 }
974
975 otError DBusThreadObject::SetActiveDatasetTlvsHandler(DBusMessageIter &aIter)
976 {
977     auto                     threadHelper = mNcp->GetThreadHelper();
978     std::vector<uint8_t>     data;
979     otOperationalDatasetTlvs datasetTlvs;
980     otError                  error = OT_ERROR_NONE;
981
982     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
983     VerifyOrExit(data.size() <= sizeof(datasetTlvs.mTlvs));
984     std::copy(std::begin(data), std::end(data), std::begin(datasetTlvs.mTlvs));
985     datasetTlvs.mLength = data.size();
986     error               = otDatasetSetActiveTlvs(threadHelper->GetInstance(), &datasetTlvs);
987
988 exit:
989     return error;
990 }
991
992 otError DBusThreadObject::GetActiveDatasetTlvsHandler(DBusMessageIter &aIter)
993 {
994     auto                     threadHelper = mNcp->GetThreadHelper();
995     otError                  error        = OT_ERROR_NONE;
996     std::vector<uint8_t>     data;
997     otOperationalDatasetTlvs datasetTlvs;
998
999     SuccessOrExit(error = otDatasetGetActiveTlvs(threadHelper->GetInstance(), &datasetTlvs));
1000     data = std::vector<uint8_t>{std::begin(datasetTlvs.mTlvs), std::begin(datasetTlvs.mTlvs) + datasetTlvs.mLength};
1001
1002     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1003
1004 exit:
1005     return error;
1006 }
1007
1008 otError DBusThreadObject::SetRadioRegionHandler(DBusMessageIter &aIter)
1009 {
1010     auto        threadHelper = mNcp->GetThreadHelper();
1011     std::string radioRegion;
1012     uint16_t    regionCode;
1013     otError     error = OT_ERROR_NONE;
1014
1015     VerifyOrExit(DBusMessageExtractFromVariant(&aIter, radioRegion) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1016     VerifyOrExit(radioRegion.size() == sizeof(uint16_t), error = OT_ERROR_INVALID_ARGS);
1017     regionCode = radioRegion[0] << 8 | radioRegion[1];
1018
1019     error = otPlatRadioSetRegion(threadHelper->GetInstance(), regionCode);
1020
1021 exit:
1022     return error;
1023 }
1024
1025 otError DBusThreadObject::GetRadioRegionHandler(DBusMessageIter &aIter)
1026 {
1027     auto        threadHelper = mNcp->GetThreadHelper();
1028     otError     error        = OT_ERROR_NONE;
1029     std::string radioRegion;
1030     uint16_t    regionCode;
1031
1032     SuccessOrExit(error = otPlatRadioGetRegion(threadHelper->GetInstance(), &regionCode));
1033     radioRegion.resize(sizeof(uint16_t), '\0');
1034     radioRegion[0] = static_cast<char>((regionCode >> 8) & 0xff);
1035     radioRegion[1] = static_cast<char>(regionCode & 0xff);
1036
1037     VerifyOrExit(DBusMessageEncodeToVariant(&aIter, radioRegion) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1038
1039 exit:
1040     return error;
1041 }
1042
1043 } // namespace DBus
1044 } // namespace otbr