Update OT CLI Commands

View source on GitHub

We generate CLI Commands from the CLI source files in the openthread GitHub repository.

This guide provides instructions on how to use our custom Doxygen comments that we use to create the command list.

Get started

To document a CLI command, complete the following steps. It's important that you follow these steps in the order provided.

  1. Find the associated Cmd from the openthread/src/cli directory. For example, to find ba state, search for Cmd("ba"). Each command will have an associated function template:

    template <> otError Interpreter::Process<Cmd("ba")>(Arg aArgs[])
  2. In the function template, locate the correct command logic. For example, ba state:

    else if (aArgs[0] == "state")
  3. Before the logic begins, start the @cli Doxygen block:

     * @cli ba state
  4. Next, immediately below @cli, add examples using @code. Include at least one example. Do not include the > prompt, and make sure to document the full return output, including the standard Done response.

     * @code
     * ba state
     * Started
     * Done
     * @endcode

Because CLI commands provide command-line access to common API methods and functions, some of the commands share the same description as their corresponding API. If the command description is the same, complete the following steps:

  1. Find the associated API from the openthread/include/openthread directory. For example, ba state maps to otBorderAgentGetState.

  2. Use the api_copy command, then enter the API name directly below it. In front of the API definition, make sure to use the pound sign # to create the automatic Doxygen link.

    @par api_copy

Here's a complete example of the minimum Doxygen comments required to automatically generate an OT CLI command:

 * @cli ba state
 * @code
 * ba state
 * Started
 * Done
 * @endcode
 * @par api_copy
 * #otBorderAgentGetState

To review the HTML output, refer to ba state. For advanced examples and additional options, refer to the following sections.

CLI template options

CLI commands are grouped by one continuous comment block, beginning with the ALIAS tag @cli. Multiple @code examples are supported.

The order you specify each tag is important.

  • @cparam must come after @code
  • If you're copying an API description, @par api_copy must come after @cparam
 * @cli command name (overload1,overload2)
 * @code
 * command name arg1
 * Done
 * @endcode
 * @cparam command name @ca{arg1} [@ca{opt-arg}] [@ca{choose-1}|@ca{choose-2}]
 * Optional parameter description; displays below the Parameter heading.
 * *   Markdown and lists are supported.
 * @par api_copy
 * #{apiName}
 * @par
 * Optional CLI specific paragraph. Markdown and lists are supported.
 * @note Notes are supported.
 * @csa{other command name}
 * @sa API method or function name

Next, learn more about how each ALIAS tag is used.

Command names

Any text after @cli becomes the command name header. This header is used in dynamic linking, for example the netdata publish prefix command:

 * @cli netdata publish prefix

Other commands might be more complex. For example, netdata publish dnssrp unicast provides a few options:

  1. Publish by address and port number
  2. Publish by port number and a device's Mesh-Local EID

If a command is overloaded, use parentheses to uniquely identify the command.

 * @cli netdata publish dnssrp unicast (mle)
 * @cli netdata publish dnssrp unicast (addr,port)

Command descriptions

There are three ways to document command descriptions. You can copy the API description, use the API description but add additional information, or provide a completely unique description that belongs only to the CLI command. In the next sections, we'll go over each method.

Copy the corresponding API description

Use api_copy to copy the corresponding API method or function. When you copy APIs, make sure that the description will work for both the API and the CLI command. Avoid using phrases that apply only to a function, for example This function or This method. Prefer an active voice, for example Gets the or Sets the.

 * @par api_copy
 * #otBorderAgentGetState

Add more information to the API description

If you'd like to use api_copy but need to add additional information that applies only to the CLI command, use @par. After the @par tag, make sure to drop down to the next line.

 * @par api_copy
 * #otBorderAgentGetState
 * @par
 * CLI description here; add a few things that do not apply to the API method.
 * @par
 * Start a new paragraph.

These paragraphs display after the API description.

Provide CLI-specific descriptions only

Some CLI commands use multiple APIs, or differ from the API call. Others don't have an associated API, for example netdata help. To provide a separate description, use @par. Do not include a @par title, and start your description on the next line. In this scenario, do not use @api_copy.

 * @cli netdata help
 * @code
 * netdata help
 * ...
 * show
 * steeringdata
 * unpublish
 * Done
 * @endcode
 * @par
 * Gets a list of `netdata` CLI commands.


Define command parameters using @cparam and @ca.

  • Put brackets [ ] around optional arguments.
  • Use vertical bars | (pipes) between argument choices.
  • To display parameter details, you can enter sentences and markdown lists below the @cparam tag.

Parameters with details

 * @cparam netdata publish prefix @ca{prefix} [@ca{padcrosnD}] [@ca{high}|@ca{med}|@ca{low}]
 * OT CLI uses mapped arguments to configure #otBorderRouterConfig values. @moreinfo{the @overview}.

To review the HTML output, refer to netdata publish prefix.

Parameters with markdown lists

You can also use lists after @cparam. This is helpful for when you'd like to provide details about the command arguments that are used.

 * @cparam netdata show [@ca{local}] [@ca{-x}]
 * *   The optional `-x` argument gets Network Data as hex-encoded TLVs.
 * *   The optional `local` argument gets local Network Data to sync with Leader.

