xref: /aosp_15_r20/external/openthread/src/posix/main.c (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2018, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include "platform/openthread-posix-config.h"
30*cfb92d14SAndroid Build Coastguard Worker 
31*cfb92d14SAndroid Build Coastguard Worker #include <openthread/config.h>
32*cfb92d14SAndroid Build Coastguard Worker 
33*cfb92d14SAndroid Build Coastguard Worker #include <assert.h>
34*cfb92d14SAndroid Build Coastguard Worker #include <errno.h>
35*cfb92d14SAndroid Build Coastguard Worker #include <getopt.h>
36*cfb92d14SAndroid Build Coastguard Worker #include <libgen.h>
37*cfb92d14SAndroid Build Coastguard Worker #include <signal.h>
38*cfb92d14SAndroid Build Coastguard Worker #include <stdio.h>
39*cfb92d14SAndroid Build Coastguard Worker #include <stdlib.h>
40*cfb92d14SAndroid Build Coastguard Worker #include <string.h>
41*cfb92d14SAndroid Build Coastguard Worker #include <syslog.h>
42*cfb92d14SAndroid Build Coastguard Worker #include <unistd.h>
43*cfb92d14SAndroid Build Coastguard Worker #ifdef __linux__
44*cfb92d14SAndroid Build Coastguard Worker #include <sys/prctl.h>
45*cfb92d14SAndroid Build Coastguard Worker #endif
46*cfb92d14SAndroid Build Coastguard Worker 
47*cfb92d14SAndroid Build Coastguard Worker #ifndef HAVE_LIBEDIT
48*cfb92d14SAndroid Build Coastguard Worker #define HAVE_LIBEDIT 0
49*cfb92d14SAndroid Build Coastguard Worker #endif
50*cfb92d14SAndroid Build Coastguard Worker 
51*cfb92d14SAndroid Build Coastguard Worker #ifndef HAVE_LIBREADLINE
52*cfb92d14SAndroid Build Coastguard Worker #define HAVE_LIBREADLINE 0
53*cfb92d14SAndroid Build Coastguard Worker #endif
54*cfb92d14SAndroid Build Coastguard Worker 
55*cfb92d14SAndroid Build Coastguard Worker #include <openthread/cli.h>
56*cfb92d14SAndroid Build Coastguard Worker #include <openthread/diag.h>
57*cfb92d14SAndroid Build Coastguard Worker #include <openthread/logging.h>
58*cfb92d14SAndroid Build Coastguard Worker #include <openthread/tasklet.h>
59*cfb92d14SAndroid Build Coastguard Worker #include <openthread/thread.h>
60*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/radio.h>
61*cfb92d14SAndroid Build Coastguard Worker #if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
62*cfb92d14SAndroid Build Coastguard Worker #include <openthread/cli.h>
63*cfb92d14SAndroid Build Coastguard Worker #include "cli/cli_config.h"
64*cfb92d14SAndroid Build Coastguard Worker #endif
65*cfb92d14SAndroid Build Coastguard Worker #include <common/code_utils.hpp>
66*cfb92d14SAndroid Build Coastguard Worker #include <lib/platform/exit_code.h>
67*cfb92d14SAndroid Build Coastguard Worker #include <lib/platform/reset_util.h>
68*cfb92d14SAndroid Build Coastguard Worker #include <lib/spinel/coprocessor_type.h>
69*cfb92d14SAndroid Build Coastguard Worker #include <openthread/openthread-system.h>
70*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/misc.h>
71*cfb92d14SAndroid Build Coastguard Worker 
72*cfb92d14SAndroid Build Coastguard Worker /**
73*cfb92d14SAndroid Build Coastguard Worker  * Initializes NCP app.
74*cfb92d14SAndroid Build Coastguard Worker  *
75*cfb92d14SAndroid Build Coastguard Worker  * @param[in]  aInstance    A pointer to the OpenThread instance.
76*cfb92d14SAndroid Build Coastguard Worker  *
77*cfb92d14SAndroid Build Coastguard Worker  */
78*cfb92d14SAndroid Build Coastguard Worker void otAppNcpInit(otInstance *aInstance);
79*cfb92d14SAndroid Build Coastguard Worker 
80*cfb92d14SAndroid Build Coastguard Worker /**
81*cfb92d14SAndroid Build Coastguard Worker  * Deinitializes NCP app.
82*cfb92d14SAndroid Build Coastguard Worker  *
83*cfb92d14SAndroid Build Coastguard Worker  */
84*cfb92d14SAndroid Build Coastguard Worker void otAppNcpUpdate(otSysMainloopContext *aContext);
85*cfb92d14SAndroid Build Coastguard Worker 
86*cfb92d14SAndroid Build Coastguard Worker /**
87*cfb92d14SAndroid Build Coastguard Worker  * Updates the file descriptor sets with file descriptors used by console.
88*cfb92d14SAndroid Build Coastguard Worker  *
89*cfb92d14SAndroid Build Coastguard Worker  * @param[in,out]   aMainloop   A pointer to the mainloop context.
90*cfb92d14SAndroid Build Coastguard Worker  *
91*cfb92d14SAndroid Build Coastguard Worker  */
92*cfb92d14SAndroid Build Coastguard Worker void otAppNcpProcess(const otSysMainloopContext *aContext);
93*cfb92d14SAndroid Build Coastguard Worker 
94*cfb92d14SAndroid Build Coastguard Worker /**
95*cfb92d14SAndroid Build Coastguard Worker  * Initializes CLI app.
96*cfb92d14SAndroid Build Coastguard Worker  *
97*cfb92d14SAndroid Build Coastguard Worker  * @param[in]  aInstance    A pointer to the OpenThread instance.
98*cfb92d14SAndroid Build Coastguard Worker  *
99*cfb92d14SAndroid Build Coastguard Worker  */
100*cfb92d14SAndroid Build Coastguard Worker void otAppCliInit(otInstance *aInstance);
101*cfb92d14SAndroid Build Coastguard Worker 
102*cfb92d14SAndroid Build Coastguard Worker /**
103*cfb92d14SAndroid Build Coastguard Worker  * Deinitializes CLI app.
104*cfb92d14SAndroid Build Coastguard Worker  *
105*cfb92d14SAndroid Build Coastguard Worker  */
106*cfb92d14SAndroid Build Coastguard Worker void otAppCliDeinit(void);
107*cfb92d14SAndroid Build Coastguard Worker 
108*cfb92d14SAndroid Build Coastguard Worker /**
109*cfb92d14SAndroid Build Coastguard Worker  * Updates the file descriptor sets with file descriptors used by console.
110*cfb92d14SAndroid Build Coastguard Worker  *
111*cfb92d14SAndroid Build Coastguard Worker  * @param[in,out]   aMainloop   A pointer to the mainloop context.
112*cfb92d14SAndroid Build Coastguard Worker  *
113*cfb92d14SAndroid Build Coastguard Worker  */
114*cfb92d14SAndroid Build Coastguard Worker void otAppCliUpdate(otSysMainloopContext *aMainloop);
115*cfb92d14SAndroid Build Coastguard Worker 
116*cfb92d14SAndroid Build Coastguard Worker /**
117*cfb92d14SAndroid Build Coastguard Worker  * Performs console driver processing.
118*cfb92d14SAndroid Build Coastguard Worker  *
119*cfb92d14SAndroid Build Coastguard Worker  * @param[in]    aMainloop      A pointer to the mainloop context.
120*cfb92d14SAndroid Build Coastguard Worker  *
121*cfb92d14SAndroid Build Coastguard Worker  */
122*cfb92d14SAndroid Build Coastguard Worker void otAppCliProcess(const otSysMainloopContext *aMainloop);
123*cfb92d14SAndroid Build Coastguard Worker 
124*cfb92d14SAndroid Build Coastguard Worker typedef struct PosixConfig
125*cfb92d14SAndroid Build Coastguard Worker {
126*cfb92d14SAndroid Build Coastguard Worker     otPlatformConfig mPlatformConfig;    ///< Platform configuration.
127*cfb92d14SAndroid Build Coastguard Worker     otLogLevel       mLogLevel;          ///< Debug level of logging.
128*cfb92d14SAndroid Build Coastguard Worker     bool             mPrintRadioVersion; ///< Whether to print radio firmware version.
129*cfb92d14SAndroid Build Coastguard Worker     bool             mIsVerbose;         ///< Whether to print log to stderr.
130*cfb92d14SAndroid Build Coastguard Worker } PosixConfig;
131*cfb92d14SAndroid Build Coastguard Worker 
132*cfb92d14SAndroid Build Coastguard Worker /**
133*cfb92d14SAndroid Build Coastguard Worker  * Defines the argument return values.
134*cfb92d14SAndroid Build Coastguard Worker  *
135*cfb92d14SAndroid Build Coastguard Worker  */
136*cfb92d14SAndroid Build Coastguard Worker enum
137*cfb92d14SAndroid Build Coastguard Worker {
138*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_BACKBONE_INTERFACE_NAME = 'B',
139*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_DEBUG_LEVEL             = 'd',
140*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_DRY_RUN                 = 'n',
141*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_HELP                    = 'h',
142*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_INTERFACE_NAME          = 'I',
143*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_PERSISTENT_INTERFACE    = 'p',
144*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_TIME_SPEED              = 's',
145*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_VERBOSE                 = 'v',
146*cfb92d14SAndroid Build Coastguard Worker 
147*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_SHORT_MAX = 128,
148*cfb92d14SAndroid Build Coastguard Worker 
149*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_RADIO_VERSION,
150*cfb92d14SAndroid Build Coastguard Worker     OT_POSIX_OPT_REAL_TIME_SIGNAL,
151*cfb92d14SAndroid Build Coastguard Worker };
152*cfb92d14SAndroid Build Coastguard Worker 
153*cfb92d14SAndroid Build Coastguard Worker static const struct option kOptions[] = {
154*cfb92d14SAndroid Build Coastguard Worker     {"backbone-interface-name", required_argument, NULL, OT_POSIX_OPT_BACKBONE_INTERFACE_NAME},
155*cfb92d14SAndroid Build Coastguard Worker     {"debug-level", required_argument, NULL, OT_POSIX_OPT_DEBUG_LEVEL},
156*cfb92d14SAndroid Build Coastguard Worker     {"dry-run", no_argument, NULL, OT_POSIX_OPT_DRY_RUN},
157*cfb92d14SAndroid Build Coastguard Worker     {"help", no_argument, NULL, OT_POSIX_OPT_HELP},
158*cfb92d14SAndroid Build Coastguard Worker     {"interface-name", required_argument, NULL, OT_POSIX_OPT_INTERFACE_NAME},
159*cfb92d14SAndroid Build Coastguard Worker     {"persistent-interface", no_argument, NULL, OT_POSIX_OPT_PERSISTENT_INTERFACE},
160*cfb92d14SAndroid Build Coastguard Worker     {"radio-version", no_argument, NULL, OT_POSIX_OPT_RADIO_VERSION},
161*cfb92d14SAndroid Build Coastguard Worker     {"real-time-signal", required_argument, NULL, OT_POSIX_OPT_REAL_TIME_SIGNAL},
162*cfb92d14SAndroid Build Coastguard Worker     {"time-speed", required_argument, NULL, OT_POSIX_OPT_TIME_SPEED},
163*cfb92d14SAndroid Build Coastguard Worker     {"verbose", no_argument, NULL, OT_POSIX_OPT_VERBOSE},
164*cfb92d14SAndroid Build Coastguard Worker     {0, 0, 0, 0}};
165*cfb92d14SAndroid Build Coastguard Worker 
PrintUsage(const char * aProgramName,FILE * aStream,int aExitCode)166*cfb92d14SAndroid Build Coastguard Worker static void PrintUsage(const char *aProgramName, FILE *aStream, int aExitCode)
167*cfb92d14SAndroid Build Coastguard Worker {
168*cfb92d14SAndroid Build Coastguard Worker     fprintf(aStream,
169*cfb92d14SAndroid Build Coastguard Worker             "Syntax:\n"
170*cfb92d14SAndroid Build Coastguard Worker             "    %s [Options] RadioURL [RadioURL]\n"
171*cfb92d14SAndroid Build Coastguard Worker             "Options:\n"
172*cfb92d14SAndroid Build Coastguard Worker             "    -B  --backbone-interface-name Backbone network interface name.\n"
173*cfb92d14SAndroid Build Coastguard Worker             "    -d  --debug-level             Debug level of logging.\n"
174*cfb92d14SAndroid Build Coastguard Worker             "    -h  --help                    Display this usage information.\n"
175*cfb92d14SAndroid Build Coastguard Worker             "    -I  --interface-name name     Thread network interface name.\n"
176*cfb92d14SAndroid Build Coastguard Worker             "    -n  --dry-run                 Just verify if arguments is valid and radio spinel is compatible.\n"
177*cfb92d14SAndroid Build Coastguard Worker             "        --radio-version           Print radio firmware version.\n"
178*cfb92d14SAndroid Build Coastguard Worker             "    -p  --persistent-interface    Persistent the created thread network interface\n"
179*cfb92d14SAndroid Build Coastguard Worker             "    -s  --time-speed factor       Time speed up factor.\n"
180*cfb92d14SAndroid Build Coastguard Worker             "    -v  --verbose                 Also log to stderr.\n",
181*cfb92d14SAndroid Build Coastguard Worker             aProgramName);
182*cfb92d14SAndroid Build Coastguard Worker #ifdef __linux__
183*cfb92d14SAndroid Build Coastguard Worker     fprintf(aStream,
184*cfb92d14SAndroid Build Coastguard Worker             "        --real-time-signal        (Linux only) The real-time signal number for microsecond timer.\n"
185*cfb92d14SAndroid Build Coastguard Worker             "                                  Use +N for relative value to SIGRTMIN, and use N for absolute value.\n");
186*cfb92d14SAndroid Build Coastguard Worker 
187*cfb92d14SAndroid Build Coastguard Worker #endif
188*cfb92d14SAndroid Build Coastguard Worker     fprintf(aStream, "%s", otSysGetRadioUrlHelpString());
189*cfb92d14SAndroid Build Coastguard Worker     exit(aExitCode);
190*cfb92d14SAndroid Build Coastguard Worker }
191*cfb92d14SAndroid Build Coastguard Worker 
ParseArg(int aArgCount,char * aArgVector[],PosixConfig * aConfig)192*cfb92d14SAndroid Build Coastguard Worker static void ParseArg(int aArgCount, char *aArgVector[], PosixConfig *aConfig)
193*cfb92d14SAndroid Build Coastguard Worker {
194*cfb92d14SAndroid Build Coastguard Worker     memset(aConfig, 0, sizeof(*aConfig));
195*cfb92d14SAndroid Build Coastguard Worker 
196*cfb92d14SAndroid Build Coastguard Worker     aConfig->mPlatformConfig.mPersistentInterface = false;
197*cfb92d14SAndroid Build Coastguard Worker     aConfig->mPlatformConfig.mSpeedUpFactor       = 1;
198*cfb92d14SAndroid Build Coastguard Worker     aConfig->mLogLevel                            = OT_LOG_LEVEL_CRIT;
199*cfb92d14SAndroid Build Coastguard Worker     aConfig->mPlatformConfig.mInterfaceName       = OPENTHREAD_POSIX_CONFIG_THREAD_NETIF_DEFAULT_NAME;
200*cfb92d14SAndroid Build Coastguard Worker #ifdef __linux__
201*cfb92d14SAndroid Build Coastguard Worker     aConfig->mPlatformConfig.mRealTimeSignal = SIGRTMIN;
202*cfb92d14SAndroid Build Coastguard Worker #endif
203*cfb92d14SAndroid Build Coastguard Worker 
204*cfb92d14SAndroid Build Coastguard Worker     optind = 1;
205*cfb92d14SAndroid Build Coastguard Worker 
206*cfb92d14SAndroid Build Coastguard Worker     while (true)
207*cfb92d14SAndroid Build Coastguard Worker     {
208*cfb92d14SAndroid Build Coastguard Worker         int index  = 0;
209*cfb92d14SAndroid Build Coastguard Worker         int option = getopt_long(aArgCount, aArgVector, "B:d:hI:nps:v", kOptions, &index);
210*cfb92d14SAndroid Build Coastguard Worker 
211*cfb92d14SAndroid Build Coastguard Worker         if (option == -1)
212*cfb92d14SAndroid Build Coastguard Worker         {
213*cfb92d14SAndroid Build Coastguard Worker             break;
214*cfb92d14SAndroid Build Coastguard Worker         }
215*cfb92d14SAndroid Build Coastguard Worker 
216*cfb92d14SAndroid Build Coastguard Worker         switch (option)
217*cfb92d14SAndroid Build Coastguard Worker         {
218*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_DEBUG_LEVEL:
219*cfb92d14SAndroid Build Coastguard Worker             aConfig->mLogLevel = (otLogLevel)atoi(optarg);
220*cfb92d14SAndroid Build Coastguard Worker             break;
221*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_HELP:
222*cfb92d14SAndroid Build Coastguard Worker             PrintUsage(aArgVector[0], stdout, OT_EXIT_SUCCESS);
223*cfb92d14SAndroid Build Coastguard Worker             break;
224*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_INTERFACE_NAME:
225*cfb92d14SAndroid Build Coastguard Worker             aConfig->mPlatformConfig.mInterfaceName = optarg;
226*cfb92d14SAndroid Build Coastguard Worker             break;
227*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_PERSISTENT_INTERFACE:
228*cfb92d14SAndroid Build Coastguard Worker             aConfig->mPlatformConfig.mPersistentInterface = true;
229*cfb92d14SAndroid Build Coastguard Worker             break;
230*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_BACKBONE_INTERFACE_NAME:
231*cfb92d14SAndroid Build Coastguard Worker             aConfig->mPlatformConfig.mBackboneInterfaceName = optarg;
232*cfb92d14SAndroid Build Coastguard Worker             break;
233*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_DRY_RUN:
234*cfb92d14SAndroid Build Coastguard Worker             aConfig->mPlatformConfig.mDryRun = true;
235*cfb92d14SAndroid Build Coastguard Worker             break;
236*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_TIME_SPEED:
237*cfb92d14SAndroid Build Coastguard Worker         {
238*cfb92d14SAndroid Build Coastguard Worker             char *endptr = NULL;
239*cfb92d14SAndroid Build Coastguard Worker 
240*cfb92d14SAndroid Build Coastguard Worker             aConfig->mPlatformConfig.mSpeedUpFactor = (uint32_t)strtol(optarg, &endptr, 0);
241*cfb92d14SAndroid Build Coastguard Worker 
242*cfb92d14SAndroid Build Coastguard Worker             if (*endptr != '\0' || aConfig->mPlatformConfig.mSpeedUpFactor == 0)
243*cfb92d14SAndroid Build Coastguard Worker             {
244*cfb92d14SAndroid Build Coastguard Worker                 fprintf(stderr, "Invalid value for TimerSpeedUpFactor: %s\n", optarg);
245*cfb92d14SAndroid Build Coastguard Worker                 exit(OT_EXIT_INVALID_ARGUMENTS);
246*cfb92d14SAndroid Build Coastguard Worker             }
247*cfb92d14SAndroid Build Coastguard Worker             break;
248*cfb92d14SAndroid Build Coastguard Worker         }
249*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_VERBOSE:
250*cfb92d14SAndroid Build Coastguard Worker             aConfig->mIsVerbose = true;
251*cfb92d14SAndroid Build Coastguard Worker             break;
252*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_RADIO_VERSION:
253*cfb92d14SAndroid Build Coastguard Worker             aConfig->mPrintRadioVersion = true;
254*cfb92d14SAndroid Build Coastguard Worker             break;
255*cfb92d14SAndroid Build Coastguard Worker #ifdef __linux__
256*cfb92d14SAndroid Build Coastguard Worker         case OT_POSIX_OPT_REAL_TIME_SIGNAL:
257*cfb92d14SAndroid Build Coastguard Worker             if (optarg[0] == '+')
258*cfb92d14SAndroid Build Coastguard Worker             {
259*cfb92d14SAndroid Build Coastguard Worker                 aConfig->mPlatformConfig.mRealTimeSignal = SIGRTMIN + atoi(&optarg[1]);
260*cfb92d14SAndroid Build Coastguard Worker             }
261*cfb92d14SAndroid Build Coastguard Worker             else
262*cfb92d14SAndroid Build Coastguard Worker             {
263*cfb92d14SAndroid Build Coastguard Worker                 aConfig->mPlatformConfig.mRealTimeSignal = atoi(optarg);
264*cfb92d14SAndroid Build Coastguard Worker             }
265*cfb92d14SAndroid Build Coastguard Worker             break;
266*cfb92d14SAndroid Build Coastguard Worker #endif // __linux__
267*cfb92d14SAndroid Build Coastguard Worker         case '?':
268*cfb92d14SAndroid Build Coastguard Worker             PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
269*cfb92d14SAndroid Build Coastguard Worker             break;
270*cfb92d14SAndroid Build Coastguard Worker         default:
271*cfb92d14SAndroid Build Coastguard Worker             assert(false);
272*cfb92d14SAndroid Build Coastguard Worker             break;
273*cfb92d14SAndroid Build Coastguard Worker         }
274*cfb92d14SAndroid Build Coastguard Worker     }
275*cfb92d14SAndroid Build Coastguard Worker 
276*cfb92d14SAndroid Build Coastguard Worker     for (; optind < aArgCount; optind++)
277*cfb92d14SAndroid Build Coastguard Worker     {
278*cfb92d14SAndroid Build Coastguard Worker         VerifyOrDie(aConfig->mPlatformConfig.mCoprocessorUrls.mNum <
279*cfb92d14SAndroid Build Coastguard Worker                         OT_ARRAY_LENGTH(aConfig->mPlatformConfig.mCoprocessorUrls.mUrls),
280*cfb92d14SAndroid Build Coastguard Worker                     OT_EXIT_INVALID_ARGUMENTS);
281*cfb92d14SAndroid Build Coastguard Worker         aConfig->mPlatformConfig.mCoprocessorUrls.mUrls[aConfig->mPlatformConfig.mCoprocessorUrls.mNum++] =
282*cfb92d14SAndroid Build Coastguard Worker             aArgVector[optind];
283*cfb92d14SAndroid Build Coastguard Worker     }
284*cfb92d14SAndroid Build Coastguard Worker 
285*cfb92d14SAndroid Build Coastguard Worker     if (aConfig->mPlatformConfig.mCoprocessorUrls.mNum == 0)
286*cfb92d14SAndroid Build Coastguard Worker     {
287*cfb92d14SAndroid Build Coastguard Worker         PrintUsage(aArgVector[0], stderr, OT_EXIT_INVALID_ARGUMENTS);
288*cfb92d14SAndroid Build Coastguard Worker     }
289*cfb92d14SAndroid Build Coastguard Worker }
290*cfb92d14SAndroid Build Coastguard Worker 
InitInstance(PosixConfig * aConfig)291*cfb92d14SAndroid Build Coastguard Worker static otInstance *InitInstance(PosixConfig *aConfig)
292*cfb92d14SAndroid Build Coastguard Worker {
293*cfb92d14SAndroid Build Coastguard Worker     otInstance *instance = NULL;
294*cfb92d14SAndroid Build Coastguard Worker 
295*cfb92d14SAndroid Build Coastguard Worker     syslog(LOG_INFO, "Running %s", otGetVersionString());
296*cfb92d14SAndroid Build Coastguard Worker     syslog(LOG_INFO, "Thread version: %hu", otThreadGetVersion());
297*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otLoggingSetLevel(aConfig->mLogLevel));
298*cfb92d14SAndroid Build Coastguard Worker 
299*cfb92d14SAndroid Build Coastguard Worker     instance = otSysInit(&aConfig->mPlatformConfig);
300*cfb92d14SAndroid Build Coastguard Worker     VerifyOrDie(instance != NULL, OT_EXIT_FAILURE);
301*cfb92d14SAndroid Build Coastguard Worker     syslog(LOG_INFO, "Thread interface: %s", otSysGetThreadNetifName());
302*cfb92d14SAndroid Build Coastguard Worker 
303*cfb92d14SAndroid Build Coastguard Worker     if (aConfig->mPlatformConfig.mCoprocessorType != OT_COPROCESSOR_RCP)
304*cfb92d14SAndroid Build Coastguard Worker     {
305*cfb92d14SAndroid Build Coastguard Worker         printf("Only RCP is supported by posix app now!\n");
306*cfb92d14SAndroid Build Coastguard Worker         exit(OT_EXIT_FAILURE);
307*cfb92d14SAndroid Build Coastguard Worker     }
308*cfb92d14SAndroid Build Coastguard Worker 
309*cfb92d14SAndroid Build Coastguard Worker     if (aConfig->mPrintRadioVersion)
310*cfb92d14SAndroid Build Coastguard Worker     {
311*cfb92d14SAndroid Build Coastguard Worker         printf("%s\n", otPlatRadioGetVersionString(instance));
312*cfb92d14SAndroid Build Coastguard Worker     }
313*cfb92d14SAndroid Build Coastguard Worker     else
314*cfb92d14SAndroid Build Coastguard Worker     {
315*cfb92d14SAndroid Build Coastguard Worker         syslog(LOG_INFO, "RCP version: %s", otPlatRadioGetVersionString(instance));
316*cfb92d14SAndroid Build Coastguard Worker     }
317*cfb92d14SAndroid Build Coastguard Worker 
318*cfb92d14SAndroid Build Coastguard Worker     if (aConfig->mPlatformConfig.mDryRun)
319*cfb92d14SAndroid Build Coastguard Worker     {
320*cfb92d14SAndroid Build Coastguard Worker         exit(OT_EXIT_SUCCESS);
321*cfb92d14SAndroid Build Coastguard Worker     }
322*cfb92d14SAndroid Build Coastguard Worker 
323*cfb92d14SAndroid Build Coastguard Worker     return instance;
324*cfb92d14SAndroid Build Coastguard Worker }
325*cfb92d14SAndroid Build Coastguard Worker 
otTaskletsSignalPending(otInstance * aInstance)326*cfb92d14SAndroid Build Coastguard Worker void otTaskletsSignalPending(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); }
327*cfb92d14SAndroid Build Coastguard Worker 
otPlatReset(otInstance * aInstance)328*cfb92d14SAndroid Build Coastguard Worker void otPlatReset(otInstance *aInstance)
329*cfb92d14SAndroid Build Coastguard Worker {
330*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aInstance);
331*cfb92d14SAndroid Build Coastguard Worker 
332*cfb92d14SAndroid Build Coastguard Worker     gPlatResetReason = OT_PLAT_RESET_REASON_SOFTWARE;
333*cfb92d14SAndroid Build Coastguard Worker 
334*cfb92d14SAndroid Build Coastguard Worker     otSysDeinit();
335*cfb92d14SAndroid Build Coastguard Worker 
336*cfb92d14SAndroid Build Coastguard Worker     longjmp(gResetJump, 1);
337*cfb92d14SAndroid Build Coastguard Worker     assert(false);
338*cfb92d14SAndroid Build Coastguard Worker }
339*cfb92d14SAndroid Build Coastguard Worker 
ProcessNetif(void * aContext,uint8_t aArgsLength,char * aArgs[])340*cfb92d14SAndroid Build Coastguard Worker static otError ProcessNetif(void *aContext, uint8_t aArgsLength, char *aArgs[])
341*cfb92d14SAndroid Build Coastguard Worker {
342*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aContext);
343*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgsLength);
344*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgs);
345*cfb92d14SAndroid Build Coastguard Worker 
346*cfb92d14SAndroid Build Coastguard Worker     otCliOutputFormat("%s:%u\r\n", otSysGetThreadNetifName(), otSysGetThreadNetifIndex());
347*cfb92d14SAndroid Build Coastguard Worker 
348*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
349*cfb92d14SAndroid Build Coastguard Worker }
350*cfb92d14SAndroid Build Coastguard Worker 
351*cfb92d14SAndroid Build Coastguard Worker #if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
ProcessExit(void * aContext,uint8_t aArgsLength,char * aArgs[])352*cfb92d14SAndroid Build Coastguard Worker static otError ProcessExit(void *aContext, uint8_t aArgsLength, char *aArgs[])
353*cfb92d14SAndroid Build Coastguard Worker {
354*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aContext);
355*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgsLength);
356*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgs);
357*cfb92d14SAndroid Build Coastguard Worker 
358*cfb92d14SAndroid Build Coastguard Worker     exit(EXIT_SUCCESS);
359*cfb92d14SAndroid Build Coastguard Worker }
360*cfb92d14SAndroid Build Coastguard Worker #endif
361*cfb92d14SAndroid Build Coastguard Worker 
362*cfb92d14SAndroid Build Coastguard Worker static const otCliCommand kCommands[] = {
363*cfb92d14SAndroid Build Coastguard Worker #if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
364*cfb92d14SAndroid Build Coastguard Worker     {"exit", ProcessExit},
365*cfb92d14SAndroid Build Coastguard Worker #endif
366*cfb92d14SAndroid Build Coastguard Worker     {"netif", ProcessNetif},
367*cfb92d14SAndroid Build Coastguard Worker };
368*cfb92d14SAndroid Build Coastguard Worker 
main(int argc,char * argv[])369*cfb92d14SAndroid Build Coastguard Worker int main(int argc, char *argv[])
370*cfb92d14SAndroid Build Coastguard Worker {
371*cfb92d14SAndroid Build Coastguard Worker     otInstance *instance;
372*cfb92d14SAndroid Build Coastguard Worker     int         rval = 0;
373*cfb92d14SAndroid Build Coastguard Worker     PosixConfig config;
374*cfb92d14SAndroid Build Coastguard Worker 
375*cfb92d14SAndroid Build Coastguard Worker #ifdef __linux__
376*cfb92d14SAndroid Build Coastguard Worker     // Ensure we terminate this process if the
377*cfb92d14SAndroid Build Coastguard Worker     // parent process dies.
378*cfb92d14SAndroid Build Coastguard Worker     prctl(PR_SET_PDEATHSIG, SIGHUP);
379*cfb92d14SAndroid Build Coastguard Worker #endif
380*cfb92d14SAndroid Build Coastguard Worker 
381*cfb92d14SAndroid Build Coastguard Worker     OT_SETUP_RESET_JUMP(argv);
382*cfb92d14SAndroid Build Coastguard Worker 
383*cfb92d14SAndroid Build Coastguard Worker     ParseArg(argc, argv, &config);
384*cfb92d14SAndroid Build Coastguard Worker     openlog(argv[0], LOG_PID | (config.mIsVerbose ? LOG_PERROR : 0), LOG_DAEMON);
385*cfb92d14SAndroid Build Coastguard Worker     setlogmask(setlogmask(0) & LOG_UPTO(LOG_DEBUG));
386*cfb92d14SAndroid Build Coastguard Worker     instance = InitInstance(&config);
387*cfb92d14SAndroid Build Coastguard Worker 
388*cfb92d14SAndroid Build Coastguard Worker #if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
389*cfb92d14SAndroid Build Coastguard Worker     otAppCliInit(instance);
390*cfb92d14SAndroid Build Coastguard Worker #endif
391*cfb92d14SAndroid Build Coastguard Worker 
392*cfb92d14SAndroid Build Coastguard Worker #if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE || OPENTHREAD_POSIX_CONFIG_DAEMON_CLI_ENABLE
393*cfb92d14SAndroid Build Coastguard Worker     IgnoreError(otCliSetUserCommands(kCommands, OT_ARRAY_LENGTH(kCommands), instance));
394*cfb92d14SAndroid Build Coastguard Worker #endif
395*cfb92d14SAndroid Build Coastguard Worker 
396*cfb92d14SAndroid Build Coastguard Worker     while (true)
397*cfb92d14SAndroid Build Coastguard Worker     {
398*cfb92d14SAndroid Build Coastguard Worker         otSysMainloopContext mainloop;
399*cfb92d14SAndroid Build Coastguard Worker 
400*cfb92d14SAndroid Build Coastguard Worker         otTaskletsProcess(instance);
401*cfb92d14SAndroid Build Coastguard Worker 
402*cfb92d14SAndroid Build Coastguard Worker         FD_ZERO(&mainloop.mReadFdSet);
403*cfb92d14SAndroid Build Coastguard Worker         FD_ZERO(&mainloop.mWriteFdSet);
404*cfb92d14SAndroid Build Coastguard Worker         FD_ZERO(&mainloop.mErrorFdSet);
405*cfb92d14SAndroid Build Coastguard Worker 
406*cfb92d14SAndroid Build Coastguard Worker         mainloop.mMaxFd           = -1;
407*cfb92d14SAndroid Build Coastguard Worker         mainloop.mTimeout.tv_sec  = 10;
408*cfb92d14SAndroid Build Coastguard Worker         mainloop.mTimeout.tv_usec = 0;
409*cfb92d14SAndroid Build Coastguard Worker 
410*cfb92d14SAndroid Build Coastguard Worker #if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
411*cfb92d14SAndroid Build Coastguard Worker         otAppCliUpdate(&mainloop);
412*cfb92d14SAndroid Build Coastguard Worker #endif
413*cfb92d14SAndroid Build Coastguard Worker 
414*cfb92d14SAndroid Build Coastguard Worker         otSysMainloopUpdate(instance, &mainloop);
415*cfb92d14SAndroid Build Coastguard Worker 
416*cfb92d14SAndroid Build Coastguard Worker         if (otSysMainloopPoll(&mainloop) >= 0)
417*cfb92d14SAndroid Build Coastguard Worker         {
418*cfb92d14SAndroid Build Coastguard Worker             otSysMainloopProcess(instance, &mainloop);
419*cfb92d14SAndroid Build Coastguard Worker #if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
420*cfb92d14SAndroid Build Coastguard Worker             otAppCliProcess(&mainloop);
421*cfb92d14SAndroid Build Coastguard Worker #endif
422*cfb92d14SAndroid Build Coastguard Worker         }
423*cfb92d14SAndroid Build Coastguard Worker         else if (errno != EINTR)
424*cfb92d14SAndroid Build Coastguard Worker         {
425*cfb92d14SAndroid Build Coastguard Worker             perror("select");
426*cfb92d14SAndroid Build Coastguard Worker             ExitNow(rval = OT_EXIT_FAILURE);
427*cfb92d14SAndroid Build Coastguard Worker         }
428*cfb92d14SAndroid Build Coastguard Worker     }
429*cfb92d14SAndroid Build Coastguard Worker 
430*cfb92d14SAndroid Build Coastguard Worker #if !OPENTHREAD_POSIX_CONFIG_DAEMON_ENABLE
431*cfb92d14SAndroid Build Coastguard Worker     otAppCliDeinit();
432*cfb92d14SAndroid Build Coastguard Worker #endif
433*cfb92d14SAndroid Build Coastguard Worker 
434*cfb92d14SAndroid Build Coastguard Worker exit:
435*cfb92d14SAndroid Build Coastguard Worker     otSysDeinit();
436*cfb92d14SAndroid Build Coastguard Worker 
437*cfb92d14SAndroid Build Coastguard Worker     return rval;
438*cfb92d14SAndroid Build Coastguard Worker }
439