1use crate::mux::connection::{usbmuxd_socket_address, UsbmuxStream};
2use crate::mux::protocol::*;
3use crate::mux::{MuxDevice, MuxError};
4
5pub struct MuxClient {
7 stream: UsbmuxStream,
8 tag: u32,
9}
10
11impl MuxClient {
12 pub async fn connect() -> Result<Self, MuxError> {
14 let addr = usbmuxd_socket_address();
15 let stream = UsbmuxStream::connect(&addr).await?;
16 Ok(Self { stream, tag: 1 })
17 }
18
19 pub async fn list_devices(&mut self) -> Result<Vec<MuxDevice>, MuxError> {
21 let req = ListDevicesRequest {
22 message_type: "ListDevices",
23 prog_name: "ios-rs",
24 client_version_string: "ios-rs-0.1",
25 };
26 let tag = self.next_tag();
27 send_plist(&mut self.stream, &req, tag).await?;
28 let resp: DeviceList = recv_plist(&mut self.stream).await?;
29 Ok(resp
30 .device_list
31 .into_iter()
32 .map(MuxDevice::from_raw)
33 .collect())
34 }
35
36 pub async fn read_buid(&mut self) -> Result<String, MuxError> {
38 let req = ReadBuidRequest {
39 message_type: "ReadBUID",
40 prog_name: "ios-rs",
41 client_version_string: "ios-rs-0.1",
42 bundle_id: "rs.ios",
43 lib_usbmux_version: 3,
44 };
45 let tag = self.next_tag();
46 send_plist(&mut self.stream, &req, tag).await?;
47 let resp: ReadBuidResponse = recv_plist(&mut self.stream).await?;
48 Ok(resp.buid)
49 }
50
51 pub async fn read_pair_record(&mut self, udid: &str) -> Result<(), MuxError> {
53 let req = ReadPairRecordRequest {
54 message_type: "ReadPairRecord",
55 prog_name: "ios-rs",
56 client_version_string: "ios-rs-0.1",
57 bundle_id: "rs.ios",
58 lib_usbmux_version: 3,
59 pair_record_id: udid.to_string(),
60 };
61 let tag = self.next_tag();
62 send_plist(&mut self.stream, &req, tag).await?;
63 let _: plist::Value = recv_plist(&mut self.stream).await?;
64 Ok(())
65 }
66
67 pub async fn connect_to_port(
69 mut self,
70 device_id: u32,
71 port: u16,
72 ) -> Result<UsbmuxStream, MuxError> {
73 let be_port = port.to_be();
74 let req = ConnectRequest {
75 message_type: "Connect",
76 prog_name: "ios-rs",
77 client_version_string: "ios-rs-0.1",
78 bundle_id: "rs.ios",
79 lib_usbmux_version: 3,
80 device_id,
81 port_number: be_port,
82 };
83 let tag = self.next_tag();
84 send_plist(&mut self.stream, &req, tag).await?;
85 let resp: ConnectResponse = recv_plist(&mut self.stream).await?;
86 if resp.number != 0 {
87 return Err(MuxError::Protocol(format!(
88 "usbmuxd connect failed: code {}",
89 resp.number
90 )));
91 }
92 Ok(self.stream)
93 }
94
95 fn next_tag(&mut self) -> u32 {
96 let t = self.tag;
97 self.tag += 1;
98 t
99 }
100}