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}