# Automatic configuration of port identifiers

**URL:** <https://forum.opencyphal.org/t/automatic-configuration-of-port-identifiers/840>\
**Category:** Development & Maintenance\
**Created:** [May 21, 2020, 6:03pm UTC](https://forum.opencyphal.org/t/automatic-configuration-of-port-identifiers/840 "2020-05-21T18:03:31Z")\
**Posts on this page:** 1\
**Showing post:** 3

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [June 6, 2020, 12:57am UTC](https://forum.opencyphal.org/t/automatic-configuration-of-port-identifiers/840/3 "2020-06-06T00:57:13Z")

</div>

Here is the demo that I promised last Thursday for @PetervdPerk @dagar and @tsc21. The demo shows how to configure a subject-ID via `uavcan.register.Access.1`.

## Building the demo

We are going to need [libcanard](https://github.com/UAVCAN/libcanard) and a [SocketCAN facade for it](https://github.com/UAVCAN/platform_specific_components/pull/10). It is assumed that the host system is GNU/Linux. The build is trivial:

```cmake
cmake_minimum_required(VERSION 3.16)
project(demo C)
set(CMAKE_C_STANDARD 11)
include_directories(libcanard socketcan)
add_executable(demo demo.c libcanard/canard.c socketcan/socketcan.c)

```

Or just:

```auto
gcc demo.c libcanard/canard.c socketcan/socketcan.c -I socketcan -I libcanard

```

[demo.c](https://forum.opencyphal.org/uploads/short-url/b3I9dbS8nkaa7IHoy62PGOcZqKW.c) is attached. Its logic should be self-explanatory.

## Evaluating the demo

To evaluate the demo, we are going to need the PyUAVCAN CLI tool: `pip install pyuavcan[cli]`

Set up a virtual CAN bus:

```bash
sudo modprobe can && sudo modprobe can_raw && sudo modprobe vcan # Load the kernel modules
sudo ip link add dev vcan0 type vcan # Register a new virtual CAN interface named "vcan0"
sudo ip link set vcan0 mtu 72 # This is to enable CAN FD (optional)
sudo ip link set up vcan0

```

You can listen to the traffic on the bus using **`candump -decaxta any`**. Arch-based users will find it in AUR under the name `can-utils`; Debian-based distros ship it under the same name.

Prepare the PyUAVCAN CLI tool:

```bash
cd ~/test
pyuavcan dsdl-gen-pkg path/to/public_regulated_data_types/uavcan
export PYTHONPATH=~/test # To make generated packages importable

```

Launch the compiled demo on `vcan0` using node-ID 42: `./demo vcan0 42`

Open a new terminal to listen for its heartbeats:

```bash
$ pyuavcan sub uavcan.node.Heartbeat.1.0 --tr='CAN(can.media.socketcan.SocketCANMedia("vcan0", 64), None)'
---
32085:
  uptime: 824
  health: 0
  mode: 0
  vendor_specific_status_code: 0
...

```

Open another terminal and read the current register value by calling `uavcan.register.Access.1.0` on the node-ID 42:

```bash
$ pyuavcan call 42 uavcan.register.Access.1.0 '{name: {name: uavcan.pub.measurement}}' --tr='CAN(can.media.socketcan.SocketCANMedia("vcan0", 8), 125)'
---
384:
  timestamp:
    microsecond: 0
  mutable: true
  persistent: false
  value:
    natural16:
      value:
      - 65535

```

You may also briefly see another heartbeat emitted by the above command. If you read a non-existent register, you get an empty response back as prescribed by the register protocol spec:

```bash
$ pyuavcan call 42 uavcan.register.Access.1.0 '{name: {name: no.such.register}}' --tr='CAN(can.media.socketcan.SocketCANMedia("vcan0", 8), 125)'
---
384:
  timestamp:
    microsecond: 0
  mutable: false
  persistent: false
  value:
    empty: {}

```

Okay, now let’s suppose that we’re going to use a subject-ID of 5555 for our measurement messages. Open a new terminal and launch a subscriber on subject-ID 5555 of type String:

```bash
pyuavcan sub 5555.uavcan.primitive.String.1.0 --tr='CAN(can.media.socketcan.SocketCANMedia("vcan0", 64), None)'

```

You will see nothing because the node doesn’t know the subject-ID yet. So we configure it:

```bash
$ pyuavcan call 42 uavcan.register.Access.1.0 '{name: {name: uavcan.pub.measurement}, value: {natural16: {value: [5555]}}}' --tr='CAN(can.media.socketcan.SocketCANMedia("vcan0", 8), 125)'
---
384:
  timestamp:
    microsecond: 0
  mutable: true
  persistent: false
  value:
    natural16:
      value:
      - 5555

```

We received a response that contains the same value that we’ve just written which means that everything went well. Now we can see the published messages in the subscriber tool:

```yaml
---
5555:
  value: So it goes.

---
5555:
  value: So it goes.

...

```

The invocation of `uavcan.register.Access.1` can be done manually by the integrator who is configuring the node for use with a particular end system, although it is inconvenient and requires special tools, not to mention dealing with the awkward YAML syntax of the PyUAVCAN CLI tool. Despite the inconvenience, it works as a first step. We will be building a better user experience on top of this without affecting the end-nodes in any way: the improvements will be focused on the so-called “master node” (UAVCAN is masterless so this is to be understood as the application-level master, like the FMU on a UAV). PX4 can [expose the register API via QGC](https://mavlink.io/en/guide/uavcan_interaction.html) as a first step (this will be needed anyway regardless of the logic discussed here). Later we can extend the functionality to implement true plug-and-play automatic subject-ID configuration as described in the OP post.

Please note that even though the subject-ID is configured at runtime, it would be a mistake to call it “dynamic”, because it is not changing while the system is running. Instead, it is to be configured once at the system definition time, and hence we call it _static runtime-assigned_.

---

_[View the full topic](https://forum.opencyphal.org/t/automatic-configuration-of-port-identifiers/840)._
