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
Metadata
Release files for can-cannelloni 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| can_cannelloni-0.1.0.tar.gz | 16.5 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| can_cannelloni-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 26.8 kB
Release files / can_cannelloni-0.1.0.tar.gz
| Download URL | can_cannelloni-0.1.0.tar.gz |
|---|---|
| Size | 16.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
adcea3fdc9b77dec3d586fff746930781fed64599a60dbabd2f373809b1cd80a
|
|
BLAKE2b-256 checksum How to use checksums |
17f49c6e54cf64f337f3763613f3d39f0cea1593f0e0c4fb892c15db7a53ff80
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2025.
Transparency logRelease files / can_cannelloni-0.1.0-py3-none-any.whl
| Download URL | can_cannelloni-0.1.0-py3-none-any.whl |
|---|---|
| Size | 10.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5e254c11d638cc03f79b3180e772b61cce5948febe89d41bfa4497b7e73f2b5a
|
|
BLAKE2b-256 checksum How to use checksums |
518f53918670d86ca4e4dc3b11b1b9d4a253607a23342860728763a47d4c259d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2025.
Transparency logSecurity for can-cannelloni 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for can_cannelloni-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.