2525#include <linux/can/error.h>
2626#include <linux/sockios.h>
2727
28- #define RXLEN 128
28+ #define RXLEN 256
2929
3030int sc = -1 ;
3131
@@ -40,7 +40,7 @@ void state_bcm() {
4040
4141 struct {
4242 struct bcm_msg_head msg_head ;
43- struct can_frame frame ;
43+ struct canfd_frame frame ;
4444 } msg ;
4545
4646 struct {
@@ -56,7 +56,7 @@ void state_bcm() {
5656 return ;
5757 }
5858
59- memset (& caddr , 0 , sizeof (caddr ));
59+ memset (& caddr , 0 , sizeof (caddr ));
6060 caddr .can_family = PF_CAN ;
6161 /* can_ifindex is set to 0 (any device) => need for sendto() */
6262
@@ -102,12 +102,12 @@ void state_bcm() {
102102
103103 /* Check if this is an error frame */
104104 if (msg .msg_head .can_id & CAN_ERR_FLAG ) {
105- if (msg .frame .can_dlc != CAN_ERR_DLC ) {
105+ if (msg .frame .len != CAN_ERR_DLC ) {
106106 PRINT_ERROR ("Error frame has a wrong DLC!\n" )
107107 } else {
108108 snprintf (rxmsg , RXLEN , "< error %03X %ld.%06ld " , msg .msg_head .can_id , tv .tv_sec , tv .tv_usec );
109109
110- for ( i = 0 ; i < msg .frame .can_dlc ; i ++ )
110+ for ( i = 0 ; i < msg .frame .len ; i ++ )
111111 snprintf (rxmsg + strlen (rxmsg ), RXLEN - strlen (rxmsg ), "%02X " ,
112112 msg .frame .data [i ]);
113113
@@ -116,15 +116,34 @@ void state_bcm() {
116116 tcp_quickack (client_socket );
117117 }
118118 } else {
119- if (msg .msg_head .can_id & CAN_EFF_FLAG ) {
120- snprintf (rxmsg , RXLEN , "< frame %08X %ld.%06ld " ,
121- msg .msg_head .can_id & CAN_EFF_MASK , tv .tv_sec , tv .tv_usec );
122- } else {
123- snprintf (rxmsg , RXLEN , "< frame %03X %ld.%06ld " ,
124- msg .msg_head .can_id & CAN_SFF_MASK , tv .tv_sec , tv .tv_usec );
119+ // fprintf(stderr, "msg.msg_head.can_id: %d ret size: %d\n", msg.msg_head.can_id, ret);
120+ switch (ret ) {
121+ // if the frame is a classic CAN frame
122+ case sizeof (struct can_frame ):
123+ if (msg .msg_head .can_id & CAN_EFF_FLAG ) {
124+ snprintf (rxmsg , RXLEN , "< frame %08X %ld.%06ld " ,
125+ msg .msg_head .can_id & CAN_EFF_MASK , tv .tv_sec , tv .tv_usec );
126+ } else {
127+ snprintf (rxmsg , RXLEN , "< frame %03X %ld.%06ld " ,
128+ msg .msg_head .can_id & CAN_SFF_MASK , tv .tv_sec , tv .tv_usec );
129+ }
130+ break ;
131+ // if the frame is a CAN FD frame
132+ case sizeof (struct canfd_frame ):
133+ if (msg .msg_head .can_id & CAN_EFF_FLAG ) {
134+ snprintf (rxmsg , RXLEN , "< fdframe %08X %02X %ld.%06ld " ,
135+ msg .msg_head .can_id & CAN_EFF_MASK , msg .msg_head .flags , tv .tv_sec , tv .tv_usec );
136+ } else {
137+ snprintf (rxmsg , RXLEN , "< fdframe %03X %02X %ld.%06ld " ,
138+ msg .msg_head .can_id & CAN_SFF_MASK , msg .msg_head .flags , tv .tv_sec , tv .tv_usec );
139+ }
140+ break ;
141+ default :
142+ PRINT_ERROR ("Unknown frame size %d\n" , ret );
143+ return ;
125144 }
126145
127- for ( i = 0 ; i < msg .frame .can_dlc ; i ++ )
146+ for ( i = 0 ; i < msg .frame .len ; i ++ )
128147 snprintf (rxmsg + strlen (rxmsg ), RXLEN - strlen (rxmsg ), "%02X " ,
129148 msg .frame .data [i ]);
130149
@@ -139,6 +158,8 @@ void state_bcm() {
139158
140159 ret = receive_command (client_socket , buf );
141160
161+ fprintf (stderr , "buf: %s\n" , buf );
162+
142163 if (ret != 0 ) {
143164 state = STATE_SHUTDOWN ;
144165 return ;
@@ -170,7 +191,7 @@ void state_bcm() {
170191 "%hhx %hhx %hhx %hhx %hhx %hhx "
171192 "%hhx %hhx >" ,
172193 & msg .msg_head .can_id ,
173- & msg .frame .can_dlc ,
194+ & msg .frame .len ,
174195 & msg .frame .data [0 ],
175196 & msg .frame .data [1 ],
176197 & msg .frame .data [2 ],
@@ -181,8 +202,8 @@ void state_bcm() {
181202 & msg .frame .data [7 ]);
182203
183204 if ( (items < 2 ) ||
184- (msg .frame .can_dlc > 8 ) ||
185- (items != 2 + msg .frame .can_dlc )) {
205+ (msg .frame .len > 8 ) ||
206+ (items != 2 + msg .frame .len )) {
186207 PRINT_ERROR ("Syntax error in send command\n" )
187208 return ;
188209 }
@@ -200,14 +221,81 @@ void state_bcm() {
200221 (struct sockaddr * )& caddr , sizeof (caddr ));
201222 }
202223 /* Add a send job */
224+ } else if (!strncmp ("< fdsend " , buf , 9 )) {
225+ // First, read the fixed part of the frame
226+ items = sscanf (buf , "< %*s %x %hhx %hhu" ,
227+ & msg .msg_head .can_id ,
228+ & msg .frame .flags ,
229+ & msg .frame .len );
230+
231+ if (items != 3 ) {
232+ PRINT_ERROR ("Syntax error in fdsend command\n" );
233+ return ;
234+ }
235+
236+ // Ensure frame.len does not exceed the maximum allowed length
237+ if (msg .frame .len > 64 ) {
238+ PRINT_ERROR ("Frame length exceeds maximum allowed length\n" );
239+ return ;
240+ }
241+
242+ // Construct the format string for the dynamically based on frame.len
243+ char format [256 ];
244+ snprintf (format , sizeof (format ), "< %%*s %%x %%hhx %%hhu" );
245+ for (int i = 0 ; i < msg .frame .len ; i ++ ) {
246+ strncat (format , " %hhx" , sizeof (format ) - strlen (format ) - 1 );
247+ }
248+ strncat (format , " >" , sizeof (format ) - strlen (format ) - 1 );
249+
250+ // Read the variable-length frame.data
251+ items = sscanf (buf , format ,
252+ & msg .msg_head .can_id ,
253+ & msg .frame .flags ,
254+ & msg .frame .len ,
255+ & msg .frame .data [0 ], & msg .frame .data [1 ], & msg .frame .data [2 ], & msg .frame .data [3 ],
256+ & msg .frame .data [4 ], & msg .frame .data [5 ], & msg .frame .data [6 ], & msg .frame .data [7 ],
257+ & msg .frame .data [8 ], & msg .frame .data [9 ], & msg .frame .data [10 ], & msg .frame .data [11 ],
258+ & msg .frame .data [12 ], & msg .frame .data [13 ], & msg .frame .data [14 ], & msg .frame .data [15 ],
259+ & msg .frame .data [16 ], & msg .frame .data [17 ], & msg .frame .data [18 ], & msg .frame .data [19 ],
260+ & msg .frame .data [20 ], & msg .frame .data [21 ], & msg .frame .data [22 ], & msg .frame .data [23 ],
261+ & msg .frame .data [24 ], & msg .frame .data [25 ], & msg .frame .data [26 ], & msg .frame .data [27 ],
262+ & msg .frame .data [28 ], & msg .frame .data [29 ], & msg .frame .data [30 ], & msg .frame .data [31 ],
263+ & msg .frame .data [32 ], & msg .frame .data [33 ], & msg .frame .data [34 ], & msg .frame .data [35 ],
264+ & msg .frame .data [36 ], & msg .frame .data [37 ], & msg .frame .data [38 ], & msg .frame .data [39 ],
265+ & msg .frame .data [40 ], & msg .frame .data [41 ], & msg .frame .data [42 ], & msg .frame .data [43 ],
266+ & msg .frame .data [44 ], & msg .frame .data [45 ], & msg .frame .data [46 ], & msg .frame .data [47 ],
267+ & msg .frame .data [48 ], & msg .frame .data [49 ], & msg .frame .data [50 ], & msg .frame .data [51 ],
268+ & msg .frame .data [52 ], & msg .frame .data [53 ], & msg .frame .data [54 ], & msg .frame .data [55 ],
269+ & msg .frame .data [56 ], & msg .frame .data [57 ], & msg .frame .data [58 ], & msg .frame .data [59 ],
270+ & msg .frame .data [60 ], & msg .frame .data [61 ], & msg .frame .data [62 ], & msg .frame .data [63 ]);
271+
272+ if ( (items < 2 ) ||
273+ (msg .frame .len > 64 ) ||
274+ (items != 3 + msg .frame .len )) {
275+ PRINT_ERROR ("Syntax error in fdsend command\n" )
276+ return ;
277+ }
278+
279+ /* < fdsend XXXXXXXX ... > check for extended identifier */
280+ if (element_length (buf , 2 ) == 8 )
281+ msg .msg_head .can_id |= CAN_EFF_FLAG ;
282+
283+ msg .msg_head .opcode = TX_SEND ;
284+ msg .frame .can_id = msg .msg_head .can_id ;
285+
286+ if (!ioctl (sc , SIOCGIFINDEX , & ifr )) {
287+ caddr .can_ifindex = ifr .ifr_ifindex ;
288+ sendto (sc , & msg , sizeof (msg ), 0 , (struct sockaddr * )& caddr , sizeof (caddr ));
289+ }
203290 } else if (!strncmp ("< add " , buf , 6 )) {
291+ fprintf (stderr , "%s\n" , buf );
204292 items = sscanf (buf , "< %*s %lu %lu %x %hhu "
205293 "%hhx %hhx %hhx %hhx %hhx %hhx "
206294 "%hhx %hhx >" ,
207295 & msg .msg_head .ival2 .tv_sec ,
208296 & msg .msg_head .ival2 .tv_usec ,
209297 & msg .msg_head .can_id ,
210- & msg .frame .can_dlc ,
298+ & msg .frame .len ,
211299 & msg .frame .data [0 ],
212300 & msg .frame .data [1 ],
213301 & msg .frame .data [2 ],
@@ -218,8 +306,8 @@ void state_bcm() {
218306 & msg .frame .data [7 ]);
219307
220308 if ( (items < 4 ) ||
221- (msg .frame .can_dlc > 8 ) ||
222- (items != 4 + msg .frame .can_dlc ) ) {
309+ (msg .frame .len > 8 ) ||
310+ (items != 4 + msg .frame .len ) ) {
223311 PRINT_ERROR ("Syntax error in add command.\n" );
224312 return ;
225313 }
@@ -243,7 +331,7 @@ void state_bcm() {
243331 "%hhx %hhx %hhx %hhx %hhx %hhx "
244332 "%hhx %hhx >" ,
245333 & msg .msg_head .can_id ,
246- & msg .frame .can_dlc ,
334+ & msg .frame .len ,
247335 & msg .frame .data [0 ],
248336 & msg .frame .data [1 ],
249337 & msg .frame .data [2 ],
@@ -254,8 +342,8 @@ void state_bcm() {
254342 & msg .frame .data [7 ]);
255343
256344 if ( (items < 2 ) ||
257- (msg .frame .can_dlc > 8 ) ||
258- (items != 2 + msg .frame .can_dlc )) {
345+ (msg .frame .len > 8 ) ||
346+ (items != 2 + msg .frame .len )) {
259347 PRINT_ERROR ("Syntax error in update send job command\n" )
260348 return ;
261349 }
@@ -303,7 +391,7 @@ void state_bcm() {
303391 & msg .msg_head .ival2 .tv_sec ,
304392 & msg .msg_head .ival2 .tv_usec ,
305393 & msg .msg_head .can_id ,
306- & msg .frame .can_dlc ,
394+ & msg .frame .len ,
307395 & msg .frame .data [0 ],
308396 & msg .frame .data [1 ],
309397 & msg .frame .data [2 ],
@@ -314,8 +402,8 @@ void state_bcm() {
314402 & msg .frame .data [7 ]);
315403
316404 if ( (items < 4 ) ||
317- (msg .frame .can_dlc > 8 ) ||
318- (items != 4 + msg .frame .can_dlc ) ) {
405+ (msg .frame .len > 8 ) ||
406+ (items != 4 + msg .frame .len ) ) {
319407 PRINT_ERROR ("syntax error in filter command.\n" )
320408 return ;
321409 }
0 commit comments