1pub mod basic {
3 use crate::apex::time::basic::*;
4 use crate::apex::types::basic::*;
5
6 pub type SamplingPortName = ApexName;
7
8 pub type SamplingPortId = ApexLongInteger;
14
15 #[repr(u32)]
16 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
17 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18 #[cfg_attr(feature = "strum", derive(strum::FromRepr))]
19 pub enum Validity {
20 Invalid = 0,
21 Valid = 1,
22 }
23
24 #[derive(Debug, Clone, PartialEq, Eq)]
25 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26 pub struct ApexSamplingPortStatus {
27 pub refresh_period: ApexSystemTime,
28 pub max_message_size: MessageSize,
29 pub port_direction: PortDirection,
30 pub last_msg_validity: Validity,
31 }
32
33 pub trait ApexSamplingPortP4 {
34 fn create_sampling_port(
36 sampling_port_name: SamplingPortName,
37 max_message_size: MessageSize,
38 port_direction: PortDirection,
39 refresh_period: ApexSystemTime,
40 ) -> Result<SamplingPortId, ErrorReturnCode>;
41
42 fn write_sampling_message(
43 sampling_port_id: SamplingPortId,
44 message: &[ApexByte],
45 ) -> Result<(), ErrorReturnCode>;
46
47 unsafe fn read_sampling_message(
51 sampling_port_id: SamplingPortId,
52 message: &mut [ApexByte],
53 ) -> Result<(Validity, MessageSize), ErrorReturnCode>;
54 }
55
56 pub trait ApexSamplingPortP1: ApexSamplingPortP4 {
57 fn get_sampling_port_id(
58 sampling_port_name: SamplingPortName,
59 ) -> Result<SamplingPortId, ErrorReturnCode>;
60
61 fn get_sampling_port_status(
62 sampling_port_id: SamplingPortId,
63 ) -> Result<ApexSamplingPortStatus, ErrorReturnCode>;
64 }
65}
66
67pub mod abstraction {
69 use core::borrow::Borrow;
70 use core::marker::PhantomData;
71 use core::ops::Deref;
72 use core::sync::atomic::AtomicPtr;
73 use core::time::Duration;
74
75 use super::basic::{ApexSamplingPortP1, ApexSamplingPortP4, ApexSamplingPortStatus};
76 pub use super::basic::{SamplingPortId, Validity};
78 use crate::apex::types::basic::PortDirection;
79 use crate::prelude::*;
80
81 #[derive(Debug, Clone, PartialEq, Eq)]
82 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
83 pub struct SamplingPortStatus {
84 pub refresh_period: SystemTime,
85 pub max_message_size: MessageSize,
86 pub port_direction: PortDirection,
87 pub last_msg_validity: Validity,
88 }
89
90 impl From<ApexSamplingPortStatus> for SamplingPortStatus {
91 fn from(s: ApexSamplingPortStatus) -> Self {
92 SamplingPortStatus {
93 refresh_period: s.refresh_period.into(),
94 max_message_size: s.max_message_size,
95 port_direction: s.port_direction,
96 last_msg_validity: s.last_msg_validity,
97 }
98 }
99 }
100
101 #[derive(Debug, Clone)]
102 pub struct ConstSamplingPortSource<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext>(
103 SamplingPortSource<S>,
104 );
105
106 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext> Deref
107 for ConstSamplingPortSource<MSG_SIZE, S>
108 {
109 type Target = SamplingPortSource<S>;
110
111 fn deref(&self) -> &Self::Target {
112 &self.0
113 }
114 }
115
116 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext> AsRef<SamplingPortSource<S>>
117 for ConstSamplingPortSource<MSG_SIZE, S>
118 {
119 fn as_ref(&self) -> &SamplingPortSource<S> {
120 &self.0
121 }
122 }
123
124 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext> Borrow<SamplingPortSource<S>>
125 for ConstSamplingPortSource<MSG_SIZE, S>
126 {
127 fn borrow(&self) -> &SamplingPortSource<S> {
128 &self.0
129 }
130 }
131
132 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext> TryFrom<SamplingPortSource<S>>
133 for ConstSamplingPortSource<MSG_SIZE, S>
134 {
135 type Error = Error;
136
137 fn try_from(port: SamplingPortSource<S>) -> Result<Self, Self::Error> {
138 if port.msg_size != MSG_SIZE {
139 return Err(Error::InvalidConfig);
140 }
141
142 Ok(ConstSamplingPortSource(port))
143 }
144 }
145
146 #[derive(Debug, Clone)]
147 pub struct ConstSamplingPortDestination<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext>(
148 SamplingPortDestination<S>,
149 );
150
151 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext> Deref
152 for ConstSamplingPortDestination<MSG_SIZE, S>
153 {
154 type Target = SamplingPortDestination<S>;
155
156 fn deref(&self) -> &Self::Target {
157 &self.0
158 }
159 }
160
161 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext> AsRef<SamplingPortDestination<S>>
162 for ConstSamplingPortDestination<MSG_SIZE, S>
163 {
164 fn as_ref(&self) -> &SamplingPortDestination<S> {
165 &self.0
166 }
167 }
168
169 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext> Borrow<SamplingPortDestination<S>>
170 for ConstSamplingPortDestination<MSG_SIZE, S>
171 {
172 fn borrow(&self) -> &SamplingPortDestination<S> {
173 &self.0
174 }
175 }
176
177 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext> TryFrom<SamplingPortDestination<S>>
178 for ConstSamplingPortDestination<MSG_SIZE, S>
179 {
180 type Error = Error;
181
182 fn try_from(port: SamplingPortDestination<S>) -> Result<Self, Self::Error> {
183 if port.msg_size != MSG_SIZE {
184 return Err(Error::InvalidConfig);
185 }
186
187 Ok(ConstSamplingPortDestination(port))
188 }
189 }
190
191 #[derive(Debug)]
192 pub struct SamplingPortSource<S: ApexSamplingPortP4Ext> {
193 _b: PhantomData<AtomicPtr<S>>,
194 id: SamplingPortId,
195 msg_size: MessageSize,
196 }
197
198 impl<S: ApexSamplingPortP4Ext> Clone for SamplingPortSource<S> {
199 fn clone(&self) -> Self {
200 Self {
201 _b: self._b,
202 id: self.id,
203 msg_size: self.msg_size,
204 }
205 }
206 }
207
208 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext>
209 From<ConstSamplingPortSource<MSG_SIZE, S>> for SamplingPortSource<S>
210 {
211 fn from(port: ConstSamplingPortSource<MSG_SIZE, S>) -> Self {
212 port.0
213 }
214 }
215
216 #[derive(Debug)]
217 pub struct SamplingPortDestination<S: ApexSamplingPortP4Ext> {
218 _b: PhantomData<AtomicPtr<S>>,
219 id: SamplingPortId,
220 msg_size: MessageSize,
221 refresh: Duration,
222 }
223
224 impl<S: ApexSamplingPortP4Ext> Clone for SamplingPortDestination<S> {
225 fn clone(&self) -> Self {
226 Self {
227 _b: self._b,
228 id: self.id,
229 msg_size: self.msg_size,
230 refresh: self.refresh,
231 }
232 }
233 }
234
235 impl<const MSG_SIZE: MessageSize, S: ApexSamplingPortP4Ext>
236 From<ConstSamplingPortDestination<MSG_SIZE, S>> for SamplingPortDestination<S>
237 {
238 fn from(port: ConstSamplingPortDestination<MSG_SIZE, S>) -> Self {
239 port.0
240 }
241 }
242
243 pub trait ApexSamplingPortP4Ext: ApexSamplingPortP4 + Sized {
244 fn sampling_port_send_unchecked(
245 id: SamplingPortId,
246 buffer: &[ApexByte],
247 ) -> Result<(), Error>;
248
249 unsafe fn sampling_port_receive_unchecked(
253 id: SamplingPortId,
254 buffer: &mut [ApexByte],
255 ) -> Result<(Validity, &[ApexByte]), Error>;
256 }
257
258 pub trait ApexSamplingPortP1Ext: ApexSamplingPortP1 + Sized {
259 fn get_const_sampling_port_source<const MSG_SIZE: MessageSize>(
262 name: Name,
263 ) -> Result<ConstSamplingPortSource<MSG_SIZE, Self>, Error>;
264
265 fn get_const_sampling_port_destination<const MSG_SIZE: MessageSize>(
268 name: Name,
269 ) -> Result<ConstSamplingPortDestination<MSG_SIZE, Self>, Error>;
270
271 fn get_sampling_port_source(name: Name) -> Result<SamplingPortSource<Self>, Error>;
273
274 fn get_sampling_port_destination(
276 name: Name,
277 ) -> Result<SamplingPortDestination<Self>, Error>;
278 }
279
280 impl<S: ApexSamplingPortP4> ApexSamplingPortP4Ext for S {
281 fn sampling_port_send_unchecked(
282 id: SamplingPortId,
283 buffer: &[ApexByte],
284 ) -> Result<(), Error> {
285 S::write_sampling_message(id, buffer)?;
286 Ok(())
287 }
288
289 unsafe fn sampling_port_receive_unchecked(
290 id: SamplingPortId,
291 buffer: &mut [ApexByte],
292 ) -> Result<(Validity, &[ApexByte]), Error> {
293 let (val, len) = S::read_sampling_message(id, buffer)?;
294 Ok((val, &buffer[..(len as usize)]))
295 }
296 }
297
298 impl<S: ApexSamplingPortP1> ApexSamplingPortP1Ext for S {
299 fn get_const_sampling_port_source<const MSG_SIZE: MessageSize>(
302 name: Name,
303 ) -> Result<ConstSamplingPortSource<MSG_SIZE, Self>, Error> {
304 S::get_sampling_port_source(name)?.try_into()
305 }
306
307 fn get_const_sampling_port_destination<const MSG_SIZE: MessageSize>(
310 name: Name,
311 ) -> Result<ConstSamplingPortDestination<MSG_SIZE, Self>, Error> {
312 S::get_sampling_port_destination(name)?.try_into()
313 }
314
315 fn get_sampling_port_source(name: Name) -> Result<SamplingPortSource<Self>, Error> {
317 let id = S::get_sampling_port_id(name.into())?;
318 let SamplingPortStatus {
323 refresh_period: _,
324 max_message_size: msg_size,
325 port_direction,
326 ..
327 } = S::get_sampling_port_status(id).unwrap().into();
328
329 if port_direction != PortDirection::Source {
330 return Err(Error::InvalidConfig);
331 }
332
333 Ok(SamplingPortSource {
334 _b: Default::default(),
335 id,
336 msg_size,
337 })
338 }
339
340 fn get_sampling_port_destination(
342 name: Name,
343 ) -> Result<SamplingPortDestination<Self>, Error> {
344 let id = S::get_sampling_port_id(name.into())?;
345 let SamplingPortStatus {
350 refresh_period,
351 max_message_size: msg_size,
352 port_direction,
353 ..
354 } = S::get_sampling_port_status(id)?.into();
355
356 if port_direction != PortDirection::Destination {
357 return Err(Error::InvalidConfig);
358 }
359
360 Ok(SamplingPortDestination {
361 _b: Default::default(),
362 id,
363 msg_size,
364 refresh: refresh_period.unwrap_duration(),
367 })
368 }
369 }
370
371 impl<S: ApexSamplingPortP4Ext> SamplingPortSource<S> {
372 pub fn send(&self, buffer: &[ApexByte]) -> Result<(), Error> {
373 buffer.validate_write(self.msg_size)?;
374 S::sampling_port_send_unchecked(self.id, buffer)
375 }
376
377 pub const fn id(&self) -> SamplingPortId {
378 self.id
379 }
380
381 pub const fn size(&self) -> MessageSize {
382 self.msg_size
383 }
384 }
385
386 impl<S: ApexSamplingPortP1Ext> SamplingPortSource<S> {
387 pub fn from_name(name: Name) -> Result<SamplingPortSource<S>, Error> {
388 S::get_sampling_port_source(name)
389 }
390
391 pub fn status(&self) -> SamplingPortStatus {
392 S::get_sampling_port_status(self.id).unwrap().into()
397 }
398 }
399
400 impl<S: ApexSamplingPortP4Ext> SamplingPortDestination<S> {
401 pub fn receive<'a>(
402 &self,
403 buffer: &'a mut [ApexByte],
404 ) -> Result<(Validity, &'a [ApexByte]), Error> {
405 buffer.validate_read(self.msg_size)?;
406 unsafe { S::sampling_port_receive_unchecked(self.id, buffer) }
407 }
408
409 pub const fn id(&self) -> SamplingPortId {
410 self.id
411 }
412
413 pub const fn size(&self) -> MessageSize {
414 self.msg_size
415 }
416
417 pub const fn refresh_period(&self) -> Duration {
418 self.refresh
419 }
420 }
421
422 impl<S: ApexSamplingPortP1Ext> SamplingPortDestination<S> {
423 pub fn from_name(name: Name) -> Result<SamplingPortDestination<S>, Error> {
424 S::get_sampling_port_destination(name)
425 }
426
427 pub fn status(&self) -> SamplingPortStatus {
428 S::get_sampling_port_status(self.id).unwrap().into()
433 }
434 }
435
436 impl<S: ApexSamplingPortP4Ext> StartContext<S> {
437 pub fn create_const_sampling_port_source<const MSG_SIZE: MessageSize>(
438 &mut self,
439 name: Name,
440 ) -> Result<ConstSamplingPortSource<MSG_SIZE, S>, Error> {
441 let port = self.create_sampling_port_source(name, MSG_SIZE)?;
442 Ok(ConstSamplingPortSource(port))
443 }
444 pub fn create_const_sampling_port_destination<const MSG_SIZE: MessageSize>(
445 &mut self,
446 name: Name,
447 refresh: Duration,
448 ) -> Result<ConstSamplingPortDestination<MSG_SIZE, S>, Error> {
449 let port = self.create_sampling_port_destination(name, MSG_SIZE, refresh)?;
450 Ok(ConstSamplingPortDestination(port))
451 }
452
453 pub fn create_sampling_port_source(
454 &mut self,
455 name: Name,
456 msg_size: MessageSize,
457 ) -> Result<SamplingPortSource<S>, Error> {
458 let id = S::create_sampling_port(
459 name.into(),
460 msg_size,
461 PortDirection::Source,
462 SystemTime::Normal(Duration::from_nanos(1)).into(),
466 )?;
467 Ok(SamplingPortSource {
468 _b: Default::default(),
469 id,
470 msg_size,
471 })
472 }
473 pub fn create_sampling_port_destination(
474 &mut self,
475 name: Name,
476 msg_size: MessageSize,
477 refresh: Duration,
478 ) -> Result<SamplingPortDestination<S>, Error> {
479 let id = S::create_sampling_port(
480 name.into(),
481 msg_size,
482 PortDirection::Destination,
483 SystemTime::Normal(refresh).into(),
484 )?;
485 Ok(SamplingPortDestination {
486 _b: Default::default(),
487 id,
488 msg_size,
489 refresh,
490 })
491 }
492 }
493}