Skip to content

Commit 2626cdf

Browse files
committed
refactor: introduce Transport trait
1 parent 0ea08c2 commit 2626cdf

6 files changed

Lines changed: 295 additions & 48 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
**/*.dSYM/

Cargo.lock

Lines changed: 195 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cd321x.rs

Lines changed: 23 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
* Copyright The Asahi Linux Contributors
55
*/
66

7+
use crate::transport::Transport;
78
use crate::{Error, Result};
89
use log::{error, info};
910
use std::{
10-
fs::{self, OpenOptions},
11-
io::Read,
12-
path, thread,
11+
thread,
1312
time::{Duration, Instant},
1413
};
1514

@@ -25,59 +24,36 @@ enum VdmSopType {
2524
SopStar = 0b11,
2625
}
2726

28-
pub(crate) struct Device {
29-
path: path::PathBuf,
30-
key: Vec<u8>,
27+
pub(crate) struct Device<'a> {
28+
transport: &'a mut dyn Transport,
3129
}
3230

33-
fn verify_device(dev: &str) -> Result<path::PathBuf> {
34-
let mut fname = OpenOptions::new()
35-
.read(true)
36-
.open(path::Path::new(dev).join("name"))
37-
.unwrap();
38-
let mut data = Vec::new();
39-
fname.read_to_end(&mut data).unwrap();
40-
let name = std::str::from_utf8(&data).map_err(Error::Utf8)?.trim();
41-
if name != "cd321x" {
42-
error!("{dev}/name \"{name}\" does not match \"cd321x\"");
43-
return Err(Error::TypecController);
44-
}
45-
46-
let vdm_dir = path::Path::new(dev).join("cd321x_vdm");
47-
if !vdm_dir.exists() {
48-
error!("{} does not exists", vdm_dir.display());
49-
return Err(Error::FeatureMissing);
50-
}
51-
Ok(vdm_dir.to_path_buf())
52-
}
53-
54-
impl Device {
55-
pub(crate) fn new(dev: &str, code: String) -> Result<Self> {
56-
let device = Self {
57-
path: verify_device(dev)?,
58-
key: code.into_bytes().into_iter().rev().collect::<Vec<u8>>(),
59-
};
60-
device.lock(device.key.as_slice())?;
31+
impl<'a> Device<'a> {
32+
pub(crate) fn new(transport: &'a mut dyn Transport, code: &str) -> Result<Self> {
33+
let mut key = code.as_bytes().to_vec();
34+
key.reverse();
35+
let mut device = Self { transport };
36+
device.lock(&key)?;
6137
device.dbma(true)?;
6238

6339
Ok(device)
6440
}
6541

66-
fn command(&self, command: &[u8; 4], data: &[u8]) -> Result<()> {
42+
fn command(&mut self, command: &[u8; 4], data: &[u8]) -> Result<()> {
6743
let data: Vec<u8> = [command, data].concat();
68-
fs::write(self.path.as_path().join("command"), &data).map_err(Error::Io)
44+
self.transport.write(&data).map_err(Error::Io)
6945
}
7046

71-
fn lock(&self, key: &[u8]) -> Result<()> {
47+
fn lock(&mut self, key: &[u8]) -> Result<()> {
7248
self.command(b"LOCK", key)
7349
}
7450

75-
fn dbma(&self, debug: bool) -> Result<()> {
51+
fn dbma(&mut self, debug: bool) -> Result<()> {
7652
let data: [u8; 1] = if debug { [1] } else { [0] };
7753
self.command(b"DBMa", &data)
7854
}
7955

80-
fn vdms(&self, sop: VdmSopType, vdos: &[u32]) -> Result<()> {
56+
fn vdms(&mut self, sop: VdmSopType, vdos: &[u32]) -> Result<()> {
8157
if vdos.is_empty() || vdos.len() > 7 {
8258
return Err(Error::InvalidArgument);
8359
}
@@ -89,13 +65,13 @@ impl Device {
8965
self.command(b"VDMs", &data)
9066
}
9167

92-
fn dven(&self, vdos: &[u32]) -> Result<()> {
68+
fn dven(&mut self, vdos: &[u32]) -> Result<()> {
9369
let data: Vec<u8> = vdos.iter().flat_map(|val| val.to_le_bytes()).collect();
9470
self.command(b"DEVn", &data)
9571
}
9672

97-
fn is_connected(&self) -> Option<bool> {
98-
let data: Vec<u8> = fs::read(self.path.as_path().join("power_status")).ok()?;
73+
fn is_connected(&mut self) -> Option<bool> {
74+
let data: Vec<u8> = self.transport.read(0).ok()?;
9975
let string = std::str::from_utf8(&data).ok()?;
10076
if string.len() < 6 {
10177
return None;
@@ -105,18 +81,18 @@ impl Device {
10581
Some((power_status & 1) != 0)
10682
}
10783

108-
pub(crate) fn dfu(&self) -> Result<()> {
84+
pub(crate) fn dfu(&mut self) -> Result<()> {
10985
let vdos: [u32; 3] = [0x5ac8012, 0x106, 0x80010000];
11086
info!("Rebooting target into DFU mode...");
11187
self.vdms(VdmSopType::SopStar, &vdos)
11288
}
113-
pub(crate) fn reboot(&self) -> Result<()> {
89+
pub(crate) fn reboot(&mut self) -> Result<()> {
11490
let vdos: [u32; 3] = [0x5ac8012, 0x105, 0x80000000];
11591
info!("Rebooting target into normal mode...");
11692
self.vdms(VdmSopType::SopStar, &vdos)
11793
}
11894

119-
pub(crate) fn reboot_serial(&self) -> Result<()> {
95+
pub(crate) fn reboot_serial(&mut self) -> Result<()> {
12096
self.reboot()?;
12197
info!("Waiting for connection...");
12298

@@ -138,7 +114,7 @@ impl Device {
138114
self.serial()
139115
}
140116

141-
pub(crate) fn serial(&self) -> Result<()> {
117+
pub(crate) fn serial(&mut self) -> Result<()> {
142118
let vdos: [u32; 2] = [0x5ac8012, 0x1840306];
143119
info!("Putting target into serial mode...");
144120
self.vdms(VdmSopType::SopStar, &vdos)?;
@@ -147,7 +123,7 @@ impl Device {
147123
}
148124
}
149125

150-
impl Drop for Device {
126+
impl Drop for Device<'_> {
151127
fn drop(&mut self) {
152128
let lock: [u8; 4] = [0, 0, 0, 0];
153129
let _ = self.dbma(false);

src/main.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
*/
66

77
pub mod cd321x;
8+
pub mod transport;
89

910
use env_logger::Env;
1011
use log::error;
1112
use std::{fs, process::ExitCode};
13+
use transport::sysfs::SysfsTransport;
1214

1315
#[derive(Debug)]
1416
#[allow(dead_code)]
@@ -56,7 +58,8 @@ fn vdmtool() -> Result<()> {
5658
return Err(Error::Compatible);
5759
}
5860
let code = device.to_uppercase();
59-
let device = cd321x::Device::new(matches.get_one::<String>("device").unwrap(), code)?;
61+
let mut transport = SysfsTransport::new(matches.get_one::<String>("device").unwrap())?;
62+
let mut device = cd321x::Device::new(&mut transport, &code)?;
6063

6164
match matches.subcommand() {
6265
Some(("dfu", _)) => {

src/transport/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
pub mod sysfs;
2+
3+
pub trait Transport {
4+
fn write(&mut self, data: &[u8]) -> std::io::Result<()>;
5+
/// If `len == 0`, reads the full payload (backend-defined).
6+
fn read(&mut self, len: usize) -> std::io::Result<Vec<u8>>;
7+
}

0 commit comments

Comments
 (0)