External Commands
External commands can be supported by yangcli-pro and yp-shell.
This support is limited to the functionality available to existing yangcli-pro commands:
Access local data structures
Access local files
Generate log output
Send 1 or 2 commands to the server
Override or add to the existing reply output processing
YANG for Command Definitions
The YANG module definition is used for several tasks:
process command line input, including command name and input parameters
control tab key completion
provide help text for commands and input parameters
The YANG syntax is restricted for CLI command purposes:
must statement validation is not done
unique statement validation is not done
Example Command Definition:
rpc example-cmd {
description "Example external command";
input {
leaf parm1 {
type string;
description "The first example parameter";
}
leaf parm2 {
type int32;
description "The second example parameter";
}
}
}
yp-show API Functions
There are a limited number of API functions available to add an external command.
A yangcli-pro or yp-shell command requires at least 3 components:
YANG module “RPC statement” defining the command syntax
Callback function to do the command when requested by user input
Call to the registration function to add the command into the program
External Command Callback Function
The callback function for the external command must use the “yangcli_command_cbfn_t” definition in yangcli.h:
/* Callback template for a local command
*
* Handles the command line for the specified command
*
* INPUTS:
* server_cb == server control block to use
* session_cb == session control block to use
* rpc == object template for the command
* line == input command line to execute
* len == offset into the line to start processing
* this can be > 0 if the command is the left-hand-side
* of an assignment statement
* RETURNS:
* status
*/
typedef status_t
(*yangcli_command_cbfn_t) (server_cb_t *server_cb,
session_cb_t *session_cb,
obj_template_t *rpc,
const xmlChar *line,
uint32 len);
The following example callback can be found in example-fan.cpp
/********************************************************************
* FUNCTION do_example_cmd (local RPC)
*
* Do Example Command
*
* INPUTS:
* server_cb == server control block to use
* session_cb == session control block to use
* rpc == RPC method for the example-cmd command
* line == CLI input in progress
* len == offset into line buffer to start parsing
*
* RETURNS:
* status
*********************************************************************/
static status_t
do_example_cmd (server_cb_t *server_cb,
session_cb_t *session_cb,
obj_template_t *rpc,
const xmlChar *line,
uint32 len)
{
(void)rpc;
status_t res = NO_ERR;
val_value_t *valset =
get_valset(server_cb, session_cb, rpc, &line[len], &res);
if (valset && (res == NO_ERR)) {
val_value_t *parm1 =
val_find_child(valset, MODNAME, (const xmlChar *)"parm1");
if (parm1) {
log_debug("\nGot parm1=%s", VAL_STR(parm1));
}
val_value_t *parm2 =
val_find_child(valset, MODNAME, (const xmlChar *)"parm2");
if (parm2) {
log_debug("\nGot parm2=%d", VAL_INT32(parm2));
}
/* do something with the parameters */
}
val_free_value(valset);
return res;
} /* do_example_cmd */
Key steps:
the input line is parsed. This should be done even if no input parameters to make sure no extra parameters are present.
a val_value_t tree is produced representing a container of all the input parameters that were parsed
the parameters are checked with “val_find_child”
the callback does the work required for the command
the val_value_t for the input parameters is freed
Register an External Command
The “register_command” function is called from the yp_show_init function to register an external command:
/********************************************************************
* FUNCTION register_command
*
* INPUTS:
* server_cb == server control block to use
* module == module name containing the RPC method
* ycli_command_name == RPC method name
* command_fn == pointer to callback function for this command
* is_top_cmd == TRUE if opt-level command
* yangcli_ok == TRUE if OK for yangcli to use it
* ypshell_ok == TRUE if OK for yp-shell to use it
* ypserver_ok == TRUE if OK for yp-server to use it
*
* RETURNS:
* status of the operation
*********************************************************************/
extern status_t
register_command (
server_cb_t *server_cb,
const xmlChar *module,
const xmlChar *ycli_command_name,
yangcli_command_cbfn_t command_fn,
boolean is_top_cmd,
boolean yangcli_ok,
boolean ypshell_ok,
boolean ypserver_ok);
Usage Example: (from example-fan.cpp)
server_cb_t *server_cb = get_default_server_cb();
if (server_cb == NULL){
res = ERR_NCX_NOT_FOUND;
} else {
res = register_command(server_cb,
MODNAME,
(const xmlChar *)"example-cmd",
do_example_cmd,
TRUE, // is_top_cmd
TRUE, // yangcli_ok
TRUE, // ypshell_ok
FALSE); // ypserver_ok (not used)
}
Usage Notes:
The YANG module identified by “module” must already be loaded
The command name cannot be a duplicate of any command in yangcli-pro.yang
The command name cannot be a duplicate of any other external command
The “is_top_cmd” field must be set to TRUE
The “ypserver_ok field is ignored but should be set to FALSE