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