xref: /aosp_15_r20/external/openthread/examples/apps/cli/main.c (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <assert.h>
30 #ifdef __linux__
31 #include <signal.h>
32 #include <sys/prctl.h>
33 #endif
34 
35 #include <openthread-core-config.h>
36 #include <openthread/config.h>
37 
38 #include <openthread/cli.h>
39 #include <openthread/diag.h>
40 #include <openthread/tasklet.h>
41 #include <openthread/platform/logging.h>
42 #include <openthread/platform/misc.h>
43 
44 #include "openthread-system.h"
45 #include "cli/cli_config.h"
46 #include "common/code_utils.hpp"
47 
48 #include "lib/platform/reset_util.h"
49 
50 /**
51  * Initializes the CLI app.
52  *
53  * @param[in]  aInstance  The OpenThread instance structure.
54  *
55  */
56 extern void otAppCliInit(otInstance *aInstance);
57 
58 #if OPENTHREAD_CONFIG_HEAP_EXTERNAL_ENABLE
otPlatCAlloc(size_t aNum,size_t aSize)59 OT_TOOL_WEAK void *otPlatCAlloc(size_t aNum, size_t aSize) { return calloc(aNum, aSize); }
60 
otPlatFree(void * aPtr)61 OT_TOOL_WEAK void otPlatFree(void *aPtr) { free(aPtr); }
62 #endif
63 
otTaskletsSignalPending(otInstance * aInstance)64 void otTaskletsSignalPending(otInstance *aInstance) { OT_UNUSED_VARIABLE(aInstance); }
65 
66 #if OPENTHREAD_POSIX && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
ProcessExit(void * aContext,uint8_t aArgsLength,char * aArgs[])67 static otError ProcessExit(void *aContext, uint8_t aArgsLength, char *aArgs[])
68 {
69     OT_UNUSED_VARIABLE(aContext);
70     OT_UNUSED_VARIABLE(aArgsLength);
71     OT_UNUSED_VARIABLE(aArgs);
72 
73     exit(EXIT_SUCCESS);
74 }
75 
76 #if OPENTHREAD_EXAMPLES_SIMULATION
77 extern otError ProcessNodeIdFilter(void *aContext, uint8_t aArgsLength, char *aArgs[]);
78 #endif
79 
80 static const otCliCommand kCommands[] = {
81     {"exit", ProcessExit},
82 #if OPENTHREAD_EXAMPLES_SIMULATION
83     /*
84      * The CLI command `nodeidfilter` only works for simulation in real time.
85      *
86      * It can be used either as an allow list or a deny list. Once the filter is cleared, the first `nodeidfilter allow`
87      * or `nodeidfilter deny` will determine whether it is set up as an allow or deny list. Subsequent calls should
88      * use the same sub-command to add new node IDs, e.g., if we first call `nodeidfilter allow` (which sets the filter
89      * up  as an allow list), a subsequent `nodeidfilter deny` will result in `InvalidState` error.
90      *
91      * The usage of the command `nodeidfilter`:
92      *     - `nodeidfilter deny <nodeid>` :  It denies the connection to a specified node (use as deny-list).
93      *     - `nodeidfilter allow <nodeid> :  It allows the connection to a specified node (use as allow-list).
94      *     - `nodeidfilter clear`         :  It restores the filter state to default.
95      *     - `nodeidfilter`               :  Outputs filter mode (allow-list or deny-list) and filtered node IDs.
96      */
97     {"nodeidfilter", ProcessNodeIdFilter},
98 #endif
99 };
100 #endif // OPENTHREAD_POSIX && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
101 
main(int argc,char * argv[])102 int main(int argc, char *argv[])
103 {
104     otInstance *instance;
105 
106 #ifdef __linux__
107     // Ensure we terminate this process if the
108     // parent process dies.
109     prctl(PR_SET_PDEATHSIG, SIGHUP);
110 #endif
111 
112     OT_SETUP_RESET_JUMP(argv);
113 
114 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
115     size_t   otInstanceBufferLength = 0;
116     uint8_t *otInstanceBuffer       = NULL;
117 #endif
118 
119 pseudo_reset:
120 
121     otSysInit(argc, argv);
122 
123 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
124     // Call to query the buffer size
125     (void)otInstanceInit(NULL, &otInstanceBufferLength);
126 
127     // Call to allocate the buffer
128     otInstanceBuffer = (uint8_t *)malloc(otInstanceBufferLength);
129     assert(otInstanceBuffer);
130 
131     // Initialize OpenThread with the buffer
132     instance = otInstanceInit(otInstanceBuffer, &otInstanceBufferLength);
133 #else
134     instance = otInstanceInitSingle();
135 #endif
136     assert(instance);
137 
138     otAppCliInit(instance);
139 
140 #if OPENTHREAD_POSIX && !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
141     IgnoreError(otCliSetUserCommands(kCommands, OT_ARRAY_LENGTH(kCommands), instance));
142 #endif
143 
144 #if OPENTHREAD_CONFIG_PLATFORM_LOG_CRASH_DUMP_ENABLE
145     IgnoreError(otPlatLogCrashDump());
146 #endif
147 
148     while (!otSysPseudoResetWasRequested())
149     {
150         otTaskletsProcess(instance);
151         otSysProcessDrivers(instance);
152     }
153 
154     otInstanceFinalize(instance);
155 #if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE
156     free(otInstanceBuffer);
157 #endif
158 
159     goto pseudo_reset;
160 
161     return 0;
162 }
163 
164 #if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP
otPlatLog(otLogLevel aLogLevel,otLogRegion aLogRegion,const char * aFormat,...)165 void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...)
166 {
167     va_list ap;
168 
169     va_start(ap, aFormat);
170     otCliPlatLogv(aLogLevel, aLogRegion, aFormat, ap);
171     va_end(ap);
172 }
173 #endif
174