python-can backend for Cannelloni protocol
Project description
python-can-cannelloni
A python-can backend that connects to a cannelloni TCP server (client side).
It speaks exactly the same minimal stream as the server codec:
[ CANID u32 (big-endian, with EFF/RTR/ERR bits) ][ LEN u8 (0..8) ][ DATA LEN bytes ]
- No outer packet header, no extra flag bytes
- Classic CAN only (DLC ≤ 8; CAN‑FD is intentionally rejected on TX)
- On connect both peers send the banner
CANNELLONIv1(without\0) - TCP socket uses TCP_NODELAY and keepalive by default
- Background RX loop with optional auto‑reconnect
Repository layout
python-can-cannelloni/
├─ pyproject.toml
├─ README.md
└─ can_cannelloni/
├─ __init__.py # exposes CannelloniBus
├─ bus.py # python-can BusABC implementation + RX loop
└─ protocol.py # encode/decode for the wire format + handshake
(Optional tests:)
tests/
└─ test_bus.py
Requirements
- Python 3.10+
python-can >= 4.3
Install in editable mode to register the plugin entry point:
pip install -e .
pyproject.toml:
[project.entry-points."can.interface"]
cannelloni = "can_cannelloni.bus:CannelloniBus"
Quick start
import can
# Option A: pass "host:port" in channel
bus = can.Bus(interface="cannelloni", channel="172.31.11.43:20000")
# Option B: use host/port kwargs
# bus = can.Bus(interface="cannelloni", host="172.31.11.43", port=20000)
# Send a classic CAN frame (extended-id example)
bus.send(
can.Message(
arbitration_id=0x6F4A,
data=b"\xFE\x21\x78\x28",
is_extended_id=True,
)
)
# Receive (1.0 s timeout)
msg = bus.recv(1.0)
print(msg)
bus.shutdown()
You can use python-can utilities like Notifier, Logger, BufferedReader, etc.
Constructor options
All options go to can.Bus(interface="cannelloni", ...):
| Option | Type | Default | Description |
|---|---|---|---|
channel |
str | – | "host:port" (alt. to host/port) |
host |
str | – | Server IP/hostname |
port |
int | – | Server TCP port |
nodelay |
bool | True |
Set TCP_NODELAY |
keepalive |
bool | True |
Enable TCP keepalive |
handshake_timeout |
float | 2.0 |
Timeout awaiting banner |
reconnect |
bool | True |
Auto‑reconnect on drop |
reconnect_interval |
float | 1.0 |
Seconds between attempts |
rx_queue_size |
int | 10000 |
Bounded RX queue size |
Filters (client‑side)
# Only receive 0x100 (standard 11-bit)
bus.set_filters([{"can_id": 0x100, "can_mask": 0x7FF, "extended": False}])
Filtering is applied locally in the client for maximum compatibility across
python-canversions.
Protocol details
- Handshake: both ends immediately send
CANNELLONIv1(no terminator). - Frame on the TCP stream:
CANIDu32 big‑endian with SocketCAN‑style bits:0x80000000→ EFF (extended id)0x40000000→ RTR (remote)0x20000000→ ERR (error)
LENu8; valid range0..8(top bit, if set on the wire, is ignored; parser masks with& 0x7F)DATALEN bytes
- No CAN‑FD: TX with
is_fd=Trueis rejected; RX withLEN>8is considered invalid and the parser attempts a 1‑byte resync.
Troubleshooting
- Weird DLC (e.g., 254) or garbage IDs
This indicates a header mismatch. Ensure the layout is exactly!IB(big‑endianu32 CANID+u8 LEN) and there are no extra bytes in the header. - Handshake errors
The server must expect/emitCANNELLONIv1(no\0); transparent TCP path is required (no TLS/HTTP proxies). - No frames
Verify reachability (telnet host port), server logs, and that frames are classic CAN (DLC ≤ 8).
Testing
Minimal pytest to validate sending, receiving, and client‑side filtering.
Run:
pytest -q
Contributing
PRs and issues welcome. Please include tests for protocol changes and keep the wire format exactly as documented (or make it configurable).
License
MIT
# SPDX-License-Identifier: MIT
# Copyright (c) 2025 Klaudiusz Staniek
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file can_cannelloni-0.1.0.tar.gz.
File metadata
- Download URL: can_cannelloni-0.1.0.tar.gz
- Upload date:
- Size: 16.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
adcea3fdc9b77dec3d586fff746930781fed64599a60dbabd2f373809b1cd80a
|
|
| MD5 |
3fed8fe3bcf13f0eb715d42dc7242bbf
|
|
| BLAKE2b-256 |
17f49c6e54cf64f337f3763613f3d39f0cea1593f0e0c4fb892c15db7a53ff80
|
Provenance
The following attestation bundles were made for can_cannelloni-0.1.0.tar.gz:
Publisher:
ci.yml on kstaniek/python-can-cannelloni
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
can_cannelloni-0.1.0.tar.gz -
Subject digest:
adcea3fdc9b77dec3d586fff746930781fed64599a60dbabd2f373809b1cd80a - Sigstore transparency entry: 564211126
- Sigstore integration time:
-
Permalink:
kstaniek/python-can-cannelloni@1bda24510fca101f52cbcea10d124a08f2b0fbd2 -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/kstaniek
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@1bda24510fca101f52cbcea10d124a08f2b0fbd2 -
Trigger Event:
release
-
Statement type:
File details
Details for the file can_cannelloni-0.1.0-py3-none-any.whl.
File metadata
- Download URL: can_cannelloni-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e254c11d638cc03f79b3180e772b61cce5948febe89d41bfa4497b7e73f2b5a
|
|
| MD5 |
6f7aa236fa41475407a02c9028d3330a
|
|
| BLAKE2b-256 |
518f53918670d86ca4e4dc3b11b1b9d4a253607a23342860728763a47d4c259d
|
Provenance
The following attestation bundles were made for can_cannelloni-0.1.0-py3-none-any.whl:
Publisher:
ci.yml on kstaniek/python-can-cannelloni
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
can_cannelloni-0.1.0-py3-none-any.whl -
Subject digest:
5e254c11d638cc03f79b3180e772b61cce5948febe89d41bfa4497b7e73f2b5a - Sigstore transparency entry: 564211127
- Sigstore integration time:
-
Permalink:
kstaniek/python-can-cannelloni@1bda24510fca101f52cbcea10d124a08f2b0fbd2 -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/kstaniek
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@1bda24510fca101f52cbcea10d124a08f2b0fbd2 -
Trigger Event:
release
-
Statement type: