2 * Copyright (c) 2020, The OpenThread Authors.
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.
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.
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>
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"
47 #if OTBR_ENABLE_LEGACY
48 #include <ot-legacy-pairing-ext.h>
51 using std::placeholders::_1;
52 using std::placeholders::_2;
54 static std::string GetDeviceRoleName(otDeviceRole aRole)
60 case OT_DEVICE_ROLE_DISABLED:
61 roleName = OTBR_ROLE_NAME_DISABLED;
63 case OT_DEVICE_ROLE_DETACHED:
64 roleName = OTBR_ROLE_NAME_DETACHED;
66 case OT_DEVICE_ROLE_CHILD:
67 roleName = OTBR_ROLE_NAME_CHILD;
69 case OT_DEVICE_ROLE_ROUTER:
70 roleName = OTBR_ROLE_NAME_ROUTER;
72 case OT_DEVICE_ROLE_LEADER:
73 roleName = OTBR_ROLE_NAME_LEADER;
80 static uint64_t ConvertOpenThreadUint64(const uint8_t *aValue)
84 for (size_t i = 0; i < sizeof(uint64_t); i++)
86 val = (val << 8) | aValue[i];
94 DBusThreadObject::DBusThreadObject(DBusConnection * aConnection,
95 const std::string & aInterfaceName,
96 otbr::Ncp::ControllerOpenThread *aNcp)
97 : DBusObject(aConnection, OTBR_DBUS_OBJECT_PREFIX + aInterfaceName)
102 otbrError DBusThreadObject::Init(void)
104 otbrError error = DBusObject::Init();
105 auto threadHelper = mNcp->GetThreadHelper();
107 threadHelper->AddDeviceRoleHandler(std::bind(&DBusThreadObject::DeviceRoleHandler, this, _1));
108 mNcp->RegisterResetHandler(std::bind(&DBusThreadObject::NcpResetHandler, this));
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));
133 RegisterMethod(DBUS_INTERFACE_INTROSPECTABLE, DBUS_INTROSPECT_METHOD,
134 std::bind(&DBusThreadObject::IntrospectHandler, this, _1));
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));
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));
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));
208 void DBusThreadObject::DeviceRoleHandler(otDeviceRole aDeviceRole)
210 SignalPropertyChanged(OTBR_DBUS_THREAD_INTERFACE, OTBR_DBUS_PROPERTY_DEVICE_ROLE, GetDeviceRoleName(aDeviceRole));
213 void DBusThreadObject::NcpResetHandler(void)
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));
220 void DBusThreadObject::ScanHandler(DBusRequest &aRequest)
222 auto threadHelper = mNcp->GetThreadHelper();
223 threadHelper->Scan(std::bind(&DBusThreadObject::ReplyScanResult, this, aRequest, _1, _2));
226 void DBusThreadObject::ReplyScanResult(DBusRequest & aRequest,
228 const std::vector<otActiveScanResult> &aResult)
230 std::vector<ActiveScanResult> results;
232 if (aError != OT_ERROR_NONE)
234 aRequest.ReplyOtResult(aError);
238 for (const auto &r : aResult)
240 ActiveScanResult result;
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;
256 results.emplace_back(result);
259 aRequest.Reply(std::tie(results));
263 void DBusThreadObject::AttachHandler(DBusRequest &aRequest)
265 auto threadHelper = mNcp->GetThreadHelper();
269 std::vector<uint8_t> masterKey;
270 std::vector<uint8_t> pskc;
271 uint32_t channelMask;
273 auto args = std::tie(masterKey, panid, name, extPanId, pskc, channelMask);
275 if (IsDBusMessageEmpty(*aRequest.GetMessage()))
277 threadHelper->Attach([aRequest](otError aError) mutable { aRequest.ReplyOtResult(aError); });
279 else if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
281 aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
285 threadHelper->Attach(name, panid, extPanId, masterKey, pskc, channelMask,
286 [aRequest](otError aError) mutable { aRequest.ReplyOtResult(aError); });
290 void DBusThreadObject::FactoryResetHandler(DBusRequest &aRequest)
292 aRequest.ReplyOtResult(OT_ERROR_NONE);
293 otInstanceFactoryReset(mNcp->GetThreadHelper()->GetInstance());
296 void DBusThreadObject::ResetHandler(DBusRequest &aRequest)
298 aRequest.ReplyOtResult(OT_ERROR_NONE);
299 otInstanceReset(mNcp->GetThreadHelper()->GetInstance());
302 void DBusThreadObject::JoinerStartHandler(DBusRequest &aRequest)
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);
308 if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
310 aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
314 threadHelper->JoinerStart(pskd, provisionUrl, vendorName, vendorModel, vendorSwVersion, vendorData,
315 [aRequest](otError aError) mutable { aRequest.ReplyOtResult(aError); });
319 void DBusThreadObject::JoinerStopHandler(DBusRequest &aRequest)
321 auto threadHelper = mNcp->GetThreadHelper();
323 otJoinerStop(threadHelper->GetInstance());
324 aRequest.ReplyOtResult(OT_ERROR_NONE);
327 void DBusThreadObject::PermitUnsecureJoinHandler(DBusRequest &aRequest)
329 #ifdef OTBR_ENABLE_UNSECURE_JOIN
330 auto threadHelper = mNcp->GetThreadHelper();
333 auto args = std::tie(port, timeout);
335 if (DBusMessageToTuple(*aRequest.GetMessage(), args) != OTBR_ERROR_NONE)
337 aRequest.ReplyOtResult(OT_ERROR_INVALID_ARGS);
341 aRequest.ReplyOtResult(threadHelper->PermitUnsecureJoin(port, timeout));
344 aRequest.ReplyOtResult(OT_ERROR_NOT_IMPLEMENTED);
348 void DBusThreadObject::AddOnMeshPrefixHandler(DBusRequest &aRequest)
350 auto threadHelper = mNcp->GetThreadHelper();
351 OnMeshPrefix onMeshPrefix;
352 auto args = std::tie(onMeshPrefix);
353 otError error = OT_ERROR_NONE;
354 otBorderRouterConfig config;
356 VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
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;
370 SuccessOrExit(error = otBorderRouterAddOnMeshPrefix(threadHelper->GetInstance(), &config));
371 SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
374 aRequest.ReplyOtResult(error);
377 void DBusThreadObject::RemoveOnMeshPrefixHandler(DBusRequest &aRequest)
379 auto threadHelper = mNcp->GetThreadHelper();
380 Ip6Prefix onMeshPrefix;
381 auto args = std::tie(onMeshPrefix);
382 otError error = OT_ERROR_NONE;
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;
390 SuccessOrExit(error = otBorderRouterRemoveOnMeshPrefix(threadHelper->GetInstance(), &prefix));
391 SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
394 aRequest.ReplyOtResult(error);
397 void DBusThreadObject::AddExternalRouteHandler(DBusRequest &aRequest)
399 auto threadHelper = mNcp->GetThreadHelper();
401 auto args = std::tie(route);
402 otError error = OT_ERROR_NONE;
403 otExternalRouteConfig otRoute;
404 otIp6Prefix & prefix = otRoute.mPrefix;
406 VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
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;
414 SuccessOrExit(error = otBorderRouterAddRoute(threadHelper->GetInstance(), &otRoute));
417 SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
421 aRequest.ReplyOtResult(error);
424 void DBusThreadObject::RemoveExternalRouteHandler(DBusRequest &aRequest)
426 auto threadHelper = mNcp->GetThreadHelper();
427 Ip6Prefix routePrefix;
428 auto args = std::tie(routePrefix);
429 otError error = OT_ERROR_NONE;
432 VerifyOrExit(DBusMessageToTuple(*aRequest.GetMessage(), args) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
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;
438 SuccessOrExit(error = otBorderRouterRemoveRoute(threadHelper->GetInstance(), &prefix));
439 SuccessOrExit(error = otBorderRouterRegister(threadHelper->GetInstance()));
442 aRequest.ReplyOtResult(error);
445 void DBusThreadObject::IntrospectHandler(DBusRequest &aRequest)
447 std::string xmlString(
448 #include "dbus/server/introspect.hpp"
451 aRequest.Reply(std::tie(xmlString));
454 otError DBusThreadObject::SetMeshLocalPrefixHandler(DBusMessageIter &aIter)
456 auto threadHelper = mNcp->GetThreadHelper();
457 otMeshLocalPrefix prefix;
458 std::array<uint8_t, OTBR_IP6_PREFIX_SIZE> data{};
459 otError error = OT_ERROR_NONE;
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);
469 otError DBusThreadObject::SetLegacyUlaPrefixHandler(DBusMessageIter &aIter)
471 #if OTBR_ENABLE_LEGACY
472 std::array<uint8_t, OTBR_IP6_PREFIX_SIZE> data;
473 otError error = OT_ERROR_NONE;
475 VerifyOrExit(DBusMessageExtractFromVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
476 otSetLegacyUlaPrefix(&data[0]);
481 OTBR_UNUSED_VARIABLE(aIter);
483 return OT_ERROR_NOT_IMPLEMENTED;
484 #endif // OTBR_ENABLE_LEGACY
487 otError DBusThreadObject::SetLinkModeHandler(DBusMessageIter &aIter)
489 auto threadHelper = mNcp->GetThreadHelper();
491 otLinkModeConfig otCfg;
492 otError error = OT_ERROR_NONE;
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);
504 otError DBusThreadObject::GetLinkModeHandler(DBusMessageIter &aIter)
506 auto threadHelper = mNcp->GetThreadHelper();
507 otLinkModeConfig otCfg = otThreadGetLinkMode(threadHelper->GetInstance());
509 otError error = OT_ERROR_NONE;
511 cfg.mDeviceType = otCfg.mDeviceType;
512 cfg.mNetworkData = otCfg.mNetworkData;
513 cfg.mRxOnWhenIdle = otCfg.mRxOnWhenIdle;
515 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, cfg) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
521 otError DBusThreadObject::GetDeviceRoleHandler(DBusMessageIter &aIter)
523 auto threadHelper = mNcp->GetThreadHelper();
524 otDeviceRole role = otThreadGetDeviceRole(threadHelper->GetInstance());
525 std::string roleName = GetDeviceRoleName(role);
526 otError error = OT_ERROR_NONE;
528 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, roleName) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
534 otError DBusThreadObject::GetNetworkNameHandler(DBusMessageIter &aIter)
536 auto threadHelper = mNcp->GetThreadHelper();
537 std::string networkName = otThreadGetNetworkName(threadHelper->GetInstance());
538 otError error = OT_ERROR_NONE;
540 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, networkName) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
546 otError DBusThreadObject::GetPanIdHandler(DBusMessageIter &aIter)
548 auto threadHelper = mNcp->GetThreadHelper();
549 uint16_t panId = otLinkGetPanId(threadHelper->GetInstance());
550 otError error = OT_ERROR_NONE;
552 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, panId) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
558 otError DBusThreadObject::GetExtPanIdHandler(DBusMessageIter &aIter)
560 auto threadHelper = mNcp->GetThreadHelper();
561 const otExtendedPanId *extPanId = otThreadGetExtendedPanId(threadHelper->GetInstance());
562 uint64_t extPanIdVal;
563 otError error = OT_ERROR_NONE;
565 extPanIdVal = ConvertOpenThreadUint64(extPanId->m8);
567 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, extPanIdVal) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
573 otError DBusThreadObject::GetChannelHandler(DBusMessageIter &aIter)
575 auto threadHelper = mNcp->GetThreadHelper();
576 uint16_t channel = otLinkGetChannel(threadHelper->GetInstance());
577 otError error = OT_ERROR_NONE;
579 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, channel) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
585 otError DBusThreadObject::GetMasterKeyHandler(DBusMessageIter &aIter)
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;
592 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, keyVal) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
598 otError DBusThreadObject::GetCcaFailureRateHandler(DBusMessageIter &aIter)
600 auto threadHelper = mNcp->GetThreadHelper();
601 uint16_t failureRate = otLinkGetCcaFailureRate(threadHelper->GetInstance());
602 otError error = OT_ERROR_NONE;
604 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, failureRate) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
610 otError DBusThreadObject::GetLinkCountersHandler(DBusMessageIter &aIter)
612 auto threadHelper = mNcp->GetThreadHelper();
613 const otMacCounters *otCounters = otLinkGetCounters(threadHelper->GetInstance());
614 MacCounters counters;
615 otError error = OT_ERROR_NONE;
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;
650 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, counters) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
656 otError DBusThreadObject::GetIp6CountersHandler(DBusMessageIter &aIter)
658 auto threadHelper = mNcp->GetThreadHelper();
659 const otIpCounters *otCounters = otThreadGetIp6Counters(threadHelper->GetInstance());
661 otError error = OT_ERROR_NONE;
663 counters.mTxSuccess = otCounters->mTxSuccess;
664 counters.mTxFailure = otCounters->mTxFailure;
665 counters.mRxSuccess = otCounters->mRxSuccess;
666 counters.mRxFailure = otCounters->mRxFailure;
668 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, counters) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
674 otError DBusThreadObject::GetSupportedChannelMaskHandler(DBusMessageIter &aIter)
676 auto threadHelper = mNcp->GetThreadHelper();
677 uint32_t channelMask = otLinkGetSupportedChannelMask(threadHelper->GetInstance());
678 otError error = OT_ERROR_NONE;
680 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, channelMask) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
686 otError DBusThreadObject::GetRloc16Handler(DBusMessageIter &aIter)
688 auto threadHelper = mNcp->GetThreadHelper();
689 otError error = OT_ERROR_NONE;
690 uint16_t rloc16 = otThreadGetRloc16(threadHelper->GetInstance());
692 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, rloc16) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
698 otError DBusThreadObject::GetExtendedAddressHandler(DBusMessageIter &aIter)
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);
705 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, extendedAddress) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
711 otError DBusThreadObject::GetRouterIdHandler(DBusMessageIter &aIter)
713 auto threadHelper = mNcp->GetThreadHelper();
714 otError error = OT_ERROR_NONE;
715 uint16_t rloc16 = otThreadGetRloc16(threadHelper->GetInstance());
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);
726 otError DBusThreadObject::GetLeaderDataHandler(DBusMessageIter &aIter)
728 auto threadHelper = mNcp->GetThreadHelper();
729 otError error = OT_ERROR_NONE;
730 struct otLeaderData data;
731 LeaderData leaderData;
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);
745 otError DBusThreadObject::GetNetworkDataHandler(DBusMessageIter &aIter)
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;
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);
762 otError DBusThreadObject::GetStableNetworkDataHandler(DBusMessageIter &aIter)
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;
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);
779 otError DBusThreadObject::GetLocalLeaderWeightHandler(DBusMessageIter &aIter)
781 auto threadHelper = mNcp->GetThreadHelper();
782 otError error = OT_ERROR_NONE;
783 uint8_t weight = otThreadGetLocalLeaderWeight(threadHelper->GetInstance());
785 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, weight) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
791 otError DBusThreadObject::GetChannelMonitorSampleCountHandler(DBusMessageIter &aIter)
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());
798 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, cnt) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
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
808 otError DBusThreadObject::GetChannelMonitorAllChannelQualities(DBusMessageIter &aIter)
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;
817 for (uint8_t i = 0; i < kNumChannels; i++)
819 if (channelMask & (1U << i))
821 uint16_t occupancy = otChannelMonitorGetChannelOccupancy(threadHelper->GetInstance(), i);
823 quality.emplace_back(ChannelQuality{i, occupancy});
827 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, quality) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
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
837 otError DBusThreadObject::GetChildTableHandler(DBusMessageIter &aIter)
839 auto threadHelper = mNcp->GetThreadHelper();
840 otError error = OT_ERROR_NONE;
841 uint16_t childIndex = 0;
842 otChildInfo childInfo;
843 std::vector<ChildInfo> childTable;
845 while (otThreadGetChildInfoByIndex(threadHelper->GetInstance(), childIndex, &childInfo) == OT_ERROR_NONE)
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);
867 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, childTable) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
873 otError DBusThreadObject::GetNeighborTableHandler(DBusMessageIter &aIter)
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;
881 while (otThreadGetNextNeighborInfo(threadHelper->GetInstance(), &iter, &neighborInfo) == OT_ERROR_NONE)
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);
902 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, neighborTable) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
908 otError DBusThreadObject::GetPartitionIDHandler(DBusMessageIter &aIter)
910 auto threadHelper = mNcp->GetThreadHelper();
911 otError error = OT_ERROR_NONE;
912 uint32_t partitionId = otThreadGetPartitionId(threadHelper->GetInstance());
914 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, partitionId) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
920 otError DBusThreadObject::GetInstantRssiHandler(DBusMessageIter &aIter)
922 auto threadHelper = mNcp->GetThreadHelper();
923 otError error = OT_ERROR_NONE;
924 int8_t rssi = otPlatRadioGetRssi(threadHelper->GetInstance());
926 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, rssi) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
932 otError DBusThreadObject::GetRadioTxPowerHandler(DBusMessageIter &aIter)
934 auto threadHelper = mNcp->GetThreadHelper();
935 otError error = OT_ERROR_NONE;
938 SuccessOrExit(error = otPlatRadioGetTransmitPower(threadHelper->GetInstance(), &txPower));
940 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, txPower) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
946 otError DBusThreadObject::GetExternalRoutesHandler(DBusMessageIter &aIter)
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;
954 while (otNetDataGetNextRoute(threadHelper->GetInstance(), &iter, &config) == OT_ERROR_NONE)
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);
968 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, externalRouteTable) == OTBR_ERROR_NONE,
969 error = OT_ERROR_INVALID_ARGS);
975 otError DBusThreadObject::SetActiveDatasetTlvsHandler(DBusMessageIter &aIter)
977 auto threadHelper = mNcp->GetThreadHelper();
978 std::vector<uint8_t> data;
979 otOperationalDatasetTlvs datasetTlvs;
980 otError error = OT_ERROR_NONE;
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);
992 otError DBusThreadObject::GetActiveDatasetTlvsHandler(DBusMessageIter &aIter)
994 auto threadHelper = mNcp->GetThreadHelper();
995 otError error = OT_ERROR_NONE;
996 std::vector<uint8_t> data;
997 otOperationalDatasetTlvs datasetTlvs;
999 SuccessOrExit(error = otDatasetGetActiveTlvs(threadHelper->GetInstance(), &datasetTlvs));
1000 data = std::vector<uint8_t>{std::begin(datasetTlvs.mTlvs), std::begin(datasetTlvs.mTlvs) + datasetTlvs.mLength};
1002 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, data) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);
1008 otError DBusThreadObject::SetRadioRegionHandler(DBusMessageIter &aIter)
1010 auto threadHelper = mNcp->GetThreadHelper();
1011 std::string radioRegion;
1012 uint16_t regionCode;
1013 otError error = OT_ERROR_NONE;
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];
1019 error = otPlatRadioSetRegion(threadHelper->GetInstance(), regionCode);
1025 otError DBusThreadObject::GetRadioRegionHandler(DBusMessageIter &aIter)
1027 auto threadHelper = mNcp->GetThreadHelper();
1028 otError error = OT_ERROR_NONE;
1029 std::string radioRegion;
1030 uint16_t regionCode;
1032 SuccessOrExit(error = otPlatRadioGetRegion(threadHelper->GetInstance(), ®ionCode));
1033 radioRegion.resize(sizeof(uint16_t), '\0');
1034 radioRegion[0] = static_cast<char>((regionCode >> 8) & 0xff);
1035 radioRegion[1] = static_cast<char>(regionCode & 0xff);
1037 VerifyOrExit(DBusMessageEncodeToVariant(&aIter, radioRegion) == OTBR_ERROR_NONE, error = OT_ERROR_INVALID_ARGS);