GPS Device
Loading...
Searching...
No Matches
Command Public API

Public functions to interact with the command subsystem. More...

Collaboration diagram for Command Public API:

Functions

ERR_te cmd_register (CMD_CLIENT_INFO_ts *cmd_client_info)
 Registers a client with the command subsystem.
ERR_te cmd_deregister (CMD_CLIENT_INFO_ts const *cmd_client_info)
 Deregisters a client from the command subsystem.
ERR_te cmd_execute (char *console_text)
 Parses and executes a command from a console text string.

Detailed Description

Public functions to interact with the command subsystem.

Function Documentation

◆ cmd_register()

ERR_te cmd_register ( CMD_CLIENT_INFO_ts * cmd_client_info)

Registers a client with the command subsystem.

Adds the client's CMD_CLIENT_INFO_ts to the internal client table, making its commands available for dispatch via cmd_execute.

The pointer cmd_client_info must remain valid until the client calls cmd_deregister.

Parameters
[in]cmd_client_infoPointer to the client descriptor to register.
Returns
  • ERR_OK on success
  • ERR_NOT_ENOUGH_SPACE if the maximum number of clients is already registered
See also
cmd_register

Definition at line 51 of file cmd.c.

51 {
52 for(uint8_t i = 0; i < CONFIG_CMD_MAX_CLIENTS; i++) {
53 if(internal_state.cmd_client_info_arr[i] == (void*)0) {
54 internal_state.cmd_client_info_arr[i] = cmd_client_info;
55 break;
56 }
57 else if(i == CONFIG_CMD_MAX_CLIENTS - 1) {
59 }
60 }
61
62 return ERR_OK;
63}
static struct internal_state_s internal_state
Singleton instance of the SysTick driver internal state.
@ ERR_OK
Definition err.h:36
@ ERR_NOT_ENOUGH_SPACE
Definition err.h:49
Here is the caller graph for this function:

◆ cmd_deregister()

ERR_te cmd_deregister ( CMD_CLIENT_INFO_ts const * cmd_client_info)

Deregisters a client from the command subsystem.

Removes the client identified by cmd_client_info from the internal client table, making its commands unavailable for future dispatch.

Parameters
[in]cmd_client_infoPointer to the client descriptor to deregister.
Returns
  • ERR_OK on success
  • ERR_DEINITIALIZATION_FAILURE if the client was not found in the table
See also
cmd_deregister

Definition at line 66 of file cmd.c.

66 {
67 for(uint8_t i = 0; i < CONFIG_CMD_MAX_CLIENTS; i++) {
68 if(internal_state.cmd_client_info_arr[i] == cmd_client_info) {
69 internal_state.cmd_client_info_arr[i] = (void*)0;
70 break;
71 }
72 else if(i == CONFIG_CMD_MAX_CLIENTS - 1) {
74 }
75 }
76
77 return ERR_OK;
78}
@ ERR_DEINITIALIZATION_FAILURE
Definition err.h:44
Here is the caller graph for this function:

◆ cmd_execute()

ERR_te cmd_execute ( char * console_text)

Parses and executes a command from a console text string.

Tokenizes console_text by spaces and dispatches to the appropriate handler based on the following built-in command hierarchy:

  • version — prints the firmware version
  • help [<client>] — lists all commands or those of a specific client
  • * log [<level>] — gets or sets the log level of all registered clients
  • <client> log [<level>] — gets or sets the log level of a specific client
  • <client> <command> [args...] — dispatches to the matching client handler
Parameters
[in]console_textNull-terminated string containing the command to execute. The string is modified in place during tokenization.
Returns
  • ERR_OK on success
  • ERR_INVALID_ARGUMENT if the input is empty, malformed, or no matching command is found
  • Other error codes propagated from the invoked command handler
See also
cmd_execute

Definition at line 81 of file cmd.c.

