Trident IoT Zigbee SDK
 
Loading...
Searching...
No Matches
Zigbee Command Line Interface

Back to Trident IoT SDK

Overview


The Trident Zigbee Command Line Interface (CLI) provides a way to interact with a device through a hierarchical, table driven, extensible interface. Many CLI commands are pre-defined for the Zigbee stack and for the services and ZCL plugins. Custom, user defined tables can easily be created to add project specific CLI functionality.

The most common physical interface for the CLI is through a UART, but there are other ways of capturing character strings and passing them to the CLI for parsing. One of these is the Trident Zigbee Remote CLI manufacturer specific cluster. This allows remote interaction with the CLI on a specific device through the Zigbee network rather than with a physical UART connection.

Note
The CLI supports up and down arrow command history scrolling and left and right arrow command editing

How It Works


Command Strings

The CLI is based on standard argc and argv parsing as well as optarg. argc is an integer that contains the count of the space delimited arguments passed to the CLI parser, and argv is an array of char strings, with each element being an argument. For example, the string "this is a test" will result in argc == 4, and argv being

Arg Parsing
argv[0] "this"
argv[1] "is"
argv[2] "a"
argv[3] "test"

optarg allows parsing of command arguments. The CLI uses the short form of options to keep command strings as short as possible. A command with an option will look like "send -a 0x1234". In this case, the command is "send", "-a" is an option, and 0x1234 is the argument for the "-a" option. Not all commands require options, and many commands have optional options. Also, not all command options require arguments.

Existing commands will provide a "usage" help string if they are missing required options or if the -h option is provided. Here is the usage string for the "send" command:

test> send -h
usage: send -a short addr [-d dest ep <default 1>] [-s src ep <default 1>] [-e aps encrypt <default don't aps encrypt>] [-n no aps ack <default aps ack>]

Usage string syntax puts optional options inside [] and default values of option arguments inside <>.

Command Tables

The CLI uses tables to define command strings, the function to invoke on a command string match, and a description string to display when there are no matches. Here is part of the general_commands table, which is the root table of the CLI:

TR_CLI_COMMAND_TABLE(general_commands) =
{
{ "info", cli_cmd_info, "Print device information" },
{ "reset", cli_cmd_reset, "Reset the device" },
{ "version", cli_cmd_version, "Display the stack version" },
.
.
.
TR_CLI_COMMAND_TABLE_END
};

Each table entry constitutes a CLI command. In the example above, "info" is the string that the CLI will try and match, cli_cmd_info is the function to invoke when a match is made, and "Print device information" is the description to show for that command.

Command Matching

The CLI is implemented with "exact or least character match" on command strings. This requires fewer characters in the command string input than exact match only, and has advantages when using a non-UART interface.

  • Exact match will succeed only when all characters and the string length of the command string match a command string in the table.
  • Least character match will succeed when the characters in the command string match the first n characters in the table and there is only 1 match in the table. An example of "exact or least character match" is shown below.
TR_CLI_COMMAND_TABLE(example_commands) =
{
{ "reset", cli_cmd_reset, "Reset the device" },
{ "reset_test", cli_cmd_reset_test, "Test the reset function" },
{ "reset_uart", cli_cmd_reset_uart, "Reset the UART" },
TR_CLI_COMMAND_TABLE_END
};
Command String Entered Command Matched Function Called
"reset" "reset" cli_cmd_reset
"reset_u" "reset_uart" cli_cmd_reset_uart
"reset_" no match commands and descriptions will be printed

Table Hierarchy

The CLI command table structure supports hierarchy or nested commands, resulting in command strings that simply point to a sub-table for further matching. Below is an example of nested commands.

TR_CLI_COMMAND_TABLE(example_commands) =
{
{ "info", cli_cmd_info, "Print device information" },
{ "version", cli_cmd_version, "Display the stack version" },
{ "reset", TR_CLI_SUB_COMMANDS, TR_CLI_SUB_COMMAND_TABLE(reset_commands) },
TR_CLI_COMMAND_TABLE_END
};

In the above table, the command string "reset" will pass the next argument in the command string to the reset_commands table for matching. If the reset_commands table looks like this:

TR_CLI_COMMAND_TABLE(reset_commands) =
{
{ "device", cli_cmd_reset, "Reset the device" },
{ "test", cli_cmd_reset_test, "Test the reset function" },
{ "uart", cli_cmd_reset_uart, "Reset the UART" },
TR_CLI_COMMAND_TABLE_END
};

then entering a command string of "reset" or just "res" will print the commands and their descriptions like this:

test> reset
device Reset the device
test Test the reset function
uart Reset the UART

With the sub-table, the command string matching will look like this:

Command String Entered Command Matched Function Called
"reset dev" "device" cli_cmd_reset
"reset test" "test" cli_cmd_reset_test
"reset u" "uart" cli_cmd_reset_uart

CLI Configuration


Configuring The UART

The UART configuration is done in the project tr_hal_config.h file. This is uniqe per project build target. In this file you must set the UART to be used as well as the pins for UART TX and RX. For the DKNCM11 development board, the follwing UART pin configuration should be used:

#define UART_DBG_PORT_ID 0
#define GPIO_UART_DBG_RX 16
#define GPIO_UART_DBG_TX 17

By default, the CLI UART (aka debug port) is configured as:

UART Port Settings
Baud Rate 115,200
Parity none
Data Bits 8
Stop Bits 1

Setting The Prompt

The CLI prompt can be configured in the tr_plugin_config.h file which is unique per project. Refer to the Command Line Interface (CLI) services plugin for the settings.

CLI User Extension


Refer to the Door Lock SZED sample app project for an example of a user extension of the CLI. The custom command table implementation is in src/lock_cli.c.

Configuration

Custom user command tables are enabled by defining the following macros in the project tr_plugin_config.h file.

Macro Name Value Matched Function
#define CUSTOM_CLI_COMMANDS_ENABLE
Enable the custom command table
#define CUSTOM_CLI_TOPLEVEL
"cmd_string" Define the top level command string for the custom CLI command table

Creating Command Tables

The custom command tables take the following format:

TR_CLI_COMMAND_TABLE(custom_cli_commands) =
{
{ "cmd_string", command_function, "Command description" },
.
.
{ "subcommand", TR_CLI_SUB_COMMANDS, TR_CLI_SUB_COMMAND_TABLE(name_of_subcommand_table) },
TR_CLI_COMMAND_TABLE_END
};

TR_CLI_COMMAND_TABLE is a macro used to begin the declaration of the table. The root user custom command table name must be custom_cli_commands. Command table entries can be added as needed, including adding sub-command tables as shown in Table Hierarchy. The command table(s) must be terminated with TR_CLI_COMMAND_TABLE_END. Command strings may include "-" and/or "_" and other special characters, but cannot have a space in them.

Writing CLI Functions

TODO: explain how to write a CLI function using option and argument processing

Remote CLI


The Remote CLI Server plugin allows command strings to be received over the air via Zigbee packets. The command strings are passed to the CLI for parsing just like UART command strings are. The output from the CLI command execution is then packaged up and sent back out over Zigbee. The Remote CLI Client plugin is used to send remote CLI commands to a node on the Zigbee network. This feature provides powerful field debug capability, especially if the product vendor created custom commands to extend the CLI for thier specific use cases.