adb_client/server_device/commands/
recv.rs1use crate::{
2 Result,
3 models::{ADBCommand, ADBLocalCommand, SyncCommand},
4 server_device::ADBServerDevice,
5};
6use byteorder::{LittleEndian, ReadBytesExt};
7use std::io::{BufReader, BufWriter, Read, Write};
8
9struct ADBRecvCommandReader<R: Read> {
11 inner: R,
12 remaining_data_bytes_to_read: usize,
13}
14
15impl<R: Read> ADBRecvCommandReader<R> {
16 pub const fn new(inner: R) -> Self {
17 Self {
18 inner,
19 remaining_data_bytes_to_read: 0,
20 }
21 }
22}
23
24impl<R: Read> Read for ADBRecvCommandReader<R> {
25 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
26 if self.remaining_data_bytes_to_read == 0 {
29 let mut header = [0_u8; 4];
30 self.inner.read_exact(&mut header)?;
31
32 match &header[..] {
33 b"DATA" => {
34 let length = self.inner.read_u32::<LittleEndian>()? as usize;
35 let min_data_to_read = std::cmp::min(length, buf.len());
37 let effective_read = self.inner.read(&mut buf[0..min_data_to_read])?;
38 self.remaining_data_bytes_to_read = length - effective_read;
39
40 Ok(effective_read)
41 }
42 b"DONE" => Ok(0),
43 b"FAIL" => {
44 let length = self.inner.read_u32::<LittleEndian>()? as usize;
45 let mut error_msg = vec![0; length];
46 self.inner.read_exact(&mut error_msg)?;
47
48 Err(std::io::Error::other(format!(
49 "ADB request failed: {}",
50 String::from_utf8_lossy(&error_msg)
51 )))
52 }
53 _ => Err(std::io::Error::other(format!(
54 "Unknown response from device {header:#?}"
55 ))),
56 }
57 } else {
58 let data_to_read = std::cmp::min(self.remaining_data_bytes_to_read, buf.len());
60 self.inner.read_exact(&mut buf[..data_to_read])?;
61
62 self.remaining_data_bytes_to_read -= data_to_read;
63
64 Ok(data_to_read)
65 }
66 }
67}
68
69const BUFFER_SIZE: usize = 65535;
70
71impl ADBServerDevice {
72 pub fn pull(&mut self, path: &dyn AsRef<str>, stream: &mut dyn Write) -> Result<()> {
74 self.set_serial_transport()?;
75
76 self.transport
78 .send_adb_request(&ADBCommand::Local(ADBLocalCommand::Sync))?;
79
80 self.transport.send_sync_request(&SyncCommand::Recv)?;
82
83 self.handle_recv_command(path, stream)
84 }
85
86 fn handle_recv_command<S: AsRef<str>>(&self, from: S, output: &mut dyn Write) -> Result<()> {
87 let mut raw_connection = self.transport.get_raw_connection()?;
88
89 let from_as_bytes = from.as_ref().as_bytes();
90 let mut buffer = Vec::with_capacity(4 + from_as_bytes.len());
91 buffer.extend_from_slice(&(u32::try_from(from.as_ref().len())?).to_le_bytes());
92 buffer.extend_from_slice(from_as_bytes);
93 raw_connection.write_all(&buffer)?;
94
95 let reader = ADBRecvCommandReader::new(raw_connection);
96 std::io::copy(
97 &mut BufReader::with_capacity(BUFFER_SIZE, reader),
98 &mut BufWriter::with_capacity(BUFFER_SIZE, output),
99 )?;
100
101 Ok(())
103 }
104}