Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions adb_cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ version.workspace = true
workspace = true

[dependencies]
adb_client = { version = "^3.0.1", features = ["mdns", "usb"] }
clap = { version = "4.5.54", features = ["derive"] }
env_logger = { version = "0.11.8" }
adb_client = { version = "^3.1.1", features = ["mdns", "usb"] }
clap = { version = "4.5.60", features = ["derive"] }
env_logger = { version = "0.11.9" }
log = { version = "0.4.29" }
tabwriter = { version = "1.4.1" }

Expand Down
3 changes: 2 additions & 1 deletion adb_cli/src/models/adb_cli_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ impl From<adb_client::RustADBError> for ADBCliError {
| RustADBError::USBDeviceNotFound(_, _)
| RustADBError::WrongFileExtension(_)
| RustADBError::AddrParseError(_)
| RustADBError::DeviceBusy => Self::Standard(value),
| RustADBError::DeviceBusy
| RustADBError::Timeout => Self::Standard(value),
}
}
}
12 changes: 6 additions & 6 deletions adb_client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ usb = ["dep:rusb"]
[dependencies]
base64 = { version = "0.22.1" }
byteorder = { version = "1.5.0" }
chrono = { version = "0.4.43", default-features = false, features = ["std"] }
chrono = { version = "0.4.44", default-features = false, features = ["std"] }
image = { version = "0.25.9", default-features = false, features = ["png"] }
log = { version = "0.4.29" }
num-bigint = { version = "0.8.6", package = "num-bigint-dig" }
num-traits = { version = "0.2.19" }
quick-protobuf = { version = "0.8.1" }
rand = { version = "0.10.0" }
rcgen = { version = "0.14.6", default-features = false, features = [
rcgen = { version = "0.14.7", default-features = false, features = [
"ring",
"pem",
] }
regex = { version = "1.12.2", features = ["perf", "std", "unicode"] }
regex = { version = "1.12.3", features = ["perf", "std", "unicode"] }
rsa = { version = "0.9.10" }
rustls = { version = "0.23.36", default-features = false, features = ["ring", "std", "tls12", "logging"] }
rustls = { version = "0.23.37", default-features = false, features = ["ring", "std", "tls12", "logging"] }
rustls-pki-types = { version = "1.14.0" }
sha1 = { version = "0.10.6", features = ["oid"] }
thiserror = { version = "2.0.18" }
Expand All @@ -56,8 +56,8 @@ num_enum = { version = "0.7.5" }
#########

[dev-dependencies]
anyhow = { version = "1.0.100" }
criterion = { version = "0.8.1" } # Used for benchmarks
anyhow = { version = "1.0.102" }
criterion = { version = "0.8.2" } # Used for benchmarks

[[bench]]
harness = false
Expand Down
3 changes: 3 additions & 0 deletions adb_client/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ pub enum RustADBError {
/// An unknown file mode was encountered in list
#[error("Unknown file mode {0}")]
UnknownFileMode(u32),
/// Timeout while waiting for response
#[error("timeout while waiting for response")]
Timeout,
}

impl<T> From<std::sync::PoisonError<T>> for RustADBError {
Expand Down
54 changes: 31 additions & 23 deletions adb_client/src/message_devices/adb_message_device.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use rand::RngExt;
use std::{path::Path, time::Duration};
use std::path::Path;

use crate::{
Result, RustADBError,
adb_transport::ADBTransport,
message_devices::{
adb_message_transport::ADBMessageTransport,
adb_multiplexer::ADBMessageMultiplexer,
adb_session::ADBSession,
adb_transport_message::{
ADBTransportMessage, AUTH_RSAPUBLICKEY, AUTH_SIGNATURE, AUTH_TOKEN,
Expand All @@ -20,7 +22,7 @@ use crate::{
/// Structure is totally agnostic over which transport is truly used.
#[derive(Debug)]
pub(crate) struct ADBMessageDevice<T: ADBMessageTransport> {
transport: T,
multiplexer: ADBMessageMultiplexer<T>,
}

impl<T: ADBMessageTransport> ADBMessageDevice<T> {
Expand All @@ -36,19 +38,17 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
ADBRsaKey::new_random()?
};

let mut message_device = Self { transport };
let mut message_device = Self {
multiplexer: ADBMessageMultiplexer::new(transport),
};
message_device.connect(&private_key)?;

Ok(message_device)
}

pub(crate) fn get_transport_mut(&mut self) -> &mut T {
&mut self.transport
}

/// Send initial connect
fn connect(&mut self, private_key: &ADBRsaKey) -> Result<()> {
self.get_transport_mut().connect()?;
self.multiplexer.connect()?;

let message = ADBTransportMessage::try_new(
MessageCommand::Cnxn,
Expand All @@ -57,21 +57,21 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
format!("host::{}\0", env!("CARGO_PKG_NAME")).as_bytes(),
)?;

self.get_transport_mut().write_message(message)?;
self.multiplexer.write_message(message)?;

let message = self.get_transport_mut().read_message()?;
let message = self.multiplexer.read_authentication_message()?;

// Check if a client is requesting a secure connection and upgrade it if necessary
match message.header().command() {
MessageCommand::Stls => {
self.get_transport_mut()
self.multiplexer
.write_message(ADBTransportMessage::try_new(
MessageCommand::Stls,
1,
0,
&[],
)?)?;
self.get_transport_mut().upgrade_connection()?;
self.multiplexer.upgrade_connection()?;
log::debug!("Connection successfully upgraded from TCP to TLS");
Ok(())
}
Expand Down Expand Up @@ -116,15 +116,17 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {

let message = ADBTransportMessage::try_new(MessageCommand::Auth, AUTH_SIGNATURE, 0, &sign)?;

self.transport.write_message(message)?;
self.multiplexer.write_message(message)?;

let received_response = self.transport.read_message()?;
let received_response = self.multiplexer.read_authentication_message()?;

if received_response.header().command() == MessageCommand::Cnxn {
log::info!(
"Authentication OK, device info {}",
String::from_utf8(received_response.into_payload())?
);
// Authentication is OK, we can now consider sessions
self.multiplexer.set_authenticated();
return Ok(());
}

Expand All @@ -134,11 +136,11 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
let message =
ADBTransportMessage::try_new(MessageCommand::Auth, AUTH_RSAPUBLICKEY, 0, &pubkey)?;

self.transport.write_message(message)?;
self.multiplexer.write_message(message)?;

let response = self
.transport
.read_message_with_timeout(Duration::from_secs(10))
.multiplexer
.read_authentication_message()
.and_then(|message| {
message.assert_command(MessageCommand::Cnxn)?;
Ok(message)
Expand All @@ -148,6 +150,9 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
"Authentication OK, device info {}",
String::from_utf8(response.into_payload())?
);
// Authentication is OK, we can now consider sessions
self.multiplexer.set_authenticated();

Ok(())
}

Expand All @@ -165,9 +170,12 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
0,
cmd.to_string().as_bytes(),
)?;
self.transport.write_message(message)?;
log::debug!("here");
self.multiplexer.write_message(message)?;
log::debug!("after");

let response = self.transport.read_message()?;
let response = self.multiplexer.read_message(local_id)?;
log::debug!("got message from multiplexer");

if response.header().command() != MessageCommand::Okay {
return Err(RustADBError::ADBRequestFailed(format!(
Expand All @@ -184,13 +192,13 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
}

Ok(ADBSession::new(
self.transport.clone(),
self.multiplexer.clone(),
local_id,
response.header().arg0(),
))
}

pub(crate) fn end_transaction(&mut self, session: &mut ADBSession<T>) -> Result<()> {
pub(crate) fn end_transaction(session: &mut ADBSession<T>) -> Result<()> {
let quit_buffer = MessageSubcommand::Quit.with_arg(0u32);
session.send_and_expect_okay(ADBTransportMessage::try_new(
MessageCommand::Write,
Expand All @@ -199,14 +207,14 @@ impl<T: ADBMessageTransport> ADBMessageDevice<T> {
&quit_buffer.encode(),
)?)?;

let _discard_close = self.transport.read_message()?;
let _discard_close = session.read_message()?;
Ok(())
}
}

impl<T: ADBMessageTransport> Drop for ADBMessageDevice<T> {
fn drop(&mut self) {
// Best effort here
let _ = self.get_transport_mut().disconnect();
let _ = self.multiplexer.disconnect();
}
}
Loading
Loading