xref: /aosp_15_r20/external/ot-br-posix/src/agent/main.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *    Copyright (c) 2017, 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 "AGENT"
30*4a64e381SAndroid Build Coastguard Worker 
31*4a64e381SAndroid Build Coastguard Worker #include <openthread-br/config.h>
32*4a64e381SAndroid Build Coastguard Worker 
33*4a64e381SAndroid Build Coastguard Worker #include <algorithm>
34*4a64e381SAndroid Build Coastguard Worker #include <vector>
35*4a64e381SAndroid Build Coastguard Worker 
36*4a64e381SAndroid Build Coastguard Worker #include <assert.h>
37*4a64e381SAndroid Build Coastguard Worker #include <getopt.h>
38*4a64e381SAndroid Build Coastguard Worker #include <stdio.h>
39*4a64e381SAndroid Build Coastguard Worker #include <stdlib.h>
40*4a64e381SAndroid Build Coastguard Worker #include <string.h>
41*4a64e381SAndroid Build Coastguard Worker #include <unistd.h>
42*4a64e381SAndroid Build Coastguard Worker 
43*4a64e381SAndroid Build Coastguard Worker #include <openthread/logging.h>
44*4a64e381SAndroid Build Coastguard Worker #include <openthread/platform/radio.h>
45*4a64e381SAndroid Build Coastguard Worker 
46*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_PLATFORM_ANDROID
47*4a64e381SAndroid Build Coastguard Worker #include <cutils/properties.h>
48*4a64e381SAndroid Build Coastguard Worker #endif
49*4a64e381SAndroid Build Coastguard Worker 
50*4a64e381SAndroid Build Coastguard Worker #include "agent/application.hpp"
51*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
52*4a64e381SAndroid Build Coastguard Worker #include "common/logging.hpp"
53*4a64e381SAndroid Build Coastguard Worker #include "common/mainloop.hpp"
54*4a64e381SAndroid Build Coastguard Worker #include "common/types.hpp"
55*4a64e381SAndroid Build Coastguard Worker #include "ncp/thread_host.hpp"
56*4a64e381SAndroid Build Coastguard Worker 
57*4a64e381SAndroid Build Coastguard Worker #ifdef OTBR_ENABLE_PLATFORM_ANDROID
58*4a64e381SAndroid Build Coastguard Worker #include <log/log.h>
59*4a64e381SAndroid Build Coastguard Worker #ifndef __ANDROID__
60*4a64e381SAndroid Build Coastguard Worker #error "OTBR_ENABLE_PLATFORM_ANDROID can be enabled for only Android devices"
61*4a64e381SAndroid Build Coastguard Worker #endif
62*4a64e381SAndroid Build Coastguard Worker #endif
63*4a64e381SAndroid Build Coastguard Worker 
64*4a64e381SAndroid Build Coastguard Worker static const char kDefaultInterfaceName[] = "wpan0";
65*4a64e381SAndroid Build Coastguard Worker 
66*4a64e381SAndroid Build Coastguard Worker // Port number used by Rest server.
67*4a64e381SAndroid Build Coastguard Worker static const uint32_t kPortNumber = 8081;
68*4a64e381SAndroid Build Coastguard Worker 
69*4a64e381SAndroid Build Coastguard Worker enum
70*4a64e381SAndroid Build Coastguard Worker {
71*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_BACKBONE_INTERFACE_NAME = 'B',
72*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_DEBUG_LEVEL             = 'd',
73*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_HELP                    = 'h',
74*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_INTERFACE_NAME          = 'I',
75*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_VERBOSE                 = 'v',
76*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_SYSLOG_DISABLE          = 's',
77*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_VERSION                 = 'V',
78*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_SHORTMAX                = 128,
79*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_RADIO_VERSION,
80*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_AUTO_ATTACH,
81*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_REST_LISTEN_ADDR,
82*4a64e381SAndroid Build Coastguard Worker     OTBR_OPT_REST_LISTEN_PORT,
83*4a64e381SAndroid Build Coastguard Worker };
84*4a64e381SAndroid Build Coastguard Worker 
85*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_ENABLE_PLATFORM_ANDROID
86*4a64e381SAndroid Build Coastguard Worker static jmp_buf sResetJump;
87*4a64e381SAndroid Build Coastguard Worker #endif
88*4a64e381SAndroid Build Coastguard Worker static otbr::Application *gApp = nullptr;
89*4a64e381SAndroid Build Coastguard Worker 
90*4a64e381SAndroid Build Coastguard Worker void                       __gcov_flush();
91*4a64e381SAndroid Build Coastguard Worker static const struct option kOptions[] = {
92*4a64e381SAndroid Build Coastguard Worker     {"backbone-ifname", required_argument, nullptr, OTBR_OPT_BACKBONE_INTERFACE_NAME},
93*4a64e381SAndroid Build Coastguard Worker     {"debug-level", required_argument, nullptr, OTBR_OPT_DEBUG_LEVEL},
94*4a64e381SAndroid Build Coastguard Worker     {"help", no_argument, nullptr, OTBR_OPT_HELP},
95*4a64e381SAndroid Build Coastguard Worker     {"thread-ifname", required_argument, nullptr, OTBR_OPT_INTERFACE_NAME},
96*4a64e381SAndroid Build Coastguard Worker     {"verbose", no_argument, nullptr, OTBR_OPT_VERBOSE},
97*4a64e381SAndroid Build Coastguard Worker     {"syslog-disable", no_argument, nullptr, OTBR_OPT_SYSLOG_DISABLE},
98*4a64e381SAndroid Build Coastguard Worker     {"version", no_argument, nullptr, OTBR_OPT_VERSION},
99*4a64e381SAndroid Build Coastguard Worker     {"radio-version", no_argument, nullptr, OTBR_OPT_RADIO_VERSION},
100*4a64e381SAndroid Build Coastguard Worker     {"auto-attach", optional_argument, nullptr, OTBR_OPT_AUTO_ATTACH},
101*4a64e381SAndroid Build Coastguard Worker     {"rest-listen-address", required_argument, nullptr, OTBR_OPT_REST_LISTEN_ADDR},
102*4a64e381SAndroid Build Coastguard Worker     {"rest-listen-port", required_argument, nullptr, OTBR_OPT_REST_LISTEN_PORT},
103*4a64e381SAndroid Build Coastguard Worker     {0, 0, 0, 0}};
104*4a64e381SAndroid Build Coastguard Worker 
ParseInteger(const char * aStr,long & aOutResult)105*4a64e381SAndroid Build Coastguard Worker static bool ParseInteger(const char *aStr, long &aOutResult)
106*4a64e381SAndroid Build Coastguard Worker {
107*4a64e381SAndroid Build Coastguard Worker     bool  successful = true;
108*4a64e381SAndroid Build Coastguard Worker     char *strEnd;
109*4a64e381SAndroid Build Coastguard Worker     long  result;
110*4a64e381SAndroid Build Coastguard Worker 
111*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(aStr != nullptr, successful = false);
112*4a64e381SAndroid Build Coastguard Worker     errno  = 0;
113*4a64e381SAndroid Build Coastguard Worker     result = strtol(aStr, &strEnd, 0);
114*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(errno != ERANGE, successful = false);
115*4a64e381SAndroid Build Coastguard Worker     VerifyOrExit(aStr != strEnd, successful = false);
116*4a64e381SAndroid Build Coastguard Worker 
117*4a64e381SAndroid Build Coastguard Worker     aOutResult = result;
118*4a64e381SAndroid Build Coastguard Worker 
119*4a64e381SAndroid Build Coastguard Worker exit:
120*4a64e381SAndroid Build Coastguard Worker     return successful;
121*4a64e381SAndroid Build Coastguard Worker }
122*4a64e381SAndroid Build Coastguard Worker 
123*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_ENABLE_PLATFORM_ANDROID
124*4a64e381SAndroid Build Coastguard Worker static constexpr char kAutoAttachDisableArg[] = "--auto-attach=0";
125*4a64e381SAndroid Build Coastguard Worker static char           sAutoAttachDisableArgStorage[sizeof(kAutoAttachDisableArg)];
126*4a64e381SAndroid Build Coastguard Worker 
AppendAutoAttachDisableArg(int argc,char * argv[])127*4a64e381SAndroid Build Coastguard Worker static std::vector<char *> AppendAutoAttachDisableArg(int argc, char *argv[])
128*4a64e381SAndroid Build Coastguard Worker {
129*4a64e381SAndroid Build Coastguard Worker     std::vector<char *> args(argv, argv + argc);
130*4a64e381SAndroid Build Coastguard Worker 
131*4a64e381SAndroid Build Coastguard Worker     args.erase(std::remove_if(
132*4a64e381SAndroid Build Coastguard Worker                    args.begin(), args.end(),
133*4a64e381SAndroid Build Coastguard Worker                    [](const char *arg) { return arg != nullptr && std::string(arg).rfind("--auto-attach", 0) == 0; }),
134*4a64e381SAndroid Build Coastguard Worker                args.end());
135*4a64e381SAndroid Build Coastguard Worker     strcpy(sAutoAttachDisableArgStorage, kAutoAttachDisableArg);
136*4a64e381SAndroid Build Coastguard Worker     args.push_back(sAutoAttachDisableArgStorage);
137*4a64e381SAndroid Build Coastguard Worker     args.push_back(nullptr);
138*4a64e381SAndroid Build Coastguard Worker 
139*4a64e381SAndroid Build Coastguard Worker     return args;
140*4a64e381SAndroid Build Coastguard Worker }
141*4a64e381SAndroid Build Coastguard Worker #endif
142*4a64e381SAndroid Build Coastguard Worker 
PrintHelp(const char * aProgramName)143*4a64e381SAndroid Build Coastguard Worker static void PrintHelp(const char *aProgramName)
144*4a64e381SAndroid Build Coastguard Worker {
145*4a64e381SAndroid Build Coastguard Worker     fprintf(stderr,
146*4a64e381SAndroid Build Coastguard Worker             "Usage: %s [-I interfaceName] [-B backboneIfName] [-d DEBUG_LEVEL] [-v] [-s] [--auto-attach[=0/1]] "
147*4a64e381SAndroid Build Coastguard Worker             "RADIO_URL [RADIO_URL]\n"
148*4a64e381SAndroid Build Coastguard Worker             "    --auto-attach defaults to 1\n"
149*4a64e381SAndroid Build Coastguard Worker             "    -s disables syslog and prints to standard out\n",
150*4a64e381SAndroid Build Coastguard Worker             aProgramName);
151*4a64e381SAndroid Build Coastguard Worker     fprintf(stderr, "%s", otSysGetRadioUrlHelpString());
152*4a64e381SAndroid Build Coastguard Worker }
153*4a64e381SAndroid Build Coastguard Worker 
PrintVersion(void)154*4a64e381SAndroid Build Coastguard Worker static void PrintVersion(void)
155*4a64e381SAndroid Build Coastguard Worker {
156*4a64e381SAndroid Build Coastguard Worker     printf("%s\n", OTBR_PACKAGE_VERSION);
157*4a64e381SAndroid Build Coastguard Worker }
158*4a64e381SAndroid Build Coastguard Worker 
OnAllocateFailed(void)159*4a64e381SAndroid Build Coastguard Worker static void OnAllocateFailed(void)
160*4a64e381SAndroid Build Coastguard Worker {
161*4a64e381SAndroid Build Coastguard Worker     otbrLogCrit("Allocate failure, exiting...");
162*4a64e381SAndroid Build Coastguard Worker     exit(1);
163*4a64e381SAndroid Build Coastguard Worker }
164*4a64e381SAndroid Build Coastguard Worker 
GetDefaultLogLevel(void)165*4a64e381SAndroid Build Coastguard Worker static otbrLogLevel GetDefaultLogLevel(void)
166*4a64e381SAndroid Build Coastguard Worker {
167*4a64e381SAndroid Build Coastguard Worker #if OTBR_ENABLE_PLATFORM_ANDROID
168*4a64e381SAndroid Build Coastguard Worker     // The log level is set to DEBUG by default, the final output log will be filtered by Android log system.
169*4a64e381SAndroid Build Coastguard Worker     otbrLogLevel level = OTBR_LOG_DEBUG;
170*4a64e381SAndroid Build Coastguard Worker     char         value[PROPERTY_VALUE_MAX];
171*4a64e381SAndroid Build Coastguard Worker 
172*4a64e381SAndroid Build Coastguard Worker     // Set the Android log level to INFO by default.
173*4a64e381SAndroid Build Coastguard Worker     __android_log_set_minimum_priority(ANDROID_LOG_INFO);
174*4a64e381SAndroid Build Coastguard Worker 
175*4a64e381SAndroid Build Coastguard Worker     property_get("ro.build.type", value, "user");
176*4a64e381SAndroid Build Coastguard Worker     if (!strcmp(value, "user"))
177*4a64e381SAndroid Build Coastguard Worker     {
178*4a64e381SAndroid Build Coastguard Worker         level = OTBR_LOG_WARNING;
179*4a64e381SAndroid Build Coastguard Worker     }
180*4a64e381SAndroid Build Coastguard Worker #else
181*4a64e381SAndroid Build Coastguard Worker     otbrLogLevel level = OTBR_LOG_INFO;
182*4a64e381SAndroid Build Coastguard Worker #endif
183*4a64e381SAndroid Build Coastguard Worker 
184*4a64e381SAndroid Build Coastguard Worker     return level;
185*4a64e381SAndroid Build Coastguard Worker }
186*4a64e381SAndroid Build Coastguard Worker 
PrintRadioVersionAndExit(const std::vector<const char * > & aRadioUrls)187*4a64e381SAndroid Build Coastguard Worker static void PrintRadioVersionAndExit(const std::vector<const char *> &aRadioUrls)
188*4a64e381SAndroid Build Coastguard Worker {
189*4a64e381SAndroid Build Coastguard Worker     auto host = std::unique_ptr<otbr::Ncp::ThreadHost>(
190*4a64e381SAndroid Build Coastguard Worker         otbr::Ncp::ThreadHost::Create(/* aInterfaceName */ "", aRadioUrls,
191*4a64e381SAndroid Build Coastguard Worker                                       /* aBackboneInterfaceName */ "",
192*4a64e381SAndroid Build Coastguard Worker                                       /* aDryRun */ true, /* aEnableAutoAttach */ false));
193*4a64e381SAndroid Build Coastguard Worker     const char *coprocessorVersion;
194*4a64e381SAndroid Build Coastguard Worker 
195*4a64e381SAndroid Build Coastguard Worker     host->Init();
196*4a64e381SAndroid Build Coastguard Worker 
197*4a64e381SAndroid Build Coastguard Worker     coprocessorVersion = host->GetCoprocessorVersion();
198*4a64e381SAndroid Build Coastguard Worker     printf("%s\n", coprocessorVersion);
199*4a64e381SAndroid Build Coastguard Worker 
200*4a64e381SAndroid Build Coastguard Worker     host->Deinit();
201*4a64e381SAndroid Build Coastguard Worker 
202*4a64e381SAndroid Build Coastguard Worker     exit(EXIT_SUCCESS);
203*4a64e381SAndroid Build Coastguard Worker }
204*4a64e381SAndroid Build Coastguard Worker 
realmain(int argc,char * argv[])205*4a64e381SAndroid Build Coastguard Worker static int realmain(int argc, char *argv[])
206*4a64e381SAndroid Build Coastguard Worker {
207*4a64e381SAndroid Build Coastguard Worker     otbrLogLevel              logLevel = GetDefaultLogLevel();
208*4a64e381SAndroid Build Coastguard Worker     int                       opt;
209*4a64e381SAndroid Build Coastguard Worker     int                       ret               = EXIT_SUCCESS;
210*4a64e381SAndroid Build Coastguard Worker     const char               *interfaceName     = kDefaultInterfaceName;
211*4a64e381SAndroid Build Coastguard Worker     bool                      verbose           = false;
212*4a64e381SAndroid Build Coastguard Worker     bool                      syslogDisable     = false;
213*4a64e381SAndroid Build Coastguard Worker     bool                      printRadioVersion = false;
214*4a64e381SAndroid Build Coastguard Worker     bool                      enableAutoAttach  = true;
215*4a64e381SAndroid Build Coastguard Worker     const char               *restListenAddress = "";
216*4a64e381SAndroid Build Coastguard Worker     int                       restListenPort    = kPortNumber;
217*4a64e381SAndroid Build Coastguard Worker     std::vector<const char *> radioUrls;
218*4a64e381SAndroid Build Coastguard Worker     std::vector<const char *> backboneInterfaceNames;
219*4a64e381SAndroid Build Coastguard Worker     long                      parseResult;
220*4a64e381SAndroid Build Coastguard Worker 
221*4a64e381SAndroid Build Coastguard Worker     std::set_new_handler(OnAllocateFailed);
222*4a64e381SAndroid Build Coastguard Worker 
223*4a64e381SAndroid Build Coastguard Worker     while ((opt = getopt_long(argc, argv, "B:d:hI:Vvs", kOptions, nullptr)) != -1)
224*4a64e381SAndroid Build Coastguard Worker     {
225*4a64e381SAndroid Build Coastguard Worker         switch (opt)
226*4a64e381SAndroid Build Coastguard Worker         {
227*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_BACKBONE_INTERFACE_NAME:
228*4a64e381SAndroid Build Coastguard Worker             backboneInterfaceNames.push_back(optarg);
229*4a64e381SAndroid Build Coastguard Worker             otbrLogNotice("Backbone interface: %s", optarg);
230*4a64e381SAndroid Build Coastguard Worker             break;
231*4a64e381SAndroid Build Coastguard Worker 
232*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_DEBUG_LEVEL:
233*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(ParseInteger(optarg, parseResult), ret = EXIT_FAILURE);
234*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(OTBR_LOG_EMERG <= parseResult && parseResult <= OTBR_LOG_DEBUG, ret = EXIT_FAILURE);
235*4a64e381SAndroid Build Coastguard Worker             logLevel = static_cast<otbrLogLevel>(parseResult);
236*4a64e381SAndroid Build Coastguard Worker             break;
237*4a64e381SAndroid Build Coastguard Worker 
238*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_INTERFACE_NAME:
239*4a64e381SAndroid Build Coastguard Worker             interfaceName = optarg;
240*4a64e381SAndroid Build Coastguard Worker             break;
241*4a64e381SAndroid Build Coastguard Worker 
242*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_VERBOSE:
243*4a64e381SAndroid Build Coastguard Worker             verbose = true;
244*4a64e381SAndroid Build Coastguard Worker             break;
245*4a64e381SAndroid Build Coastguard Worker 
246*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_SYSLOG_DISABLE:
247*4a64e381SAndroid Build Coastguard Worker             syslogDisable = true;
248*4a64e381SAndroid Build Coastguard Worker             break;
249*4a64e381SAndroid Build Coastguard Worker 
250*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_VERSION:
251*4a64e381SAndroid Build Coastguard Worker             PrintVersion();
252*4a64e381SAndroid Build Coastguard Worker             ExitNow();
253*4a64e381SAndroid Build Coastguard Worker             break;
254*4a64e381SAndroid Build Coastguard Worker 
255*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_HELP:
256*4a64e381SAndroid Build Coastguard Worker             PrintHelp(argv[0]);
257*4a64e381SAndroid Build Coastguard Worker             ExitNow(ret = EXIT_SUCCESS);
258*4a64e381SAndroid Build Coastguard Worker             break;
259*4a64e381SAndroid Build Coastguard Worker 
260*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_RADIO_VERSION:
261*4a64e381SAndroid Build Coastguard Worker             printRadioVersion = true;
262*4a64e381SAndroid Build Coastguard Worker             break;
263*4a64e381SAndroid Build Coastguard Worker 
264*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_AUTO_ATTACH:
265*4a64e381SAndroid Build Coastguard Worker             if (optarg == nullptr)
266*4a64e381SAndroid Build Coastguard Worker             {
267*4a64e381SAndroid Build Coastguard Worker                 enableAutoAttach = true;
268*4a64e381SAndroid Build Coastguard Worker             }
269*4a64e381SAndroid Build Coastguard Worker             else
270*4a64e381SAndroid Build Coastguard Worker             {
271*4a64e381SAndroid Build Coastguard Worker                 VerifyOrExit(ParseInteger(optarg, parseResult), ret = EXIT_FAILURE);
272*4a64e381SAndroid Build Coastguard Worker                 enableAutoAttach = parseResult;
273*4a64e381SAndroid Build Coastguard Worker             }
274*4a64e381SAndroid Build Coastguard Worker             break;
275*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_REST_LISTEN_ADDR:
276*4a64e381SAndroid Build Coastguard Worker             restListenAddress = optarg;
277*4a64e381SAndroid Build Coastguard Worker             break;
278*4a64e381SAndroid Build Coastguard Worker 
279*4a64e381SAndroid Build Coastguard Worker         case OTBR_OPT_REST_LISTEN_PORT:
280*4a64e381SAndroid Build Coastguard Worker             VerifyOrExit(ParseInteger(optarg, parseResult), ret = EXIT_FAILURE);
281*4a64e381SAndroid Build Coastguard Worker             restListenPort = parseResult;
282*4a64e381SAndroid Build Coastguard Worker             break;
283*4a64e381SAndroid Build Coastguard Worker 
284*4a64e381SAndroid Build Coastguard Worker         default:
285*4a64e381SAndroid Build Coastguard Worker             PrintHelp(argv[0]);
286*4a64e381SAndroid Build Coastguard Worker             ExitNow(ret = EXIT_FAILURE);
287*4a64e381SAndroid Build Coastguard Worker             break;
288*4a64e381SAndroid Build Coastguard Worker         }
289*4a64e381SAndroid Build Coastguard Worker     }
290*4a64e381SAndroid Build Coastguard Worker 
291*4a64e381SAndroid Build Coastguard Worker     otbrLogInit(argv[0], logLevel, verbose, syslogDisable);
292*4a64e381SAndroid Build Coastguard Worker     otbrLogNotice("Running %s", OTBR_PACKAGE_VERSION);
293*4a64e381SAndroid Build Coastguard Worker     otbrLogNotice("Thread version: %s", otbr::Ncp::RcpHost::GetThreadVersion());
294*4a64e381SAndroid Build Coastguard Worker     otbrLogNotice("Thread interface: %s", interfaceName);
295*4a64e381SAndroid Build Coastguard Worker 
296*4a64e381SAndroid Build Coastguard Worker     if (backboneInterfaceNames.empty())
297*4a64e381SAndroid Build Coastguard Worker     {
298*4a64e381SAndroid Build Coastguard Worker         otbrLogNotice("Backbone interface is not specified");
299*4a64e381SAndroid Build Coastguard Worker     }
300*4a64e381SAndroid Build Coastguard Worker 
301*4a64e381SAndroid Build Coastguard Worker     for (int i = optind; i < argc; i++)
302*4a64e381SAndroid Build Coastguard Worker     {
303*4a64e381SAndroid Build Coastguard Worker         otbrLogNotice("Radio URL: %s", argv[i]);
304*4a64e381SAndroid Build Coastguard Worker         radioUrls.push_back(argv[i]);
305*4a64e381SAndroid Build Coastguard Worker     }
306*4a64e381SAndroid Build Coastguard Worker 
307*4a64e381SAndroid Build Coastguard Worker     if (printRadioVersion)
308*4a64e381SAndroid Build Coastguard Worker     {
309*4a64e381SAndroid Build Coastguard Worker         PrintRadioVersionAndExit(radioUrls);
310*4a64e381SAndroid Build Coastguard Worker         assert(false);
311*4a64e381SAndroid Build Coastguard Worker     }
312*4a64e381SAndroid Build Coastguard Worker 
313*4a64e381SAndroid Build Coastguard Worker     {
314*4a64e381SAndroid Build Coastguard Worker         otbr::Application app(interfaceName, backboneInterfaceNames, radioUrls, enableAutoAttach, restListenAddress,
315*4a64e381SAndroid Build Coastguard Worker                               restListenPort);
316*4a64e381SAndroid Build Coastguard Worker 
317*4a64e381SAndroid Build Coastguard Worker         gApp = &app;
318*4a64e381SAndroid Build Coastguard Worker         app.Init();
319*4a64e381SAndroid Build Coastguard Worker 
320*4a64e381SAndroid Build Coastguard Worker         ret = app.Run();
321*4a64e381SAndroid Build Coastguard Worker 
322*4a64e381SAndroid Build Coastguard Worker         app.Deinit();
323*4a64e381SAndroid Build Coastguard Worker     }
324*4a64e381SAndroid Build Coastguard Worker 
325*4a64e381SAndroid Build Coastguard Worker     otbrLogDeinit();
326*4a64e381SAndroid Build Coastguard Worker 
327*4a64e381SAndroid Build Coastguard Worker exit:
328*4a64e381SAndroid Build Coastguard Worker     return ret;
329*4a64e381SAndroid Build Coastguard Worker }
330*4a64e381SAndroid Build Coastguard Worker 
otPlatReset(otInstance * aInstance)331*4a64e381SAndroid Build Coastguard Worker void otPlatReset(otInstance *aInstance)
332*4a64e381SAndroid Build Coastguard Worker {
333*4a64e381SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aInstance);
334*4a64e381SAndroid Build Coastguard Worker 
335*4a64e381SAndroid Build Coastguard Worker     gPlatResetReason = OT_PLAT_RESET_REASON_SOFTWARE;
336*4a64e381SAndroid Build Coastguard Worker 
337*4a64e381SAndroid Build Coastguard Worker     VerifyOrDie(gApp != nullptr, "gApp is null");
338*4a64e381SAndroid Build Coastguard Worker     gApp->Deinit();
339*4a64e381SAndroid Build Coastguard Worker     gApp = nullptr;
340*4a64e381SAndroid Build Coastguard Worker 
341*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_ENABLE_PLATFORM_ANDROID
342*4a64e381SAndroid Build Coastguard Worker     longjmp(sResetJump, 1);
343*4a64e381SAndroid Build Coastguard Worker     assert(false);
344*4a64e381SAndroid Build Coastguard Worker #else
345*4a64e381SAndroid Build Coastguard Worker     // Exits immediately on Android. The Android system_server will receive the
346*4a64e381SAndroid Build Coastguard Worker     // signal and decide whether (and how) to restart the ot-daemon
347*4a64e381SAndroid Build Coastguard Worker     exit(0);
348*4a64e381SAndroid Build Coastguard Worker #endif
349*4a64e381SAndroid Build Coastguard Worker }
350*4a64e381SAndroid Build Coastguard Worker 
main(int argc,char * argv[])351*4a64e381SAndroid Build Coastguard Worker int main(int argc, char *argv[])
352*4a64e381SAndroid Build Coastguard Worker {
353*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_ENABLE_PLATFORM_ANDROID
354*4a64e381SAndroid Build Coastguard Worker     if (setjmp(sResetJump))
355*4a64e381SAndroid Build Coastguard Worker     {
356*4a64e381SAndroid Build Coastguard Worker         std::vector<char *> args = AppendAutoAttachDisableArg(argc, argv);
357*4a64e381SAndroid Build Coastguard Worker 
358*4a64e381SAndroid Build Coastguard Worker         alarm(0);
359*4a64e381SAndroid Build Coastguard Worker #if OPENTHREAD_ENABLE_COVERAGE
360*4a64e381SAndroid Build Coastguard Worker         __gcov_flush();
361*4a64e381SAndroid Build Coastguard Worker #endif
362*4a64e381SAndroid Build Coastguard Worker 
363*4a64e381SAndroid Build Coastguard Worker         execvp(args[0], args.data());
364*4a64e381SAndroid Build Coastguard Worker     }
365*4a64e381SAndroid Build Coastguard Worker #endif
366*4a64e381SAndroid Build Coastguard Worker     return realmain(argc, argv);
367*4a64e381SAndroid Build Coastguard Worker }
368