blob: 0c6c5c1d8275bdc7ff3e25b8ea85a701ef5ce4a4 [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::ffi::{CStr, CString};
use std::os::raw::c_char;
use std::str;
use super::{gpiod, Error, OperationType, Result};
/// Request configuration objects
///
/// Request config objects are used to pass a set of options to the kernel at
/// the time of the line request. The mutators don't return error values. If the
/// values are invalid, in general they are silently adjusted to acceptable
/// ranges.
#[derive(Debug, Eq, PartialEq)]
pub struct Config {
pub(crate) config: *mut gpiod::gpiod_request_config,
}
impl Config {
/// Create a new request config object.
pub fn new() -> Result<Self> {
// SAFETY: The `gpiod_request_config` returned by libgpiod is guaranteed to live as long
// as the `struct Config`.
let config = unsafe { gpiod::gpiod_request_config_new() };
if config.is_null() {
return Err(Error::OperationFailed(
OperationType::RequestConfigNew,
errno::errno(),
));
}
Ok(Self { config })
}
/// Set the consumer name for the request.
///
/// If the consumer string is too long, it will be truncated to the max
/// accepted length.
pub fn set_consumer(&mut self, consumer: &str) -> Result<&mut Self> {
let consumer = CString::new(consumer).map_err(|_| Error::InvalidString)?;
// SAFETY: `gpiod_request_config` is guaranteed to be valid here.
unsafe {
gpiod::gpiod_request_config_set_consumer(
self.config,
consumer.as_ptr() as *const c_char,
)
}
Ok(self)
}
/// Get the consumer name configured in the request config.
pub fn consumer(&self) -> Result<&str> {
// SAFETY: The string returned by libgpiod is guaranteed to live as long
// as the `struct Config`.
let consumer = unsafe { gpiod::gpiod_request_config_get_consumer(self.config) };
if consumer.is_null() {
return Err(Error::OperationFailed(
OperationType::RequestConfigGetConsumer,
errno::errno(),
));
}
// SAFETY: The string is guaranteed to be valid here by the C API.
unsafe { CStr::from_ptr(consumer) }
.to_str()
.map_err(Error::StringNotUtf8)
}
/// Set the size of the kernel event buffer for the request.
pub fn set_event_buffer_size(&mut self, size: usize) -> &mut Self {
// SAFETY: `gpiod_request_config` is guaranteed to be valid here.
unsafe { gpiod::gpiod_request_config_set_event_buffer_size(self.config, size) }
self
}
/// Get the edge event buffer size setting for the request config.
pub fn event_buffer_size(&self) -> usize {
// SAFETY: `gpiod_request_config` is guaranteed to be valid here.
unsafe { gpiod::gpiod_request_config_get_event_buffer_size(self.config) as usize }
}
}
impl Drop for Config {
/// Free the request config object and release all associated resources.
fn drop(&mut self) {
// SAFETY: `gpiod_request_config` is guaranteed to be valid here.
unsafe { gpiod::gpiod_request_config_free(self.config) }
}
}