blob: d324ce675df8964cc6c7bca4983dcc7be061d3da [file] [log] [blame]
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
// SPDX-FileCopyrightText: 2022 Linaro Ltd.
// SPDX-FileCopyrightText: 2022 Viresh Kumar <viresh.kumar@linaro.org>
use std::time::Duration;
use super::{
gpiod,
line::{EdgeKind, Offset},
Error, OperationType, Result,
};
/// Line edge events handling
///
/// An edge event object contains information about a single line edge event.
/// It contains the event type, timestamp and the offset of the line on which
/// the event occurred as well as two sequence numbers (global for all lines
/// in the associated request and local for this line only).
///
/// Edge events are stored into an edge-event buffer object to improve
/// performance and to limit the number of memory allocations when a large
/// number of events are being read.
#[derive(Debug, Eq, PartialEq)]
pub struct Event(*mut gpiod::gpiod_edge_event);
impl Event {
pub fn event_clone(event: &Event) -> Result<Event> {
// SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
let event = unsafe { gpiod::gpiod_edge_event_copy(event.0) };
if event.is_null() {
return Err(Error::OperationFailed(
OperationType::EdgeEventCopy,
errno::errno(),
));
}
Ok(Self(event))
}
/// Get the event type.
pub fn event_type(&self) -> Result<EdgeKind> {
// SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
EdgeKind::new(unsafe { gpiod::gpiod_edge_event_get_event_type(self.0) } as u32)
}
/// Get the timestamp of the event.
pub fn timestamp(&self) -> Duration {
// SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
Duration::from_nanos(unsafe { gpiod::gpiod_edge_event_get_timestamp_ns(self.0) })
}
/// Get the offset of the line on which the event was triggered.
pub fn line_offset(&self) -> Offset {
// SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
unsafe { gpiod::gpiod_edge_event_get_line_offset(self.0) }
}
/// Get the global sequence number of the event.
///
/// Returns sequence number of the event relative to all lines in the
/// associated line request.
pub fn global_seqno(&self) -> usize {
// SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
unsafe {
gpiod::gpiod_edge_event_get_global_seqno(self.0)
.try_into()
.unwrap()
}
}
/// Get the event sequence number specific to concerned line.
///
/// Returns sequence number of the event relative to the line within the
/// lifetime of the associated line request.
pub fn line_seqno(&self) -> usize {
// SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
unsafe {
gpiod::gpiod_edge_event_get_line_seqno(self.0)
.try_into()
.unwrap()
}
}
}
impl Drop for Event {
/// Free the edge event.
fn drop(&mut self) {
// SAFETY: `gpiod_edge_event` is guaranteed to be valid here.
unsafe { gpiod::gpiod_edge_event_free(self.0) };
}
}