1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker * Copyright (c) 2019, 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 "RCP_HOST"
30*4a64e381SAndroid Build Coastguard Worker
31*4a64e381SAndroid Build Coastguard Worker #include "ncp/rcp_host.hpp"
32*4a64e381SAndroid Build Coastguard Worker
33*4a64e381SAndroid Build Coastguard Worker #include <assert.h>
34*4a64e381SAndroid Build Coastguard Worker #include <limits.h>
35*4a64e381SAndroid Build Coastguard Worker #include <stdio.h>
36*4a64e381SAndroid Build Coastguard Worker #include <string.h>
37*4a64e381SAndroid Build Coastguard Worker
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/dataset.h>
41*4a64e381SAndroid Build Coastguard Worker #include <openthread/dnssd_server.h>
42*4a64e381SAndroid Build Coastguard Worker #include <openthread/link_metrics.h>
43*4a64e381SAndroid Build Coastguard Worker #include <openthread/logging.h>
44*4a64e381SAndroid Build Coastguard Worker #include <openthread/nat64.h>
45*4a64e381SAndroid Build Coastguard Worker #include <openthread/srp_server.h>
46*4a64e381SAndroid Build Coastguard Worker #include <openthread/tasklet.h>
47*4a64e381SAndroid Build Coastguard Worker #include <openthread/thread.h>
48*4a64e381SAndroid Build Coastguard Worker #include <openthread/thread_ftd.h>
49*4a64e381SAndroid Build Coastguard Worker #include <openthread/trel.h>
50*4a64e381SAndroid Build Coastguard Worker #include <openthread/platform/logging.h>
51*4a64e381SAndroid Build Coastguard Worker #include <openthread/platform/misc.h>
52*4a64e381SAndroid Build Coastguard Worker #include <openthread/platform/radio.h>
53*4a64e381SAndroid Build Coastguard Worker #include <openthread/platform/settings.h>
54*4a64e381SAndroid Build Coastguard Worker
55*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
56*4a64e381SAndroid Build Coastguard Worker #include "common/logging.hpp"
57*4a64e381SAndroid Build Coastguard Worker #include "common/types.hpp"
58*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_FEATURE_FLAGS
59*4a64e381SAndroid Build Coastguard Worker #include "proto/feature_flag.pb.h"
60*4a64e381SAndroid Build Coastguard Worker #endif
61*4a64e381SAndroid Build Coastguard Worker
62*4a64e381SAndroid Build Coastguard Worker namespace otbr {
63*4a64e381SAndroid Build Coastguard Worker namespace Ncp {
64*4a64e381SAndroid Build Coastguard Worker
65*4a64e381SAndroid Build Coastguard Worker static const uint16_t kThreadVersion11 = 2; ///< Thread Version 1.1
66*4a64e381SAndroid Build Coastguard Worker static const uint16_t kThreadVersion12 = 3; ///< Thread Version 1.2
67*4a64e381SAndroid Build Coastguard Worker static const uint16_t kThreadVersion13 = 4; ///< Thread Version 1.3
68*4a64e381SAndroid Build Coastguard Worker static const uint16_t kThreadVersion14 = 5; ///< Thread Version 1.4
69*4a64e381SAndroid Build Coastguard Worker
70*4a64e381SAndroid Build Coastguard Worker // =============================== OtNetworkProperties ===============================
71*4a64e381SAndroid Build Coastguard Worker
OtNetworkProperties(void)72*4a64e381SAndroid Build Coastguard Worker OtNetworkProperties::OtNetworkProperties(void)
73*4a64e381SAndroid Build Coastguard Worker : mInstance(nullptr)
74*4a64e381SAndroid Build Coastguard Worker {
75*4a64e381SAndroid Build Coastguard Worker }
76*4a64e381SAndroid Build Coastguard Worker
GetDeviceRole(void) const77*4a64e381SAndroid Build Coastguard Worker otDeviceRole OtNetworkProperties::GetDeviceRole(void) const
78*4a64e381SAndroid Build Coastguard Worker {
79*4a64e381SAndroid Build Coastguard Worker return otThreadGetDeviceRole(mInstance);
80*4a64e381SAndroid Build Coastguard Worker }
81*4a64e381SAndroid Build Coastguard Worker
Ip6IsEnabled(void) const82*4a64e381SAndroid Build Coastguard Worker bool OtNetworkProperties::Ip6IsEnabled(void) const
83*4a64e381SAndroid Build Coastguard Worker {
84*4a64e381SAndroid Build Coastguard Worker return otIp6IsEnabled(mInstance);
85*4a64e381SAndroid Build Coastguard Worker }
86*4a64e381SAndroid Build Coastguard Worker
GetPartitionId(void) const87*4a64e381SAndroid Build Coastguard Worker uint32_t OtNetworkProperties::GetPartitionId(void) const
88*4a64e381SAndroid Build Coastguard Worker {
89*4a64e381SAndroid Build Coastguard Worker return otThreadGetPartitionId(mInstance);
90*4a64e381SAndroid Build Coastguard Worker }
91*4a64e381SAndroid Build Coastguard Worker
GetDatasetActiveTlvs(otOperationalDatasetTlvs & aDatasetTlvs) const92*4a64e381SAndroid Build Coastguard Worker void OtNetworkProperties::GetDatasetActiveTlvs(otOperationalDatasetTlvs &aDatasetTlvs) const
93*4a64e381SAndroid Build Coastguard Worker {
94*4a64e381SAndroid Build Coastguard Worker otError error = otDatasetGetActiveTlvs(mInstance, &aDatasetTlvs);
95*4a64e381SAndroid Build Coastguard Worker
96*4a64e381SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
97*4a64e381SAndroid Build Coastguard Worker {
98*4a64e381SAndroid Build Coastguard Worker aDatasetTlvs.mLength = 0;
99*4a64e381SAndroid Build Coastguard Worker memset(aDatasetTlvs.mTlvs, 0, sizeof(aDatasetTlvs.mTlvs));
100*4a64e381SAndroid Build Coastguard Worker }
101*4a64e381SAndroid Build Coastguard Worker }
102*4a64e381SAndroid Build Coastguard Worker
GetDatasetPendingTlvs(otOperationalDatasetTlvs & aDatasetTlvs) const103*4a64e381SAndroid Build Coastguard Worker void OtNetworkProperties::GetDatasetPendingTlvs(otOperationalDatasetTlvs &aDatasetTlvs) const
104*4a64e381SAndroid Build Coastguard Worker {
105*4a64e381SAndroid Build Coastguard Worker otError error = otDatasetGetPendingTlvs(mInstance, &aDatasetTlvs);
106*4a64e381SAndroid Build Coastguard Worker
107*4a64e381SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
108*4a64e381SAndroid Build Coastguard Worker {
109*4a64e381SAndroid Build Coastguard Worker aDatasetTlvs.mLength = 0;
110*4a64e381SAndroid Build Coastguard Worker memset(aDatasetTlvs.mTlvs, 0, sizeof(aDatasetTlvs.mTlvs));
111*4a64e381SAndroid Build Coastguard Worker }
112*4a64e381SAndroid Build Coastguard Worker }
113*4a64e381SAndroid Build Coastguard Worker
SetInstance(otInstance * aInstance)114*4a64e381SAndroid Build Coastguard Worker void OtNetworkProperties::SetInstance(otInstance *aInstance)
115*4a64e381SAndroid Build Coastguard Worker {
116*4a64e381SAndroid Build Coastguard Worker mInstance = aInstance;
117*4a64e381SAndroid Build Coastguard Worker }
118*4a64e381SAndroid Build Coastguard Worker
119*4a64e381SAndroid Build Coastguard Worker // =============================== RcpHost ===============================
120*4a64e381SAndroid Build Coastguard Worker
RcpHost(const char * aInterfaceName,const std::vector<const char * > & aRadioUrls,const char * aBackboneInterfaceName,bool aDryRun,bool aEnableAutoAttach)121*4a64e381SAndroid Build Coastguard Worker RcpHost::RcpHost(const char *aInterfaceName,
122*4a64e381SAndroid Build Coastguard Worker const std::vector<const char *> &aRadioUrls,
123*4a64e381SAndroid Build Coastguard Worker const char *aBackboneInterfaceName,
124*4a64e381SAndroid Build Coastguard Worker bool aDryRun,
125*4a64e381SAndroid Build Coastguard Worker bool aEnableAutoAttach)
126*4a64e381SAndroid Build Coastguard Worker : mInstance(nullptr)
127*4a64e381SAndroid Build Coastguard Worker , mEnableAutoAttach(aEnableAutoAttach)
128*4a64e381SAndroid Build Coastguard Worker {
129*4a64e381SAndroid Build Coastguard Worker VerifyOrDie(aRadioUrls.size() <= OT_PLATFORM_CONFIG_MAX_RADIO_URLS, "Too many Radio URLs!");
130*4a64e381SAndroid Build Coastguard Worker
131*4a64e381SAndroid Build Coastguard Worker memset(&mConfig, 0, sizeof(mConfig));
132*4a64e381SAndroid Build Coastguard Worker
133*4a64e381SAndroid Build Coastguard Worker mConfig.mInterfaceName = aInterfaceName;
134*4a64e381SAndroid Build Coastguard Worker mConfig.mBackboneInterfaceName = aBackboneInterfaceName;
135*4a64e381SAndroid Build Coastguard Worker mConfig.mDryRun = aDryRun;
136*4a64e381SAndroid Build Coastguard Worker
137*4a64e381SAndroid Build Coastguard Worker for (const char *url : aRadioUrls)
138*4a64e381SAndroid Build Coastguard Worker {
139*4a64e381SAndroid Build Coastguard Worker mConfig.mCoprocessorUrls.mUrls[mConfig.mCoprocessorUrls.mNum++] = url;
140*4a64e381SAndroid Build Coastguard Worker }
141*4a64e381SAndroid Build Coastguard Worker mConfig.mSpeedUpFactor = 1;
142*4a64e381SAndroid Build Coastguard Worker }
143*4a64e381SAndroid Build Coastguard Worker
~RcpHost(void)144*4a64e381SAndroid Build Coastguard Worker RcpHost::~RcpHost(void)
145*4a64e381SAndroid Build Coastguard Worker {
146*4a64e381SAndroid Build Coastguard Worker // Make sure OpenThread Instance was gracefully de-initialized.
147*4a64e381SAndroid Build Coastguard Worker assert(mInstance == nullptr);
148*4a64e381SAndroid Build Coastguard Worker }
149*4a64e381SAndroid Build Coastguard Worker
ConvertToOtbrLogLevel(otLogLevel aLogLevel)150*4a64e381SAndroid Build Coastguard Worker otbrLogLevel RcpHost::ConvertToOtbrLogLevel(otLogLevel aLogLevel)
151*4a64e381SAndroid Build Coastguard Worker {
152*4a64e381SAndroid Build Coastguard Worker otbrLogLevel otbrLogLevel;
153*4a64e381SAndroid Build Coastguard Worker
154*4a64e381SAndroid Build Coastguard Worker switch (aLogLevel)
155*4a64e381SAndroid Build Coastguard Worker {
156*4a64e381SAndroid Build Coastguard Worker case OT_LOG_LEVEL_NONE:
157*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_EMERG;
158*4a64e381SAndroid Build Coastguard Worker break;
159*4a64e381SAndroid Build Coastguard Worker case OT_LOG_LEVEL_CRIT:
160*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_CRIT;
161*4a64e381SAndroid Build Coastguard Worker break;
162*4a64e381SAndroid Build Coastguard Worker case OT_LOG_LEVEL_WARN:
163*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_WARNING;
164*4a64e381SAndroid Build Coastguard Worker break;
165*4a64e381SAndroid Build Coastguard Worker case OT_LOG_LEVEL_NOTE:
166*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_NOTICE;
167*4a64e381SAndroid Build Coastguard Worker break;
168*4a64e381SAndroid Build Coastguard Worker case OT_LOG_LEVEL_INFO:
169*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_INFO;
170*4a64e381SAndroid Build Coastguard Worker break;
171*4a64e381SAndroid Build Coastguard Worker case OT_LOG_LEVEL_DEBG:
172*4a64e381SAndroid Build Coastguard Worker default:
173*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_DEBUG;
174*4a64e381SAndroid Build Coastguard Worker break;
175*4a64e381SAndroid Build Coastguard Worker }
176*4a64e381SAndroid Build Coastguard Worker
177*4a64e381SAndroid Build Coastguard Worker return otbrLogLevel;
178*4a64e381SAndroid Build Coastguard Worker }
179*4a64e381SAndroid Build Coastguard Worker
180*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_FEATURE_FLAGS
181*4a64e381SAndroid Build Coastguard Worker /* Converts ProtoLogLevel to otbrLogLevel */
ConvertProtoToOtbrLogLevel(ProtoLogLevel aProtoLogLevel)182*4a64e381SAndroid Build Coastguard Worker otbrLogLevel ConvertProtoToOtbrLogLevel(ProtoLogLevel aProtoLogLevel)
183*4a64e381SAndroid Build Coastguard Worker {
184*4a64e381SAndroid Build Coastguard Worker otbrLogLevel otbrLogLevel;
185*4a64e381SAndroid Build Coastguard Worker
186*4a64e381SAndroid Build Coastguard Worker switch (aProtoLogLevel)
187*4a64e381SAndroid Build Coastguard Worker {
188*4a64e381SAndroid Build Coastguard Worker case PROTO_LOG_EMERG:
189*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_EMERG;
190*4a64e381SAndroid Build Coastguard Worker break;
191*4a64e381SAndroid Build Coastguard Worker case PROTO_LOG_ALERT:
192*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_ALERT;
193*4a64e381SAndroid Build Coastguard Worker break;
194*4a64e381SAndroid Build Coastguard Worker case PROTO_LOG_CRIT:
195*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_CRIT;
196*4a64e381SAndroid Build Coastguard Worker break;
197*4a64e381SAndroid Build Coastguard Worker case PROTO_LOG_ERR:
198*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_ERR;
199*4a64e381SAndroid Build Coastguard Worker break;
200*4a64e381SAndroid Build Coastguard Worker case PROTO_LOG_WARNING:
201*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_WARNING;
202*4a64e381SAndroid Build Coastguard Worker break;
203*4a64e381SAndroid Build Coastguard Worker case PROTO_LOG_NOTICE:
204*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_NOTICE;
205*4a64e381SAndroid Build Coastguard Worker break;
206*4a64e381SAndroid Build Coastguard Worker case PROTO_LOG_INFO:
207*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_INFO;
208*4a64e381SAndroid Build Coastguard Worker break;
209*4a64e381SAndroid Build Coastguard Worker case PROTO_LOG_DEBUG:
210*4a64e381SAndroid Build Coastguard Worker default:
211*4a64e381SAndroid Build Coastguard Worker otbrLogLevel = OTBR_LOG_DEBUG;
212*4a64e381SAndroid Build Coastguard Worker break;
213*4a64e381SAndroid Build Coastguard Worker }
214*4a64e381SAndroid Build Coastguard Worker
215*4a64e381SAndroid Build Coastguard Worker return otbrLogLevel;
216*4a64e381SAndroid Build Coastguard Worker }
217*4a64e381SAndroid Build Coastguard Worker #endif
218*4a64e381SAndroid Build Coastguard Worker
SetOtbrAndOtLogLevel(otbrLogLevel aLevel)219*4a64e381SAndroid Build Coastguard Worker otError RcpHost::SetOtbrAndOtLogLevel(otbrLogLevel aLevel)
220*4a64e381SAndroid Build Coastguard Worker {
221*4a64e381SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
222*4a64e381SAndroid Build Coastguard Worker otbrLogSetLevel(aLevel);
223*4a64e381SAndroid Build Coastguard Worker error = otLoggingSetLevel(ConvertToOtLogLevel(aLevel));
224*4a64e381SAndroid Build Coastguard Worker return error;
225*4a64e381SAndroid Build Coastguard Worker }
226*4a64e381SAndroid Build Coastguard Worker
Init(void)227*4a64e381SAndroid Build Coastguard Worker void RcpHost::Init(void)
228*4a64e381SAndroid Build Coastguard Worker {
229*4a64e381SAndroid Build Coastguard Worker otbrError error = OTBR_ERROR_NONE;
230*4a64e381SAndroid Build Coastguard Worker otLogLevel level = ConvertToOtLogLevel(otbrLogGetLevel());
231*4a64e381SAndroid Build Coastguard Worker
232*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_FEATURE_FLAGS && OTBR_ENABLE_TREL
233*4a64e381SAndroid Build Coastguard Worker FeatureFlagList featureFlagList;
234*4a64e381SAndroid Build Coastguard Worker #endif
235*4a64e381SAndroid Build Coastguard Worker
236*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(otLoggingSetLevel(level) == OT_ERROR_NONE, error = OTBR_ERROR_OPENTHREAD);
237*4a64e381SAndroid Build Coastguard Worker
238*4a64e381SAndroid Build Coastguard Worker mInstance = otSysInit(&mConfig);
239*4a64e381SAndroid Build Coastguard Worker assert(mInstance != nullptr);
240*4a64e381SAndroid Build Coastguard Worker
241*4a64e381SAndroid Build Coastguard Worker {
242*4a64e381SAndroid Build Coastguard Worker otError result = otSetStateChangedCallback(mInstance, &RcpHost::HandleStateChanged, this);
243*4a64e381SAndroid Build Coastguard Worker
244*4a64e381SAndroid Build Coastguard Worker agent::ThreadHelper::LogOpenThreadResult("Set state callback", result);
245*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(result == OT_ERROR_NONE, error = OTBR_ERROR_OPENTHREAD);
246*4a64e381SAndroid Build Coastguard Worker }
247*4a64e381SAndroid Build Coastguard Worker
248*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_FEATURE_FLAGS && OTBR_ENABLE_TREL
249*4a64e381SAndroid Build Coastguard Worker // Enable/Disable trel according to feature flag default value.
250*4a64e381SAndroid Build Coastguard Worker otTrelSetEnabled(mInstance, featureFlagList.enable_trel());
251*4a64e381SAndroid Build Coastguard Worker #endif
252*4a64e381SAndroid Build Coastguard Worker
253*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_SRP_ADVERTISING_PROXY
254*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_SRP_SERVER_AUTO_ENABLE_MODE
255*4a64e381SAndroid Build Coastguard Worker // Let SRP server use auto-enable mode. The auto-enable mode delegates the control of SRP server to the Border
256*4a64e381SAndroid Build Coastguard Worker // Routing Manager. SRP server automatically starts when bi-directional connectivity is ready.
257*4a64e381SAndroid Build Coastguard Worker otSrpServerSetAutoEnableMode(mInstance, /* aEnabled */ true);
258*4a64e381SAndroid Build Coastguard Worker #else
259*4a64e381SAndroid Build Coastguard Worker otSrpServerSetEnabled(mInstance, /* aEnabled */ true);
260*4a64e381SAndroid Build Coastguard Worker #endif
261*4a64e381SAndroid Build Coastguard Worker #endif
262*4a64e381SAndroid Build Coastguard Worker
263*4a64e381SAndroid Build Coastguard Worker #if !OTBR_ENABLE_FEATURE_FLAGS
264*4a64e381SAndroid Build Coastguard Worker // Bring up all features when feature flags is not supported.
265*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_NAT64
266*4a64e381SAndroid Build Coastguard Worker otNat64SetEnabled(mInstance, /* aEnabled */ true);
267*4a64e381SAndroid Build Coastguard Worker #endif
268*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_DNS_UPSTREAM_QUERY
269*4a64e381SAndroid Build Coastguard Worker otDnssdUpstreamQuerySetEnabled(mInstance, /* aEnabled */ true);
270*4a64e381SAndroid Build Coastguard Worker #endif
271*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_DHCP6_PD
272*4a64e381SAndroid Build Coastguard Worker otBorderRoutingDhcp6PdSetEnabled(mInstance, /* aEnabled */ true);
273*4a64e381SAndroid Build Coastguard Worker #endif
274*4a64e381SAndroid Build Coastguard Worker #endif // OTBR_ENABLE_FEATURE_FLAGS
275*4a64e381SAndroid Build Coastguard Worker
276*4a64e381SAndroid Build Coastguard Worker mThreadHelper = MakeUnique<otbr::agent::ThreadHelper>(mInstance, this);
277*4a64e381SAndroid Build Coastguard Worker
278*4a64e381SAndroid Build Coastguard Worker OtNetworkProperties::SetInstance(mInstance);
279*4a64e381SAndroid Build Coastguard Worker
280*4a64e381SAndroid Build Coastguard Worker exit:
281*4a64e381SAndroid Build Coastguard Worker SuccessOrDie(error, "Failed to initialize the RCP Host!");
282*4a64e381SAndroid Build Coastguard Worker }
283*4a64e381SAndroid Build Coastguard Worker
284*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_FEATURE_FLAGS
ApplyFeatureFlagList(const FeatureFlagList & aFeatureFlagList)285*4a64e381SAndroid Build Coastguard Worker otError RcpHost::ApplyFeatureFlagList(const FeatureFlagList &aFeatureFlagList)
286*4a64e381SAndroid Build Coastguard Worker {
287*4a64e381SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
288*4a64e381SAndroid Build Coastguard Worker // Save a cached copy of feature flags for debugging purpose.
289*4a64e381SAndroid Build Coastguard Worker mAppliedFeatureFlagListBytes = aFeatureFlagList.SerializeAsString();
290*4a64e381SAndroid Build Coastguard Worker
291*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_NAT64
292*4a64e381SAndroid Build Coastguard Worker otNat64SetEnabled(mInstance, aFeatureFlagList.enable_nat64());
293*4a64e381SAndroid Build Coastguard Worker #endif
294*4a64e381SAndroid Build Coastguard Worker
295*4a64e381SAndroid Build Coastguard Worker if (aFeatureFlagList.enable_detailed_logging())
296*4a64e381SAndroid Build Coastguard Worker {
297*4a64e381SAndroid Build Coastguard Worker error = SetOtbrAndOtLogLevel(ConvertProtoToOtbrLogLevel(aFeatureFlagList.detailed_logging_level()));
298*4a64e381SAndroid Build Coastguard Worker }
299*4a64e381SAndroid Build Coastguard Worker else
300*4a64e381SAndroid Build Coastguard Worker {
301*4a64e381SAndroid Build Coastguard Worker error = SetOtbrAndOtLogLevel(otbrLogGetDefaultLevel());
302*4a64e381SAndroid Build Coastguard Worker }
303*4a64e381SAndroid Build Coastguard Worker
304*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_TREL
305*4a64e381SAndroid Build Coastguard Worker otTrelSetEnabled(mInstance, aFeatureFlagList.enable_trel());
306*4a64e381SAndroid Build Coastguard Worker #endif
307*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_DNS_UPSTREAM_QUERY
308*4a64e381SAndroid Build Coastguard Worker otDnssdUpstreamQuerySetEnabled(mInstance, aFeatureFlagList.enable_dns_upstream_query());
309*4a64e381SAndroid Build Coastguard Worker #endif
310*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_DHCP6_PD
311*4a64e381SAndroid Build Coastguard Worker otBorderRoutingDhcp6PdSetEnabled(mInstance, aFeatureFlagList.enable_dhcp6_pd());
312*4a64e381SAndroid Build Coastguard Worker #endif
313*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_LINK_METRICS_TELEMETRY
314*4a64e381SAndroid Build Coastguard Worker otLinkMetricsManagerSetEnabled(mInstance, aFeatureFlagList.enable_link_metrics_manager());
315*4a64e381SAndroid Build Coastguard Worker #endif
316*4a64e381SAndroid Build Coastguard Worker
317*4a64e381SAndroid Build Coastguard Worker return error;
318*4a64e381SAndroid Build Coastguard Worker }
319*4a64e381SAndroid Build Coastguard Worker #endif
320*4a64e381SAndroid Build Coastguard Worker
Deinit(void)321*4a64e381SAndroid Build Coastguard Worker void RcpHost::Deinit(void)
322*4a64e381SAndroid Build Coastguard Worker {
323*4a64e381SAndroid Build Coastguard Worker assert(mInstance != nullptr);
324*4a64e381SAndroid Build Coastguard Worker
325*4a64e381SAndroid Build Coastguard Worker otSysDeinit();
326*4a64e381SAndroid Build Coastguard Worker mInstance = nullptr;
327*4a64e381SAndroid Build Coastguard Worker
328*4a64e381SAndroid Build Coastguard Worker OtNetworkProperties::SetInstance(nullptr);
329*4a64e381SAndroid Build Coastguard Worker mThreadStateChangedCallbacks.clear();
330*4a64e381SAndroid Build Coastguard Worker mResetHandlers.clear();
331*4a64e381SAndroid Build Coastguard Worker
332*4a64e381SAndroid Build Coastguard Worker mSetThreadEnabledReceiver = nullptr;
333*4a64e381SAndroid Build Coastguard Worker mScheduleMigrationReceiver = nullptr;
334*4a64e381SAndroid Build Coastguard Worker }
335*4a64e381SAndroid Build Coastguard Worker
HandleStateChanged(otChangedFlags aFlags)336*4a64e381SAndroid Build Coastguard Worker void RcpHost::HandleStateChanged(otChangedFlags aFlags)
337*4a64e381SAndroid Build Coastguard Worker {
338*4a64e381SAndroid Build Coastguard Worker for (auto &stateCallback : mThreadStateChangedCallbacks)
339*4a64e381SAndroid Build Coastguard Worker {
340*4a64e381SAndroid Build Coastguard Worker stateCallback(aFlags);
341*4a64e381SAndroid Build Coastguard Worker }
342*4a64e381SAndroid Build Coastguard Worker
343*4a64e381SAndroid Build Coastguard Worker mThreadHelper->StateChangedCallback(aFlags);
344*4a64e381SAndroid Build Coastguard Worker }
345*4a64e381SAndroid Build Coastguard Worker
Update(MainloopContext & aMainloop)346*4a64e381SAndroid Build Coastguard Worker void RcpHost::Update(MainloopContext &aMainloop)
347*4a64e381SAndroid Build Coastguard Worker {
348*4a64e381SAndroid Build Coastguard Worker if (otTaskletsArePending(mInstance))
349*4a64e381SAndroid Build Coastguard Worker {
350*4a64e381SAndroid Build Coastguard Worker aMainloop.mTimeout = ToTimeval(Microseconds::zero());
351*4a64e381SAndroid Build Coastguard Worker }
352*4a64e381SAndroid Build Coastguard Worker
353*4a64e381SAndroid Build Coastguard Worker otSysMainloopUpdate(mInstance, &aMainloop);
354*4a64e381SAndroid Build Coastguard Worker }
355*4a64e381SAndroid Build Coastguard Worker
Process(const MainloopContext & aMainloop)356*4a64e381SAndroid Build Coastguard Worker void RcpHost::Process(const MainloopContext &aMainloop)
357*4a64e381SAndroid Build Coastguard Worker {
358*4a64e381SAndroid Build Coastguard Worker otTaskletsProcess(mInstance);
359*4a64e381SAndroid Build Coastguard Worker
360*4a64e381SAndroid Build Coastguard Worker otSysMainloopProcess(mInstance, &aMainloop);
361*4a64e381SAndroid Build Coastguard Worker
362*4a64e381SAndroid Build Coastguard Worker if (IsAutoAttachEnabled() && mThreadHelper->TryResumeNetwork() == OT_ERROR_NONE)
363*4a64e381SAndroid Build Coastguard Worker {
364*4a64e381SAndroid Build Coastguard Worker DisableAutoAttach();
365*4a64e381SAndroid Build Coastguard Worker }
366*4a64e381SAndroid Build Coastguard Worker }
367*4a64e381SAndroid Build Coastguard Worker
IsAutoAttachEnabled(void)368*4a64e381SAndroid Build Coastguard Worker bool RcpHost::IsAutoAttachEnabled(void)
369*4a64e381SAndroid Build Coastguard Worker {
370*4a64e381SAndroid Build Coastguard Worker return mEnableAutoAttach;
371*4a64e381SAndroid Build Coastguard Worker }
372*4a64e381SAndroid Build Coastguard Worker
DisableAutoAttach(void)373*4a64e381SAndroid Build Coastguard Worker void RcpHost::DisableAutoAttach(void)
374*4a64e381SAndroid Build Coastguard Worker {
375*4a64e381SAndroid Build Coastguard Worker mEnableAutoAttach = false;
376*4a64e381SAndroid Build Coastguard Worker }
377*4a64e381SAndroid Build Coastguard Worker
PostTimerTask(Milliseconds aDelay,TaskRunner::Task<void> aTask)378*4a64e381SAndroid Build Coastguard Worker void RcpHost::PostTimerTask(Milliseconds aDelay, TaskRunner::Task<void> aTask)
379*4a64e381SAndroid Build Coastguard Worker {
380*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post(std::move(aDelay), std::move(aTask));
381*4a64e381SAndroid Build Coastguard Worker }
382*4a64e381SAndroid Build Coastguard Worker
RegisterResetHandler(std::function<void (void)> aHandler)383*4a64e381SAndroid Build Coastguard Worker void RcpHost::RegisterResetHandler(std::function<void(void)> aHandler)
384*4a64e381SAndroid Build Coastguard Worker {
385*4a64e381SAndroid Build Coastguard Worker mResetHandlers.emplace_back(std::move(aHandler));
386*4a64e381SAndroid Build Coastguard Worker }
387*4a64e381SAndroid Build Coastguard Worker
AddThreadStateChangedCallback(ThreadStateChangedCallback aCallback)388*4a64e381SAndroid Build Coastguard Worker void RcpHost::AddThreadStateChangedCallback(ThreadStateChangedCallback aCallback)
389*4a64e381SAndroid Build Coastguard Worker {
390*4a64e381SAndroid Build Coastguard Worker mThreadStateChangedCallbacks.emplace_back(std::move(aCallback));
391*4a64e381SAndroid Build Coastguard Worker }
392*4a64e381SAndroid Build Coastguard Worker
Reset(void)393*4a64e381SAndroid Build Coastguard Worker void RcpHost::Reset(void)
394*4a64e381SAndroid Build Coastguard Worker {
395*4a64e381SAndroid Build Coastguard Worker gPlatResetReason = OT_PLAT_RESET_REASON_SOFTWARE;
396*4a64e381SAndroid Build Coastguard Worker
397*4a64e381SAndroid Build Coastguard Worker otSysDeinit();
398*4a64e381SAndroid Build Coastguard Worker mInstance = nullptr;
399*4a64e381SAndroid Build Coastguard Worker
400*4a64e381SAndroid Build Coastguard Worker Init();
401*4a64e381SAndroid Build Coastguard Worker for (auto &handler : mResetHandlers)
402*4a64e381SAndroid Build Coastguard Worker {
403*4a64e381SAndroid Build Coastguard Worker handler();
404*4a64e381SAndroid Build Coastguard Worker }
405*4a64e381SAndroid Build Coastguard Worker mEnableAutoAttach = true;
406*4a64e381SAndroid Build Coastguard Worker }
407*4a64e381SAndroid Build Coastguard Worker
GetThreadVersion(void)408*4a64e381SAndroid Build Coastguard Worker const char *RcpHost::GetThreadVersion(void)
409*4a64e381SAndroid Build Coastguard Worker {
410*4a64e381SAndroid Build Coastguard Worker const char *version;
411*4a64e381SAndroid Build Coastguard Worker
412*4a64e381SAndroid Build Coastguard Worker switch (otThreadGetVersion())
413*4a64e381SAndroid Build Coastguard Worker {
414*4a64e381SAndroid Build Coastguard Worker case kThreadVersion11:
415*4a64e381SAndroid Build Coastguard Worker version = "1.1.1";
416*4a64e381SAndroid Build Coastguard Worker break;
417*4a64e381SAndroid Build Coastguard Worker case kThreadVersion12:
418*4a64e381SAndroid Build Coastguard Worker version = "1.2.0";
419*4a64e381SAndroid Build Coastguard Worker break;
420*4a64e381SAndroid Build Coastguard Worker case kThreadVersion13:
421*4a64e381SAndroid Build Coastguard Worker version = "1.3.0";
422*4a64e381SAndroid Build Coastguard Worker break;
423*4a64e381SAndroid Build Coastguard Worker case kThreadVersion14:
424*4a64e381SAndroid Build Coastguard Worker version = "1.4.0";
425*4a64e381SAndroid Build Coastguard Worker break;
426*4a64e381SAndroid Build Coastguard Worker default:
427*4a64e381SAndroid Build Coastguard Worker otbrLogEmerg("Unexpected thread version %hu", otThreadGetVersion());
428*4a64e381SAndroid Build Coastguard Worker exit(-1);
429*4a64e381SAndroid Build Coastguard Worker }
430*4a64e381SAndroid Build Coastguard Worker return version;
431*4a64e381SAndroid Build Coastguard Worker }
432*4a64e381SAndroid Build Coastguard Worker
Join(const otOperationalDatasetTlvs & aActiveOpDatasetTlvs,const AsyncResultReceiver & aReceiver)433*4a64e381SAndroid Build Coastguard Worker void RcpHost::Join(const otOperationalDatasetTlvs &aActiveOpDatasetTlvs, const AsyncResultReceiver &aReceiver)
434*4a64e381SAndroid Build Coastguard Worker {
435*4a64e381SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aActiveOpDatasetTlvs);
436*4a64e381SAndroid Build Coastguard Worker
437*4a64e381SAndroid Build Coastguard Worker // TODO: Implement Join under RCP mode.
438*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post([aReceiver](void) { aReceiver(OT_ERROR_NOT_IMPLEMENTED, "Not implemented!"); });
439*4a64e381SAndroid Build Coastguard Worker }
440*4a64e381SAndroid Build Coastguard Worker
Leave(const AsyncResultReceiver & aReceiver)441*4a64e381SAndroid Build Coastguard Worker void RcpHost::Leave(const AsyncResultReceiver &aReceiver)
442*4a64e381SAndroid Build Coastguard Worker {
443*4a64e381SAndroid Build Coastguard Worker // TODO: Implement Leave under RCP mode.
444*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post([aReceiver](void) { aReceiver(OT_ERROR_NOT_IMPLEMENTED, "Not implemented!"); });
445*4a64e381SAndroid Build Coastguard Worker }
446*4a64e381SAndroid Build Coastguard Worker
ScheduleMigration(const otOperationalDatasetTlvs & aPendingOpDatasetTlvs,const AsyncResultReceiver aReceiver)447*4a64e381SAndroid Build Coastguard Worker void RcpHost::ScheduleMigration(const otOperationalDatasetTlvs &aPendingOpDatasetTlvs,
448*4a64e381SAndroid Build Coastguard Worker const AsyncResultReceiver aReceiver)
449*4a64e381SAndroid Build Coastguard Worker {
450*4a64e381SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
451*4a64e381SAndroid Build Coastguard Worker std::string errorMsg;
452*4a64e381SAndroid Build Coastguard Worker otOperationalDataset emptyDataset;
453*4a64e381SAndroid Build Coastguard Worker
454*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mInstance != nullptr, error = OT_ERROR_INVALID_STATE, errorMsg = "OT is not initialized");
455*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(IsAttached(), error = OT_ERROR_FAILED,
456*4a64e381SAndroid Build Coastguard Worker errorMsg = "Cannot schedule migration when this device is detached");
457*4a64e381SAndroid Build Coastguard Worker
458*4a64e381SAndroid Build Coastguard Worker // TODO: check supported channel mask
459*4a64e381SAndroid Build Coastguard Worker
460*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = otDatasetSendMgmtPendingSet(mInstance, &emptyDataset, aPendingOpDatasetTlvs.mTlvs,
461*4a64e381SAndroid Build Coastguard Worker static_cast<uint8_t>(aPendingOpDatasetTlvs.mLength),
462*4a64e381SAndroid Build Coastguard Worker SendMgmtPendingSetCallback, this),
463*4a64e381SAndroid Build Coastguard Worker errorMsg = "Failed to send MGMT_PENDING_SET.req");
464*4a64e381SAndroid Build Coastguard Worker
465*4a64e381SAndroid Build Coastguard Worker exit:
466*4a64e381SAndroid Build Coastguard Worker if (error != OT_ERROR_NONE)
467*4a64e381SAndroid Build Coastguard Worker {
468*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post([aReceiver, error, errorMsg](void) { aReceiver(error, errorMsg); });
469*4a64e381SAndroid Build Coastguard Worker }
470*4a64e381SAndroid Build Coastguard Worker else
471*4a64e381SAndroid Build Coastguard Worker {
472*4a64e381SAndroid Build Coastguard Worker // otDatasetSendMgmtPendingSet() returns OT_ERROR_BUSY if it has already been called before but the
473*4a64e381SAndroid Build Coastguard Worker // callback hasn't been invoked. So we can guarantee that mMigrationReceiver is always nullptr here
474*4a64e381SAndroid Build Coastguard Worker assert(mScheduleMigrationReceiver == nullptr);
475*4a64e381SAndroid Build Coastguard Worker mScheduleMigrationReceiver = aReceiver;
476*4a64e381SAndroid Build Coastguard Worker }
477*4a64e381SAndroid Build Coastguard Worker }
478*4a64e381SAndroid Build Coastguard Worker
SendMgmtPendingSetCallback(otError aError,void * aContext)479*4a64e381SAndroid Build Coastguard Worker void RcpHost::SendMgmtPendingSetCallback(otError aError, void *aContext)
480*4a64e381SAndroid Build Coastguard Worker {
481*4a64e381SAndroid Build Coastguard Worker static_cast<RcpHost *>(aContext)->SendMgmtPendingSetCallback(aError);
482*4a64e381SAndroid Build Coastguard Worker }
483*4a64e381SAndroid Build Coastguard Worker
SendMgmtPendingSetCallback(otError aError)484*4a64e381SAndroid Build Coastguard Worker void RcpHost::SendMgmtPendingSetCallback(otError aError)
485*4a64e381SAndroid Build Coastguard Worker {
486*4a64e381SAndroid Build Coastguard Worker SafeInvokeAndClear(mScheduleMigrationReceiver, aError, "");
487*4a64e381SAndroid Build Coastguard Worker }
488*4a64e381SAndroid Build Coastguard Worker
SetThreadEnabled(bool aEnabled,const AsyncResultReceiver aReceiver)489*4a64e381SAndroid Build Coastguard Worker void RcpHost::SetThreadEnabled(bool aEnabled, const AsyncResultReceiver aReceiver)
490*4a64e381SAndroid Build Coastguard Worker {
491*4a64e381SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
492*4a64e381SAndroid Build Coastguard Worker bool receiveResultHere = true;
493*4a64e381SAndroid Build Coastguard Worker
494*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mInstance != nullptr, error = OT_ERROR_INVALID_STATE);
495*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mSetThreadEnabledReceiver == nullptr, error = OT_ERROR_BUSY);
496*4a64e381SAndroid Build Coastguard Worker
497*4a64e381SAndroid Build Coastguard Worker if (aEnabled)
498*4a64e381SAndroid Build Coastguard Worker {
499*4a64e381SAndroid Build Coastguard Worker otOperationalDatasetTlvs datasetTlvs;
500*4a64e381SAndroid Build Coastguard Worker
501*4a64e381SAndroid Build Coastguard Worker if (otDatasetGetActiveTlvs(mInstance, &datasetTlvs) != OT_ERROR_NOT_FOUND && datasetTlvs.mLength > 0 &&
502*4a64e381SAndroid Build Coastguard Worker otThreadGetDeviceRole(mInstance) == OT_DEVICE_ROLE_DISABLED)
503*4a64e381SAndroid Build Coastguard Worker {
504*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = otIp6SetEnabled(mInstance, true));
505*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = otThreadSetEnabled(mInstance, true));
506*4a64e381SAndroid Build Coastguard Worker }
507*4a64e381SAndroid Build Coastguard Worker }
508*4a64e381SAndroid Build Coastguard Worker else
509*4a64e381SAndroid Build Coastguard Worker {
510*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = otThreadDetachGracefully(mInstance, DisableThreadAfterDetach, this));
511*4a64e381SAndroid Build Coastguard Worker mSetThreadEnabledReceiver = aReceiver;
512*4a64e381SAndroid Build Coastguard Worker receiveResultHere = false;
513*4a64e381SAndroid Build Coastguard Worker }
514*4a64e381SAndroid Build Coastguard Worker
515*4a64e381SAndroid Build Coastguard Worker exit:
516*4a64e381SAndroid Build Coastguard Worker if (receiveResultHere)
517*4a64e381SAndroid Build Coastguard Worker {
518*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post([aReceiver, error](void) { aReceiver(error, ""); });
519*4a64e381SAndroid Build Coastguard Worker }
520*4a64e381SAndroid Build Coastguard Worker }
521*4a64e381SAndroid Build Coastguard Worker
GetChannelMasks(const ChannelMasksReceiver & aReceiver,const AsyncResultReceiver & aErrReceiver)522*4a64e381SAndroid Build Coastguard Worker void RcpHost::GetChannelMasks(const ChannelMasksReceiver &aReceiver, const AsyncResultReceiver &aErrReceiver)
523*4a64e381SAndroid Build Coastguard Worker {
524*4a64e381SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
525*4a64e381SAndroid Build Coastguard Worker uint32_t supportedChannelMask;
526*4a64e381SAndroid Build Coastguard Worker uint32_t preferredChannelMask;
527*4a64e381SAndroid Build Coastguard Worker
528*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mInstance != nullptr, error = OT_ERROR_INVALID_STATE);
529*4a64e381SAndroid Build Coastguard Worker
530*4a64e381SAndroid Build Coastguard Worker supportedChannelMask = otLinkGetSupportedChannelMask(mInstance);
531*4a64e381SAndroid Build Coastguard Worker preferredChannelMask = otPlatRadioGetPreferredChannelMask(mInstance);
532*4a64e381SAndroid Build Coastguard Worker
533*4a64e381SAndroid Build Coastguard Worker exit:
534*4a64e381SAndroid Build Coastguard Worker if (error == OT_ERROR_NONE)
535*4a64e381SAndroid Build Coastguard Worker {
536*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post([aReceiver, supportedChannelMask, preferredChannelMask](void) {
537*4a64e381SAndroid Build Coastguard Worker aReceiver(supportedChannelMask, preferredChannelMask);
538*4a64e381SAndroid Build Coastguard Worker });
539*4a64e381SAndroid Build Coastguard Worker }
540*4a64e381SAndroid Build Coastguard Worker else
541*4a64e381SAndroid Build Coastguard Worker {
542*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post([aErrReceiver, error](void) { aErrReceiver(error, "OT is not initialized"); });
543*4a64e381SAndroid Build Coastguard Worker }
544*4a64e381SAndroid Build Coastguard Worker }
545*4a64e381SAndroid Build Coastguard Worker
SetChannelMaxPowers(const std::vector<ChannelMaxPower> & aChannelMaxPowers,const AsyncResultReceiver & aReceiver)546*4a64e381SAndroid Build Coastguard Worker void RcpHost::SetChannelMaxPowers(const std::vector<ChannelMaxPower> &aChannelMaxPowers,
547*4a64e381SAndroid Build Coastguard Worker const AsyncResultReceiver &aReceiver)
548*4a64e381SAndroid Build Coastguard Worker {
549*4a64e381SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
550*4a64e381SAndroid Build Coastguard Worker std::string errorMsg;
551*4a64e381SAndroid Build Coastguard Worker
552*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mInstance != nullptr, error = OT_ERROR_INVALID_STATE, errorMsg = "OT is not initialized");
553*4a64e381SAndroid Build Coastguard Worker
554*4a64e381SAndroid Build Coastguard Worker for (ChannelMaxPower channelMaxPower : aChannelMaxPowers)
555*4a64e381SAndroid Build Coastguard Worker {
556*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((channelMaxPower.mChannel >= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MIN) &&
557*4a64e381SAndroid Build Coastguard Worker (channelMaxPower.mChannel <= OT_RADIO_2P4GHZ_OQPSK_CHANNEL_MAX),
558*4a64e381SAndroid Build Coastguard Worker error = OT_ERROR_INVALID_ARGS, errorMsg = "The channel is invalid");
559*4a64e381SAndroid Build Coastguard Worker }
560*4a64e381SAndroid Build Coastguard Worker
561*4a64e381SAndroid Build Coastguard Worker for (ChannelMaxPower channelMaxPower : aChannelMaxPowers)
562*4a64e381SAndroid Build Coastguard Worker {
563*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Set channel max power: channel=%u, maxPower=%u", static_cast<uint32_t>(channelMaxPower.mChannel),
564*4a64e381SAndroid Build Coastguard Worker static_cast<uint32_t>(channelMaxPower.mMaxPower));
565*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = otPlatRadioSetChannelTargetPower(
566*4a64e381SAndroid Build Coastguard Worker mInstance, static_cast<uint8_t>(channelMaxPower.mChannel), channelMaxPower.mMaxPower),
567*4a64e381SAndroid Build Coastguard Worker errorMsg = "Failed to set channel max power");
568*4a64e381SAndroid Build Coastguard Worker }
569*4a64e381SAndroid Build Coastguard Worker
570*4a64e381SAndroid Build Coastguard Worker exit:
571*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post([aReceiver, error, errorMsg](void) { aReceiver(error, errorMsg); });
572*4a64e381SAndroid Build Coastguard Worker }
573*4a64e381SAndroid Build Coastguard Worker
DisableThreadAfterDetach(void * aContext)574*4a64e381SAndroid Build Coastguard Worker void RcpHost::DisableThreadAfterDetach(void *aContext)
575*4a64e381SAndroid Build Coastguard Worker {
576*4a64e381SAndroid Build Coastguard Worker static_cast<RcpHost *>(aContext)->DisableThreadAfterDetach();
577*4a64e381SAndroid Build Coastguard Worker }
578*4a64e381SAndroid Build Coastguard Worker
DisableThreadAfterDetach(void)579*4a64e381SAndroid Build Coastguard Worker void RcpHost::DisableThreadAfterDetach(void)
580*4a64e381SAndroid Build Coastguard Worker {
581*4a64e381SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
582*4a64e381SAndroid Build Coastguard Worker std::string errorMsg;
583*4a64e381SAndroid Build Coastguard Worker
584*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = otThreadSetEnabled(mInstance, false), errorMsg = "Failed to disable Thread stack");
585*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = otIp6SetEnabled(mInstance, false), errorMsg = "Failed to disable Thread interface");
586*4a64e381SAndroid Build Coastguard Worker
587*4a64e381SAndroid Build Coastguard Worker exit:
588*4a64e381SAndroid Build Coastguard Worker SafeInvokeAndClear(mSetThreadEnabledReceiver, error, errorMsg);
589*4a64e381SAndroid Build Coastguard Worker }
590*4a64e381SAndroid Build Coastguard Worker
SetCountryCode(const std::string & aCountryCode,const AsyncResultReceiver & aReceiver)591*4a64e381SAndroid Build Coastguard Worker void RcpHost::SetCountryCode(const std::string &aCountryCode, const AsyncResultReceiver &aReceiver)
592*4a64e381SAndroid Build Coastguard Worker {
593*4a64e381SAndroid Build Coastguard Worker static constexpr int kCountryCodeLength = 2;
594*4a64e381SAndroid Build Coastguard Worker otError error = OT_ERROR_NONE;
595*4a64e381SAndroid Build Coastguard Worker std::string errorMsg;
596*4a64e381SAndroid Build Coastguard Worker uint16_t countryCode;
597*4a64e381SAndroid Build Coastguard Worker
598*4a64e381SAndroid Build Coastguard Worker VerifyOrExit((aCountryCode.length() == kCountryCodeLength) && isalpha(aCountryCode[0]) && isalpha(aCountryCode[1]),
599*4a64e381SAndroid Build Coastguard Worker error = OT_ERROR_INVALID_ARGS, errorMsg = "The country code is invalid");
600*4a64e381SAndroid Build Coastguard Worker
601*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("Set country code: %c%c", aCountryCode[0], aCountryCode[1]);
602*4a64e381SAndroid Build Coastguard Worker VerifyOrExit(mInstance != nullptr, error = OT_ERROR_INVALID_STATE, errorMsg = "OT is not initialized");
603*4a64e381SAndroid Build Coastguard Worker
604*4a64e381SAndroid Build Coastguard Worker countryCode = static_cast<uint16_t>((aCountryCode[0] << 8) | aCountryCode[1]);
605*4a64e381SAndroid Build Coastguard Worker SuccessOrExit(error = otLinkSetRegion(mInstance, countryCode), errorMsg = "Failed to set the country code");
606*4a64e381SAndroid Build Coastguard Worker
607*4a64e381SAndroid Build Coastguard Worker exit:
608*4a64e381SAndroid Build Coastguard Worker mTaskRunner.Post([aReceiver, error, errorMsg](void) { aReceiver(error, errorMsg); });
609*4a64e381SAndroid Build Coastguard Worker }
610*4a64e381SAndroid Build Coastguard Worker
IsAttached(void)611*4a64e381SAndroid Build Coastguard Worker bool RcpHost::IsAttached(void)
612*4a64e381SAndroid Build Coastguard Worker {
613*4a64e381SAndroid Build Coastguard Worker otDeviceRole role = GetDeviceRole();
614*4a64e381SAndroid Build Coastguard Worker
615*4a64e381SAndroid Build Coastguard Worker return role == OT_DEVICE_ROLE_CHILD || role == OT_DEVICE_ROLE_ROUTER || role == OT_DEVICE_ROLE_LEADER;
616*4a64e381SAndroid Build Coastguard Worker }
617*4a64e381SAndroid Build Coastguard Worker
618*4a64e381SAndroid Build Coastguard Worker /*
619*4a64e381SAndroid Build Coastguard Worker * Provide, if required an "otPlatLog()" function
620*4a64e381SAndroid Build Coastguard Worker */
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)621*4a64e381SAndroid Build Coastguard Worker extern "C" void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
622*4a64e381SAndroid Build Coastguard Worker {
623*4a64e381SAndroid Build Coastguard Worker OT_UNUSED_VARIABLE(aLogRegion);
624*4a64e381SAndroid Build Coastguard Worker
625*4a64e381SAndroid Build Coastguard Worker otbrLogLevel otbrLogLevel = RcpHost::ConvertToOtbrLogLevel(aLogLevel);
626*4a64e381SAndroid Build Coastguard Worker
627*4a64e381SAndroid Build Coastguard Worker va_list ap;
628*4a64e381SAndroid Build Coastguard Worker va_start(ap, aFormat);
629*4a64e381SAndroid Build Coastguard Worker otbrLogvNoFilter(otbrLogLevel, aFormat, ap);
630*4a64e381SAndroid Build Coastguard Worker va_end(ap);
631*4a64e381SAndroid Build Coastguard Worker }
632*4a64e381SAndroid Build Coastguard Worker
otPlatLogHandleLevelChanged(otLogLevel aLogLevel)633*4a64e381SAndroid Build Coastguard Worker extern "C" void otPlatLogHandleLevelChanged(otLogLevel aLogLevel)
634*4a64e381SAndroid Build Coastguard Worker {
635*4a64e381SAndroid Build Coastguard Worker otbrLogSetLevel(RcpHost::ConvertToOtbrLogLevel(aLogLevel));
636*4a64e381SAndroid Build Coastguard Worker otbrLogInfo("OpenThread log level changed to %d", aLogLevel);
637*4a64e381SAndroid Build Coastguard Worker }
638*4a64e381SAndroid Build Coastguard Worker
639*4a64e381SAndroid Build Coastguard Worker } // namespace Ncp
640*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
641