Skip to content

Commit

Permalink
Multiple event types when waiting for event
Browse files Browse the repository at this point in the history
  • Loading branch information
ChocolateLoverRaj committed Jul 3, 2024
1 parent 94f055f commit 1c8d728
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 41 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 36 additions & 22 deletions crosec/src/wait_event/event.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use async_std::io::ReadExt;
use num::FromPrimitive;
use std::io;
use std::mem::size_of;
use strum::IntoEnumIterator;
use strum_macros::EnumIter;

use bytemuck::{from_bytes, Pod, Zeroable};
use num_derive::FromPrimitive;
Expand Down Expand Up @@ -32,8 +35,37 @@ pub enum EcMkbpEvent {
Sysrq(u32),
CecEvent(u32),
}
impl EcMkbpEvent {
fn max_event_size() -> usize {
EcMkbpEventType::iter()
.map(|e| e.data_size())
.max()
.unwrap_or_default()
}

fn from_bytes(bytes: &[u8]) -> Self {
let event_type = EcMkbpEventType::from_u8(bytes[0]).unwrap();
event_type.event_from_bytes(&mut bytes[1..1 + event_type.data_size()].to_vec())

Check warning

Code scanning / clippy

the method event_from_bytes doesn't need a mutable reference Warning

the method event\_from\_bytes doesn't need a mutable reference
}

pub(crate) fn read_sync<T: std::io::Read>(stream: &mut T) -> io::Result<Self> {
let mut buf: Vec<u8> =
vec![Default::default(); size_of::<EcMkbpEventType>() + Self::max_event_size()];
stream.read(&mut buf)?;

Check failure

Code scanning / clippy

read amount is not handled Error

read amount is not handled
Ok(Self::from_bytes(&buf))
}

pub(crate) async fn read_async<T: async_std::io::Read + Unpin>(
stream: &mut T,
) -> io::Result<Self> {
let mut buf: Vec<u8> =
vec![Default::default(); size_of::<EcMkbpEventType>() + Self::max_event_size()];
stream.read(&mut buf).await?;
Ok(Self::from_bytes(&buf))
}
}

#[derive(Debug, FromPrimitive, Clone, Copy)]
#[derive(Debug, FromPrimitive, Clone, Copy, EnumIter, PartialEq)]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[repr(u8)]
pub enum EcMkbpEventType {
Expand Down Expand Up @@ -68,33 +100,15 @@ impl EcMkbpEventType {
}
}

fn parse_event(&self, event: &mut Vec<u8>) -> EcMkbpEvent {
debug_assert_eq!(event[0], *self as u8);
event.remove(0);
let data = event;
fn event_from_bytes(&self, event: &[u8]) -> EcMkbpEvent {
match self {
EcMkbpEventType::Fingerprint => {
EcMkbpEvent::Fingerprint(from_bytes::<EcMkbpEventFingerprint>(&data).to_owned())
EcMkbpEvent::Fingerprint(from_bytes::<EcMkbpEventFingerprint>(&event).to_owned())

Check warning

Code scanning / clippy

this expression creates a reference which is immediately dereferenced by the compiler Warning

this expression creates a reference which is immediately dereferenced by the compiler
}
EcMkbpEventType::HostEvent => {
EcMkbpEvent::HostEvent(from_bytes::<EcMkbpEventHostEvent>(&data).to_owned())
EcMkbpEvent::HostEvent(from_bytes::<EcMkbpEventHostEvent>(&event).to_owned())

Check warning

Code scanning / clippy

this expression creates a reference which is immediately dereferenced by the compiler Warning

this expression creates a reference which is immediately dereferenced by the compiler
}
event_type => panic!("{event_type:#?} from_bytes not implemented yet"),
}
}

pub(crate) fn read_sync<T: std::io::Read>(&self, stream: &mut T) -> io::Result<EcMkbpEvent> {
let mut event = vec![Default::default(); size_of::<Self>() + self.data_size()];
stream.read_exact(&mut event)?;
Ok(self.parse_event(&mut event))
}

pub(crate) async fn read_async<T: async_std::io::Read + Unpin>(
&self,
stream: &mut T,
) -> io::Result<EcMkbpEvent> {
let mut event = vec![Default::default(); size_of::<Self>() + self.data_size()];
stream.read_exact(&mut event).await?;
Ok(self.parse_event(&mut event))
}
}
41 changes: 27 additions & 14 deletions crosec/src/wait_event/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::io;
use std::os::fd::AsRawFd;
use std::{io, os::fd::AsRawFd};

