Skip to content

Commit b5eeb45

Browse files
committed
Auto merge of #2006 - djarek:linux-can.h, r=JohnTitor
Define basic Linux SocketCAN constants and types Add definitions from `linux/can.h`, which is a "base" header for remainder of SocketCAN functionality. CAN bus (ISO-11898) is a communication standard used in automotive, automation and industrial solutions. Linux provides a socket-like interface to access raw CAN and protocols based on CAN, such as ISO-TP(ISO-15765) or SAE-J1939.
2 parents 473a6b5 + e18dc03 commit b5eeb45

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

libc-test/build.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2442,6 +2442,7 @@ fn test_linux(target: &str) {
24422442
headers! {
24432443
cfg:
24442444
"asm/mman.h",
2445+
"linux/can.h",
24452446
"linux/dccp.h",
24462447
"linux/errqueue.h",
24472448
"linux/falloc.h",
@@ -2556,6 +2557,9 @@ fn test_linux(target: &str) {
25562557
});
25572558

25582559
cfg.skip_struct(move |ty| {
2560+
if ty.starts_with("__c_anonymous_") {
2561+
return true;
2562+
}
25592563
match ty {
25602564
// These cannot be tested when "resolv.h" is included and are tested
25612565
// in the `linux_elf.rs` file.
@@ -2591,6 +2595,9 @@ fn test_linux(target: &str) {
25912595
// which is absent in musl, has to be defined.
25922596
"__exit_status" if musl => true,
25932597

2598+
// FIXME: CI's kernel header version is old.
2599+
"sockaddr_can" => true,
2600+
25942601
_ => false,
25952602
}
25962603
});
@@ -2697,6 +2704,11 @@ fn test_linux(target: &str) {
26972704
| "IFLA_PERM_ADDRESS"
26982705
| "IFLA_PROTO_DOWN_REASON" => true,
26992706

2707+
// FIXME: They require recent kernel header:
2708+
| "CAN_J1939"
2709+
| "CAN_RAW_FILTER_MAX"
2710+
| "CAN_NPROTO" => true,
2711+
27002712
_ => false,
27012713
}
27022714
});
@@ -2757,7 +2769,9 @@ fn test_linux(target: &str) {
27572769
// this one is an anonymous union
27582770
(struct_ == "ff_effect" && field == "u") ||
27592771
// `__exit_status` type is a patch which is absent in musl
2760-
(struct_ == "utmpx" && field == "ut_exit" && musl)
2772+
(struct_ == "utmpx" && field == "ut_exit" && musl) ||
2773+
// `can_addr` is an anonymous union
2774+
(struct_ == "sockaddr_can" && field == "can_addr")
27612775
});
27622776

