xref: /aosp_15_r20/external/ot-br-posix/src/android/otdaemon_server.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
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