cli.h 17 KB

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