1 /*
2 * Copyright (c) 2023, 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 <linux/in.h>
30 #define OTBR_LOG_TAG "BINDER"
31
32 #include "android/otdaemon_server.hpp"
33
34 #include <algorithm>
35 #include <net/if.h>
36 #include <random>
37 #include <string.h>
38
39 #include <android/binder_manager.h>
40 #include <android/binder_process.h>
41 #include <openthread/border_agent.h>
42 #include <openthread/border_router.h>
43 #include <openthread/cli.h>
44 #include <openthread/dnssd_server.h>
45 #include <openthread/icmp6.h>
46 #include <openthread/ip6.h>
47 #include <openthread/link.h>
48 #include <openthread/nat64.h>
49 #include <openthread/openthread-system.h>
50 #include <openthread/srp_server.h>
51 #include <openthread/platform/infra_if.h>
52 #include <openthread/platform/radio.h>
53
54 #include "agent/vendor.hpp"
55 #include "android/android_rcp_host.hpp"
56 #include "android/common_utils.hpp"
57 #include "android/otdaemon_telemetry.hpp"
58 #include "common/code_utils.hpp"
59 #include "ncp/thread_host.hpp"
60
61 #define BYTE_ARR_END(arr) ((arr) + sizeof(arr))
62
63 namespace otbr {
64
65 namespace vendor {
66
newInstance(Application & aApplication)67 std::shared_ptr<VendorServer> VendorServer::newInstance(Application &aApplication)
68 {
69 return ndk::SharedRefBase::make<Android::OtDaemonServer>(
70 static_cast<otbr::Ncp::RcpHost &>(aApplication.GetHost()),
71 static_cast<otbr::Android::MdnsPublisher &>(aApplication.GetPublisher()), aApplication.GetBorderAgent());
72 }
73
74 } // namespace vendor
75
76 } // namespace otbr
77
78 namespace otbr {
79 namespace Android {
80
81 static const char OTBR_SERVICE_NAME[] = "ot_daemon";
82 static constexpr size_t kMaxIp6Size = 1280;
83
ThreadEnabledStateToString(int enabledState)84 static const char *ThreadEnabledStateToString(int enabledState)
85 {
86 switch (enabledState)
87 {
88 case IOtDaemon::OT_STATE_ENABLED:
89 return "ENABLED";
90 case IOtDaemon::OT_STATE_DISABLED:
91 return "DISABLED";
92 case IOtDaemon::OT_STATE_DISABLING:
93 return "DISABLING";
94 default:
95 assert(false);
96 return "UNKNOWN";
97 }
98 }
99
100 OtDaemonServer *OtDaemonServer::sOtDaemonServer = nullptr;
101
OtDaemonServer(otbr::Ncp::RcpHost & aRcpHost,otbr::Mdns::Publisher & aMdnsPublisher,otbr::BorderAgent & aBorderAgent)102 OtDaemonServer::OtDaemonServer(otbr::Ncp::RcpHost &aRcpHost,
103 otbr::Mdns::Publisher &aMdnsPublisher,
104 otbr::BorderAgent &aBorderAgent)
105 : mHost(aRcpHost)
106 , mAndroidHost(CreateAndroidHost())
107 , mMdnsPublisher(static_cast<MdnsPublisher &>(aMdnsPublisher))
108 , mBorderAgent(aBorderAgent)
109 {
110 mClientDeathRecipient =
111 ::ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(&OtDaemonServer::BinderDeathCallback));
112 sOtDaemonServer = this;
113 }
114
Init(void)115 void OtDaemonServer::Init(void)
116 {
117 binder_exception_t exp = AServiceManager_registerLazyService(asBinder().get(), OTBR_SERVICE_NAME);
118 SuccessOrDie(exp, "Failed to register OT daemon binder service");
119
120 assert(GetOtInstance() != nullptr);
121
122 mHost.AddThreadStateChangedCallback([this](otChangedFlags aFlags) { StateCallback(aFlags); });
123 otIp6SetAddressCallback(GetOtInstance(), OtDaemonServer::AddressCallback, this);
124 otIp6SetReceiveCallback(GetOtInstance(), OtDaemonServer::ReceiveCallback, this);
125 otBackboneRouterSetMulticastListenerCallback(GetOtInstance(), OtDaemonServer::HandleBackboneMulticastListenerEvent,
126 this);
127 otIcmp6SetEchoMode(GetOtInstance(), OT_ICMP6_ECHO_HANDLER_DISABLED);
128 otIp6SetReceiveFilterEnabled(GetOtInstance(), true);
129 otNat64SetReceiveIp4Callback(GetOtInstance(), &OtDaemonServer::ReceiveCallback, this);
130 mBorderAgent.AddEphemeralKeyChangedCallback([this]() { HandleEpskcStateChanged(); });
131 mBorderAgent.SetEphemeralKeyEnabled(true);
132 otSysUpstreamDnsServerSetResolvConfEnabled(false);
133
134 mTaskRunner.Post(kTelemetryCheckInterval, [this]() { PushTelemetryIfConditionMatch(); });
135 }
136
BinderDeathCallback(void * aBinderServer)137 void OtDaemonServer::BinderDeathCallback(void *aBinderServer)
138 {
139 OtDaemonServer *thisServer = static_cast<OtDaemonServer *>(aBinderServer);
140
141 otbrLogCrit("system_server is dead, removing configs and callbacks...");
142
143 thisServer->mMeshcopTxts = {};
144 thisServer->mINsdPublisher = nullptr;
145
146 // Note that the INsdPublisher reference is held in MdnsPublisher
147 thisServer->mMdnsPublisher.SetINsdPublisher(nullptr);
148
149 thisServer->mCallback = nullptr;
150 thisServer->mTunFd.set(-1); // the original FD will be closed automatically
151 }
152
StateCallback(otChangedFlags aFlags)153 void OtDaemonServer::StateCallback(otChangedFlags aFlags)
154 {
155 std::vector<OnMeshPrefixConfig> onMeshPrefixes;
156
157 assert(GetOtInstance() != nullptr);
158
159 if (RefreshOtDaemonState(aFlags))
160 {
161 if (mCallback == nullptr)
162 {
163 otbrLogWarning("Ignoring OT state changes: callback is not set");
164 }
165 else
166 {
167 NotifyStateChanged(/* aListenerId*/ -1);
168 }
169 }
170
171 if (aFlags & OT_CHANGED_THREAD_BACKBONE_ROUTER_STATE)
172 {
173 if (mCallback == nullptr)
174 {
175 otbrLogWarning("Ignoring OT backbone router state changes: callback is not set");
176 }
177 else
178 {
179 mCallback->onBackboneRouterStateChanged(GetBackboneRouterState());
180 }
181 }
182
183 if ((aFlags & OT_CHANGED_THREAD_NETDATA) && RefreshOnMeshPrefixes())
184 {
185 if (mCallback == nullptr)
186 {
187 otbrLogWarning("Ignoring OT netdata changes: callback is not set");
188 }
189 else
190 {
191 onMeshPrefixes.assign(mOnMeshPrefixes.begin(), mOnMeshPrefixes.end());
192 mCallback->onPrefixChanged(onMeshPrefixes);
193 }
194 }
195 }
196
RefreshOnMeshPrefixes()197 bool OtDaemonServer::RefreshOnMeshPrefixes()
198 {
199 std::set<OnMeshPrefixConfig> onMeshPrefixConfigs;
200 otNetworkDataIterator iterator = OT_NETWORK_DATA_ITERATOR_INIT;
201 otBorderRouterConfig config;
202 bool rv = false;
203
204 VerifyOrExit(GetOtInstance() != nullptr, otbrLogWarning("Can't get on mesh prefixes: OT is not initialized"));
205
206 while (otNetDataGetNextOnMeshPrefix(GetOtInstance(), &iterator, &config) == OT_ERROR_NONE)
207 {
208 OnMeshPrefixConfig onMeshPrefixConfig;
209
210 onMeshPrefixConfig.prefix.assign(std::begin(config.mPrefix.mPrefix.mFields.m8),
211 std::end(config.mPrefix.mPrefix.mFields.m8));
212 onMeshPrefixConfig.prefixLength = config.mPrefix.mLength;
213 onMeshPrefixConfigs.insert(onMeshPrefixConfig);
214 }
215
216 if (mOnMeshPrefixes != onMeshPrefixConfigs)
217 {
218 mOnMeshPrefixes = std::move(onMeshPrefixConfigs);
219 rv = true;
220 }
221 exit:
222 return rv;
223 }
224
ConvertToAddressInfo(const otNetifAddress & aAddress)225 Ipv6AddressInfo OtDaemonServer::ConvertToAddressInfo(const otNetifAddress &aAddress)
226 {
227 Ipv6AddressInfo addrInfo;
228 otIp6Prefix addressPrefix{aAddress.mAddress, aAddress.mPrefixLength};
229
230 addrInfo.address.assign(std::begin(aAddress.mAddress.mFields.m8), std::end(aAddress.mAddress.mFields.m8));
231 addrInfo.prefixLength = aAddress.mPrefixLength;
232 addrInfo.isPreferred = aAddress.mPreferred;
233 addrInfo.isMeshLocal = aAddress.mMeshLocal;
234 addrInfo.isActiveOmr = otNetDataContainsOmrPrefix(GetOtInstance(), &addressPrefix);
235 return addrInfo;
236 }
237
ConvertToAddressInfo(const otNetifMulticastAddress & aAddress)238 Ipv6AddressInfo OtDaemonServer::ConvertToAddressInfo(const otNetifMulticastAddress &aAddress)
239 {
240 Ipv6AddressInfo addrInfo;
241
242 addrInfo.address.assign(std::begin(aAddress.mAddress.mFields.m8), std::end(aAddress.mAddress.mFields.m8));
243 return addrInfo;
244 }
245
AddressCallback(const otIp6AddressInfo * aAddressInfo,bool aIsAdded,void * aBinderServer)246 void OtDaemonServer::AddressCallback(const otIp6AddressInfo *aAddressInfo, bool aIsAdded, void *aBinderServer)
247 {
248 OT_UNUSED_VARIABLE(aAddressInfo);
249 OT_UNUSED_VARIABLE(aIsAdded);
250 OtDaemonServer *thisServer = static_cast<OtDaemonServer *>(aBinderServer);
251 std::vector<Ipv6AddressInfo> addrInfoList;
252 const otNetifAddress *unicastAddrs = otIp6GetUnicastAddresses(thisServer->GetOtInstance());
253 const otNetifMulticastAddress *multicastAddrs = otIp6GetMulticastAddresses(thisServer->GetOtInstance());
254
255 for (const otNetifAddress *addr = unicastAddrs; addr != nullptr; addr = addr->mNext)
256 {
257 addrInfoList.push_back(thisServer->ConvertToAddressInfo(*addr));
258 }
259 for (const otNetifMulticastAddress *maddr = multicastAddrs; maddr != nullptr; maddr = maddr->mNext)
260 {
261 addrInfoList.push_back(thisServer->ConvertToAddressInfo(*maddr));
262 }
263 if (thisServer->mCallback != nullptr)
264 {
265 thisServer->mCallback->onAddressChanged(addrInfoList);
266 }
267 else
268 {
269 otbrLogWarning("OT daemon callback is not set");
270 }
271 }
272
ReceiveCallback(otMessage * aMessage,void * aBinderServer)273 void OtDaemonServer::ReceiveCallback(otMessage *aMessage, void *aBinderServer)
274 {
275 static_cast<OtDaemonServer *>(aBinderServer)->ReceiveCallback(aMessage);
276 }
277
278 // TODO: b/291053118 - We should reuse the same code in openthread/src/posix/platform/netif.cpp
ReceiveCallback(otMessage * aMessage)279 void OtDaemonServer::ReceiveCallback(otMessage *aMessage)
280 {
281 char packet[kMaxIp6Size];
282 uint16_t length = otMessageGetLength(aMessage);
283 int fd = mTunFd.get();
284
285 VerifyOrExit(fd != -1, otbrLogWarning("Ignoring egress packet: invalid tunnel FD"));
286
287 if (otMessageRead(aMessage, 0, packet, sizeof(packet)) != length)
288 {
289 otbrLogWarning("Failed to read packet from otMessage");
290 ExitNow();
291 }
292
293 if (write(fd, packet, length) != length)
294 {
295 otbrLogWarning("Failed to send packet over tunnel interface: %s", strerror(errno));
296 }
297
298 exit:
299 otMessageFree(aMessage);
300 }
301
302 static constexpr uint8_t kIpVersion4 = 4;
303 static constexpr uint8_t kIpVersion6 = 6;
304
305 // TODO: b/291053118 - We should reuse the same code in openthread/src/posix/platform/netif.cpp
getIpVersion(const uint8_t * data)306 static uint8_t getIpVersion(const uint8_t *data)
307 {
308 assert(data != nullptr);
309
310 // Mute compiler warnings.
311 OT_UNUSED_VARIABLE(kIpVersion4);
312 OT_UNUSED_VARIABLE(kIpVersion6);
313
314 return (static_cast<uint8_t>(data[0]) >> 4) & 0x0F;
315 }
316
317 // TODO: b/291053118 - we should use a shared library with ot-posix to handle packet translations
318 // between the tunnel interface and Thread.
TransmitCallback(void)319 void OtDaemonServer::TransmitCallback(void)
320 {
321 char packet[kMaxIp6Size];
322 ssize_t length;
323 otMessage *message = nullptr;
324 otError error = OT_ERROR_NONE;
325 otMessageSettings settings;
326 int fd = mTunFd.get();
327 bool isIp4;
328
329 assert(GetOtInstance() != nullptr);
330
331 VerifyOrExit(fd != -1);
332
333 length = read(fd, packet, sizeof(packet));
334
335 if (length == -1)
336 {
337 otbrLogWarning("Failed to read packet from tunnel interface: %s", strerror(errno));
338 ExitNow();
339 }
340 else if (length == 0)
341 {
342 otbrLogWarning("Unexpected EOF on the tunnel FD");
343 ExitNow();
344 }
345
346 VerifyOrExit(GetOtInstance() != nullptr, otbrLogWarning("Ignoring tunnel packet: OT is not initialized"));
347
348 settings.mLinkSecurityEnabled = (otThreadGetDeviceRole(GetOtInstance()) != OT_DEVICE_ROLE_DISABLED);
349 settings.mPriority = OT_MESSAGE_PRIORITY_LOW;
350
351 isIp4 = (getIpVersion(reinterpret_cast<uint8_t *>(packet)) == kIpVersion4);
352 message = isIp4 ? otIp4NewMessage(GetOtInstance(), &settings) : otIp6NewMessage(GetOtInstance(), &settings);
353 VerifyOrExit(message != nullptr, error = OT_ERROR_NO_BUFS);
354 otMessageSetOrigin(message, OT_MESSAGE_ORIGIN_HOST_UNTRUSTED);
355
356 SuccessOrExit(error = otMessageAppend(message, packet, static_cast<uint16_t>(length)));
357
358 error = isIp4 ? otNat64Send(GetOtInstance(), message) : otIp6Send(GetOtInstance(), message);
359 message = nullptr;
360
361 exit:
362 if (message != nullptr)
363 {
364 otMessageFree(message);
365 }
366
367 if (error != OT_ERROR_NONE)
368 {
369 if (error == OT_ERROR_DROP)
370 {
371 otbrLogInfo("Dropped tunnel packet (length=%d)", length);
372 }
373 else
374 {
375 otbrLogWarning("Failed to transmit tunnel packet: %s", otThreadErrorToString(error));
376 }
377 }
378 }
379
HandleEpskcStateChanged(void * aBinderServer)380 void OtDaemonServer::HandleEpskcStateChanged(void *aBinderServer)
381 {
382 static_cast<OtDaemonServer *>(aBinderServer)->HandleEpskcStateChanged();
383 }
384
HandleEpskcStateChanged(void)385 void OtDaemonServer::HandleEpskcStateChanged(void)
386 {
387 mState.ephemeralKeyState = GetEphemeralKeyState();
388
389 NotifyStateChanged(/* aListenerId*/ -1);
390 }
391
NotifyStateChanged(int64_t aListenerId)392 void OtDaemonServer::NotifyStateChanged(int64_t aListenerId)
393 {
394 if (mState.ephemeralKeyState == OT_EPHEMERAL_KEY_DISABLED)
395 {
396 mState.ephemeralKeyLifetimeMillis = 0;
397 }
398 else
399 {
400 mState.ephemeralKeyLifetimeMillis =
401 mEphemeralKeyExpiryMillis -
402 std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch())
403 .count();
404 }
405 if (mCallback != nullptr)
406 {
407 mCallback->onStateChanged(mState, aListenerId);
408 }
409 }
410
GetEphemeralKeyState(void)411 int OtDaemonServer::GetEphemeralKeyState(void)
412 {
413 int ephemeralKeyState;
414
415 if (otBorderAgentIsEphemeralKeyActive(GetOtInstance()))
416 {
417 if (otBorderAgentGetState(GetOtInstance()) == OT_BORDER_AGENT_STATE_ACTIVE)
418 {
419 ephemeralKeyState = OT_EPHEMERAL_KEY_IN_USE;
420 }
421 else
422 {
423 ephemeralKeyState = OT_EPHEMERAL_KEY_ENABLED;
424 }
425 }
426 else
427 {
428 ephemeralKeyState = OT_EPHEMERAL_KEY_DISABLED;
429 }
430
431 return ephemeralKeyState;
432 }
433
GetBackboneRouterState()434 BackboneRouterState OtDaemonServer::GetBackboneRouterState()
435 {
436 BackboneRouterState state;
437 otBackboneRouterState bbrState;
438 otBackboneRouterMulticastListenerInfo info;
439 otBackboneRouterMulticastListenerIterator iter = OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ITERATOR_INIT;
440 state.listeningAddresses = std::vector<std::string>();
441
442 VerifyOrExit(GetOtInstance() != nullptr, otbrLogWarning("Can't get bbr state: OT is not initialized"));
443
444 bbrState = otBackboneRouterGetState(GetOtInstance());
445 switch (bbrState)
446 {
447 case OT_BACKBONE_ROUTER_STATE_DISABLED:
448 case OT_BACKBONE_ROUTER_STATE_SECONDARY:
449 state.multicastForwardingEnabled = false;
450 break;
451 case OT_BACKBONE_ROUTER_STATE_PRIMARY:
452 state.multicastForwardingEnabled = true;
453 break;
454 }
455
456 while (otBackboneRouterMulticastListenerGetNext(GetOtInstance(), &iter, &info) == OT_ERROR_NONE)
457 {
458 char string[OT_IP6_ADDRESS_STRING_SIZE];
459
460 otIp6AddressToString(&info.mAddress, string, sizeof(string));
461 state.listeningAddresses.push_back(string);
462 }
463
464 exit:
465 return state;
466 }
467
HandleBackboneMulticastListenerEvent(void * aBinderServer,otBackboneRouterMulticastListenerEvent aEvent,const otIp6Address * aAddress)468 void OtDaemonServer::HandleBackboneMulticastListenerEvent(void *aBinderServer,
469 otBackboneRouterMulticastListenerEvent aEvent,
470 const otIp6Address *aAddress)
471 {
472 OtDaemonServer *thisServer = static_cast<OtDaemonServer *>(aBinderServer);
473 char addressString[OT_IP6_ADDRESS_STRING_SIZE];
474
475 otIp6AddressToString(aAddress, addressString, sizeof(addressString));
476
477 otbrLogInfo("Multicast forwarding address changed, %s is %s", addressString,
478 (aEvent == OT_BACKBONE_ROUTER_MULTICAST_LISTENER_ADDED) ? "added" : "removed");
479
480 if (thisServer->mCallback == nullptr)
481 {
482 otbrLogWarning("Ignoring OT multicast listener event: callback is not set");
483 ExitNow();
484 }
485 thisServer->mCallback->onBackboneRouterStateChanged(thisServer->GetBackboneRouterState());
486
487 exit:
488 return;
489 }
490
GetOtInstance()491 otInstance *OtDaemonServer::GetOtInstance()
492 {
493 return mHost.GetInstance();
494 }
495
Update(MainloopContext & aMainloop)496 void OtDaemonServer::Update(MainloopContext &aMainloop)
497 {
498 int fd = mTunFd.get();
499
500 if (fd != -1)
501 {
502 FD_SET(fd, &aMainloop.mReadFdSet);
503 aMainloop.mMaxFd = std::max(aMainloop.mMaxFd, fd);
504 }
505 }
506
Process(const MainloopContext & aMainloop)507 void OtDaemonServer::Process(const MainloopContext &aMainloop)
508 {
509 int fd = mTunFd.get();
510
511 if (fd != -1 && FD_ISSET(fd, &aMainloop.mReadFdSet))
512 {
513 TransmitCallback();
514 }
515 }
516
CreateAndroidHost(void)517 std::unique_ptr<AndroidThreadHost> OtDaemonServer::CreateAndroidHost(void)
518 {
519 std::unique_ptr<AndroidThreadHost> host;
520
521 switch (mHost.GetCoprocessorType())
522 {
523 case OT_COPROCESSOR_RCP:
524 host = std::make_unique<AndroidRcpHost>(static_cast<otbr::Ncp::RcpHost &>(mHost));
525 break;
526
527 case OT_COPROCESSOR_NCP:
528 default:
529 DieNow("Unknown coprocessor type!");
530 break;
531 }
532
533 return host;
534 }
535
initialize(const bool aEnabled,const OtDaemonConfiguration & aConfiguration,const ScopedFileDescriptor & aTunFd,const std::shared_ptr<INsdPublisher> & aINsdPublisher,const MeshcopTxtAttributes & aMeshcopTxts,const std::string & aCountryCode,const bool aTrelEnabled,const std::shared_ptr<IOtDaemonCallback> & aCallback)536 Status OtDaemonServer::initialize(const bool aEnabled,
537 const OtDaemonConfiguration &aConfiguration,
538 const ScopedFileDescriptor &aTunFd,
539 const std::shared_ptr<INsdPublisher> &aINsdPublisher,
540 const MeshcopTxtAttributes &aMeshcopTxts,
541 const std::string &aCountryCode,
542 const bool aTrelEnabled,
543 const std::shared_ptr<IOtDaemonCallback> &aCallback)
544 {
545 otbrLogInfo("OT daemon is initialized by system server (enabled=%s, tunFd=%d)", (aEnabled ? "true" : "false"),
546 aTunFd.get());
547
548 // The copy constructor of `ScopedFileDescriptor` is deleted. It is unable to pass the `aTunFd`
549 // to the lambda function. The processing method of `aTunFd` doesn't call OpenThread functions,
550 // we can process `aTunFd` directly in front of the task.
551 mTunFd = aTunFd.dup();
552
553 mINsdPublisher = aINsdPublisher;
554 mMeshcopTxts = aMeshcopTxts;
555
556 mTaskRunner.Post(
557 [aEnabled, aConfiguration, aINsdPublisher, aMeshcopTxts, aCallback, aCountryCode, aTrelEnabled, this]() {
558 initializeInternal(aEnabled, aConfiguration, mINsdPublisher, mMeshcopTxts, aCountryCode, aTrelEnabled,
559 aCallback);
560 });
561
562 return Status::ok();
563 }
564
initializeInternal(const bool aEnabled,const OtDaemonConfiguration & aConfiguration,const std::shared_ptr<INsdPublisher> & aINsdPublisher,const MeshcopTxtAttributes & aMeshcopTxts,const std::string & aCountryCode,const bool aTrelEnabled,const std::shared_ptr<IOtDaemonCallback> & aCallback)565 void OtDaemonServer::initializeInternal(const bool aEnabled,
566 const OtDaemonConfiguration &aConfiguration,
567 const std::shared_ptr<INsdPublisher> &aINsdPublisher,
568 const MeshcopTxtAttributes &aMeshcopTxts,
569 const std::string &aCountryCode,
570 const bool aTrelEnabled,
571 const std::shared_ptr<IOtDaemonCallback> &aCallback)
572 {
573 std::string instanceName = aMeshcopTxts.vendorName + " " + aMeshcopTxts.modelName;
574 Mdns::Publisher::TxtList nonStandardTxts;
575 otbrError error;
576
577 mAndroidHost->SetConfiguration(aConfiguration, nullptr /* aReceiver */);
578 setCountryCodeInternal(aCountryCode, nullptr /* aReceiver */);
579 registerStateCallbackInternal(aCallback, -1 /* listenerId */);
580
581 mMdnsPublisher.SetINsdPublisher(aINsdPublisher);
582
583 for (const auto &txtAttr : aMeshcopTxts.nonStandardTxtEntries)
584 {
585 nonStandardTxts.emplace_back(txtAttr.name.c_str(), txtAttr.value.data(), txtAttr.value.size());
586 }
587 error = mBorderAgent.SetMeshCopServiceValues(instanceName, aMeshcopTxts.modelName, aMeshcopTxts.vendorName,
588 aMeshcopTxts.vendorOui, nonStandardTxts);
589 if (error != OTBR_ERROR_NONE)
590 {
591 otbrLogCrit("Failed to set MeshCoP values: %d", static_cast<int>(error));
592 }
593
594 mBorderAgent.SetEnabled(aEnabled && aConfiguration.borderRouterEnabled);
595 mAndroidHost->SetTrelEnabled(aTrelEnabled);
596
597 if (aEnabled)
598 {
599 EnableThread(nullptr /* aReceiver */);
600 }
601 else
602 {
603 UpdateThreadEnabledState(OT_STATE_DISABLED, nullptr /* aReceiver */);
604 }
605 }
606
terminate(void)607 Status OtDaemonServer::terminate(void)
608 {
609 mTaskRunner.Post([]() {
610 otbrLogWarning("Terminating ot-daemon process...");
611 exit(0);
612 });
613 return Status::ok();
614 }
615
UpdateThreadEnabledState(const int enabled,const std::shared_ptr<IOtStatusReceiver> & aReceiver)616 void OtDaemonServer::UpdateThreadEnabledState(const int enabled, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
617 {
618 VerifyOrExit(enabled != mState.threadEnabled);
619
620 otbrLogInfo("Thread enabled state changed: %s -> %s", ThreadEnabledStateToString(mState.threadEnabled),
621 ThreadEnabledStateToString(enabled));
622 mState.threadEnabled = enabled;
623
624 if (aReceiver != nullptr)
625 {
626 aReceiver->onSuccess();
627 }
628
629 // Enables the BorderAgent module only when Thread is enabled and configured a Border Router,
630 // so that it won't publish the MeshCoP mDNS service when unnecessary
631 // TODO: b/376217403 - enables / disables OT Border Agent at runtime
632 mBorderAgent.SetEnabled(enabled == OT_STATE_ENABLED && mAndroidHost->GetConfiguration().borderRouterEnabled);
633
634 NotifyStateChanged(/* aListenerId*/ -1);
635
636 exit:
637 return;
638 }
639
EnableThread(const std::shared_ptr<IOtStatusReceiver> & aReceiver)640 void OtDaemonServer::EnableThread(const std::shared_ptr<IOtStatusReceiver> &aReceiver)
641 {
642 otOperationalDatasetTlvs datasetTlvs;
643
644 if (otDatasetGetActiveTlvs(GetOtInstance(), &datasetTlvs) != OT_ERROR_NOT_FOUND && datasetTlvs.mLength > 0 &&
645 !isAttached())
646 {
647 (void)otIp6SetEnabled(GetOtInstance(), true);
648 (void)otThreadSetEnabled(GetOtInstance(), true);
649 }
650 UpdateThreadEnabledState(OT_STATE_ENABLED, aReceiver);
651 }
652
setThreadEnabled(const bool aEnabled,const std::shared_ptr<IOtStatusReceiver> & aReceiver)653 Status OtDaemonServer::setThreadEnabled(const bool aEnabled, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
654 {
655 mTaskRunner.Post([aEnabled, aReceiver, this]() { setThreadEnabledInternal(aEnabled, aReceiver); });
656
657 return Status::ok();
658 }
659
setThreadEnabledInternal(const bool aEnabled,const std::shared_ptr<IOtStatusReceiver> & aReceiver)660 void OtDaemonServer::setThreadEnabledInternal(const bool aEnabled, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
661 {
662 int error = OT_ERROR_NONE;
663 std::string message;
664
665 VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
666
667 VerifyOrExit(mState.threadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
668
669 if ((mState.threadEnabled == OT_STATE_ENABLED) == aEnabled)
670 {
671 aReceiver->onSuccess();
672 ExitNow();
673 }
674
675 if (aEnabled)
676 {
677 EnableThread(aReceiver);
678 }
679 else
680 {
681 // `aReceiver` should not be set here because the operation isn't finished yet
682 UpdateThreadEnabledState(OT_STATE_DISABLING, nullptr /* aReceiver */);
683
684 LeaveGracefully([aReceiver, this]() {
685 // Ignore errors as those operations should always succeed
686 (void)otThreadSetEnabled(GetOtInstance(), false);
687 (void)otIp6SetEnabled(GetOtInstance(), false);
688 UpdateThreadEnabledState(OT_STATE_DISABLED, aReceiver);
689 });
690 }
691
692 exit:
693 if (error != OT_ERROR_NONE)
694 {
695 PropagateResult(error, message, aReceiver);
696 }
697 }
698
activateEphemeralKeyMode(const int64_t aLifetimeMillis,const std::shared_ptr<IOtStatusReceiver> & aReceiver)699 Status OtDaemonServer::activateEphemeralKeyMode(const int64_t aLifetimeMillis,
700 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
701 {
702 mTaskRunner.Post(
703 [aLifetimeMillis, aReceiver, this]() { activateEphemeralKeyModeInternal(aLifetimeMillis, aReceiver); });
704
705 return Status::ok();
706 }
707
activateEphemeralKeyModeInternal(const int64_t aLifetimeMillis,const std::shared_ptr<IOtStatusReceiver> & aReceiver)708 void OtDaemonServer::activateEphemeralKeyModeInternal(const int64_t aLifetimeMillis,
709 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
710 {
711 int error = OT_ERROR_NONE;
712 std::string message;
713 std::string passcode;
714
715 VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
716 VerifyOrExit(isAttached(), error = static_cast<int>(IOtDaemon::ErrorCode::OT_ERROR_FAILED_PRECONDITION),
717 message = "Cannot activate ephemeral key mode when this device is not attached to Thread network");
718 VerifyOrExit(!otBorderAgentIsEphemeralKeyActive(GetOtInstance()), error = OT_ERROR_BUSY,
719 message = "ephemeral key mode is already activated");
720
721 otbrLogInfo("Activating ephemeral key mode with %lldms lifetime.", aLifetimeMillis);
722
723 SuccessOrExit(error = mBorderAgent.CreateEphemeralKey(passcode), message = "Failed to create ephemeral key");
724 SuccessOrExit(error = otBorderAgentSetEphemeralKey(GetOtInstance(), passcode.c_str(),
725 static_cast<uint32_t>(aLifetimeMillis), 0 /* aUdpPort */),
726 message = "Failed to set ephemeral key");
727
728 exit:
729 if (aReceiver != nullptr)
730 {
731 if (error == OT_ERROR_NONE)
732 {
733 mState.ephemeralKeyPasscode = passcode;
734 mEphemeralKeyExpiryMillis = std::chrono::duration_cast<std::chrono::milliseconds>(
735 std::chrono::steady_clock::now().time_since_epoch())
736 .count() +
737 aLifetimeMillis;
738 aReceiver->onSuccess();
739 }
740 else
741 {
742 aReceiver->onError(error, message);
743 }
744 }
745 }
746
deactivateEphemeralKeyMode(const std::shared_ptr<IOtStatusReceiver> & aReceiver)747 Status OtDaemonServer::deactivateEphemeralKeyMode(const std::shared_ptr<IOtStatusReceiver> &aReceiver)
748 {
749 mTaskRunner.Post([aReceiver, this]() { deactivateEphemeralKeyModeInternal(aReceiver); });
750
751 return Status::ok();
752 }
753
deactivateEphemeralKeyModeInternal(const std::shared_ptr<IOtStatusReceiver> & aReceiver)754 void OtDaemonServer::deactivateEphemeralKeyModeInternal(const std::shared_ptr<IOtStatusReceiver> &aReceiver)
755 {
756 int error = OT_ERROR_NONE;
757 std::string message;
758
759 VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
760 otbrLogInfo("Deactivating ephemeral key mode.");
761
762 VerifyOrExit(otBorderAgentIsEphemeralKeyActive(GetOtInstance()), error = OT_ERROR_NONE);
763
764 otBorderAgentDisconnect(GetOtInstance());
765 otBorderAgentClearEphemeralKey(GetOtInstance());
766
767 exit:
768 PropagateResult(error, message, aReceiver);
769 }
770
registerStateCallback(const std::shared_ptr<IOtDaemonCallback> & aCallback,int64_t aListenerId)771 Status OtDaemonServer::registerStateCallback(const std::shared_ptr<IOtDaemonCallback> &aCallback, int64_t aListenerId)
772 {
773 mTaskRunner.Post([aCallback, aListenerId, this]() { registerStateCallbackInternal(aCallback, aListenerId); });
774
775 return Status::ok();
776 }
777
registerStateCallbackInternal(const std::shared_ptr<IOtDaemonCallback> & aCallback,int64_t aListenerId)778 void OtDaemonServer::registerStateCallbackInternal(const std::shared_ptr<IOtDaemonCallback> &aCallback,
779 int64_t aListenerId)
780 {
781 VerifyOrExit(GetOtInstance() != nullptr, otbrLogWarning("OT is not initialized"));
782
783 mCallback = aCallback;
784 if (mCallback != nullptr)
785 {
786 AIBinder_linkToDeath(mCallback->asBinder().get(), mClientDeathRecipient.get(), this);
787 }
788
789 // To ensure that a client app can get the latest correct state immediately when registering a
790 // state callback, here needs to invoke the callback
791 RefreshOtDaemonState(/* aFlags */ 0xffffffff);
792 NotifyStateChanged(aListenerId);
793 mCallback->onBackboneRouterStateChanged(GetBackboneRouterState());
794
795 exit:
796 return;
797 }
798
RefreshOtDaemonState(otChangedFlags aFlags)799 bool OtDaemonServer::RefreshOtDaemonState(otChangedFlags aFlags)
800 {
801 bool haveUpdates = false;
802
803 if (aFlags & OT_CHANGED_THREAD_NETIF_STATE)
804 {
805 mState.isInterfaceUp = mHost.Ip6IsEnabled();
806 haveUpdates = true;
807 }
808
809 if (aFlags & OT_CHANGED_THREAD_ROLE)
810 {
811 mState.deviceRole = mHost.GetDeviceRole();
812 haveUpdates = true;
813 }
814
815 if (aFlags & OT_CHANGED_THREAD_PARTITION_ID)
816 {
817 mState.partitionId = mHost.GetPartitionId();
818 haveUpdates = true;
819 }
820
821 if (aFlags & OT_CHANGED_ACTIVE_DATASET)
822 {
823 otOperationalDatasetTlvs datasetTlvs;
824 mHost.GetDatasetActiveTlvs(datasetTlvs);
825 mState.activeDatasetTlvs.assign(datasetTlvs.mTlvs, datasetTlvs.mTlvs + datasetTlvs.mLength);
826
827 haveUpdates = true;
828 }
829
830 if (aFlags & OT_CHANGED_PENDING_DATASET)
831 {
832 otOperationalDatasetTlvs datasetTlvs;
833 mHost.GetDatasetPendingTlvs(datasetTlvs);
834 mState.pendingDatasetTlvs.assign(datasetTlvs.mTlvs, datasetTlvs.mTlvs + datasetTlvs.mLength);
835
836 haveUpdates = true;
837 }
838
839 if (isAttached() && !mState.activeDatasetTlvs.empty() && mJoinReceiver != nullptr)
840 {
841 otbrLogInfo("Join succeeded");
842 mJoinReceiver->onSuccess();
843 mJoinReceiver = nullptr;
844 }
845
846 return haveUpdates;
847 }
848
849 /**
850 * Returns `true` if the two TLV lists are representing the same Operational Dataset.
851 *
852 * Note this method works even if TLVs in `aLhs` and `aRhs` are not ordered.
853 */
areDatasetsEqual(const otOperationalDatasetTlvs & aLhs,const otOperationalDatasetTlvs & aRhs)854 static bool areDatasetsEqual(const otOperationalDatasetTlvs &aLhs, const otOperationalDatasetTlvs &aRhs)
855 {
856 bool result = false;
857
858 otOperationalDataset lhsDataset;
859 otOperationalDataset rhsDataset;
860 otOperationalDatasetTlvs lhsNormalizedTlvs;
861 otOperationalDatasetTlvs rhsNormalizedTlvs;
862
863 // Sort the TLVs in the TLV byte arrays by leveraging the deterministic nature of the two OT APIs
864 SuccessOrExit(otDatasetParseTlvs(&aLhs, &lhsDataset));
865 SuccessOrExit(otDatasetParseTlvs(&aRhs, &rhsDataset));
866 otDatasetConvertToTlvs(&lhsDataset, &lhsNormalizedTlvs);
867 otDatasetConvertToTlvs(&rhsDataset, &rhsNormalizedTlvs);
868
869 result = (lhsNormalizedTlvs.mLength == rhsNormalizedTlvs.mLength) &&
870 (memcmp(lhsNormalizedTlvs.mTlvs, rhsNormalizedTlvs.mTlvs, lhsNormalizedTlvs.mLength) == 0);
871
872 exit:
873 return result;
874 }
875
join(const std::vector<uint8_t> & aActiveOpDatasetTlvs,const std::shared_ptr<IOtStatusReceiver> & aReceiver)876 Status OtDaemonServer::join(const std::vector<uint8_t> &aActiveOpDatasetTlvs,
877 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
878 {
879 mTaskRunner.Post([aActiveOpDatasetTlvs, aReceiver, this]() { joinInternal(aActiveOpDatasetTlvs, aReceiver); });
880
881 return Status::ok();
882 }
883
joinInternal(const std::vector<uint8_t> & aActiveOpDatasetTlvs,const std::shared_ptr<IOtStatusReceiver> & aReceiver)884 void OtDaemonServer::joinInternal(const std::vector<uint8_t> &aActiveOpDatasetTlvs,
885 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
886 {
887 int error = OT_ERROR_NONE;
888 std::string message;
889 otOperationalDatasetTlvs newDatasetTlvs;
890 otOperationalDatasetTlvs curDatasetTlvs;
891
892 VerifyOrExit(mState.threadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
893
894 VerifyOrExit(mState.threadEnabled == OT_STATE_ENABLED,
895 error = static_cast<int>(IOtDaemon::ErrorCode::OT_ERROR_THREAD_DISABLED),
896 message = "Thread is disabled");
897
898 otbrLogInfo("Start joining...");
899
900 VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
901
902 std::copy(aActiveOpDatasetTlvs.begin(), aActiveOpDatasetTlvs.end(), newDatasetTlvs.mTlvs);
903 newDatasetTlvs.mLength = static_cast<uint8_t>(aActiveOpDatasetTlvs.size());
904
905 error = otDatasetGetActiveTlvs(GetOtInstance(), &curDatasetTlvs);
906 if (error == OT_ERROR_NONE && areDatasetsEqual(newDatasetTlvs, curDatasetTlvs) && isAttached())
907 {
908 // Do not leave and re-join if this device has already joined the same network. This can help elimilate
909 // unnecessary connectivity and topology disruption and save the time for re-joining. It's more useful for use
910 // cases where Thread networks are dynamically brought up and torn down (e.g. Thread on mobile phones).
911 aReceiver->onSuccess();
912 ExitNow();
913 }
914
915 if (otThreadGetDeviceRole(GetOtInstance()) != OT_DEVICE_ROLE_DISABLED)
916 {
917 LeaveGracefully([aActiveOpDatasetTlvs, aReceiver, this]() {
918 FinishLeave(true /* aEraseDataset */, nullptr);
919 join(aActiveOpDatasetTlvs, aReceiver);
920 });
921 ExitNow();
922 }
923
924 SuccessOrExit(error = otDatasetSetActiveTlvs(GetOtInstance(), &newDatasetTlvs),
925 message = "Failed to set Active Operational Dataset");
926
927 // TODO(b/273160198): check how we can implement join as a child
928
929 // Shouldn't we have an equivalent `otThreadAttach` method vs `otThreadDetachGracefully`?
930 SuccessOrExit(error = otIp6SetEnabled(GetOtInstance(), true), message = "Failed to bring up Thread interface");
931 SuccessOrExit(error = otThreadSetEnabled(GetOtInstance(), true), message = "Failed to bring up Thread stack");
932
933 // Abort an ongoing join()
934 if (mJoinReceiver != nullptr)
935 {
936 mJoinReceiver->onError(OT_ERROR_ABORT, "Join() is aborted");
937 }
938 mJoinReceiver = aReceiver;
939
940 exit:
941 if (error != OT_ERROR_NONE)
942 {
943 PropagateResult(error, message, aReceiver);
944 }
945 }
946
leave(bool aEraseDataset,const std::shared_ptr<IOtStatusReceiver> & aReceiver)947 Status OtDaemonServer::leave(bool aEraseDataset, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
948 {
949 mTaskRunner.Post([aEraseDataset, aReceiver, this]() { leaveInternal(aEraseDataset, aReceiver); });
950
951 return Status::ok();
952 }
953
leaveInternal(bool aEraseDataset,const std::shared_ptr<IOtStatusReceiver> & aReceiver)954 void OtDaemonServer::leaveInternal(bool aEraseDataset, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
955 {
956 std::string message;
957 int error = OT_ERROR_NONE;
958
959 VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
960
961 VerifyOrExit(mState.threadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
962
963 if (mState.threadEnabled == OT_STATE_DISABLED)
964 {
965 FinishLeave(aEraseDataset, aReceiver);
966 ExitNow();
967 }
968
969 LeaveGracefully([aEraseDataset, aReceiver, this]() { FinishLeave(aEraseDataset, aReceiver); });
970
971 exit:
972 if (error != OT_ERROR_NONE)
973 {
974 PropagateResult(error, message, aReceiver);
975 }
976 }
977
FinishLeave(bool aEraseDataset,const std::shared_ptr<IOtStatusReceiver> & aReceiver)978 void OtDaemonServer::FinishLeave(bool aEraseDataset, const std::shared_ptr<IOtStatusReceiver> &aReceiver)
979 {
980 if (aEraseDataset)
981 {
982 (void)otInstanceErasePersistentInfo(GetOtInstance());
983 }
984
985 // TODO: b/323301831 - Re-init the Application class.
986 if (aReceiver != nullptr)
987 {
988 aReceiver->onSuccess();
989 }
990 }
991
LeaveGracefully(const LeaveCallback & aReceiver)992 void OtDaemonServer::LeaveGracefully(const LeaveCallback &aReceiver)
993 {
994 mLeaveCallbacks.push_back(aReceiver);
995
996 // Ignores the OT_ERROR_BUSY error if a detach has already been requested
997 (void)otThreadDetachGracefully(GetOtInstance(), DetachGracefullyCallback, this);
998 }
999
DetachGracefullyCallback(void * aBinderServer)1000 void OtDaemonServer::DetachGracefullyCallback(void *aBinderServer)
1001 {
1002 OtDaemonServer *thisServer = static_cast<OtDaemonServer *>(aBinderServer);
1003 thisServer->DetachGracefullyCallback();
1004 }
1005
DetachGracefullyCallback(void)1006 void OtDaemonServer::DetachGracefullyCallback(void)
1007 {
1008 otbrLogInfo("detach success...");
1009
1010 if (mJoinReceiver != nullptr)
1011 {
1012 mJoinReceiver->onError(OT_ERROR_ABORT, "Aborted by leave/disable operation");
1013 mJoinReceiver = nullptr;
1014 }
1015
1016 if (mMigrationReceiver != nullptr)
1017 {
1018 mMigrationReceiver->onError(OT_ERROR_ABORT, "Aborted by leave/disable operation");
1019 mMigrationReceiver = nullptr;
1020 }
1021
1022 for (auto &callback : mLeaveCallbacks)
1023 {
1024 callback();
1025 }
1026 mLeaveCallbacks.clear();
1027 }
1028
isAttached()1029 bool OtDaemonServer::isAttached()
1030 {
1031 otDeviceRole role = otThreadGetDeviceRole(GetOtInstance());
1032
1033 return role == OT_DEVICE_ROLE_CHILD || role == OT_DEVICE_ROLE_ROUTER || role == OT_DEVICE_ROLE_LEADER;
1034 }
1035
scheduleMigration(const std::vector<uint8_t> & aPendingOpDatasetTlvs,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1036 Status OtDaemonServer::scheduleMigration(const std::vector<uint8_t> &aPendingOpDatasetTlvs,
1037 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1038 {
1039 mTaskRunner.Post(
1040 [aPendingOpDatasetTlvs, aReceiver, this]() { scheduleMigrationInternal(aPendingOpDatasetTlvs, aReceiver); });
1041
1042 return Status::ok();
1043 }
1044
scheduleMigrationInternal(const std::vector<uint8_t> & aPendingOpDatasetTlvs,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1045 void OtDaemonServer::scheduleMigrationInternal(const std::vector<uint8_t> &aPendingOpDatasetTlvs,
1046 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1047 {
1048 int error = OT_ERROR_NONE;
1049 std::string message;
1050 otOperationalDataset emptyDataset;
1051
1052 VerifyOrExit(mState.threadEnabled != OT_STATE_DISABLING, error = OT_ERROR_BUSY, message = "Thread is disabling");
1053
1054 VerifyOrExit(mState.threadEnabled == OT_STATE_ENABLED,
1055 error = static_cast<int>(IOtDaemon::ErrorCode::OT_ERROR_THREAD_DISABLED),
1056 message = "Thread is disabled");
1057
1058 if (GetOtInstance() == nullptr)
1059 {
1060 message = "OT is not initialized";
1061 ExitNow(error = OT_ERROR_INVALID_STATE);
1062 }
1063 if (!isAttached())
1064 {
1065 message = "Cannot schedule migration when this device is detached";
1066 ExitNow(error = static_cast<int>(IOtDaemon::ErrorCode::OT_ERROR_FAILED_PRECONDITION));
1067 }
1068
1069 // TODO: check supported channel mask
1070
1071 error = otDatasetSendMgmtPendingSet(GetOtInstance(), &emptyDataset, aPendingOpDatasetTlvs.data(),
1072 static_cast<uint8_t>(aPendingOpDatasetTlvs.size()), SendMgmtPendingSetCallback,
1073 /* aBinderServer= */ this);
1074 if (error != OT_ERROR_NONE)
1075 {
1076 message = "Failed to send MGMT_PENDING_SET.req";
1077 }
1078
1079 exit:
1080 if (error != OT_ERROR_NONE)
1081 {
1082 PropagateResult(error, message, aReceiver);
1083 }
1084 else
1085 {
1086 // otDatasetSendMgmtPendingSet() returns OT_ERROR_BUSY if it has already been called before but the
1087 // callback hasn't been invoked. So we can guarantee that mMigrationReceiver is always nullptr here
1088 assert(mMigrationReceiver == nullptr);
1089 mMigrationReceiver = aReceiver;
1090 }
1091 }
1092
SendMgmtPendingSetCallback(otError aResult,void * aBinderServer)1093 void OtDaemonServer::SendMgmtPendingSetCallback(otError aResult, void *aBinderServer)
1094 {
1095 OtDaemonServer *thisServer = static_cast<OtDaemonServer *>(aBinderServer);
1096
1097 if (thisServer->mMigrationReceiver != nullptr)
1098 {
1099 PropagateResult(aResult, "Failed to register Pending Dataset to leader", thisServer->mMigrationReceiver);
1100 thisServer->mMigrationReceiver = nullptr;
1101 }
1102 }
1103
setCountryCode(const std::string & aCountryCode,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1104 Status OtDaemonServer::setCountryCode(const std::string &aCountryCode,
1105 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1106 {
1107 mTaskRunner.Post([aCountryCode, aReceiver, this]() { setCountryCodeInternal(aCountryCode, aReceiver); });
1108
1109 return Status::ok();
1110 }
1111
setCountryCodeInternal(const std::string & aCountryCode,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1112 void OtDaemonServer::setCountryCodeInternal(const std::string &aCountryCode,
1113 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1114 {
1115 mHost.SetCountryCode(aCountryCode, [aReceiver](otError aError, const std::string &aMessage) {
1116 PropagateResult(aError, aMessage, aReceiver);
1117 });
1118 }
1119
getChannelMasks(const std::shared_ptr<IChannelMasksReceiver> & aReceiver)1120 Status OtDaemonServer::getChannelMasks(const std::shared_ptr<IChannelMasksReceiver> &aReceiver)
1121 {
1122 mTaskRunner.Post([aReceiver, this]() { getChannelMasksInternal(aReceiver); });
1123
1124 return Status::ok();
1125 }
1126
getChannelMasksInternal(const std::shared_ptr<IChannelMasksReceiver> & aReceiver)1127 void OtDaemonServer::getChannelMasksInternal(const std::shared_ptr<IChannelMasksReceiver> &aReceiver)
1128 {
1129 auto channelMasksReceiver = [aReceiver](uint32_t aSupportedChannelMask, uint32_t aPreferredChannelMask) {
1130 aReceiver->onSuccess(aSupportedChannelMask, aPreferredChannelMask);
1131 };
1132 auto errorReceiver = [aReceiver](otError aError, const std::string &aMessage) {
1133 aReceiver->onError(aError, aMessage);
1134 };
1135 mHost.GetChannelMasks(channelMasksReceiver, errorReceiver);
1136 }
1137
setChannelMaxPowers(const std::vector<ChannelMaxPower> & aChannelMaxPowers,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1138 Status OtDaemonServer::setChannelMaxPowers(const std::vector<ChannelMaxPower> &aChannelMaxPowers,
1139 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1140 {
1141 mTaskRunner.Post(
1142 [aChannelMaxPowers, aReceiver, this]() { setChannelMaxPowersInternal(aChannelMaxPowers, aReceiver); });
1143
1144 return Status::ok();
1145 }
1146
setChannelMaxPowersInternal(const std::vector<ChannelMaxPower> & aChannelMaxPowers,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1147 Status OtDaemonServer::setChannelMaxPowersInternal(const std::vector<ChannelMaxPower> &aChannelMaxPowers,
1148 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1149 {
1150 // Transform aidl ChannelMaxPower to ThreadHost::ChannelMaxPower
1151 std::vector<Ncp::ThreadHost::ChannelMaxPower> channelMaxPowers(aChannelMaxPowers.size());
1152 std::transform(aChannelMaxPowers.begin(), aChannelMaxPowers.end(), channelMaxPowers.begin(),
1153 [](const ChannelMaxPower &aChannelMaxPower) {
1154 // INT_MIN indicates that the corresponding channel is disabled in Thread Android API
1155 // `setChannelMaxPowers()` INT16_MAX indicates that the corresponding channel is disabled in
1156 // OpenThread API `otPlatRadioSetChannelTargetPower()`.
1157 return Ncp::ThreadHost::ChannelMaxPower(
1158 aChannelMaxPower.channel,
1159 aChannelMaxPower.maxPower == INT_MIN
1160 ? INT16_MAX
1161 : std::clamp(aChannelMaxPower.maxPower, INT16_MIN, INT16_MAX - 1));
1162 });
1163
1164 mHost.SetChannelMaxPowers(channelMaxPowers, [aReceiver](otError aError, const std::string &aMessage) {
1165 PropagateResult(aError, aMessage, aReceiver);
1166 });
1167
1168 return Status::ok();
1169 }
1170
setConfiguration(const OtDaemonConfiguration & aConfiguration,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1171 Status OtDaemonServer::setConfiguration(const OtDaemonConfiguration &aConfiguration,
1172 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1173 {
1174 mTaskRunner.Post(
1175 [aConfiguration, aReceiver, this]() { mAndroidHost->SetConfiguration(aConfiguration, aReceiver); });
1176
1177 return Status::ok();
1178 }
1179
setInfraLinkInterfaceName(const std::optional<std::string> & aInterfaceName,const ScopedFileDescriptor & aIcmp6Socket,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1180 Status OtDaemonServer::setInfraLinkInterfaceName(const std::optional<std::string> &aInterfaceName,
1181 const ScopedFileDescriptor &aIcmp6Socket,
1182 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1183 {
1184 int icmp6Socket = aIcmp6Socket.dup().release();
1185
1186 mTaskRunner.Post([interfaceName = aInterfaceName.value_or(""), icmp6Socket, aReceiver, this]() {
1187 mAndroidHost->SetInfraLinkInterfaceName(interfaceName, icmp6Socket, aReceiver);
1188 });
1189
1190 return Status::ok();
1191 }
1192
runOtCtlCommand(const std::string & aCommand,const bool aIsInteractive,const std::shared_ptr<IOtOutputReceiver> & aReceiver)1193 Status OtDaemonServer::runOtCtlCommand(const std::string &aCommand,
1194 const bool aIsInteractive,
1195 const std::shared_ptr<IOtOutputReceiver> &aReceiver)
1196 {
1197 mTaskRunner.Post([aCommand, aIsInteractive, aReceiver, this]() {
1198 runOtCtlCommandInternal(aCommand, aIsInteractive, aReceiver);
1199 });
1200
1201 return Status::ok();
1202 }
1203
setInfraLinkNat64Prefix(const std::optional<std::string> & aNat64Prefix,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1204 Status OtDaemonServer::setInfraLinkNat64Prefix(const std::optional<std::string> &aNat64Prefix,
1205 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1206 {
1207 mTaskRunner.Post([nat64Prefix = aNat64Prefix.value_or(""), aReceiver, this]() {
1208 mAndroidHost->SetInfraLinkNat64Prefix(nat64Prefix, aReceiver);
1209 });
1210
1211 return Status::ok();
1212 }
1213
runOtCtlCommandInternal(const std::string & aCommand,const bool aIsInteractive,const std::shared_ptr<IOtOutputReceiver> & aReceiver)1214 void OtDaemonServer::runOtCtlCommandInternal(const std::string &aCommand,
1215 const bool aIsInteractive,
1216 const std::shared_ptr<IOtOutputReceiver> &aReceiver)
1217 {
1218 mAndroidHost->RunOtCtlCommand(aCommand, aIsInteractive, aReceiver);
1219 }
1220
setInfraLinkDnsServers(const std::vector<std::string> & aDnsServers,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1221 Status OtDaemonServer::setInfraLinkDnsServers(const std::vector<std::string> &aDnsServers,
1222 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1223 {
1224 mTaskRunner.Post(
1225 [aDnsServers, aReceiver, this]() { mAndroidHost->SetInfraLinkDnsServers(aDnsServers, aReceiver); });
1226
1227 return Status::ok();
1228 }
1229
dump(int aFd,const char ** aArgs,uint32_t aNumArgs)1230 binder_status_t OtDaemonServer::dump(int aFd, const char **aArgs, uint32_t aNumArgs)
1231 {
1232 return mAndroidHost->Dump(aFd, aArgs, aNumArgs);
1233 }
1234
PushTelemetryIfConditionMatch()1235 void OtDaemonServer::PushTelemetryIfConditionMatch()
1236 {
1237 VerifyOrExit(GetOtInstance() != nullptr);
1238
1239 // TODO: Push telemetry per kTelemetryUploadIntervalThreshold instead of on startup.
1240 // TODO: Save unpushed telemetries in local cache to avoid data loss.
1241 RetrieveAndPushAtoms(GetOtInstance());
1242 mTaskRunner.Post(kTelemetryUploadIntervalThreshold, [this]() { PushTelemetryIfConditionMatch(); });
1243
1244 exit:
1245 return;
1246 }
1247
setNat64Cidr(const std::optional<std::string> & aCidr,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1248 Status OtDaemonServer::setNat64Cidr(const std::optional<std::string> &aCidr,
1249 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1250 {
1251 mTaskRunner.Post([aCidr, aReceiver, this]() { setNat64CidrInternal(aCidr, aReceiver); });
1252
1253 return Status::ok();
1254 }
1255
setNat64CidrInternal(const std::optional<std::string> & aCidr,const std::shared_ptr<IOtStatusReceiver> & aReceiver)1256 void OtDaemonServer::setNat64CidrInternal(const std::optional<std::string> &aCidr,
1257 const std::shared_ptr<IOtStatusReceiver> &aReceiver)
1258 {
1259 otError error = OT_ERROR_NONE;
1260 std::string message;
1261
1262 VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
1263
1264 if (aCidr.has_value())
1265 {
1266 otIp4Cidr nat64Cidr{};
1267
1268 otbrLogInfo("Setting NAT64 CIDR: %s", aCidr->c_str());
1269 SuccessOrExit(error = otIp4CidrFromString(aCidr->c_str(), &nat64Cidr), message = "Failed to parse NAT64 CIDR");
1270 SuccessOrExit(error = otNat64SetIp4Cidr(GetOtInstance(), &nat64Cidr), message = "Failed to set NAT64 CIDR");
1271 }
1272 else
1273 {
1274 otbrLogInfo("Clearing NAT64 CIDR");
1275 otNat64ClearIp4Cidr(GetOtInstance());
1276 }
1277
1278 exit:
1279 PropagateResult(error, message, aReceiver);
1280 }
1281
1282 } // namespace Android
1283 } // namespace otbr
1284