xref: /aosp_15_r20/external/ot-br-posix/src/android/android_rcp_host.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *  Copyright (c) 2024, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker  *  All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker  *
5*4a64e381SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker  *
16*4a64e381SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker  */
28*4a64e381SAndroid Build Coastguard Worker 
29*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "ARCP_HOST"
30*4a64e381SAndroid Build Coastguard Worker 
31*4a64e381SAndroid Build Coastguard Worker #include "android_rcp_host.hpp"
32*4a64e381SAndroid Build Coastguard Worker 
33*4a64e381SAndroid Build Coastguard Worker #include <net/if.h>
34*4a64e381SAndroid Build Coastguard Worker #include <vector>
35*4a64e381SAndroid Build Coastguard Worker 
36*4a64e381SAndroid Build Coastguard Worker #include <android-base/file.h>
37*4a64e381SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
38*4a64e381SAndroid Build Coastguard Worker #include <openthread/backbone_router_ftd.h>
39*4a64e381SAndroid Build Coastguard Worker #include <openthread/border_routing.h>
40*4a64e381SAndroid Build Coastguard Worker #include <openthread/dnssd_server.h>
41*4a64e381SAndroid Build Coastguard Worker #include <openthread/ip6.h>
42*4a64e381SAndroid Build Coastguard Worker #include <openthread/nat64.h>
43*4a64e381SAndroid Build Coastguard Worker #include <openthread/openthread-system.h>
44*4a64e381SAndroid Build Coastguard Worker #include <openthread/srp_server.h>
45*4a64e381SAndroid Build Coastguard Worker #include <openthread/thread.h>
46*4a64e381SAndroid Build Coastguard Worker #include <openthread/trel.h>
47*4a64e381SAndroid Build Coastguard Worker #include <openthread/platform/infra_if.h>
48*4a64e381SAndroid Build Coastguard Worker #include <openthread/platform/trel.h>
49*4a64e381SAndroid Build Coastguard Worker 
50*4a64e381SAndroid Build Coastguard Worker #include "android/common_utils.hpp"
51*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
52*4a64e381SAndroid Build Coastguard Worker 
53*4a64e381SAndroid Build Coastguard Worker namespace otbr {
54*4a64e381SAndroid Build Coastguard Worker namespace Android {
55*4a64e381SAndroid Build Coastguard Worker 
56*4a64e381SAndroid Build Coastguard Worker AndroidRcpHost *AndroidRcpHost::sAndroidRcpHost = nullptr;
57*4a64e381SAndroid Build Coastguard Worker 
AndroidRcpHost(Ncp::RcpHost & aRcpHost)58*4a64e381SAndroid Build Coastguard Worker AndroidRcpHost::AndroidRcpHost(Ncp::RcpHost &aRcpHost)
59*4a64e381SAndroid Build Coastguard Worker     : mRcpHost(aRcpHost)
60*4a64e381SAndroid Build Coastguard Worker     , mConfiguration()
61*4a64e381SAndroid Build Coastguard Worker     , mInfraIcmp6Socket(-1)
62*4a64e381SAndroid Build Coastguard Worker {
63*4a64e381SAndroid Build Coastguard Worker     mInfraLinkState.interfaceName = "";
64*4a64e381SAndroid Build Coastguard Worker 
65*4a64e381SAndroid Build Coastguard Worker     sAndroidRcpHost = this;
66*4a64e381SAndroid Build Coastguard Worker }
67*4a64e381SAndroid Build Coastguard Worker 
SetConfiguration(const OtDaemonConfiguration & aConfiguration,const std::shared_ptr<IOtStatusReceiver> & aReceiver)68*4a64e381SAndroid Build Coastguard Worker void AndroidRcpHost::SetConfiguration(const OtDaemonConfiguration              &aConfiguration,
69*4a64e381SAndroid Build Coastguard Worker                                       const std::shared_ptr<IOtStatusReceiver> &aReceiver)
70*4a64e381SAndroid Build Coastguard Worker {
71*4a64e381SAndroid Build Coastguard Worker     otError          error = OT_ERROR_NONE;
72*4a64e381SAndroid Build Coastguard Worker     std::string      message;
73*4a64e381SAndroid Build Coastguard Worker     otLinkModeConfig linkModeConfig;
74*4a64e381SAndroid Build Coastguard Worker 
75*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Set configuration: %s", aConfiguration.toString().c_str());
76*4a64e381SAndroid Build Coastguard Worker 
77*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
78*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(aConfiguration != mConfiguration);
79*4a64e381SAndroid Build Coastguard Worker 
80*4a64e381SAndroid Build Coastguard Worker     // TODO: b/343814054 - Support enabling/disabling DHCPv6-PD.
81*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(!aConfiguration.dhcpv6PdEnabled, error = OT_ERROR_NOT_IMPLEMENTED,
82*4a64e381SAndroid Build Coastguard Worker                  message = "DHCPv6-PD is not supported");
83*4a64e381SAndroid Build Coastguard Worker     otNat64SetEnabled(GetOtInstance(), aConfiguration.nat64Enabled);
84*4a64e381SAndroid Build Coastguard Worker     // DNS upstream query is enabled if and only if NAT64 is enabled.
85*4a64e381SAndroid Build Coastguard Worker     otDnssdUpstreamQuerySetEnabled(GetOtInstance(), aConfiguration.nat64Enabled);
86*4a64e381SAndroid Build Coastguard Worker 
87*4a64e381SAndroid Build Coastguard Worker     linkModeConfig = GetLinkModeConfig(aConfiguration.borderRouterEnabled);
88*4a64e381SAndroid Build Coastguard Worker     SuccessOrExit(error = otThreadSetLinkMode(GetOtInstance(), linkModeConfig), message = "Failed to set link mode");
89*4a64e381SAndroid Build Coastguard Worker     if (aConfiguration.borderRouterEnabled)
90*4a64e381SAndroid Build Coastguard Worker     {
91*4a64e381SAndroid Build Coastguard Worker         otSrpServerSetAutoEnableMode(GetOtInstance(), true);
92*4a64e381SAndroid Build Coastguard Worker         SetBorderRouterEnabled(true);
93*4a64e381SAndroid Build Coastguard Worker     }
94*4a64e381SAndroid Build Coastguard Worker     else
95*4a64e381SAndroid Build Coastguard Worker     {
96*4a64e381SAndroid Build Coastguard Worker         // This automatically disables the auto-enable mode which is designed for border router
97*4a64e381SAndroid Build Coastguard Worker         otSrpServerSetEnabled(GetOtInstance(), true);
98*4a64e381SAndroid Build Coastguard Worker 
99*4a64e381SAndroid Build Coastguard Worker         SetBorderRouterEnabled(false);
100*4a64e381SAndroid Build Coastguard Worker     }
101*4a64e381SAndroid Build Coastguard Worker 
102*4a64e381SAndroid Build Coastguard Worker     mConfiguration = aConfiguration;
103*4a64e381SAndroid Build Coastguard Worker 
104*4a64e381SAndroid Build Coastguard Worker exit:
105*4a64e381SAndroid Build Coastguard Worker     PropagateResult(error, message, aReceiver);
106*4a64e381SAndroid Build Coastguard Worker }
107*4a64e381SAndroid Build Coastguard Worker 
SetInfraLinkInterfaceName(const std::string & aInterfaceName,int aIcmp6Socket,const std::shared_ptr<IOtStatusReceiver> & aReceiver)108*4a64e381SAndroid Build Coastguard Worker void AndroidRcpHost::SetInfraLinkInterfaceName(const std::string                        &aInterfaceName,
109*4a64e381SAndroid Build Coastguard Worker                                                int                                       aIcmp6Socket,
110*4a64e381SAndroid Build Coastguard Worker                                                const std::shared_ptr<IOtStatusReceiver> &aReceiver)
111*4a64e381SAndroid Build Coastguard Worker {
112*4a64e381SAndroid Build Coastguard Worker     otError           error = OT_ERROR_NONE;
113*4a64e381SAndroid Build Coastguard Worker     std::string       message;
114*4a64e381SAndroid Build Coastguard Worker     const std::string infraIfName  = aInterfaceName;
115*4a64e381SAndroid Build Coastguard Worker     unsigned int      infraIfIndex = if_nametoindex(infraIfName.c_str());
116*4a64e381SAndroid Build Coastguard Worker 
117*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Setting infra link state: %s", aInterfaceName.c_str());
118*4a64e381SAndroid Build Coastguard Worker 
119*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(GetOtInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
120*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(mConfiguration.borderRouterEnabled, error = OT_ERROR_INVALID_STATE,
121*4a64e381SAndroid Build Coastguard Worker                  message = "Set infra link state when border router is disabled");
122*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(mInfraLinkState.interfaceName != aInterfaceName || aIcmp6Socket != mInfraIcmp6Socket);
123*4a64e381SAndroid Build Coastguard Worker 
124*4a64e381SAndroid Build Coastguard Worker     if (infraIfIndex != 0 && aIcmp6Socket > 0)
125*4a64e381SAndroid Build Coastguard Worker     {
126*4a64e381SAndroid Build Coastguard Worker         SuccessOrExit(error   = otBorderRoutingSetEnabled(GetOtInstance(), false /* aEnabled */),
127*4a64e381SAndroid Build Coastguard Worker                       message = "failed to disable border routing");
128*4a64e381SAndroid Build Coastguard Worker         otSysSetInfraNetif(infraIfName.c_str(), aIcmp6Socket);
129*4a64e381SAndroid Build Coastguard Worker         aIcmp6Socket = -1;
130*4a64e381SAndroid Build Coastguard Worker         SuccessOrExit(error   = otBorderRoutingInit(GetOtInstance(), infraIfIndex, otSysInfraIfIsRunning()),
131*4a64e381SAndroid Build Coastguard Worker                       message = "failed to initialize border routing");
132*4a64e381SAndroid Build Coastguard Worker         SuccessOrExit(error   = otBorderRoutingSetEnabled(GetOtInstance(), true /* aEnabled */),
133*4a64e381SAndroid Build Coastguard Worker                       message = "failed to enable border routing");
134*4a64e381SAndroid Build Coastguard Worker         // TODO: b/320836258 - Make BBR independently configurable
135*4a64e381SAndroid Build Coastguard Worker         otBackboneRouterSetEnabled(GetOtInstance(), true /* aEnabled */);
136*4a64e381SAndroid Build Coastguard Worker     }
137*4a64e381SAndroid Build Coastguard Worker     else
138*4a64e381SAndroid Build Coastguard Worker     {
139*4a64e381SAndroid Build Coastguard Worker         SuccessOrExit(error   = otBorderRoutingSetEnabled(GetOtInstance(), false /* aEnabled */),
140*4a64e381SAndroid Build Coastguard Worker                       message = "failed to disable border routing");
141*4a64e381SAndroid Build Coastguard Worker         otBackboneRouterSetEnabled(GetOtInstance(), false /* aEnabled */);
142*4a64e381SAndroid Build Coastguard Worker     }
143*4a64e381SAndroid Build Coastguard Worker 
144*4a64e381SAndroid Build Coastguard Worker     mInfraLinkState.interfaceName = aInterfaceName;
145*4a64e381SAndroid Build Coastguard Worker     mInfraIcmp6Socket             = aIcmp6Socket;
146*4a64e381SAndroid Build Coastguard Worker 
147*4a64e381SAndroid Build Coastguard Worker     SetTrelEnabled(mTrelEnabled);
148*4a64e381SAndroid Build Coastguard Worker 
149*4a64e381SAndroid Build Coastguard Worker exit:
150*4a64e381SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
151*4a64e381SAndroid Build Coastguard Worker     {
152*4a64e381SAndroid Build Coastguard Worker         close(aIcmp6Socket);
153*4a64e381SAndroid Build Coastguard Worker     }
154*4a64e381SAndroid Build Coastguard Worker     PropagateResult(error, message, aReceiver);
155*4a64e381SAndroid Build Coastguard Worker }
156*4a64e381SAndroid Build Coastguard Worker 
SetTrelEnabled(bool aEnabled)157*4a64e381SAndroid Build Coastguard Worker void AndroidRcpHost::SetTrelEnabled(bool aEnabled)
158*4a64e381SAndroid Build Coastguard Worker {
159*4a64e381SAndroid Build Coastguard Worker     mTrelEnabled = aEnabled;
160*4a64e381SAndroid Build Coastguard Worker 
161*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("%s TREL", aEnabled ? "Enabling" : "Disabling");
162*4a64e381SAndroid Build Coastguard Worker 
163*4a64e381SAndroid Build Coastguard Worker     // Tear down TREL if it's been initialized/enabled already.
164*4a64e381SAndroid Build Coastguard Worker     otTrelSetEnabled(GetOtInstance(), false);
165*4a64e381SAndroid Build Coastguard Worker     otSysTrelDeinit();
166*4a64e381SAndroid Build Coastguard Worker 
167*4a64e381SAndroid Build Coastguard Worker     if (mTrelEnabled && mInfraLinkState.interfaceName != "")
168*4a64e381SAndroid Build Coastguard Worker     {
169*4a64e381SAndroid Build Coastguard Worker         otSysTrelInit(mInfraLinkState.interfaceName.value_or("").c_str());
170*4a64e381SAndroid Build Coastguard Worker         otTrelSetEnabled(GetOtInstance(), true);
171*4a64e381SAndroid Build Coastguard Worker     }
172*4a64e381SAndroid Build Coastguard Worker }
173*4a64e381SAndroid Build Coastguard Worker 
SetInfraLinkNat64Prefix(const std::string & aNat64Prefix,const std::shared_ptr<IOtStatusReceiver> & aReceiver)174*4a64e381SAndroid Build Coastguard Worker void AndroidRcpHost::SetInfraLinkNat64Prefix(const std::string                        &aNat64Prefix,
175*4a64e381SAndroid Build Coastguard Worker                                              const std::shared_ptr<IOtStatusReceiver> &aReceiver)
176*4a64e381SAndroid Build Coastguard Worker {
177*4a64e381SAndroid Build Coastguard Worker     otError     error = OT_ERROR_NONE;
178*4a64e381SAndroid Build Coastguard Worker     std::string message;
179*4a64e381SAndroid Build Coastguard Worker 
180*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Setting infra link NAT64 prefix: %s", aNat64Prefix.c_str());
181*4a64e381SAndroid Build Coastguard Worker 
182*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(mRcpHost.GetInstance() != nullptr, error = OT_ERROR_INVALID_STATE, message = "OT is not initialized");
183*4a64e381SAndroid Build Coastguard Worker 
184*4a64e381SAndroid Build Coastguard Worker     mInfraLinkState.nat64Prefix = aNat64Prefix;
185*4a64e381SAndroid Build Coastguard Worker     NotifyNat64PrefixDiscoveryDone();
186*4a64e381SAndroid Build Coastguard Worker 
187*4a64e381SAndroid Build Coastguard Worker exit:
188*4a64e381SAndroid Build Coastguard Worker     PropagateResult(error, message, aReceiver);
189*4a64e381SAndroid Build Coastguard Worker }
190*4a64e381SAndroid Build Coastguard Worker 
RunOtCtlCommand(const std::string & aCommand,const bool aIsInteractive,const std::shared_ptr<IOtOutputReceiver> & aReceiver)191*4a64e381SAndroid Build Coastguard Worker void AndroidRcpHost::RunOtCtlCommand(const std::string                        &aCommand,
192*4a64e381SAndroid Build Coastguard Worker                                      const bool                                aIsInteractive,
193*4a64e381SAndroid Build Coastguard Worker                                      const std::shared_ptr<IOtOutputReceiver> &aReceiver)
194*4a64e381SAndroid Build Coastguard Worker {
195*4a64e381SAndroid Build Coastguard Worker     otSysCliInitUsingDaemon(GetOtInstance());
196*4a64e381SAndroid Build Coastguard Worker 
197*4a64e381SAndroid Build Coastguard Worker     if (!aCommand.empty())
198*4a64e381SAndroid Build Coastguard Worker     {
199*4a64e381SAndroid Build Coastguard Worker         std::string command = aCommand;
200*4a64e381SAndroid Build Coastguard Worker 
201*4a64e381SAndroid Build Coastguard Worker         mIsOtCtlInteractiveMode = aIsInteractive;
202*4a64e381SAndroid Build Coastguard Worker         mOtCtlOutputReceiver    = aReceiver;
203*4a64e381SAndroid Build Coastguard Worker 
204*4a64e381SAndroid Build Coastguard Worker         otCliInit(GetOtInstance(), AndroidRcpHost::OtCtlCommandCallback, this);
205*4a64e381SAndroid Build Coastguard Worker         otCliInputLine(command.data());
206*4a64e381SAndroid Build Coastguard Worker     }
207*4a64e381SAndroid Build Coastguard Worker }
208*4a64e381SAndroid Build Coastguard Worker 
OtCtlCommandCallback(void * aBinderServer,const char * aFormat,va_list aArguments)209*4a64e381SAndroid Build Coastguard Worker int AndroidRcpHost::OtCtlCommandCallback(void *aBinderServer, const char *aFormat, va_list aArguments)
210*4a64e381SAndroid Build Coastguard Worker {
211*4a64e381SAndroid Build Coastguard Worker     return static_cast<AndroidRcpHost *>(aBinderServer)->OtCtlCommandCallback(aFormat, aArguments);
212*4a64e381SAndroid Build Coastguard Worker }
213*4a64e381SAndroid Build Coastguard Worker 
OtCtlCommandCallback(const char * aFormat,va_list aArguments)214*4a64e381SAndroid Build Coastguard Worker int AndroidRcpHost::OtCtlCommandCallback(const char *aFormat, va_list aArguments)
215*4a64e381SAndroid Build Coastguard Worker {
216*4a64e381SAndroid Build Coastguard Worker     static const std::string kPrompt = "> ";
217*4a64e381SAndroid Build Coastguard Worker     std::string              output;
218*4a64e381SAndroid Build Coastguard Worker 
219*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(mOtCtlOutputReceiver != nullptr, otSysCliInitUsingDaemon(GetOtInstance()));
220*4a64e381SAndroid Build Coastguard Worker 
221*4a64e381SAndroid Build Coastguard Worker     android::base::StringAppendV(&output, aFormat, aArguments);
222*4a64e381SAndroid Build Coastguard Worker 
223*4a64e381SAndroid Build Coastguard Worker     // Ignore CLI prompt
224*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(output != kPrompt);
225*4a64e381SAndroid Build Coastguard Worker 
226*4a64e381SAndroid Build Coastguard Worker     mOtCtlOutputReceiver->onOutput(output);
227*4a64e381SAndroid Build Coastguard Worker 
228*4a64e381SAndroid Build Coastguard Worker     // Check if the command has completed (indicated by "Done" or "Error")
229*4a64e381SAndroid Build Coastguard Worker     if (output.starts_with("Done") || output.starts_with("Error"))
230*4a64e381SAndroid Build Coastguard Worker     {
231*4a64e381SAndroid Build Coastguard Worker         mIsOtCtlOutputComplete = true;
232*4a64e381SAndroid Build Coastguard Worker     }
233*4a64e381SAndroid Build Coastguard Worker 
234*4a64e381SAndroid Build Coastguard Worker     // The OpenThread CLI consistently outputs "\r\n" as a newline character. Therefore, we use the presence of "\r\n"
235*4a64e381SAndroid Build Coastguard Worker     // following "Done" or "Error" to signal the completion of a command's output.
236*4a64e381SAndroid Build Coastguard Worker     if (mIsOtCtlOutputComplete && output.ends_with("\r\n"))
237*4a64e381SAndroid Build Coastguard Worker     {
238*4a64e381SAndroid Build Coastguard Worker         if (!mIsOtCtlInteractiveMode)
239*4a64e381SAndroid Build Coastguard Worker         {
240*4a64e381SAndroid Build Coastguard Worker             otSysCliInitUsingDaemon(GetOtInstance());
241*4a64e381SAndroid Build Coastguard Worker         }
242*4a64e381SAndroid Build Coastguard Worker         mIsOtCtlOutputComplete = false;
243*4a64e381SAndroid Build Coastguard Worker         mOtCtlOutputReceiver->onComplete();
244*4a64e381SAndroid Build Coastguard Worker     }
245*4a64e381SAndroid Build Coastguard Worker 
246*4a64e381SAndroid Build Coastguard Worker exit:
247*4a64e381SAndroid Build Coastguard Worker     return output.length();
248*4a64e381SAndroid Build Coastguard Worker }
249*4a64e381SAndroid Build Coastguard Worker 
OutputCallback(void * aContext,const char * aFormat,va_list aArguments)250*4a64e381SAndroid Build Coastguard Worker static int OutputCallback(void *aContext, const char *aFormat, va_list aArguments)
251*4a64e381SAndroid Build Coastguard Worker {
252*4a64e381SAndroid Build Coastguard Worker     std::string output;
253*4a64e381SAndroid Build Coastguard Worker 
254*4a64e381SAndroid Build Coastguard Worker     android::base::StringAppendV(&output, aFormat, aArguments);
255*4a64e381SAndroid Build Coastguard Worker 
256*4a64e381SAndroid Build Coastguard Worker     int length = output.length();
257*4a64e381SAndroid Build Coastguard Worker 
258*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(android::base::WriteStringToFd(output, *(static_cast<int *>(aContext))), length = 0);
259*4a64e381SAndroid Build Coastguard Worker 
260*4a64e381SAndroid Build Coastguard Worker exit:
261*4a64e381SAndroid Build Coastguard Worker     return length;
262*4a64e381SAndroid Build Coastguard Worker }
263*4a64e381SAndroid Build Coastguard Worker 
DumpCliCommand(std::string aCommand,int aFd)264*4a64e381SAndroid Build Coastguard Worker inline void DumpCliCommand(std::string aCommand, int aFd)
265*4a64e381SAndroid Build Coastguard Worker {
266*4a64e381SAndroid Build Coastguard Worker     android::base::WriteStringToFd(aCommand + '\n', aFd);
267*4a64e381SAndroid Build Coastguard Worker     otCliInputLine(aCommand.data());
268*4a64e381SAndroid Build Coastguard Worker }
269*4a64e381SAndroid Build Coastguard Worker 
Dump(int aFd,const char ** aArgs,uint32_t aNumArgs)270*4a64e381SAndroid Build Coastguard Worker binder_status_t AndroidRcpHost::Dump(int aFd, const char **aArgs, uint32_t aNumArgs)
271*4a64e381SAndroid Build Coastguard Worker {
272*4a64e381SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgs);
273*4a64e381SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aNumArgs);
274*4a64e381SAndroid Build Coastguard Worker 
275*4a64e381SAndroid Build Coastguard Worker     otCliInit(GetOtInstance(), OutputCallback, &aFd);
276*4a64e381SAndroid Build Coastguard Worker 
277*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("state", aFd);
278*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("srp server state", aFd);
279*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("srp server service", aFd);
280*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("srp server host", aFd);
281*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("dataset activetimestamp", aFd);
282*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("dataset channel", aFd);
283*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("dataset channelmask", aFd);
284*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("dataset extpanid", aFd);
285*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("dataset meshlocalprefix", aFd);
286*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("dataset networkname", aFd);
287*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("dataset panid", aFd);
288*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("dataset securitypolicy", aFd);
289*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("leaderdata", aFd);
290*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("eidcache", aFd);
291*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("counters mac", aFd);
292*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("counters mle", aFd);
293*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("counters ip", aFd);
294*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("router table", aFd);
295*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("neighbor table", aFd);
296*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("ipaddr -v", aFd);
297*4a64e381SAndroid Build Coastguard Worker     DumpCliCommand("netdata show", aFd);
298*4a64e381SAndroid Build Coastguard Worker 
299*4a64e381SAndroid Build Coastguard Worker     fsync(aFd);
300*4a64e381SAndroid Build Coastguard Worker 
301*4a64e381SAndroid Build Coastguard Worker     otSysCliInitUsingDaemon(GetOtInstance());
302*4a64e381SAndroid Build Coastguard Worker 
303*4a64e381SAndroid Build Coastguard Worker     return STATUS_OK;
304*4a64e381SAndroid Build Coastguard Worker }
305*4a64e381SAndroid Build Coastguard Worker 
ToOtUpstreamDnsServerAddresses(const std::vector<std::string> & aAddresses)306*4a64e381SAndroid Build Coastguard Worker std::vector<otIp6Address> ToOtUpstreamDnsServerAddresses(const std::vector<std::string> &aAddresses)
307*4a64e381SAndroid Build Coastguard Worker {
308*4a64e381SAndroid Build Coastguard Worker     std::vector<otIp6Address> addresses;
309*4a64e381SAndroid Build Coastguard Worker 
310*4a64e381SAndroid Build Coastguard Worker     // TODO: b/363738575 - support IPv6
311*4a64e381SAndroid Build Coastguard Worker     for (const auto &addressString : aAddresses)
312*4a64e381SAndroid Build Coastguard Worker     {
313*4a64e381SAndroid Build Coastguard Worker         otIp6Address ip6Address;
314*4a64e381SAndroid Build Coastguard Worker         otIp4Address ip4Address;
315*4a64e381SAndroid Build Coastguard Worker 
316*4a64e381SAndroid Build Coastguard Worker         if (otIp4AddressFromString(addressString.c_str(), &ip4Address) != OT_ERROR_NONE)
317*4a64e381SAndroid Build Coastguard Worker         {
318*4a64e381SAndroid Build Coastguard Worker             continue;
319*4a64e381SAndroid Build Coastguard Worker         }
320*4a64e381SAndroid Build Coastguard Worker         otIp4ToIp4MappedIp6Address(&ip4Address, &ip6Address);
321*4a64e381SAndroid Build Coastguard Worker         addresses.push_back(ip6Address);
322*4a64e381SAndroid Build Coastguard Worker     }
323*4a64e381SAndroid Build Coastguard Worker 
324*4a64e381SAndroid Build Coastguard Worker     return addresses;
325*4a64e381SAndroid Build Coastguard Worker }
326*4a64e381SAndroid Build Coastguard Worker 
SetInfraLinkDnsServers(const std::vector<std::string> & aDnsServers,const std::shared_ptr<IOtStatusReceiver> & aReceiver)327*4a64e381SAndroid Build Coastguard Worker void AndroidRcpHost::SetInfraLinkDnsServers(const std::vector<std::string>           &aDnsServers,
328*4a64e381SAndroid Build Coastguard Worker                                             const std::shared_ptr<IOtStatusReceiver> &aReceiver)
329*4a64e381SAndroid Build Coastguard Worker {
330*4a64e381SAndroid Build Coastguard Worker     otError     error = OT_ERROR_NONE;
331*4a64e381SAndroid Build Coastguard Worker     std::string message;
332*4a64e381SAndroid Build Coastguard Worker     auto        dnsServers = ToOtUpstreamDnsServerAddresses(aDnsServers);
333*4a64e381SAndroid Build Coastguard Worker 
334*4a64e381SAndroid Build Coastguard Worker     otbrLogInfo("Setting infra link DNS servers: %d servers", aDnsServers.size());
335*4a64e381SAndroid Build Coastguard Worker 
336*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(aDnsServers != mInfraLinkState.dnsServers);
337*4a64e381SAndroid Build Coastguard Worker 
338*4a64e381SAndroid Build Coastguard Worker     mInfraLinkState.dnsServers = aDnsServers;
339*4a64e381SAndroid Build Coastguard Worker     otSysUpstreamDnsSetServerList(dnsServers.data(), dnsServers.size());
340*4a64e381SAndroid Build Coastguard Worker 
341*4a64e381SAndroid Build Coastguard Worker exit:
342*4a64e381SAndroid Build Coastguard Worker     PropagateResult(error, message, aReceiver);
343*4a64e381SAndroid Build Coastguard Worker }
344*4a64e381SAndroid Build Coastguard Worker 
NotifyNat64PrefixDiscoveryDone(void)345*4a64e381SAndroid Build Coastguard Worker void AndroidRcpHost::NotifyNat64PrefixDiscoveryDone(void)
346*4a64e381SAndroid Build Coastguard Worker {
347*4a64e381SAndroid Build Coastguard Worker     otIp6Prefix nat64Prefix{};
348*4a64e381SAndroid Build Coastguard Worker     uint32_t    infraIfIndex = if_nametoindex(mInfraLinkState.interfaceName.value_or("").c_str());
349*4a64e381SAndroid Build Coastguard Worker 
350*4a64e381SAndroid Build Coastguard Worker     otIp6PrefixFromString(mInfraLinkState.nat64Prefix.value_or("").c_str(), &nat64Prefix);
351*4a64e381SAndroid Build Coastguard Worker     otPlatInfraIfDiscoverNat64PrefixDone(GetOtInstance(), infraIfIndex, &nat64Prefix);
352*4a64e381SAndroid Build Coastguard Worker }
353*4a64e381SAndroid Build Coastguard Worker 
GetOtInstance(void)354*4a64e381SAndroid Build Coastguard Worker otInstance *AndroidRcpHost::GetOtInstance(void)
355*4a64e381SAndroid Build Coastguard Worker {
356*4a64e381SAndroid Build Coastguard Worker     return mRcpHost.GetInstance();
357*4a64e381SAndroid Build Coastguard Worker }
358*4a64e381SAndroid Build Coastguard Worker 
GetLinkModeConfig(bool aIsRouter)359*4a64e381SAndroid Build Coastguard Worker otLinkModeConfig AndroidRcpHost::GetLinkModeConfig(bool aIsRouter)
360*4a64e381SAndroid Build Coastguard Worker {
361*4a64e381SAndroid Build Coastguard Worker     otLinkModeConfig linkModeConfig{};
362*4a64e381SAndroid Build Coastguard Worker 
363*4a64e381SAndroid Build Coastguard Worker     if (aIsRouter)
364*4a64e381SAndroid Build Coastguard Worker     {
365*4a64e381SAndroid Build Coastguard Worker         linkModeConfig.mRxOnWhenIdle = true;
366*4a64e381SAndroid Build Coastguard Worker         linkModeConfig.mDeviceType   = true;
367*4a64e381SAndroid Build Coastguard Worker         linkModeConfig.mNetworkData  = true;
368*4a64e381SAndroid Build Coastguard Worker     }
369*4a64e381SAndroid Build Coastguard Worker     else
370*4a64e381SAndroid Build Coastguard Worker     {
371*4a64e381SAndroid Build Coastguard Worker         linkModeConfig.mRxOnWhenIdle = false;
372*4a64e381SAndroid Build Coastguard Worker         linkModeConfig.mDeviceType   = false;
373*4a64e381SAndroid Build Coastguard Worker         linkModeConfig.mNetworkData  = true;
374*4a64e381SAndroid Build Coastguard Worker     }
375*4a64e381SAndroid Build Coastguard Worker 
376*4a64e381SAndroid Build Coastguard Worker     return linkModeConfig;
377*4a64e381SAndroid Build Coastguard Worker }
378*4a64e381SAndroid Build Coastguard Worker 
SetBorderRouterEnabled(bool aEnabled)379*4a64e381SAndroid Build Coastguard Worker void AndroidRcpHost::SetBorderRouterEnabled(bool aEnabled)
380*4a64e381SAndroid Build Coastguard Worker {
381*4a64e381SAndroid Build Coastguard Worker     otError error;
382*4a64e381SAndroid Build Coastguard Worker 
383*4a64e381SAndroid Build Coastguard Worker     error = otBorderRoutingSetEnabled(GetOtInstance(), aEnabled);
384*4a64e381SAndroid Build Coastguard Worker     if (error != OT_ERROR_NONE)
385*4a64e381SAndroid Build Coastguard Worker     {
386*4a64e381SAndroid Build Coastguard Worker         otbrLogWarning("Failed to %s Border Routing: %s", (aEnabled ? "enable" : "disable"),
387*4a64e381SAndroid Build Coastguard Worker                        otThreadErrorToString(error));
388*4a64e381SAndroid Build Coastguard Worker         ExitNow();
389*4a64e381SAndroid Build Coastguard Worker     }
390*4a64e381SAndroid Build Coastguard Worker 
391*4a64e381SAndroid Build Coastguard Worker     otBackboneRouterSetEnabled(GetOtInstance(), aEnabled);
392*4a64e381SAndroid Build Coastguard Worker 
393*4a64e381SAndroid Build Coastguard Worker exit:
394*4a64e381SAndroid Build Coastguard Worker     return;
395*4a64e381SAndroid Build Coastguard Worker }
396*4a64e381SAndroid Build Coastguard Worker 
otPlatInfraIfDiscoverNat64Prefix(uint32_t aInfraIfIndex)397*4a64e381SAndroid Build Coastguard Worker extern "C" otError otPlatInfraIfDiscoverNat64Prefix(uint32_t aInfraIfIndex)
398*4a64e381SAndroid Build Coastguard Worker {
399*4a64e381SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aInfraIfIndex);
400*4a64e381SAndroid Build Coastguard Worker 
401*4a64e381SAndroid Build Coastguard Worker     AndroidRcpHost *androidRcpHost = AndroidRcpHost::Get();
402*4a64e381SAndroid Build Coastguard Worker     otError         error          = OT_ERROR_NONE;
403*4a64e381SAndroid Build Coastguard Worker 
404*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(androidRcpHost != nullptr, error = OT_ERROR_INVALID_STATE);
405*4a64e381SAndroid Build Coastguard Worker 
406*4a64e381SAndroid Build Coastguard Worker     androidRcpHost->NotifyNat64PrefixDiscoveryDone();
407*4a64e381SAndroid Build Coastguard Worker 
408*4a64e381SAndroid Build Coastguard Worker exit:
409*4a64e381SAndroid Build Coastguard Worker     return error;
410*4a64e381SAndroid Build Coastguard Worker }
411*4a64e381SAndroid Build Coastguard Worker 
412*4a64e381SAndroid Build Coastguard Worker } // namespace Android
413*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
414