mod common;
mod info_event {
use libc::EINVAL;
use std::{
sync::{
Arc, Mutex,
mpsc::{self, Receiver, Sender},
},
thread,
time::Duration,
};
use gpiosim_sys::Sim;
use libgpiod::{
Error as ChipError, OperationType,
chip::Chip,
line::{self, Direction, InfoChangeKind, Offset},
request,
};
fn request_reconfigure_line(chip: Arc<Mutex<Chip>>, tx: Sender<()>, rx: Receiver<()>) {
thread::spawn(move || {
let mut lconfig1 = line::Config::new().unwrap();
let lsettings = line::Settings::new().unwrap();
lconfig1.add_line_settings(&[7], lsettings).unwrap();
let rconfig = request::Config::new().unwrap();
let mut request = chip
.lock()
.unwrap()
.request_lines(Some(&rconfig), &lconfig1)
.unwrap();
tx.send(()).expect("Could not send signal on channel");
rx.recv().expect("Could not receive from channel");
let mut lconfig2 = line::Config::new().unwrap();
let mut lsettings = line::Settings::new().unwrap();
lsettings.set_direction(Direction::Output).unwrap();
lconfig2.add_line_settings(&[7], lsettings).unwrap();
request.reconfigure_lines(&lconfig2).unwrap();
tx.send(()).expect("Could not send signal on channel");
rx.recv().expect("Could not receive from channel");
});
}
mod watch {
use super::*;
const NGPIO: usize = 8;
const GPIO: Offset = 7;
#[test]
fn line_info() {
let sim = Sim::new(Some(NGPIO), None, true).unwrap();
let chip = Chip::open(&sim.dev_path()).unwrap();
assert_eq!(
chip.watch_line_info(NGPIO as u32).unwrap_err(),
ChipError::OperationFailed(OperationType::ChipWatchLineInfo, errno::Errno(EINVAL))
);
let info = chip.watch_line_info(GPIO).unwrap();
assert_eq!(info.offset(), GPIO);
assert!(
!chip
.wait_info_event(Some(Duration::from_millis(100)))
.unwrap()
);
}
#[test]
fn reconfigure() {
let sim = Sim::new(Some(NGPIO), None, true).unwrap();
let chip = Arc::new(Mutex::new(Chip::open(&sim.dev_path()).unwrap()));
let info = chip.lock().unwrap().watch_line_info(GPIO).unwrap();
assert_eq!(info.direction().unwrap(), Direction::Input);
let (tx_main, rx_thread) = mpsc::channel();
let (tx_thread, rx_main) = mpsc::channel();
request_reconfigure_line(chip.clone(), tx_thread, rx_thread);
rx_main.recv().expect("Could not receive from channel");
assert!(
chip.lock()
.unwrap()
.wait_info_event(Some(Duration::from_secs(1)))
.unwrap()
);
let event = chip.lock().unwrap().read_info_event().unwrap();
let ts_req = event.timestamp();
assert_eq!(event.event_type().unwrap(), InfoChangeKind::LineRequested);
assert_eq!(
event.line_info().unwrap().direction().unwrap(),
Direction::Input
);
tx_main.send(()).expect("Could not send signal on channel");
rx_main.recv().expect("Could not receive from channel");
assert!(
chip.lock()
.unwrap()
.wait_info_event(Some(Duration::from_secs(1)))
.unwrap()
);
let event = chip.lock().unwrap().read_info_event().unwrap();
let ts_rec = event.timestamp();
assert_eq!(
event.event_type().unwrap(),
InfoChangeKind::LineConfigChanged
);
assert_eq!(
event.line_info().unwrap().direction().unwrap(),
Direction::Output
);
tx_main.send(()).expect("Could not send signal on channel");
assert!(
chip.lock()
.unwrap()
.wait_info_event(Some(Duration::from_secs(1)))
.unwrap()
);
let event = chip.lock().unwrap().read_info_event().unwrap();
let ts_rel = event.timestamp();
assert_eq!(event.event_type().unwrap(), InfoChangeKind::LineReleased);
assert!(
!chip
.lock()
.unwrap()
.wait_info_event(Some(Duration::from_millis(100)))
.unwrap()
);
assert!(ts_rel > ts_rec);
assert!(ts_rec > ts_req);
}
}
}