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(), ®ionCode));
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