Management CLI: <tt>prf-mgmt</tt>
prf-mgmt is the host-side tool that talks to PacketRF nodes. It is the only management front-end the project ships, and it is intended to be the comfortable, day-to-day way to operate a device. There is no telnet, no proprietary GUI, no hidden side channel: every management operation goes through the same authenticated CoAP/CBOR command tree, and prf-mgmt is what speaks it on the host side.
This page is a tour. If you are bootstrapping a fresh device for the first time, Quick Start is the right place to be. If you want the operational manual — what to configure, in what order, for an actual NPR deployment — that is in PacketRF Operating Guide.
What it is
prf-mgmt is a Python 3.11+ CLI built on top of a small library that implements the PacketRF control protocol — request envelope encoding in CBOR, COSE-signed writes against the device's rotating nonce, response signature verification against a local trust store, schema discovery, and so on. The library is also what host-side automation (scenario scripts, hardware-in-the-loop tests) uses internally.
What you see at the command line is mostly a wrapper that:
- opens a transport — local USB serial framing, or CoAP UDP — based on the
--uriyou give it, - encodes your request,
- signs it with one of your local admin keys if the operation requires authentication,
- parses the response, optionally verifies the device's response signature against the trusted-device store,
- prints something readable.
There are two transports today and the tool does not care which one you use. The same /system/status, the same /interface/list, the same config writes — only the --uri changes.
Installing it
Three reasonable installation paths, listed roughly in order of convenience for different audiences.
From a release wheel (recommended for users)
The release artifacts on GitHub include a Python wheel named packetrf_mgmt-<version>-py3-none-any.whl. The clean way to install it is with pipx, which puts the tool in its own isolated environment and exposes it on your $PATH:
pipx install ./packetrf_mgmt-<version>-py3-none-any.whl
If you prefer to install directly from a published asset URL:
pipx install "packetrf-mgmt @ https://github.com/slintak/PacketRF/releases/download/v<version>/packetrf_mgmt-<version>-py3-none-any.whl"
Or in a regular virtualenv if that fits your habits better:
python -m venv .venv . .venv/bin/activate python -m pip install ./packetrf_mgmt-<version>-py3-none-any.whl
After install, prf-mgmt --help should return a usage summary.
From repository sources (developer workflow)
The host-side code lives under tools/mgmt/. The fastest way to get an interactive shell from a source checkout is:
make mgmtThat target runs uv sync --project tools/mgmt and starts an interactive prf-mgmt shell with the local serial URI auto-detected. Single commands without entering the shell:
uv run --project tools/mgmt prf-mgmt --help
The convention used in the rest of the documentation is to write plain prf-mgmt … commands. If you are running from sources, prepend uv run --project tools/mgmt and they are otherwise identical.
The two transports
--uri selects the transport:
serial:/dev/ttyACM0— local USB serial management framing. Use this for first-boot bootstrap and for benchwork without an IP path to the device.coap://192.168.42.1— CoAP over UDP, port5683. This is the normal transport once the device is on the network. It works over any interface the device exposes — USB CDC-NCM, Ethernet, or even over the NPR radio link itself.
The serial transport is point-to-point with one device. The CoAP transport is plain UDP and you can talk to several devices in sequence by changing the URI; nothing keeps state between calls.
If you forget to pass --uri, the tool either prompts you (in interactive shell mode) or prints an error pointing you at it.
Admin keys
PacketRF requires authenticated control writes, and the authentication is done with Ed25519 keys held on the host. The first key on a fresh device is installed during bootstrap; afterwards, prf-mgmt uses it (or any other admin key) to sign write requests.
Generate a key — once, not once per device:
prf-mgmt admin-key generate default
The name (default) is a local alias. You can have many. Keys are stored under ~/.config/packetrf/. That directory is your admin credential. Treat it the way you would treat ~/.ssh: do not lose it, do not commit it to git, do not paste it into a chat asking for help.
To use a specific admin key in a command:
prf-mgmt --uri coap://192.168.42.1 --admin-key default \ /interface/np2/set callsign=OKnABC-PRF
The --admin-key flag is only required for write requests. Read-only paths (/system/status, /interface/list, /interface/<iface>/config without arguments, /schema) work without it.
The command tree
The command paths in prf-mgmt are the same paths the firmware publishes through /schema — slash-separated, exactly as they appear on the wire. There are no shortened CLI verbs; what you type at the prompt is what hits the device.
The convention to keep in mind:
- read paths usually end in
/status(live runtime data) or/config(configured values, no arguments), - write paths usually end in
/setand takekey=valuearguments, - shared system endpoints live under
/system/*, - per-interface endpoints under
/interface/<iface>/*, - crypto and bootstrap endpoints under
/crypto/*.
The exact authoritative listing is whatever prf-mgmt /schema returns from the running device. The shape below is stable enough to plan from.
| Family | Purpose | Examples |
|---|---|---|
/system/* | Health, telemetry, reboot, schema id | /system/status, /system/mem, /system/reboot |
/interface/* | Per-interface status and configuration | /interface/list, /interface/np2/status, /interface/np2/set |
/crypto/* | Device public key, keyring, bootstrap install | /crypto/device, /crypto/bootstrap/install |
/schema | Active command tree of the running firmware | /schema |
admin-key | Local admin key store on the host (no device contact) | admin-key generate, admin-key list |
script, shell | Run scenario files / enter an interactive REPL | script foo.mgmt, shell |
bootstrap | Convenience wrapper for /crypto/bootstrap/install | bootstrap 1000 |
The last three rows do not start with a slash because they are not device-side paths; they are host-side commands implemented entirely by prf-mgmt. Everything that is a device-side path looks like its on-wire form.
A handful of useful invocations to keep handy:
# Health check across the device prf-mgmt --uri coap://192.168.42.1 /system/status prf-mgmt --uri coap://192.168.42.1 /system/mem # What interfaces are up, in what mode, with what addresses prf-mgmt --uri coap://192.168.42.1 /interface/list # Drill into the NPR side prf-mgmt --uri coap://192.168.42.1 /interface/np2/status prf-mgmt --uri coap://192.168.42.1 /interface/np2/config # Edit a config key (note: /set, not /config) prf-mgmt --uri coap://192.168.42.1 --admin-key default \ /interface/np2/set modulation_id=22 # Get the device public key — useful when adding it to a host # trust store, or when comparing what the device reports against # what your host already trusts. prf-mgmt --uri coap://192.168.42.1 /crypto/device # Clean reboot prf-mgmt --uri coap://192.168.42.1 --admin-key default /system/reboot
Interactive shell
prf-mgmt shell opens a REPL that holds the URI and admin-key selection between commands. It is the most pleasant way to work with a single device for any length of time:
$ prf-mgmt --uri coap://192.168.42.1 --admin-key default shell prf> /system/status … prf> /interface/np2/status … prf> /interface/np2/set modulation_id=22 …
The shell understands the same commands as the non-interactive form and supports tab completion driven by the device's published schema.
Scenario scripts
Repetitive configuration — the kind you do every time you set up a master, or every time you bring a slave back from a factory reset — fits naturally into a small script. PacketRF ships a handful of example scenarios under scenarios/:
scenarios/dump-all-configs.mgmtscenarios/configure-us0-from-np2-dhcp.mgmt
A scenario is a plain text file:
- one command per line,
#introduces a comment, including inline at the end of a line,- blank lines are ignored,
- execution stops on the first error.
Run one with:
prf-mgmt --uri coap://192.168.42.1 --admin-key default \ script scenarios/dump-all-configs.mgmt
make exposes a couple of common scenarios as named targets, which can be useful for keyboard automation:
make bootstrap CODE=0110 ADMIN_KEY=default make mgmt-cmd CMD="/system/status"
Response signing and trust
When the device has identity available, it signs responses as COSE_Sign1 and includes a kid (the device's key identifier) in the protected headers. prf-mgmt can verify those signatures against a host-side trusted-device store. If the device is unknown to your host, the tool will say so — that is by design, the same way SSH says "the authenticity of host can't be established" the first time you connect.
During the very first bootstrap, response signing is usually unverified — your host has no prior trust anchor for the device yet. That is expected. Add the device key to your host trust store after bootstrap to verify signed responses afterwards.
Troubleshooting first-day issues
A short list of things that bite people on day one and what to do about them.
- **
prf-mgmt: command not found** after apipxinstall: your shell has not picked up thepipxbin path yet. Runpipx ensurepathand start a new shell. - No serial device shows up: check the serial path under
/dev/. On Linux a freshly bootstrapped device is usually/dev/ttyACM0. If your user is not in the right group (dialouton most distros), opening it will fail with a permission error. - CoAP commands time out but serial works: confirm the device's IP from
interface listover serial, and check that your host's routing actually goes through the right interface. The factory USB address is192.168.42.1, but if you have multiple PacketRF devices on USB simultaneously they all want the same address — that is a host-side conflict, not a device fault. - Write fails with
nonce_requiredornonce_stale: the device rotated the nonce while you were typing. Just retry — the tool fetches the current nonce automatically before signing. - Write fails with
unauthorized: the admin key you are using is not in the device's keyring with theadminflag. Either pick a different--admin-key, or add this key through an existing admin session.
Where to look next
- PacketRF Operating Guide — what to configure on a new node and in what order, NPR-specific.
- Control module — the protocol-level documentation of the management interface.
- Control developer guide — how endpoints are added, for firmware contributors.