81 {
82 ERR_te err;
83
84 uint16_t num_tokens = 0;
85 char *tokens[CONFIG_CMD_MAX_TOKENS];
86 CMD_CLIENT_INFO_ts *client_info;
87
88 str_tokenize(console_text, " ", CONFIG_CMD_MAX_TOKENS, tokens, &num_tokens);
89
90 if(num_tokens == 0) {
92 internal_state.subsys,
93 internal_state.log_level,
94 "cmd_execute: invalid arguments"
95 );
96
98 }
99
100 // 1. Handle wildcard commands
101 if(str_cmp("*", tokens[0]) == true) {
102 if(num_tokens < 2) {
103 // No wildcard command given after wildcard character
104 LOG_ERROR(
105 internal_state.subsys,
106 internal_state.log_level,
107 "cmd_execute: invalid arguments"
108 );
109
111 }
112 // Handle wildcard log
113 if(str_cmp("log", tokens[1]) == true) {
114 if(num_tokens == 2) {
115 for(uint8_t i = 0; i < CONFIG_CMD_MAX_CLIENTS; i++) {
116 client_info = internal_state.cmd_client_info_arr[i];
117
118 if(client_info == (void*)0) {
119 continue;
120 }
121
122 LOG_LEVEL_te log_level = *client_info->log_level_ptr;
123
124 char *log_level_name[16];
125
126 err = log_get_level_name(log_level, (char*)log_level_name);
127 if(err != ERR_OK) {
128 return err;
129 }
130
131 LOG_INFO(
132 internal_state.subsys,
133 internal_state.log_level,
134 "%s log level: %s",
135 client_info->name,
136 log_level_name
137 );
138 }
139 }
140 else if(num_tokens == 3) {
141 const char *log_level_str = tokens[2];
142
143 LOG_LEVEL_te log_level = 0;
144 err = log_level_to_int((char*)log_level_str, &log_level);
145 if(err != ERR_OK) {
146 return err;
147 }
148
149 for(uint8_t i = 0; i < CONFIG_CMD_MAX_CLIENTS; i++) {
150 client_info = internal_state.cmd_client_info_arr[i];
151
152 if(client_info == (void*)0) {
153 continue;
154 }
155
156 *client_info->log_level_ptr = log_level;
157 }
158 }
159 else {
160 LOG_ERROR(
161 internal_state.subsys,
162 internal_state.log_level,
163 "cmd_execute: invalid arguments"
164 );
165
167 }
168
169 return ERR_OK;
170 }
171 }
172
173 // 2. Handle version command
174 if(str_cmp("version", tokens[0]) == true) {
175 if(num_tokens > 1) {
176 LOG_ERROR(
177 internal_state.subsys,
178 internal_state.log_level,
179 "cmd_execute: invalid arguments"
180 );
182 }
183 LOG_INFO(
184 internal_state.subsys,
185 internal_state.log_level,
186 "Version=%s", CONFIG_VERSION
187 );
188
189 return ERR_OK;
190 }
191
192 // 3. Handle help command
193 if(str_cmp("help", tokens[0]) == true) {
194 if(num_tokens == 1) {
195 LOG_INFO(
196 internal_state.subsys,
197 internal_state.log_level,
198 "Listing general commands:"
199 );
200 LOG_INFO(
201 internal_state.subsys,
202 internal_state.log_level,
203 "1. version: Prints firmware version, usage: version"
204 );
205 LOG_INFO(
206 internal_state.subsys,
207 internal_state.log_level,
208 "2. help: Shows help information for modules, usage: help <module>"
209 );
210 LOG_INFO(
211 internal_state.subsys,
212 internal_state.log_level,
213 "3. log: Shows or sets the log level of modules, usage: log <module|*> <level>"
214 );
215
216 for(uint8_t i = 0; i < CONFIG_CMD_MAX_CLIENTS; i++) {
217 if(internal_state.cmd_client_info_arr[i] == (void*)0) {
218 continue;
219 }
220
221 client_info = internal_state.cmd_client_info_arr[i];
222
223 LOG_INFO(
224 internal_state.subsys,
225 internal_state.log_level,
226 "Listing %s commands:",
227 client_info->name
228 );
229
230 for(uint8_t j = 0; j < client_info->num_cmds; j++) {
231 LOG_INFO(
232 internal_state.subsys,
233 internal_state.log_level,
234 "%d. %s: %s", j + 1,
235 client_info->cmds_ptr[j].name,
236 client_info->cmds_ptr[j].help
237 );
238 }
239 }
240 return ERR_OK;
241 }
242 else if(num_tokens == 2) {
243 for(uint8_t i = 0; i < CONFIG_CMD_MAX_CLIENTS; i++) {
244 if(internal_state.cmd_client_info_arr[i] == (void*)0) {
245 continue;
246 }
247
248 client_info = internal_state.cmd_client_info_arr[i];
249
250 if(str_cmp(client_info->name, tokens[1]) == true) {
251 LOG_INFO(
252 internal_state.subsys,
253 internal_state.log_level,
254 "Listing %s commands:",
255 client_info->name
256 );
257
258 for(uint8_t j = 0; j < client_info->num_cmds; j++) {
259 LOG_INFO(
260 internal_state.subsys,
261 internal_state.log_level,
262 "%d. %s: %s", j + 1,
263 client_info->cmds_ptr[j].name,
264 client_info->cmds_ptr[j].help
265 );
266 }
267
268 return ERR_OK;
269 }
270 }
271 }
272 LOG_ERROR(
273 internal_state.subsys,
274 internal_state.log_level,
275 "cmd_execute: invalid arguments"
276 );
278 }
279
280 // 4. Handle client commands
281 for(uint8_t i = 0; i < CONFIG_CMD_MAX_CLIENTS; i++) {
282 if(internal_state.cmd_client_info_arr[i] == (void*)0) {
283 continue;
284 }
285
286 client_info = internal_state.cmd_client_info_arr[i];
287
288 if(str_cmp(tokens[0], client_info->name) == true) {
289 if(str_cmp(tokens[1], "log") == true) {
290 if(num_tokens == 2) {
291 LOG_LEVEL_te log_level = *client_info->log_level_ptr;
292
293 char *log_level_name[16];
294 err = log_get_level_name(log_level, (char*)log_level_name);
295 if(err != ERR_OK) {
296 return err;
297 }
298
299 LOG_INFO(
300 internal_state.subsys,
301 internal_state.log_level,
302 "%s log level: %s",
303 client_info->name,
304 log_level_name
305 );
306
307 return ERR_OK;
308 }
309 else if(num_tokens == 3) {
310 const char *log_level_str = tokens[2];
311 LOG_LEVEL_te log_level = 0;
312
313 err = log_level_to_int((char*)log_level_str, &log_level);
314 if(err != ERR_OK) {
315 return err;
316 }
317
318 *client_info->log_level_ptr = log_level;
319
320 return ERR_OK;
321 }
322 else if(num_tokens > 3) {
323 LOG_ERROR(
324 internal_state.subsys,
325 internal_state.log_level,
326 "cmd_execute: invalid arguments"
327 );
328
330 }
331 }
332 for(uint8_t j = 0; j < client_info->num_cmds; j++) {
333 if(str_cmp(tokens[1], client_info->cmds_ptr[j].name) == true) {
334 client_info->cmds_ptr[j].handler(num_tokens, tokens);
335 return ERR_OK;
336 }
337
338 if(j == client_info->num_cmds - 1) {
339 LOG_ERROR(
340 internal_state.subsys,
341 internal_state.log_level,
342 "cmd_execute: invalid arguments"
343 );
344
346 }
347 }
348 }
349 }
350 LOG_ERROR(
351 internal_state.subsys,
352 internal_state.log_level,
353 "cmd_execute: invalid arguments"
354 );
355
357}
bool str_cmp(const char *str1, const char *str2)
Compares two null-terminated strings for equality.
Definition common.c:248
int str_tokenize(char *str, const char *separator, uint16_t max_tokens, char **tokens, uint16_t *num_tokens)
Splits a string into tokens separated by a given delimiter.
Definition common.c:287
ERR_te
Standard return type used by all public API functions.
Definition err.h:35
@ ERR_INVALID_ARGUMENT
Definition err.h:38
ERR_te log_get_level_name(LOG_LEVEL_te log_level, char *str)
Converts a LOG_LEVEL_te value to its lowercase string name.
Definition log.c:153
ERR_te log_level_to_int(char const *str, LOG_LEVEL_te *log_level_o)
Converts a log level name string to its LOG_LEVEL_te value.
Definition log.c:192
#define LOG_ERROR(subsys, lvl, fmt,...)
Definition log.h:258
#define LOG_INFO(subsys, lvl, fmt,...)
Definition log.h:255
LOG_LEVEL_te
Log severity levels, in ascending order of severity.
Definition log.h:63
Describes a subsystem client registering with the command module.
Definition cmd.h:92
const uint8_t num_cmds
Definition cmd.h:97
const char *const name
Definition cmd.h:94
const CMD_INFO_ts *const cmds_ptr
Definition cmd.h:100
LOG_LEVEL_te *const log_level_ptr
Definition cmd.h:107
const CMD_HANDLER_tf handler
Definition cmd.h:80
const char *const help
Definition cmd.h:77
const char *const name
Definition cmd.h:74
Here is the call graph for this function:
Here is the caller graph for this function: