j1939_async/
stack.rs

1#![deny(warnings)]
2
3use crate::can::ApiId;
4use crate::can::Id;
5use crate::error::*;
6const FILE_CODE: u8 = 0xFD;
7
8#[cfg(feature = "embassy")]
9use crate::os::*;
10
11type Error = crate::error::Error;
12
13pub struct Stack {
14    pub name_manager: crate::name::Manager,
15    suspended: bool,
16} // struct Stack
17
18impl Stack {
19    pub fn new() -> Stack {
20        Stack {
21            name_manager: crate::name::Manager::new(),
22            suspended: false,
23        }
24    }
25
26    pub fn suspend(&mut self) {
27        self.name_manager.disable();
28        self.suspended = true;
29    }
30
31    pub fn resume(&mut self) {
32        self.name_manager.enable();
33        self.suspended = false;
34    }
35
36    pub fn is_suspended(&self) -> bool {
37        self.suspended
38    }
39
40    pub fn register_local_name(
41        &mut self,
42        iface: &mut dyn crate::can::CanInterface,
43        address: u8,
44        name: &crate::name::Name,
45    ) -> Result<bool, Error> {
46        self.name_manager.register_local_name(iface, address, name)
47    }
48
49    pub fn on_can_frame(
50        &mut self,
51        iface: &mut dyn crate::can::CanInterface,
52        id: ApiId,
53        data: &crate::can::FrameData,
54    ) -> Result<bool, Error> {
55        match id.pgn() {
56            crate::pgn::ADDRESS_CLAIMED => self.name_manager.on_can_frame(iface, id, data),
57            crate::pgn::REQUEST => self.name_manager.on_can_frame(iface, id, data),
58            _ => Ok(false),
59        }
60    }
61
62    pub fn advance_time(
63        &mut self,
64        iface: &mut dyn crate::can::CanInterface,
65        time_delta_ms: usize,
66    ) -> Result<bool, Error> {
67        self.name_manager.advance_time(iface, time_delta_ms)
68    }
69
70    pub fn get_next_timeout_ms(&self) -> Option<u32> {
71        self.name_manager.get_next_timeout_ms()
72    }
73
74    pub fn send_to_address(
75        &mut self,
76        iface: &mut dyn crate::can::CanInterface,
77        src: &crate::name::Name,
78        dest: u8,
79        pgn: u32,
80        priority: u8,
81        data: &[u8],
82    ) -> Result<(), Error> {
83        let address = self.name_manager.resolve_local(&src)?;
84
85        let id = match crate::can::new_id(pgn, address, dest, priority) {
86            Some(id) => id,
87            None => {
88                return Err(mkerr(
89                    FILE_CODE,
90                    crate::error::ErrorCode::InvalidId,
91                    line!(),
92                ))
93            }
94        };
95
96        match iface.transmit(crate::can::Frame::from_slice(id.as_raw(), data)) {
97            Ok(_) => {}
98            Err(_) => {
99                return Err(mkerr(FILE_CODE, ErrorCode::NoSpace, line!()));
100            }
101        }
102
103        Ok(())
104    }
105
106    pub fn send_broadcast(
107        &mut self,
108        iface: &mut dyn crate::can::CanInterface,
109        src: &crate::name::Name,
110        pgn: u32,
111        priority: u8,
112        data: &[u8],
113    ) -> Result<(), Error> {
114        self.send_to_address(iface, src, 0xFF, pgn, priority, data)
115    }
116}
117
118#[cfg(feature = "embassy")]
119pub struct SharedStack {
120    stack: StackInMutex,
121}
122
123#[cfg(feature = "embassy")]
124impl SharedStack {
125    pub fn new() -> SharedStack {
126        SharedStack {
127            stack: StackInMutex::new(crate::stack::Stack::new()),
128        }
129    }
130
131    pub async fn suspend(&mut self) {
132        let mut guard = self.stack.lock().await;
133        guard.suspend();
134    }
135
136    pub async fn resume(&mut self) {
137        let mut guard = self.stack.lock().await;
138        guard.resume();
139    }
140
141    pub async fn is_suspended(&self) -> bool {
142        let guard = self.stack.lock().await;
143        guard.is_suspended()
144    }
145
146    pub async fn register_local_name(
147        &self,
148        iface: &mut dyn crate::can::CanInterface,
149        address: u8,
150        name: &crate::name::Name,
151    ) -> Result<bool, Error> {
152        let mut guard = self.stack.lock().await;
153        guard.register_local_name(iface, address, name)
154    }
155
156    pub async fn get_next_timeout_ms(&self) -> Option<u32> {
157        let guard = self.stack.lock().await;
158        guard.get_next_timeout_ms()
159    }
160
161    pub async fn on_can_frame(
162        &self,
163        iface: &mut dyn crate::can::CanInterface,
164        id: ApiId,
165        data: &crate::can::FrameData,
166    ) -> Result<bool, Error> {
167        let mut guard = self.stack.lock().await;
168        guard.on_can_frame(iface, id, data)
169    }
170
171    pub async fn advance_time(
172        &self,
173        iface: &mut dyn crate::can::CanInterface,
174        time_delta_ms: usize,
175    ) -> Result<bool, Error> {
176        let mut guard = self.stack.lock().await;
177        guard.advance_time(iface, time_delta_ms)
178    }
179
180    pub async fn send_to_address(
181        &self,
182        iface: &mut dyn crate::can::CanInterface,
183        src: &crate::name::Name,
184        dest: u8,
185        pgn: u32,
186        priority: u8,
187        data: &[u8],
188    ) -> Result<(), Error> {
189        let mut guard = self.stack.lock().await;
190        guard.send_to_address(iface, src, dest, pgn, priority, data)
191    }
192
193    pub async fn send_broadcast(
194        &self,
195        iface: &mut dyn crate::can::CanInterface,
196        src: &crate::name::Name,
197        pgn: u32,
198        priority: u8,
199        data: &[u8],
200    ) -> Result<(), Error> {
201        let mut guard = self.stack.lock().await;
202        guard.send_broadcast(iface, src, pgn, priority, data)
203    }
204}