blob: a91fb3de25af2deb0feaec78f157066f54d435eb [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * Copyright (C) 2010 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#ifndef __PJLIB_UTIL_CLI_H__
20#define __PJLIB_UTIL_CLI_H__
21
22/**
23 * @file cli.h
24 * @brief Command Line Interface
25 */
26
27#include <pjlib-util/types.h>
28#include <pj/list.h>
29
30
31PJ_BEGIN_DECL
32
33/**
34 * @defgroup PJLIB_UTIL_CLI Command Line Interface Framework
35 * @{
36 * A CLI framework features an interface for defining command specification,
37 * parsing, and executing a command.
38 * It also features an interface to communicate with various front-ends,
39 * such as console, telnet.
40 * Application normally needs only one CLI instance to be created.
41 * On special cases, application could also create multiple CLI
42 * instances, with each instance has specific command structure.
43 *
44\verbatim
45| vid help Show this help screen |
46| vid enable|disable Enable or disable video in next offer/answer |
47| vid call add Add video stream for current call |
48| vid call cap N ID Set capture dev ID for stream #N in current call |
49| disable_codec g711|g722 Show this help screen |
50<CMD name='vid' id='0' desc="">
51 <CMD name='help' id='0' desc='' />
52 <CMD name='enable' id='0' desc='' />
53 <CMD name='disable' id='0' desc='' />
54 <CMD name='call' id='0' desc='' >
55 <CMD name='add' id='101' desc='...' />
56 <CMD name='cap' id='102' desc='...' >
57 <ARG name='streamno' type='int' desc='...' id='1'/>
58 <ARG name='devid' type='int' optional='1' id='2'/>
59 </CMD>
60 </CMD>
61</CMD>
62<CMD name='disable_codec' id=0 desc="">
63 <ARG name='codec_list' type='choice' id='3'>
64 <CHOICE value='g711'/>
65 <CHOICE value='g722'/>
66 </ARG>
67</CMD>
68\endverbatim
69 */
70
71/**
72 * This opaque structure represents a CLI application. A CLI application is
73 * the root placeholder of other CLI objects. In an application, one (and
74 * normally only one) CLI application instance needs to be created.
75 */
76typedef struct pj_cli_t pj_cli_t;
77
78/**
79 * Type of command id.
80 */
81typedef int pj_cli_cmd_id;
82
83/**
84 * This describes the parameters to be specified when creating a CLI
85 * application with pj_cli_create(). Application MUST initialize this
86 * structure by calling pj_cli_cfg_default() before using it.
87 */
88typedef struct pj_cli_cfg
89{
90 /**
91 * The application name, which will be used in places such as logs.
92 * This field is mandatory.
93 */
94 pj_str_t name;
95
96 /**
97 * Optional application title, which will be used in places such as
98 * window title. If not specified, the application name will be used
99 * as the title.
100 */
101 pj_str_t title;
102
103 /**
104 * The pool factory where all memory allocations will be taken from.
105 * This field is mandatory.
106 */
107 pj_pool_factory *pf;
108
109} pj_cli_cfg;
110
111/**
112 * Type of argument id.
113 */
114typedef int pj_cli_arg_id;
115
116/**
117 * Forward declaration of pj_cli_cmd_spec structure.
118 */
119typedef struct pj_cli_cmd_spec pj_cli_cmd_spec;
120
121/**
122 * Forward declaration for pj_cli_sess, which will be declared in cli_imp.h.
123 */
124typedef struct pj_cli_sess pj_cli_sess;
125
126/**
127 * Forward declaration for CLI front-end.
128 */
129typedef struct pj_cli_front_end pj_cli_front_end;
130
131/**
132 * Forward declaration for CLI argument spec structure.
133 */
134typedef struct pj_cli_arg_spec pj_cli_arg_spec;
135
136/**
137 * This structure contains the command to be executed by command handler.
138 */
139typedef struct pj_cli_cmd_val
140{
141 /** The session on which the command was executed on. */
142 pj_cli_sess *sess;
143
144 /** The command specification being executed. */
145 const pj_cli_cmd_spec *cmd;
146
147 /** Number of argvs. */
148 int argc;
149
150 /** Array of args, with argv[0] specifies the name of the cmd. */
151 pj_str_t argv[PJ_CLI_MAX_ARGS];
152
153} pj_cli_cmd_val;
154
155/**
156 * This structure contains the hints information for the end user.
157 * This structure could contain either command or argument information.
158 * The front-end will format the information and present it to the user.
159 */
160typedef struct pj_cli_hint_info
161{
162 /**
163 * The hint value.
164 */
165 pj_str_t name;
166
167 /**
168 * The hint type.
169 */
170 pj_str_t type;
171
172 /**
173 * Helpful description of the hint value.
174 */
175 pj_str_t desc;
176
177} pj_cli_hint_info;
178
179/**
180 * This structure contains extra information returned by pj_cli_sess_exec()/
181 * pj_cli_sess_parse().
182 * Upon return from the function, various other fields in this structure will
183 * be set by the function.
184 */
185typedef struct pj_cli_exec_info
186{
187 /**
188 * If command parsing failed, on return this will point to the location
189 * where the failure occurs, otherwise the value will be set to -1.
190 */
191 int err_pos;
192
193 /**
194 * If a command matching the command in the cmdline was found, on return
195 * this will be set to the command id of the command, otherwise it will be
196 * set to PJ_CLI_INVALID_CMD_ID.
197 */
198 pj_cli_cmd_id cmd_id;
199
200 /**
201 * If a command was executed, on return this will be set to the return
202 * value of the command, otherwise it will contain PJ_SUCCESS.
203 */
204 pj_status_t cmd_ret;
205
206 /**
207 * The number of hint elements
208 **/
209 unsigned hint_cnt;
210
211 /**
212 * If pj_cli_sess_parse() fails because of a missing argument or ambigous
213 * command/argument, the function returned PJ_CLI_EMISSINGARG or
214 * PJ_CLI_EAMBIGUOUS error.
215 * This field will contain the hint information. This is useful to give
216 * helpful information to the end_user.
217 */
218 pj_cli_hint_info hint[PJ_CLI_MAX_HINTS];
219
220} pj_cli_exec_info;
221
222/**
223 * This structure contains the information returned from the dynamic
224 * argument callback.
225 */
226typedef struct pj_cli_arg_choice_val
227{
228 /**
229 * The argument choice value
230 */
231 pj_str_t value;
232
233 /**
234 * Helpful description of the choice value. This text will be used when
235 * displaying the help texts for the choice value
236 */
237 pj_str_t desc;
238
239} pj_cli_arg_choice_val;
240
241/**
242 * This structure contains the parameters for pj_cli_get_dyn_choice
243 */
244typedef struct pj_cli_dyn_choice_param
245{
246 /**
247 * The session on which the command was executed on.
248 */
249 pj_cli_sess *sess;
250
251 /**
252 * The command being processed.
253 */
254 pj_cli_cmd_spec *cmd;
255
256 /**
257 * The argument id.
258 */
259 pj_cli_arg_id arg_id;
260
261 /**
262 * The maximum number of values that the choice can hold.
263 */
264 unsigned max_cnt;
265
266 /**
267 * The pool to allocate memory from.
268 */
269 pj_pool_t *pool;
270
271 /**
272 * The choice values count.
273 */
274 unsigned cnt;
275
276 /**
277 * Array containing the valid choice values.
278 */
279 pj_cli_arg_choice_val choice[PJ_CLI_MAX_CHOICE_VAL];
280} pj_cli_dyn_choice_param;
281
282/**
283 * This specifies the callback type for argument handlers, which will be
284 * called to get the valid values of the choice type arguments.
285 */
286typedef void (*pj_cli_get_dyn_choice) (pj_cli_dyn_choice_param *param);
287
288/**
289 * This specifies the callback type for command handlers, which will be
290 * executed when the specified command is invoked.
291 *
292 * @param cmd_val The command that is specified by the user.
293 *
294 * @return Return the status of the command execution.
295 */
296typedef pj_status_t (*pj_cli_cmd_handler)(pj_cli_cmd_val *cval);
297
298/**
299 * Write a log message to the CLI application. The CLI application
300 * will send the log message to all the registered front-ends.
301 *
302 * @param cli The CLI application instance.
303 * @param level Verbosity level of this message message.
304 * @param buffer The message itself.
305 * @param len Length of this message.
306 */
307PJ_DECL(void) pj_cli_write_log(pj_cli_t *cli,
308 int level,
309 const char *buffer,
310 int len);
311
312/**
313 * Create a new CLI application instance.
314 *
315 * @param cfg CLI application creation parameters.
316 * @param p_cli Pointer to receive the returned instance.
317 *
318 * @return PJ_SUCCESS on success, or the appropriate error code.
319 */
320PJ_DECL(pj_status_t) pj_cli_create(pj_cli_cfg *cfg,
321 pj_cli_t **p_cli);
322
323/**
324 * This specifies the function to get the id of the specified command
325 *
326 * @param cmd The specified command.
327 *
328 * @return The command id
329 */
330PJ_DECL(pj_cli_cmd_id) pj_cli_get_cmd_id(const pj_cli_cmd_spec *cmd);
331
332/**
333 * Get the internal parameter of the CLI instance.
334 *
335 * @param cli The CLI application instance.
336 *
337 * @return CLI parameter instance.
338 */
339PJ_DECL(pj_cli_cfg*) pj_cli_get_param(pj_cli_t *cli);
340
341/**
342 * Call this to signal application shutdown. Typically application would
343 * call this from it's "Quit" menu or similar command to quit the
344 * application.
345 *
346 * See also pj_cli_sess_end_session() to end a session instead of quitting the
347 * whole application.
348 *
349 * @param cli The CLI application instance.
350 * @param req The session on which the shutdown request is
351 * received.
352 * @param restart Indicate whether application restart is wanted.
353 */
354PJ_DECL(void) pj_cli_quit(pj_cli_t *cli, pj_cli_sess *req,
355 pj_bool_t restart);
356/**
357 * Check if application shutdown or restart has been requested.
358 *
359 * @param cli The CLI application instance.
360 *
361 * @return PJ_TRUE if pj_cli_quit() has been called.
362 */
363PJ_DECL(pj_bool_t) pj_cli_is_quitting(pj_cli_t *cli);
364
365/**
366 * Check if application restart has been requested.
367 *
368 * @param cli The CLI application instance.
369 *
370 * @return PJ_TRUE if pj_cli_quit() has been called with
371 * restart parameter set.
372 */
373PJ_DECL(pj_bool_t) pj_cli_is_restarting(pj_cli_t *cli);
374
375/**
376 * Destroy a CLI application instance. This would also close all sessions
377 * currently running for this CLI application.
378 *
379 * @param cli The CLI application.
380 */
381PJ_DECL(void) pj_cli_destroy(pj_cli_t *cli);
382
383/**
384 * Initialize a pj_cli_cfg with its default values.
385 *
386 * @param param The instance to be initialized.
387 */
388PJ_DECL(void) pj_cli_cfg_default(pj_cli_cfg *param);
389
390/**
391 * Register a front end to the CLI application.
392 *
393 * @param CLI The CLI application.
394 * @param fe The CLI front end to be registered.
395 */
396PJ_DECL(void) pj_cli_register_front_end(pj_cli_t *cli,
397 pj_cli_front_end *fe);
398
399/**
400 * Create a new complete command specification from an XML node text and
401 * register it to the CLI application.
402 *
403 * @param cli The CLI application.
404 * @param group Optional group to which this command will be added
405 * to, or specify NULL if this command is a root
406 * command.
407 * @param xml Input string containing XML node text for the
408 * command.
409 * @param handler Function handler for the command. This must be NULL
410 * if the command specifies a command group.
411 * @param p_cmd Optional pointer to store the newly created
412 * specification.
413 * @param get_choice Function handler for the argument. Specify this for
414 * dynamic choice type arguments.
415 *
416 * @return PJ_SUCCESS on success, or the appropriate error code.
417 */
418PJ_DECL(pj_status_t) pj_cli_add_cmd_from_xml(pj_cli_t *cli,
419 pj_cli_cmd_spec *group,
420 const pj_str_t *xml,
421 pj_cli_cmd_handler handler,
422 pj_cli_cmd_spec **p_cmd,
423 pj_cli_get_dyn_choice get_choice);
424/**
425 * Initialize pj_cli_exec_info with its default values.
426 *
427 * @param param The param to be initialized.
428 */
429PJ_DECL(void) pj_cli_exec_info_default(pj_cli_exec_info *param);
430
431/**
432 * Write a log message to the specific CLI session.
433 *
434 * @param sess The CLI active session.
435 * @param buffer The message itself.
436 * @param len Length of this message.
437 */
438PJ_DECL(void) pj_cli_sess_write_msg(pj_cli_sess *sess,
439 const char *buffer,
440 pj_size_t len);
441
442/**
443 * Parse an input cmdline string. The first word of the command line is the
444 * command itself, which will be matched against command specifications
445 * registered in the CLI application.
446 *
447 * Zero or more arguments follow the command name. Arguments are separated by
448 * one or more whitespaces. Argument may be placed inside a pair of quotes,
449 * double quotes, '{' and '}', or '[' and ']' pairs. This is useful when the
450 * argument itself contains whitespaces or other restricted characters. If
451 * the quote character itself is to appear in the argument, the argument then
452 * must be quoted with different quote characters. There is no character
453 * escaping facility provided by this function (such as the use of backslash
454 * '\' character).
455 *
456 * The cmdline may be followed by an extra newline (LF or CR-LF characters),
457 * which will be removed by the function. However any more characters
458 * following this newline will cause an error to be returned.
459 *
460 * @param sess The CLI session.
461 * @param cmdline The command line string to be parsed.
462 * @param val Structure to store the parsing result.
463 * @param pool The pool to allocate memory from.
464 * @param info Additional info to be returned regarding the parsing.
465 *
466 * @return This function returns the status of the parsing,
467 * which can be one of the following :
468 * - PJ_SUCCESS: a command was executed successfully.
469 * - PJ_EINVAL: invalid parameter to this function.
470 * - PJ_ENOTFOUND: command is not found.
471 * - PJ_CLI_EAMBIGUOUS: command/argument is ambiguous.
472 * - PJ_CLI_EMISSINGARG: missing argument.
473 * - PJ_CLI_EINVARG: invalid command argument.
474 * - PJ_CLI_EEXIT: "exit" has been called to end
475 * the current session. This is a signal for the
476 * application to end it's main loop.
477 */
478PJ_DECL(pj_status_t) pj_cli_sess_parse(pj_cli_sess *sess,
479 char *cmdline,
480 pj_cli_cmd_val *val,
481 pj_pool_t *pool,
482 pj_cli_exec_info *info);
483
484/**
485 * End the specified session, and destroy it to release all resources used
486 * by the session.
487 *
488 * See also pj_cli_sess and pj_cli_front_end for more info regarding the
489 * creation process.
490 * See also pj_cli_quit() to quit the whole application instead.
491 *
492 * @param sess The CLI session to be destroyed.
493 */
494PJ_DECL(void) pj_cli_sess_end_session(pj_cli_sess *sess);
495
496/**
497 * Execute a command line. This function will parse the input string to find
498 * the appropriate command and verify whether the string matches the command
499 * specifications. If matches, the command will be executed, and the return
500 * value of the command will be set in the \a cmd_ret field of the \a info
501 * argument, if specified.
502 *
503 * See also pj_cli_sess_parse() for more info regarding the cmdline format.
504 *
505 * @param sess The CLI session.
506 * @param cmdline The command line string to be executed.
507 * @param pool The pool to allocate memory from.
508 * @param info Optional pointer to receive additional information
509 * related to the execution of the command (such as
510 * the command return value).
511 *
512 * @return This function returns the status of the command
513 * parsing and execution (note that the return value
514 * of the handler itself will be returned in \a info
515 * argument, if specified). Please see the return value
516 * of pj_cli_sess_parse() for possible return values.
517 */
518PJ_DECL(pj_status_t) pj_cli_sess_exec(pj_cli_sess *sess,
519 char *cmdline,
520 pj_pool_t *pool,
521 pj_cli_exec_info *info);
522
523/**
524 * @}
525 */
526
527PJ_END_DECL
528
529#endif /* __PJLIB_UTIL_CLI_H__ */