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} impl 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}