use nix::{
libc::{ioctl, poll, pollfd},
Expand All @@ -23,18 +22,26 @@ pub enum PollData {
SomethingElseHappened(i16),
}

fn get_mask<I: IntoIterator<Item = EcMkbpEventType>>(event_types: I) -> i32 {
let mut mask = i32::default();
for event_type in event_types {
mask |= 1 << event_type as u8;
}
assert_ne!(mask, 0, "Must specify at least one event type");
mask
}

/// If no timeout is specified, this function will wait for an unlimited amount of time
pub fn wait_event_sync<File: AsRawFd + std::io::Read>(
pub fn wait_event_sync<File: AsRawFd + std::io::Read, I: IntoIterator<Item = EcMkbpEventType>>(
file: &mut File,
event_type: EcMkbpEventType,
event_types: I,
timeout: Option<i32>,
) -> Result<PollData, i32> {
let mask = 1 << event_type as u8;
unsafe {
ioctl(
file.as_raw_fd(),
request_code_none!(CROS_EC_IOC_MAGIC, 2),
mask,
get_mask(event_types),
)
};
match timeout {
Expand All @@ -48,27 +55,33 @@ pub fn wait_event_sync<File: AsRawFd + std::io::Read>(
match result {
0 => Ok(PollData::Timeout),
1 => match fds.revents {
POLL_IN => Ok(PollData::EventHappened(event_type.read_sync(file).unwrap())),
POLL_IN => Ok(PollData::EventHappened(
EcMkbpEvent::read_sync(file).unwrap(),
)),
events => Ok(PollData::SomethingElseHappened(events)),
},
result => Err(result),
}
}
None => Ok(PollData::EventHappened(event_type.read_sync(file).unwrap())),
None => Ok(PollData::EventHappened(
EcMkbpEvent::read_sync(file).unwrap(),
)),
}
}

pub async fn wait_event_async<File: AsRawFd + async_std::io::Read + Unpin>(
pub async fn wait_event_async<
File: AsRawFd + async_std::io::Read + Unpin,
I: IntoIterator<Item = EcMkbpEventType>,
>(
file: &mut File,
event_type: EcMkbpEventType,
event_types: I,
) -> io::Result<EcMkbpEvent> {
let mask = 1 << event_type as u8;
unsafe {
ioctl(
file.as_raw_fd(),
request_code_none!(CROS_EC_IOC_MAGIC, 2),
mask,
get_mask(event_types),
)
};
event_type.read_async(file).await
}
EcMkbpEvent::read_async(file).await
}
1 change: 1 addition & 0 deletions ectool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ color-eyre = "0.6.2"
clap = { version = "4.5.4", features = ["derive"] }
num-traits = "0.2.19"
image = "0.25.1"
strum = "0.26.3"
11 changes: 8 additions & 3 deletions ectool/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use fp_download_subcommand::{fp_download_subcommand, FpDownloadSubcommand};
use fp_upload_template_command::fp_upload_template_command;
use get_uptime_info_command::get_uptime_info_commnad;
use num_traits::cast::FromPrimitive;
use strum::IntoEnumIterator;

use crate::fp_get_encryption_status_command::fp_get_encryption_status_command;
use crosec::battery::battery;
Expand Down Expand Up @@ -114,8 +115,9 @@ enum Commands {
mode: Vec<FpMode>,
},
WaitEvent {
event_type: EcMkbpEventType,
event_types: Vec<EcMkbpEventType>,
/// Timeout in milliseconds
#[arg(short, long)]
timeout: Option<i32>,
#[arg(short, long)]
device: Option<Device>,
Expand Down Expand Up @@ -268,13 +270,16 @@ fn main() -> Result<()> {
println!("FP mode: {display}");
}
Commands::WaitEvent {
event_type,
mut event_types,
device,
timeout,
} => {
if event_types.len() == 0 {
event_types = EcMkbpEventType::iter().collect();
}
let mut file = File::open(device.unwrap_or_default().get_path())?;
println!("Waiting for event...");
let result = wait_event_sync(&mut file, event_type, timeout).unwrap();
let result = wait_event_sync(&mut file, event_types, timeout).unwrap();
println!("{result:#?}");
}
Commands::FpDownload { command } => fp_download_subcommand(command)?,
Expand Down

0 comments on commit 1c8d728

Please sign in to comment.