To review the HTML output, refer to netdata show.

@cli blocks must be one continuous comment with no spaces. If you add a list below @cparam and then need another paragraph below that list, use a period . to manually end the list.

* @cparam commandname [@ca{qmr}]
* [`q`, `m`, and `r`] map to #otLinkMetricsValues.
* *   `q`: Layer 2 LQI (#otLinkMetricsValues::mLqiValue).
* *   `m`: Link Margin (#otLinkMetricsValues::mLinkMarginValue).
* *   `r`: RSSI (#otLinkMetricsValues::mRssiValue).
* .
* Add another paragraph here. The dot above will end the HTML list that's generated.
* This paragraph displays under the Parameters heading, and not the command description.

For additional examples, refer to Doxygen's Lists.

You can link to other API methods or functions with #otFunctionName or @sa. Enter these links at the end of the CLI comment block.

 * @cli netdata publish prefix
 * @code
 * netdata publish prefix fd00:1234:5678::/64 paos med
 * Done
 * @endcode
 * @cparam netdata publish prefix @ca{prefix} [@ca{padcrosnD}] [@ca{high}|@ca{med}|@ca{low}]
 * OT CLI uses mapped arguments to configure #otBorderRouterConfig values. @moreinfo{the @overview}.
 * @par
 * Publish an on-mesh prefix entry. @moreinfo{@netdata}.
 * @sa otNetDataPublishOnMeshPrefix

@sa links display in the CLI and API References heading. To review the HTML output, refer to netdata publish prefix.

Sometimes, Doxygen might mistake a normal word as a link to a CLI class, for example, the word Joiner. To prevent Doxygen from linking to keywords or class names used in a sentence, use the % operator in front of the word, for example:

Clear the %Joiner discerner

For more information, refer to Automatic link generation in the Doxygen guide.

Use @csa to link to other commands.

* @csa{netdata publish dnssrp anycast}

If a command is overloaded, include the parentheses and add a comma if applicable. Don't use spaces inside the parentheses:

* @csa{netdata publish dnssrp unicast (addr,port)}
* @csa{netdata publish dnssrp unicast (mle)}

Doxygen special commands

CLI commands support the following Doxygen ALIASES and special commands:

ALIAS Example Description
@cli @cli ba port Command name. Starts a CLI comment block.
@code @code
ba port
Command example.
@ca [@ca{prefix}] Command argument. Use brackets [ ] for optional arguments.
@cparam @cparam joiner discerner @ca{discerner}
Parameter details.
Command parameters.
@par @par
Optional CLI description.
CLI specific paragraphs.
@csa @csa{prefix add} Command See Also. Links to another command.
@sa @sa otBorderRouterConfig See Also. Creates a link to an API Reference.
@overview @overview Creates a link to the OpenThread CLI Overview.
@netdata @netdata Creates a link to Display and Manage Network Data with OT CLI.
@dataset @dataset Creates a link to Display and Manage Datasets with OT CLI.
@udp @udp Creates a link to Test UDP Functionality With OT CLI.
@moreinfo @moreinfo{@netdata} Creates a referral link.
@note @note Important callout. Creates a note callout box.

Fixing lines broken by the make pretty script

Some code comments, such as CLI parameters or command output, must be on a single line for them to render correctly in the openthread.io reference. However, make pretty imposes a column-width limit, which can break the rendered output for long lines.

This situation can be addressed by adding line breaks and enclosing them with an HTML comment tag, as shown in two examples below.

The first example is the dns resolve command, which can take up to six parameters. To correctly render the syntax using Doxygen while still passing the make pretty check, the parameters must be split across three lines in the source:

* @cparam dns resolve @ca{hostname} [@ca{dns-server-IP}] <!--
* -->                 [@ca{dns-server-port}] [@ca{response-timeout-ms}] <!--
* -->                 [@ca{max-tx-attempts}] [@ca{recursion-desired-boolean}]

The second example is the output of the history ipaddr list 5 command. For the output to render properly and still pass the make pretty check, each of the five output lines must be split into two lines, as follows:

* history ipaddr list 5
* 00:00:20.327 -> event:Removed address:2001:dead:beef:cafe:c4cb:caba:8d55:e30b <!--
* -->prefixlen:64 origin:slaac scope:14 preferred:yes valid:yes rloc:no
* 00:00:59.983 -> event:Added address:2001:dead:beef:cafe:c4cb:caba:8d55:e30b <!--
* -->prefixlen:64 origin:slaac scope:14 preferred:yes valid:yes rloc:no
* 00:01:22.535 -> event:Added address:fd00:0:0:0:0:0:0:1 prefixlen:64 <!--
* -->origin:manual scope:14 preferred:yes valid:yes rloc:no
* 00:02:33.221 -> event:Added address:fdde:ad00:beef:0:0:ff:fe00:fc00 <!--
* -->prefixlen:64 origin:thread scope:3 preferred:no valid:yes rloc:no
* 00:02:33.221 -> event:Added address:fdde:ad00:beef:0:0:ff:fe00:5400 <!--
* -->prefixlen:64 origin:thread scope:3 preferred:no valid:yes rloc:yes
* Done