Skip to main content

can_hal/
filter.rs

1use crate::error::CanError;
2use crate::id::CanId;
3
4/// A hardware acceptance filter defined by an ID and a mask.
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Filter {
7    pub id: CanId,
8    pub mask: u32,
9}
10
11impl Filter {
12    /// Create a filter, masking off any bits above the ID's valid range.
13    ///
14    /// Standard IDs: mask is clamped to 11 bits (0x7FF).
15    /// Extended IDs: mask is clamped to 29 bits (0x1FFF_FFFF).
16    #[must_use]
17    pub const fn new(id: CanId, mask: u32) -> Self {
18        let max = match id {
19            CanId::Standard(_) => 0x7FF,
20            CanId::Extended(_) => 0x1FFF_FFFF,
21        };
22        Self {
23            id,
24            mask: mask & max,
25        }
26    }
27}
28
29/// Hardware acceptance filtering.
30///
31/// **Important**: The exact semantics of multiple filters depend on the backend.
32/// Some hardware (e.g. SocketCAN) supports multiple independent filters
33/// (union — a frame passes if it matches *any* filter). Other hardware
34/// (e.g. PCAN, Kvaser) only supports a single filter pair per frame type
35/// (standard / extended), so multiple filters must be merged into one, which
36/// may accept a broader range of IDs than intended.
37///
38/// For portable code that needs precise multi-ID filtering, consider using a
39/// single permissive hardware filter and applying software-level filtering on
40/// received frames.
41pub trait Filterable {
42    type Error: CanError;
43
44    /// Apply the given set of acceptance filters.
45    ///
46    /// Replaces any previously configured filters. An empty slice is equivalent
47    /// to calling [`clear_filters`](Self::clear_filters).
48    fn set_filters(&mut self, filters: &[Filter]) -> Result<(), Self::Error>;
49
50    /// Remove all acceptance filters (accept everything).
51    fn clear_filters(&mut self) -> Result<(), Self::Error>;
52}