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