1 /*
2  * Shell backend used for testing
3  *
4  * Copyright (c) 2018 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/shell/shell_dummy.h>
10 #include <zephyr/init.h>
11 
12 SHELL_DUMMY_DEFINE(shell_transport_dummy);
13 SHELL_DEFINE(shell_dummy, CONFIG_SHELL_PROMPT_DUMMY, &shell_transport_dummy, 256,
14 	     0, SHELL_FLAG_OLF_CRLF);
15 
init(const struct shell_transport * transport,const void * config,shell_transport_handler_t evt_handler,void * context)16 static int init(const struct shell_transport *transport,
17 		const void *config,
18 		shell_transport_handler_t evt_handler,
19 		void *context)
20 {
21 	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;
22 
23 	if (sh_dummy->initialized) {
24 		return -EINVAL;
25 	}
26 
27 	sh_dummy->initialized = true;
28 
29 	return 0;
30 }
31 
uninit(const struct shell_transport * transport)32 static int uninit(const struct shell_transport *transport)
33 {
34 	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;
35 
36 	if (!sh_dummy->initialized) {
37 		return -ENODEV;
38 	}
39 
40 	sh_dummy->initialized = false;
41 
42 	return 0;
43 }
44 
enable(const struct shell_transport * transport,bool blocking)45 static int enable(const struct shell_transport *transport, bool blocking)
46 {
47 	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;
48 
49 	if (!sh_dummy->initialized) {
50 		return -ENODEV;
51 	}
52 
53 	return 0;
54 }
55 
write(const struct shell_transport * transport,const void * data,size_t length,size_t * cnt)56 static int write(const struct shell_transport *transport,
57 		 const void *data, size_t length, size_t *cnt)
58 {
59 	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;
60 	size_t store_cnt;
61 
62 	if (!sh_dummy->initialized) {
63 		*cnt = 0;
64 		return -ENODEV;
65 	}
66 
67 	store_cnt = length;
68 	if (sh_dummy->len + store_cnt >= sizeof(sh_dummy->buf)) {
69 		store_cnt = sizeof(sh_dummy->buf) - sh_dummy->len - 1;
70 	}
71 	memcpy(sh_dummy->buf + sh_dummy->len, data, store_cnt);
72 	sh_dummy->len += store_cnt;
73 
74 	*cnt = length;
75 
76 	return 0;
77 }
78 
read(const struct shell_transport * transport,void * data,size_t length,size_t * cnt)79 static int read(const struct shell_transport *transport,
80 		void *data, size_t length, size_t *cnt)
81 {
82 	struct shell_dummy *sh_dummy = (struct shell_dummy *)transport->ctx;
83 
84 	if (!sh_dummy->initialized) {
85 		return -ENODEV;
86 	}
87 
88 	*cnt = 0;
89 
90 	return 0;
91 }
92 
93 const struct shell_transport_api shell_dummy_transport_api = {
94 	.init = init,
95 	.uninit = uninit,
96 	.enable = enable,
97 	.write = write,
98 	.read = read
99 };
100 
enable_shell_dummy(void)101 static int enable_shell_dummy(void)
102 {
103 	bool log_backend = CONFIG_SHELL_DUMMY_INIT_LOG_LEVEL > 0;
104 	uint32_t level = (CONFIG_SHELL_DUMMY_INIT_LOG_LEVEL > LOG_LEVEL_DBG) ?
105 		      CONFIG_LOG_MAX_LEVEL : CONFIG_SHELL_DUMMY_INIT_LOG_LEVEL;
106 	static const struct shell_backend_config_flags cfg_flags =
107 					SHELL_DEFAULT_BACKEND_CONFIG_FLAGS;
108 
109 	shell_init(&shell_dummy, NULL, cfg_flags, log_backend, level);
110 
111 	return 0;
112 }
113 SYS_INIT(enable_shell_dummy, POST_KERNEL, 0);
114 
shell_backend_dummy_get_ptr(void)115 const struct shell *shell_backend_dummy_get_ptr(void)
116 {
117 	return &shell_dummy;
118 }
119 
shell_backend_dummy_get_output(const struct shell * sh,size_t * sizep)120 const char *shell_backend_dummy_get_output(const struct shell *sh,
121 					   size_t *sizep)
122 {
123 	struct shell_dummy *sh_dummy = (struct shell_dummy *)sh->iface->ctx;
124 
125 	sh_dummy->buf[sh_dummy->len] = '\0';
126 	*sizep = sh_dummy->len;
127 	sh_dummy->len = 0;
128 
129 	return sh_dummy->buf;
130 }
131 
shell_backend_dummy_clear_output(const struct shell * sh)132 void shell_backend_dummy_clear_output(const struct shell *sh)
133 {
134 	struct shell_dummy *sh_dummy = (struct shell_dummy *)sh->iface->ctx;
135 
136 	sh_dummy->buf[0] = '\0';
137 	sh_dummy->len = 0;
138 }
139