Skip to main content

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-can versions.


Protocol details

  • Handshake: both ends immediately send CANNELLONIv1 (no terminator).
  • Frame on the TCP stream:
    • CANID u32 big‑endian with SocketCAN‑style bits:
      • 0x80000000 → EFF (extended id)
      • 0x40000000 → RTR (remote)
      • 0x20000000 → ERR (error)
    • LEN u8; valid range 0..8 (top bit, if set on the wire, is ignored; parser masks with & 0x7F)
    • DATA LEN bytes
  • No CAN‑FD: TX with is_fd=True is rejected; RX with LEN>8 is 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‑endian u32 CANID + u8 LEN) and there are no extra bytes in the header.
  • Handshake errors
    The server must expect/emit CANNELLONIv1 (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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

can_cannelloni-0.1.0.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

can_cannelloni-0.1.0-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

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

Hashes for can_cannelloni-0.1.0.tar.gz
Algorithm Hash digest
SHA256 adcea3fdc9b77dec3d586fff746930781fed64599a60dbabd2f373809b1cd80a
MD5 3fed8fe3bcf13f0eb715d42dc7242bbf
BLAKE2b-256 17f49c6e54cf64f337f3763613f3d39f0cea1593f0e0c4fb892c15db7a53ff80

See more details on using hashes here.

Provenance

The following attestation bundles were made for can_cannelloni-0.1.0.tar.gz:

Publisher: ci.yml on kstaniek/python-can-cannelloni

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for can_cannelloni-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5e254c11d638cc03f79b3180e772b61cce5948febe89d41bfa4497b7e73f2b5a
MD5 6f7aa236fa41475407a02c9028d3330a
BLAKE2b-256 518f53918670d86ca4e4dc3b11b1b9d4a253607a23342860728763a47d4c259d

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page