Skip to content

Commit 1581af0

Browse files
djarekJohnTitor
authored andcommitted
Define basic Linux SocketCAN constants and types
Add definitions from `linux/can.h`, which is a "base" header for remainder of SocketCAN functionality. Signed-off-by: Damian Jarek <damian.jarek93@gmail.com>
1 parent 6deb8a9 commit 1581af0

File tree

3 files changed

+113
-1
lines changed

3 files changed

+113
-1
lines changed

libc-test/build.rs

Lines changed: 11 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.
@@ -2697,6 +2701,10 @@ fn test_linux(target: &str) {
26972701
| "IFLA_PERM_ADDRESS"
26982702
| "IFLA_PROTO_DOWN_REASON" => true,
26992703

2704+
// FIXME: J1939 requires kernel header version 5.4 or higher,
2705+
// the MIPS CI target has a lower version
2706+
"CAN_J1939" => true,
2707+
27002708
_ => false,
27012709
}
27022710
});
@@ -2757,7 +2765,9 @@ fn test_linux(target: &str) {
27572765
// this one is an anonymous union
27582766
(struct_ == "ff_effect" && field == "u") ||
27592767
// `__exit_status` type is a patch which is absent in musl
2760-
(struct_ == "utmpx" && field == "ut_exit" && musl)
2768+
(struct_ == "utmpx" && field == "ut_exit" && musl) ||
2769+
// `can_addr` is an anonymous union
2770+
(struct_ == "sockaddr_can" && field == "can_addr")
27612771
});
27622772

27632773
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)