@@ -48,6 +48,16 @@ modm::platform::SocketCan::open(std::string deviceName)
4848 return false ;
4949 }
5050
51+ /* Enable FDCAN support */
52+ int recv_can_fd = 1 ;
53+ if (setsockopt (skt, SOL_CAN_RAW, CAN_RAW_FD_FRAMES, &recv_can_fd, sizeof (recv_can_fd)) < 0 )
54+ {
55+ MODM_LOG_ERROR << MODM_FILE_INFO;
56+ MODM_LOG_ERROR << " Failed to enable FDCAN support: " << strerror (errno) << modm::endl;
57+ close ();
58+ return false ;
59+ }
60+
5161 /* Locate the interface you wish to use */
5262 struct ifreq ifr{};
5363 if (deviceName.empty () || deviceName.size () > IFNAMSIZ - 1 ) {
@@ -104,8 +114,8 @@ modm::platform::SocketCan::getBusState()
104114bool
105115modm::platform::SocketCan::isMessageAvailable ()
106116{
107- struct can_frame frame;
108- int nbytes = recv (skt, &frame, sizeof (struct can_frame ), MSG_DONTWAIT | MSG_PEEK);
117+ struct canfd_frame frame;
118+ int nbytes = recv (skt, &frame, sizeof (struct canfd_frame ), MSG_DONTWAIT | MSG_PEEK);
109119
110120 // recv returns 'Resource temporary not available' which is wired but ignored here.
111121 /* if (nbytes < 0)
@@ -120,11 +130,17 @@ modm::platform::SocketCan::isMessageAvailable()
120130bool
121131modm::platform::SocketCan::getMessage (can::Message& message)
122132{
123- struct can_frame frame;
124- int nbytes = recv (skt, &frame, sizeof (struct can_frame ), MSG_DONTWAIT);
133+ struct canfd_frame frame;
134+ int nbytes = recv (skt, &frame, sizeof (frame ), MSG_DONTWAIT);
125135
126136 if (nbytes > 0 )
127137 {
138+ if (frame.len > modm::can::Message::capacity)
139+ {
140+ MODM_LOG_ERROR << MODM_FILE_INFO;
141+ MODM_LOG_ERROR << " Received can frame too big for configured buffer." << modm::endl;
142+ return false ;
143+ }
128144 message.identifier = frame.can_id ;
129145 message.setLength (frame.len );
130146 message.setExtended (frame.can_id & CAN_EFF_FLAG);
@@ -140,8 +156,9 @@ modm::platform::SocketCan::getMessage(can::Message& message)
140156bool
141157modm::platform::SocketCan::sendMessage (const can::Message& message)
142158{
143- struct can_frame frame;
159+ struct canfd_frame frame;
144160
161+ frame.flags = 0 ;
145162 frame.can_id = message.identifier ;
146163 if (message.isExtended ()) {
147164 frame.can_id |= CAN_EFF_FLAG;
@@ -156,7 +173,11 @@ modm::platform::SocketCan::sendMessage(const can::Message& message)
156173 frame.data [ii] = message.data [ii];
157174 }
158175
159- int bytes_sent = write ( skt, &frame, sizeof (frame) );
176+ // Send can_frame when length < 8, since other applications may not accept
177+ // canfd_frame. Both structs intentionally share the same layout
178+ // for this purpose
179+ int size = message.getLength () > 8 ? sizeof (canfd_frame) : sizeof (can_frame);
180+ int bytes_sent = write (skt, &frame, size);
160181
161182 return (bytes_sent > 0 );
162183}
0 commit comments