pub fn iso11783_decompose(id: u32) -> (u8, u32, u8, u8) {
let prio = ((id >> 26) & 0x7) as u8;
let rdp = (id >> 24) & 0x3;
let pf = ((id >> 16) & 0xff) as u8;
let ps = ((id >> 8) & 0xff) as u8;
let src = (id & 0xff) as u8;
let (pgn, dst) = if pf < 240 {
((rdp << 16) | ((pf as u32) << 8), ps)
} else {
((rdp << 16) | ((pf as u32) << 8) | ps as u32, 0xff)
};
(prio, pgn, src, dst)
}
pub fn iso11783_compose(prio: u8, pgn: u32, src: u8, dst: u8) -> u32 {
let mut id = src as u32;
let pf = (pgn >> 8) & 0xff;
if pf < 240 {
id |= (dst as u32) << 8;
id |= pgn << 8;
} else {
id |= pgn << 8;
}
id |= (prio as u32) << 26;
id
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn compose_is_inverse_of_decompose() {
assert_eq!(
iso11783_decompose(iso11783_compose(3, 0x1f50b, 0x23, 0xff)),
(3, 0x1f50b, 0x23, 0xff)
);
assert_eq!(
iso11783_decompose(iso11783_compose(6, 0xee00, 0x05, 0xff)),
(6, 0xee00, 0x05, 0xff)
);
assert_eq!(
iso11783_decompose(iso11783_compose(2, 0xef00, 0x11, 0x22)),
(2, 0xef00, 0x11, 0x22)
);
}
#[test]
fn decompose_pdu2_known_canid() {
assert_eq!(iso11783_decompose(0x0DF50B23), (3, 0x1f50b, 0x23, 0xff));
}
}