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