Repository navigation
Conversation
Prepare the raw mode for CAN FD by using struct canfd_frame as the frame buffer. For classic CAN frames the layout is identical (can_dlc and len share the same position), so there is no functional change: only CAN_MTU sized frames are read and written as long as CAN FD frames are not enabled on the socket. Clear the frame before parsing a send command, as the buffer is shared with the receive path, and check the recvmsg() return value for the exact MTU sizes. This also fixes the signed/unsigned comparison which let a failing recvmsg() (-1) pass the old 'ret < sizeof(struct can_frame)' check. Signed-off-by: Florian Roks <florian.roks@mercedes-benz.com>
Enable CAN_RAW_FD_FRAMES on the raw socket if the CAN interface supports CAN FD (MTU >= CANFD_MTU), so that CAN FD frames on the bus are received instead of being dropped. Classic CAN interfaces are not affected.
Received CAN FD frames are sent to the client as
< fdframe can_id flags seconds.useconds [data]* >
where flags is the hex value of the CANFD_BRS/CANFD_ESI bits of canfd_frame.flags and data contains up to 64 bytes. Classic CAN frames are still sent as < frame >, so clients only supporting classic CAN never receive more than 8 data bytes and can ignore the new message (as for any other unknown message).
Signed-off-by: Florian Roks <florian.roks@mercedes-benz.com>
Add a command to send a single CAN FD frame in raw mode:
< fdsend can_id flags len [data]* >
flags is the hex value of the canfd_frame.flags bits CANFD_BRS (0x01) and CANFD_ESI (0x02), len the number of data bytes (0..64) followed by the data bytes in hex. As for < send >, an 8 digit can_id selects an extended identifier. Payloads that are not a valid CAN FD data length are padded with zeros up to the next valid length.
The command is rejected if the bus does not support CAN FD. < send > stays limited to classic CAN frames.
Signed-off-by: Florian Roks <florian.roks@mercedes-benz.com>
Describe the < fdframe > and < fdsend > messages of the raw mode and the CAN FD interface requirement. Signed-off-by: Florian Roks <florian.roks@mercedes-benz.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds CAN FD support to the raw mode, as a reworked version of the approach proposed in #33 (same message syntax), split into reviewable steps as requested in #33 (comment).
Protocol
Classic CAN frames are unchanged. CAN FD frames use two new raw mode messages:
flags: hex value of thecanfd_frame.flagsbitsCANFD_BRS(0x01) andCANFD_ESI(0x02)len: 0..64 data bytes; lengths that are not a valid CAN FD data length are zero-padded to the next valid lengthcan_id: as for< frame >/< send >(8 hex digits = extended identifier)Example:
Classic frames keep using
< frame >/< send >, also on CAN FD interfaces. So existing clients are not affected: they never receive more than 8 data bytes. Like any other unknown message, they can ignore< fdframe >. Carrying the flags explicitly lets clients request bit rate switching and see BRS/ESI of received frames. In contrast, #72 reuses< frame >/< send >with up to 64 bytes and cannot transport the flags.Commits
recvmsg()result: an error (-1) used to pass theret < sizeof(struct can_frame)check.CAN_RAW_FD_FRAMESif the interface MTU is >=CANFD_MTU(CAN FD and CAN XL capable interfaces). Classic interfaces are unchanged.Out of scope for this PR: BCM mode and
socketcandcl. Both can follow separately if the raw mode protocol is accepted.Testing
Ubuntu 24.04 (WSL2, kernel 6.18), built with gcc 13 and clang 18 using
-Dlibconfig=true -Dlibsocketcan=trueas in CI. No new warnings; the existing clang warnings instate_bcm.care unchanged.Functional tests with a scripted socketcand client and can-utils:
vcanwithmtu 72:< fdsend >checked withcandump: BRS/ESI flags, standard and extended identifiers, 64 bytes, zero padding 10 -> 12 bytes< send >still sends classic frames< fdsend >commands put nothing on the bus and do not stop the server: reserved flag bit, too few/too many data bytes, len > 64, identifier out of range, missing lencansendFD frames (with/without BRS, with ESI, 64 bytes) are relayed as< fdframe >; classic and empty frames as< frame >vcanwith default MTU (CAN XL, 2060): CAN FD is enabledvcanwithmtu 16:< fdsend >is rejected with "CAN FD is not supported by bus ...";< send >and< frame >work as beforeEnd-to-end ISO-TP over CAN FD:
CAN_ISOTPsocket on the same vcan (CAN FD link layer,tx_dl64, BRS)SF_DLescape), 367, 5003 (32-bitFF_DL) and 63/64 bytes; all byte-identicalDeclaration:
The program was tested solely for our own use cases, which might differ from yours.
Florian Roks <florian.roks@mercedes-benz.com>, Mercedes-Benz Tech Innovation GmbH
Provider Information
Licensed under GPL-2.0-only or BSD-3-Clause licenses (same as project)