27632777
cfg.volatile_item(|i| {

src/unix/linux_like/linux/align.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,27 @@ macro_rules! expand_align {
5252
pub fd: ::c_int,
5353
pub pid: ::c_int,
5454
}
55+
56+
// linux/can.h
57+
#[repr(align(8))]
58+
pub struct can_frame {
59+
pub can_id: canid_t,
60+
pub can_dlc: u8,
61+
__pad: u8,
62+
__res0: u8,
63+
__res1: u8,
64+
pub data: [u8; CAN_MAX_DLEN],
65+
}
66+
67+
#[repr(align(8))]
68+
pub struct canfd_frame {
69+
pub can_id: canid_t,
70+
pub len: u8,
71+
pub flags: u8,
72+
__res0: u8,
73+
__res1: u8,
74+
pub data: [u8; CANFD_MAX_DLEN],
75+
}
5576
}
5677

5778
s_no_extra_traits! {

src/unix/linux_like/linux/mod.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ pub type Elf64_Sxword = i64;
3636
pub type Elf32_Section = u16;
3737
pub type Elf64_Section = u16;
3838

39+
// linux/can.h
40+
pub type canid_t = u32;
41+
pub type can_err_mask_t = u32;
42+
3943
#[cfg_attr(feature = "extra_traits", derive(Debug))]
4044
pub enum fpos64_t {} // FIXME: fill this out with a struct
4145
impl ::Copy for fpos64_t {}
@@ -504,6 +508,23 @@ s! {
504508
pub ee_info: u32,
505509
pub ee_data: u32,
506510
}
511+
512+
// linux/can.h
513+
pub struct __c_anonymous_sockaddr_can_tp {
514+
pub rx_id: canid_t,
515+
pub tx_id: canid_t,
516+
}
517+
518+
pub struct __c_anonymous_sockaddr_can_j1939 {
519+
pub name: u64,
520+
pub pgn: u32,
521+
pub addr: u8,
522+
}
523+
524+
pub struct can_filter {
525+
pub can_id: canid_t,
526+
pub can_mask: canid_t,
527+
}
507528
}
508529

509530
s_no_extra_traits! {
@@ -577,6 +598,26 @@ s_no_extra_traits! {
577598
}
578599
}
579600

601+
cfg_if! {
602+
if #[cfg(libc_union)] {
603+
s_no_extra_traits! {
604+
// linux/can.h
605+
#[allow(missing_debug_implementations)]
606+
pub union __c_anonymous_sockaddr_can_can_addr {
607+
pub tp: __c_anonymous_sockaddr_can_tp,
608+
pub j1939: __c_anonymous_sockaddr_can_j1939,
609+
}
610+
611+
#[allow(missing_debug_implementations)]
612+
pub struct sockaddr_can {
613+
pub can_family: ::sa_family_t,
614+
pub can_ifindex: ::c_int,
615+
pub can_addr: __c_anonymous_sockaddr_can_can_addr,
616+
}
617+
}
618+
}
619+
}
620+
580621
cfg_if! {
581622
if #[cfg(feature = "extra_traits")] {
582623
impl PartialEq for sockaddr_nl {
@@ -2584,6 +2625,46 @@ pub const EDOM: ::c_int = 33;
25842625
pub const ERANGE: ::c_int = 34;
25852626
pub const EWOULDBLOCK: ::c_int = EAGAIN;
25862627

2628+
// linux/can.h
2629+
pub const CAN_EFF_FLAG: canid_t = 0x80000000;
2630+
pub const CAN_RTR_FLAG: canid_t = 0x40000000;
2631+
pub const CAN_ERR_FLAG: canid_t = 0x20000000;
2632+
pub const CAN_SFF_MASK: canid_t = 0x000007FF;
2633+
pub const CAN_EFF_MASK: canid_t = 0x1FFFFFFF;
2634+
pub const CAN_ERR_MASK: canid_t = 0x1FFFFFFF;
2635+
2636+
pub const CAN_SFF_ID_BITS: ::c_int = 11;
2637+
pub const CAN_EFF_ID_BITS: ::c_int = 29;
2638+
2639+
pub const CAN_MAX_DLC: ::c_int = 8;
2640+
pub const CAN_MAX_DLEN: usize = 8;
2641+
pub const CANFD_MAX_DLC: ::c_int = 15;
2642+
pub const CANFD_MAX_DLEN: usize = 64;
2643+
2644+
pub const CANFD_BRS: ::c_int = 0x01;
2645+
pub const CANFD_ESI: ::c_int = 0x02;
2646+
2647+
cfg_if! {
2648+
if #[cfg(libc_const_size_of)] {
2649+
pub const CAN_MTU: usize = ::mem::size_of::<can_frame>();
2650+
pub const CANFD_MTU: usize = ::mem::size_of::<canfd_frame>();
2651+
}
2652+
}
2653+
2654+
pub const CAN_RAW: ::c_int = 1;
2655+
pub const CAN_BCM: ::c_int = 2;
2656+
pub const CAN_TP16: ::c_int = 3;
2657+
pub const CAN_TP20: ::c_int = 4;
2658+
pub const CAN_MCNET: ::c_int = 5;
2659+
pub const CAN_ISOTP: ::c_int = 6;
2660+
pub const CAN_J1939: ::c_int = 7;
2661+
pub const CAN_NPROTO: ::c_int = 8;
2662+
2663+
pub const SOL_CAN_BASE: ::c_int = 100;
2664+
2665+
pub const CAN_INV_FILTER: canid_t = 0x20000000;
2666+
pub const CAN_RAW_FILTER_MAX: ::c_int = 512;
2667+
25872668
f! {
25882669
pub fn NLA_ALIGN(len: ::c_int) -> ::c_int {
25892670
return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)

0 commit comments

Comments
 (0)