@@ -135,6 +135,14 @@ bitflags! {
135
135
const CAN_ISOTP_FORCE_RXSTMIN = 0x100 ;
136
136
/// different rx extended addressing
137
137
const CAN_ISOTP_RX_EXT_ADDR = 0x200 ;
138
+ /// wait for tx completion
139
+ const CAN_ISOTP_WAIT_TX_DONE = 0x0400 ;
140
+ /// 1-to-N functional addressing
141
+ const CAN_ISOTP_SF_BROADCAST = 0x0800 ;
142
+ /// 1-to-N transmission w/o FC
143
+ const CAN_ISOTP_CF_BROADCAST = 0x1000 ;
144
+ /// dynamic FC parameters BS/STmin
145
+ const CAN_ISOTP_DYN_FC_PARMS = 0x2000 ;
138
146
}
139
147
}
140
148
@@ -220,7 +228,12 @@ impl IsoTpOptions {
220
228
IsoTpBehaviour :: from_bits ( self . flags )
221
229
}
222
230
223
- /// set flags for isotp behaviour.
231
+ /// add the given ISO-TP behavior flags to the current flags
232
+ pub fn add_flags ( & mut self , flags : IsoTpBehaviour ) {
233
+ self . flags |= flags. bits ( ) ;
234
+ }
235
+
236
+ /// replace the current ISO-TP behavior flags with the given flags
224
237
pub fn set_flags ( & mut self , flags : IsoTpBehaviour ) {
225
238
self . flags = flags. bits ( ) ;
226
239
}
@@ -412,6 +425,13 @@ pub struct IsoTpSocket {
412
425
}
413
426
414
427
impl IsoTpSocket {
428
+ fn new ( fd : i32 ) -> Self {
429
+ Self {
430
+ fd,
431
+ recv_buffer : [ 0x00 ; RECV_BUFFER_SIZE ] ,
432
+ }
433
+ }
434
+
415
435
/// Open a named CAN ISO-TP device.
416
436
///
417
437
/// Usually the more common case, opens a socket can device by name, such
@@ -479,24 +499,28 @@ impl IsoTpSocket {
479
499
rx_flow_control_options : Option < FlowControlOptions > ,
480
500
link_layer_options : Option < LinkLayerOptions > ,
481
501
) -> Result < Self , Error > {
482
- let rx_id = match rx_id. into ( ) {
483
- Id :: Standard ( standard_id) => standard_id. as_raw ( ) as u32 ,
484
- Id :: Extended ( extended_id) => extended_id. as_raw ( ) | EFF_FLAG ,
485
- } ;
486
- let tx_id = match tx_id. into ( ) {
487
- Id :: Standard ( standard_id) => standard_id. as_raw ( ) as u32 ,
488
- Id :: Extended ( extended_id) => extended_id. as_raw ( ) | EFF_FLAG ,
489
- } ;
490
502
let addr = CanAddr {
491
503
_af_can : AF_CAN ,
492
504
if_index,
493
- rx_id,
494
- tx_id,
505
+ rx_id : Self :: to_raw_can_id ( rx_id ) ,
506
+ tx_id : Self :: to_raw_can_id ( tx_id ) ,
495
507
_pgn : 0 ,
496
508
_addr : 0 ,
497
509
} ;
498
510
499
- // open socket
511
+ let sock_fd = Self :: open_socket ( ) ?;
512
+ Self :: set_socket_opts (
513
+ sock_fd,
514
+ isotp_options,
515
+ rx_flow_control_options,
516
+ link_layer_options,
517
+ ) ?;
518
+ Self :: bind_addr ( sock_fd, addr) ?;
519
+
520
+ Ok ( Self :: new ( sock_fd) )
521
+ }
522
+
523
+ fn open_socket ( ) -> Result < i32 , Error > {
500
524
let sock_fd;
501
525
unsafe {
502
526
sock_fd = socket ( PF_CAN , SOCK_DGRAM , CAN_ISOTP ) ;
@@ -505,7 +529,37 @@ impl IsoTpSocket {
505
529
if sock_fd == -1 {
506
530
return Err ( Error :: from ( io:: Error :: last_os_error ( ) ) ) ;
507
531
}
532
+ Ok ( sock_fd)
533
+ }
534
+
535
+ fn bind_addr ( sock_fd : i32 , addr : CanAddr ) -> Result < ( ) , Error > {
536
+ let sockaddr_ptr = & addr as * const CanAddr ;
508
537
538
+ let bind_rv = unsafe {
539
+ bind (
540
+ sock_fd,
541
+ sockaddr_ptr as * const sockaddr ,
542
+ size_of :: < CanAddr > ( ) . try_into ( ) . unwrap ( ) ,
543
+ )
544
+ } ;
545
+
546
+ // FIXME: on fail, close socket (do not leak socketfds)
547
+ if bind_rv == -1 {
548
+ let e = io:: Error :: last_os_error ( ) ;
549
+ unsafe {
550
+ close ( sock_fd) ;
551
+ }
552
+ return Err ( Error :: from ( e) ) ;
553
+ }
554
+ Ok ( ( ) )
555
+ }
556
+
557
+ fn set_socket_opts (
558
+ sock_fd : i32 ,
559
+ isotp_options : Option < IsoTpOptions > ,
560
+ rx_flow_control_options : Option < FlowControlOptions > ,
561
+ link_layer_options : Option < LinkLayerOptions > ,
562
+ ) -> Result < ( ) , Error > {
509
563
// Set IsoTpOptions
510
564
if let Some ( isotp_options) = isotp_options {
511
565
let isotp_options_ptr: * const c_void = & isotp_options as * const _ as * const c_void ;
@@ -558,31 +612,14 @@ impl IsoTpSocket {
558
612
return Err ( Error :: from ( io:: Error :: last_os_error ( ) ) ) ;
559
613
}
560
614
}
615
+ Ok ( ( ) )
616
+ }
561
617
562
- // bind it
563
- let bind_rv;
564
- unsafe {
565
- let sockaddr_ptr = & addr as * const CanAddr ;
566
- bind_rv = bind (
567
- sock_fd,
568
- sockaddr_ptr as * const sockaddr ,
569
- size_of :: < CanAddr > ( ) . try_into ( ) . unwrap ( ) ,
570
- ) ;
571
- }
572
-
573
- // FIXME: on fail, close socket (do not leak socketfds)
574
- if bind_rv == -1 {
575
- let e = io:: Error :: last_os_error ( ) ;
576
- unsafe {
577
- close ( sock_fd) ;
578
- }
579
- return Err ( Error :: from ( e) ) ;
618
+ fn to_raw_can_id ( id : impl Into < Id > ) -> u32 {
619
+ match id. into ( ) {
620
+ Id :: Standard ( standard_id) => standard_id. as_raw ( ) as u32 ,
621
+ Id :: Extended ( extended_id) => extended_id. as_raw ( ) | EFF_FLAG ,
580
622
}
581
-
582
- Ok ( Self {
583
- fd : sock_fd,
584
- recv_buffer : [ 0x00 ; RECV_BUFFER_SIZE ] ,
585
- } )
586
623
}
587
624
588
625
fn close ( & mut self ) -> io:: Result < ( ) > {
0 commit comments