Repository navigation
Releases: juano2310/SuperCANBus
Release list
Duplicate client ID detection and CRC-protected ID assignment
Fixed
- CRC8 on ID assignment responses: when two clients register back-to-back, their multi-frame
ID_RESPONSEframes can interleave, and a splice can pass the serial-match check while carrying the other client's assigned ID — putting two physical devices on one ID (both then act on that ID's commands). The broker now appends a CRC8 over[assignedId][flag][serialLen][serial]and clients verify it, so a spliced response is rejected and the client retries. Backward compatible in both directions. - Duplicate-ID detection: new
onDuplicateId(callback)on the broker. Each registered ID is pinged exactly once per cycle, so a second pong within one cycle proves two devices share that ID; the callback fires once per cycle so the application can stop the ID and force re-registration.
Important: the CRC verification runs on the client side — every client device (tentacle) must be reflashed with this version to be protected from adopting a wrong ID.
See #6 for details.
Guard multi-frame reassembly against concurrent-sender interleaving
Fixed
processExtendedFrame()now tracks thetotalFramescount and next-expectedframeSeqestablished by frame 0, and rejects any subsequent frame that doesn't match instead of blindly appending it. Extended CAN IDs carry no sender/session discriminator, so previously a second multi-frame message sharing the samemsgType(e.g. two tentacles both retrying registration after a shared power event) that started before an in-progress reassembly finished could silently splice its data into the buffer - producing corrupted-but-plausible output (a dropped/garbled character) instead of a clean failure.
See #5 for details.
Fix stale online count on unregister
Fixed
unregisterClient()/unregisterClientBySerial()now remove the client from the online/connected tracking immediately, instead of only invalidating its registration. Previously a stale ID left behind by a wrong-ID collision, a corrupted-serial rejection, or a manualunregcould never time out on its own (pingAllClients()only pings still-registered mappings), permanently inflatinggetClientCount()- e.g. two physical tentacles reporting as three until reboot.
See #4 for details.
Raw frame logging hook and TX safety fixes
Improvements Made:
- Raw Frame Logging Hook
- Added
onRawFrame(RawFrameCallback)onCANPubSubBase, inherited by both broker and client - Fires for every physical CAN frame: RX fires before target-ID filtering/message-type dispatch (a broker sees all bus traffic, not just messages addressed to it), TX fires once per physical frame sent - including once per fragment of an extended/multi-frame message
- Enables external logging/sniffing of the full bus without a separate observe-mode listener node
- Added
CANControllerClass::packetData()- a non-destructive copy of the already-buffered RX payload, used internally by the raw-frame hook without disturbing existing Stream-based reads
- TX Result Correctness
- Added
sendFrame()- a single helper now used by every protocol TX call site (roughly two dozen, across both broker and client), replacing duplicated beginPacket/write/endPacket sequences publish(),subscribe(),unsubscribe(), andsendDirectMessage()now return the real transmit result instead of a hardcodedtrue- Added
getTxFailCount()- a running counter of failed transmits, for basic bus-health monitoring
- Safety Fixes
- Fixed an unclamped stack-buffer index in the registration checksum path that could overflow with a long enough serial number
- Fixed an unclamped stack-buffer index in the subscribe/topic-name path with the same overflow risk for a long enough topic name
- Fixed two
uint8_tclient-count guards that compared against 256 - always true for auint8_t, silently letting the counter wrap 255 to 0
Key Benefits:
- Full bus observability - a broker can now log 100% of CAN traffic (not just what it's addressed to) for external diagnostics/cloud logging
- TX failures are no longer silently swallowed
- Two stack-overflow-prone code paths hardened
- Wire-compatible - no message IDs or payload layouts changed; drop-in for currently-deployed clients/brokers
Deliberately out of scope for this release (tracked as follow-up work, pending hardware-in-the-loop testing): switching the ESP32 driver to the native ESP-IDF TWAI driver, bus-off recovery, non-blocking handler rework, wire-format/multi-frame-reassembly hardening, built-in client liveness/reconnect, and delivery-confirmed (ACKed) direct messages.
See docs/RAW_FRAME_LOGGING.md for the full API reference and usage examples.
Improved registration and corruption detection
Improvements Made:
- CRC8 Checksum Validation
- Added calculateCRC8() function using CRC8-CCITT polynomial
- Clients append checksum to serial number when requesting registration
- Broker validates checksum before processing - silently rejects corrupted messages
- Prevents corrupted data from being stored
- Message Length Validation
- Added isValidMessageLength() helper to validate message size
- Rejects messages that are too short or too long (outside expected range)
- Prevents buffer overflow and malformed data processing
- Enhanced Registration Flow
- Broker side: Reads message into buffer, validates checksum, then validates serial format via callback
- Client side: Calculates checksum before sending registration request
- Messages that fail checksum validation are silently discarded (no invalid ID assigned)
- Backward Compatibility
- Checksum feature controlled by CAN_PS_USE_CHECKSUM flag
- Can be disabled if needed for compatibility with older clients
- When disabled, falls back to serial validation only
Key Benefits:
- Detects corruption immediately - No invalid data reaches storage
- Silent rejection - Corrupted messages don't trigger responses, reducing bus congestion
- Low overhead - CRC8 is fast and only adds 1 byte per message
- Combined with existing protections: Validation callback + startup cleanup + deterministic delays + exponential backoff
The library now has comprehensive collision prevention:
✓ Deterministic delays (spacing between clients)
✓ Checksum validation (detect corruption)
✓ Serial format validation (application-specific via callback)
✓ Length validation (reject malformed messages)
✓ Smallest ID assignment (optimize ID usage)
Update from SuperCAN to SuperCANBus
Revamping the name will make it easier for developers to discover this enhanced version of the CAN Bus protocol!
Improve reconnection and restoration
Fixed automatic subscription restoration for clients reconnecting with known serial numbers. This critical feature now works correctly, eliminating the need for manual re-subscription after power cycles or resets.
💡 Key Features Implemented
✅ Automatic Subscription Restoration - No manual re-subscription needed
✅ Topic Name Preservation - Full names stored and restored
✅ Zero-Touch Reconnection - Complete transparency for users
✅ Flash Storage - Everything persists across power cycles
Improved P2P messages and topics restoration
Key Features Added:
✅ Fixed peer-to-peer messaging
✅ Topic name persistence in flash memory
✅ Subscription restoration with names on client reconnect
✅ clearall command for complete storage reset
Improve ping/pong and offline state
🎯 Major Features Added
- Broker-Initiated Auto-Ping System
- Broker now actively monitors client health by periodic pinging
- Configurable ping interval (default: 5 seconds)
- Configurable missed ping threshold (default: 2)
- Automatic client disconnect on timeout
- Separate runtime ping state (not stored in flash)
- Client Pong Callback
- Clients can register onPong() callback to log broker response
- Automatic response to broker pings
Add Peer to Peer communication
New Features:
- Peer-to-peer messaging API: New sendPeerMessage(targetClientId, message) method for direct client-to-client communication
- Security restriction: Only clients with permanent IDs (1-100, registered with serial numbers) can send/receive peer messages
- ID range separation:
- IDs 1-100: Permanent IDs for registered clients (supports P2P)
- IDs 101-254: Temporary IDs for unregistered clients (pub/sub only)
- New message type: CAN_PS_PEER_MSG (0x09) protocol command
Implementation Changes:
- Added handlePeerMessage() in broker to validate and forward peer messages
- Added _nextTempID field to track temporary ID assignments (starts at 101)
- Enhanced onDirectMessage() callback to handle both broker and peer messages
- Extended frame support for long peer messages
Documentation:
- New PEER_TO_PEER.md guide explaining P2P architecture and usage
- Updated PUBSUB_API.md with sendPeerMessage() documentation
- Updated SERIAL_NUMBER_MANAGEMENT.md with ID range table and P2P capabilities
- Updated QUICK_REFERENCE.md with unified messaging commands
Examples:
- New PeerToPeer.ino example demonstrating direct client-to-client messaging
- Updated ClientWithSerial.ino with unified msg:id:message command supporting both broker and peer messages
Protocol Enhancements:
- Broker validates sender and receiver have permanent IDs before forwarding
- Serial number verification in ID responses to prevent ID conflicts
- Improved subscription cleanup when clients disconnect