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}