How to use Vanetza on the cube:evk

Firat Kasmis
nfiniity GmbH

Accelerate V2X development with open-source

Vanetza is an open-source implementation of the ETSI C-ITS protocol suite. With its clean and highly customizable design it enables developers and researchers around the world to access V2X and its ETSI implementations.

Among others, it comprises the following protocols and features:

  • GeoNetworking (GN)
  • Basic Transport Protocol (BTP)
  • Decentralized Congestion Control (DCC)
  • Security
  • Support for ASN.1 messages (Facilities) such as CAM and DENM

The V2X evaluation kitcube:evk comes with native support for Vanetza and its socktap application. Socktap is an example application demonstrating API usage of Vanetza libraries, including support for our cube:evk.

RPC Interface for Remote Development

The cube:evk provides a powerful RPC (Remote Procedure Call) interface that enables remote access to V2X radio capabilities over IP networks. Built on Cap'n Proto, the cube-radio-rpc service automatically launches when V2X radios are configured, listening on TCP port 23057.

This approach offers several advantages:

  • Language flexibility — Write clients in C++, Python, Go, Rust, and more
  • Network transparency — Control radios from anywhere on the network
  • Type safety — Schema file defines the contract between server and client
  • Zero-copy serialization — Cap'n Proto's efficiency minimizes overhead

Configuration

Before using the RPC interface, configure the V2X module using the cube-v2xconfig tool. Setting the radio to C-V2X and enabling it for auto-start:

cube:~$ cube-v2xconfig start cv2x

For DSRC/ITS-G5:

cube:~$ cube-v2xconfig start dsrc

Verify the RPC service is running:

cube:~$ sudo netstat -tlnp | grep 23057
tcp6  0  0 :::23057  :::*  LISTEN  567/cube-radio-rpc

To connect the cube:evk to your local WiFi for remote access:

cube:~$ nmcli dev wifi connect '<ssid>' password '<password>'
cube:~$ ip a

Using Vanetza with RPC

Vanetza's socktap includes a built-in RPC link layer that connects directly to cube-radio-rpc — perfect for remote development and testing. Run socktap on your host machine while the cube:evk handles the V2X radio communication:

# Build vanetza with RPC support
host:~$ mkdir build && cd build
host:~$ cmake -DBUILD_SOCKTAP=ON ..
host:~$ make

# Run socktap using RPC link layer (replace with your cube's IP)
host:~$ ./bin/socktap -l rpc --rpc-host 192.168.8.201 --gpsd-host 192.168.8.201

Example output:

Starting runtime at 2025-Nov-07 10:36:01.881303
Enable application 'ca'...
Connected to RPC server id=0 version=1
RPC server's info: cube-radio=dsrc

Python RPC Client Example

You can also build custom V2X applications using the RPC interface directly. Here's how to transmit and receive V2X frames using Python:

# Setup Python environment
python3 -m venv .venv
source .venv/bin/activate
pip install pycapnp

Connect to the RPC service and identify the device:

import asyncio
import capnp

capnp.remove_import_hook()
cube_rpc = capnp.load(
    'cube_rpc.capnp',
    'Cube RPC',
    ['/usr/include/', '/usr/local/include/']
)

async def main():
    host = '192.168.8.201'  # Your cube's IP
    port = 23057

    stream = await capnp.AsyncIoStream.create_connection(host=host, port=port)
    client = capnp.TwoPartyClient(stream)
    link_layer = client.bootstrap().cast_as(cube_rpc.LinkLayer)

    # Identify the connected device
    result = await link_layer.identify()
    print(f"id: {result.id}, version: {result.version}, info: {result.info}")

if __name__ == '__main__':
    asyncio.run(capnp.run(main()))

Transmit a V2X frame:

frame = {
    "sourceAddress": bytes.fromhex("001122334455"),
    "destinationAddress": bytes.fromhex("FFFFFFFFFFFF"),
    "payload": b"Hello from Python RPC!"
}

tx_params = {
    "wlan": {
        "priority": 3,
        "power": int(10 * 8),  # 10 dBm
        "datarate": 6 * 2      # 6 Mbps
    }
}

result = await link_layer.transmitData(frame=frame, txParams=tx_params)

Subscribe to receive incoming frames:

class DataListenerImpl(cube_rpc.LinkLayer.DataListener.Server):
    async def onDataIndication(self, frame, rxParams, **kwargs):
        payload = bytes(frame.payload)
        print(f"src: {frame.sourceAddress.hex()}")
        print(f"dest: {frame.destinationAddress.hex()}")

        if rxParams.which() == 'wlan':
            power_dbm = rxParams.wlan.power / 8.0
            print(f"power: {power_dbm:.1f} dBm")

listener = DataListenerImpl()
await link_layer.subscribeData(listener=listener)
await asyncio.Event().wait()  # Keep listening

The cube:evk is ideally suited for research, development and prototyping. By providing a modern RPC interface alongside open-source tools like Vanetza, we aim to accelerate V2X development.

Visit our Knowledge Base for complete RPC documentation and more examples.

Happy coding!