Skip to content

Commit

Permalink
Auto merge of #2006 - djarek:linux-can.h, r=JohnTitor
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Jan 5, 2021
2 parents 7e7452f + 5449cae commit f8fb8cd
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 1 deletion.
8 changes: 7 additions & 1 deletion libc-test/build.rs
Expand Up @@ -2439,6 +2439,7 @@ fn test_linux(target: &str) {
headers! {
cfg:
"asm/mman.h",
"linux/can.h",
"linux/dccp.h",
"linux/errqueue.h",
"linux/falloc.h",
Expand Down Expand Up @@ -2553,6 +2554,9 @@ fn test_linux(target: &str) {
});

cfg.skip_struct(move |ty| {
if ty.starts_with("__c_anonymous_") {
return true;
}
match ty {
// These cannot be tested when "resolv.h" is included and are tested
// in the `linux_elf.rs` file.
Expand Down Expand Up @@ -2732,7 +2736,9 @@ fn test_linux(target: &str) {
// this one is an anonymous union
(struct_ == "ff_effect" && field == "u") ||
// `__exit_status` type is a patch which is absent in musl
(struct_ == "utmpx" && field == "ut_exit" && musl)
(struct_ == "utmpx" && field == "ut_exit" && musl) ||
// `can_addr` is an anonymous union
(struct_ == "sockaddr_can" && field == "can_addr")
});

cfg.volatile_item(|i| {
Expand Down
21 changes: 21 additions & 0 deletions src/unix/linux_like/linux/align.rs
Expand Up @@ -52,6 +52,27 @@ macro_rules! expand_align {
pub fd: ::c_int,
pub pid: ::c_int,
}

// linux/can.h
#[repr(align(8))]
pub struct can_frame {
pub can_id: canid_t,
pub can_dlc: u8,
__pad: u8,
__res0: u8,
__res1: u8,
pub data: [u8; CAN_MAX_DLEN],
}

#[repr(align(8))]
pub struct canfd_frame {
pub can_id: canid_t,
pub len: u8,
pub flags: u8,
__res0: u8,
__res1: u8,
pub data: [u8; CANFD_MAX_DLEN],
}
}

s_no_extra_traits! {
Expand Down
81 changes: 81 additions & 0 deletions src/unix/linux_like/linux/mod.rs
Expand Up @@ -36,6 +36,10 @@ pub type Elf64_Sxword = i64;
pub type Elf32_Section = u16;
pub type Elf64_Section = u16;

// linux/can.h
pub type canid_t = u32;
pub type can_err_mask_t = u32;

#[cfg_attr(feature = "extra_traits", derive(Debug))]
pub enum fpos64_t {} // FIXME: fill this out with a struct
impl ::Copy for fpos64_t {}
Expand Down Expand Up @@ -504,6 +508,23 @@ s! {
pub ee_info: u32,
pub ee_data: u32,
}

// linux/can.h
pub struct __c_anonymous_sockaddr_can_tp {
pub rx_id: canid_t,
pub tx_id: canid_t,
}

pub struct __c_anonymous_sockaddr_can_j1939 {
pub name: u64,
pub pgn: u32,
pub addr: u8,
}

pub struct can_filter {
pub can_id: canid_t,
pub can_mask: canid_t,
}
}

s_no_extra_traits! {
Expand Down Expand Up @@ -577,6 +598,26 @@ s_no_extra_traits! {
}
}

cfg_if! {
if #[cfg(libc_union)] {
s_no_extra_traits! {
// linux/can.h
#[allow(missing_debug_implementations)]
pub union __c_anonymous_sockaddr_can_can_addr {
pub tp: __c_anonymous_sockaddr_can_tp,
pub j1939: __c_anonymous_sockaddr_can_j1939,
}

#[allow(missing_debug_implementations)]
pub struct sockaddr_can {
pub can_family: ::sa_family_t,
pub can_ifindex: ::c_int,
pub can_addr: __c_anonymous_sockaddr_can_can_addr,
}
}
}
}

cfg_if! {
if #[cfg(feature = "extra_traits")] {
impl PartialEq for sockaddr_nl {
Expand Down Expand Up @@ -2567,6 +2608,46 @@ pub const EDOM: ::c_int = 33;
pub const ERANGE: ::c_int = 34;
pub const EWOULDBLOCK: ::c_int = EAGAIN;

// linux/can.h
pub const CAN_EFF_FLAG: canid_t = 0x80000000;
pub const CAN_RTR_FLAG: canid_t = 0x40000000;
pub const CAN_ERR_FLAG: canid_t = 0x20000000;
pub const CAN_SFF_MASK: canid_t = 0x000007FF;
pub const CAN_EFF_MASK: canid_t = 0x1FFFFFFF;
pub const CAN_ERR_MASK: canid_t = 0x1FFFFFFF;

pub const CAN_SFF_ID_BITS: ::c_int = 11;
pub const CAN_EFF_ID_BITS: ::c_int = 29;

pub const CAN_MAX_DLC: ::c_int = 8;
pub const CAN_MAX_DLEN: usize = 8;
pub const CANFD_MAX_DLC: ::c_int = 15;
pub const CANFD_MAX_DLEN: usize = 64;

pub const CANFD_BRS: ::c_int = 0x01;
pub const CANFD_ESI: ::c_int = 0x02;

cfg_if! {
if #[cfg(libc_const_size_of)] {
pub const CAN_MTU: usize = ::mem::size_of::<can_frame>();
pub const CANFD_MTU: usize = ::mem::size_of::<canfd_frame>();
}
}

pub const CAN_RAW: ::c_int = 1;
pub const CAN_BCM: ::c_int = 2;
pub const CAN_TP16: ::c_int = 3;
pub const CAN_TP20: ::c_int = 4;
pub const CAN_MCNET: ::c_int = 5;
pub const CAN_ISOTP: ::c_int = 6;
pub const CAN_J1939: ::c_int = 7;
pub const CAN_NPROTO: ::c_int = 8;

pub const SOL_CAN_BASE: ::c_int = 100;

pub const CAN_INV_FILTER: canid_t = 0x20000000;
pub const CAN_RAW_FILTER_MAX: ::c_int = 512;

f! {
pub fn NLA_ALIGN(len: ::c_int) -> ::c_int {
return ((len) + NLA_ALIGNTO - 1) & !(NLA_ALIGNTO - 1)
Expand Down

0 comments on commit f8fb8cd

Please sign in to comment.