1 /*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <stdio.h>
9 #include <zephyr/net/openthread.h>
10 #include <zephyr/sys/printk.h>
11 #include <zephyr/shell/shell.h>
12 #include <zephyr/shell/shell_uart.h>
13
14 #include <openthread/cli.h>
15 #include <openthread/instance.h>
16
17 #include "platform-zephyr.h"
18
19 #define OT_SHELL_BUFFER_SIZE CONFIG_SHELL_CMD_BUFF_SIZE
20
21 static char rx_buffer[OT_SHELL_BUFFER_SIZE];
22
23 static const struct shell *shell_p;
24 static bool is_shell_initialized;
25
ot_console_cb(void * context,const char * format,va_list arg)26 static int ot_console_cb(void *context, const char *format, va_list arg)
27 {
28 ARG_UNUSED(context);
29
30 if (shell_p == NULL) {
31 return 0;
32 }
33
34 shell_vfprintf(shell_p, SHELL_NORMAL, format, arg);
35
36 return 0;
37 }
38
39 #define SHELL_HELP_OT "OpenThread subcommands\n" \
40 "Use \"ot help\" to get the list of subcommands"
41
ot_cmd(const struct shell * sh,size_t argc,char * argv[])42 static int ot_cmd(const struct shell *sh, size_t argc, char *argv[])
43 {
44 char *buf_ptr = rx_buffer;
45 size_t buf_len = OT_SHELL_BUFFER_SIZE;
46 size_t arg_len = 0;
47 int i;
48
49 if (!is_shell_initialized) {
50 return -ENOEXEC;
51 }
52
53 for (i = 1; i < argc; i++) {
54 if (arg_len) {
55 buf_len -= arg_len + 1;
56 if (buf_len) {
57 buf_ptr[arg_len] = ' ';
58 }
59 buf_ptr += arg_len + 1;
60 }
61
62 arg_len = snprintk(buf_ptr, buf_len, "%s", argv[i]);
63
64 if (arg_len >= buf_len) {
65 shell_fprintf(sh, SHELL_WARNING,
66 "OT shell buffer full\n");
67 return -ENOEXEC;
68 }
69 }
70
71 if (i == argc) {
72 buf_len -= arg_len;
73 }
74
75 shell_p = sh;
76
77 openthread_api_mutex_lock(openthread_get_default_context());
78 otCliInputLine(rx_buffer);
79 openthread_api_mutex_unlock(openthread_get_default_context());
80
81 return 0;
82 }
83
84 SHELL_CMD_ARG_REGISTER(ot, NULL, SHELL_HELP_OT, ot_cmd, 2, 255);
85
platformShellInit(otInstance * aInstance)86 void platformShellInit(otInstance *aInstance)
87 {
88 if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL)) {
89 shell_p = shell_backend_uart_get_ptr();
90 } else {
91 shell_p = NULL;
92 }
93
94 otCliInit(aInstance, ot_console_cb, NULL);
95 is_shell_initialized = true;
96 }
97