libgpiod/edge_event.rs
1// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
2// SPDX-FileCopyrightText: 2022 Linaro Ltd.
3// SPDX-FileCopyrightText: 2022 Viresh Kumar <viresh.kumar@linaro.org>
4
5use std::time::Duration;
6
7use super::{
8 Error, OperationType, Result, gpiod,
9 line::{EdgeKind, Offset},
10};
11
12/// Line edge events handling
13///
14/// An edge event object contains information about a single line edge event.
15/// It contains the event type, timestamp and the offset of the line on which
16/// the event occurred as well as two sequence numbers (global for all lines
17/// in the associated request and local for this line only).
18///
19/// Edge events are stored into an edge-event buffer object to improve
20/// performance and to limit the number of memory allocations when a large
21/// number of events are being read.
22
23#[derive(Debug, Eq, PartialEq)]
24#[repr(transparent)]
25pub struct Event(*mut gpiod::gpiod_edge_event);
26
27// SAFETY: Event models a wrapper around an owned gpiod_edge_event and may
28// be safely sent to other threads.
29unsafe impl Send for Event {}
30
31impl Event {
32 /// Makes a copy of the event object.
33 pub fn try_clone(event: &Event) -> Result<Event> {
34 // SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
35 let event = unsafe { gpiod::gpiod_edge_event_copy(event.0) };
36 if event.is_null() {
37 return Err(Error::OperationFailed(
38 OperationType::EdgeEventCopy,
39 errno::errno(),
40 ));
41 }
42
43 Ok(Self(event))
44 }
45
46 /// Get the event type.
47 pub fn event_type(&self) -> Result<EdgeKind> {
48 // SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
49 EdgeKind::new(unsafe { gpiod::gpiod_edge_event_get_event_type(self.0) })
50 }
51
52 /// Get the timestamp of the event.
53 pub fn timestamp(&self) -> Duration {
54 // SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
55 Duration::from_nanos(unsafe { gpiod::gpiod_edge_event_get_timestamp_ns(self.0) })
56 }
57
58 /// Get the offset of the line on which the event was triggered.
59 pub fn line_offset(&self) -> Offset {
60 // SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
61 unsafe { gpiod::gpiod_edge_event_get_line_offset(self.0) }
62 }
63
64 /// Get the global sequence number of the event.
65 ///
66 /// Returns sequence number of the event relative to all lines in the
67 /// associated line request.
68 pub fn global_seqno(&self) -> usize {
69 // SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
70 unsafe {
71 gpiod::gpiod_edge_event_get_global_seqno(self.0) as usize
72 }
73 }
74
75 /// Get the event sequence number specific to concerned line.
76 ///
77 /// Returns sequence number of the event relative to the line within the
78 /// lifetime of the associated line request.
79 pub fn line_seqno(&self) -> usize {
80 // SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
81 unsafe {
82 gpiod::gpiod_edge_event_get_line_seqno(self.0) as usize
83 }
84 }
85}
86
87impl Drop for Event {
88 /// Free the edge event.
89 fn drop(&mut self) {
90 // SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
91 unsafe { gpiod::gpiod_edge_event_free(self.0) };
92 }
93}