android_usb_serial/drivers/
mod.rs1mod cdc_acm;
8mod ch34x;
9mod chrome_ccd;
10mod cp21xx;
11mod ftdi;
12mod gsm_modem;
13mod prolific;
14
15pub use cdc_acm::CdcAcmDriver;
16pub use ch34x::Ch34xDriver;
17pub use chrome_ccd::ChromeCcdDriver;
18pub use cp21xx::Cp21xxDriver;
19pub use ftdi::ftdi_baud_encoding;
20pub use ftdi::FtdiDriver;
21pub use gsm_modem::GsmModemDriver;
22pub use prolific::ProlificDriver;
23
24use crate::config::{FlowControl, LineConfig, PurgeKind};
25use crate::error::Result;
26use crate::probe::DriverType;
27use crate::reader::SerialReader;
28use crate::rx_filter::RxFilter;
29use crate::transport::{BulkIn, BulkOut, SharedTransport};
30
31pub const WRITE_TIMEOUT_MS: u32 = 5000;
33
34#[derive(Debug, Clone, Copy, Default)]
36pub struct ModemStatus {
37 pub cts: bool,
38 pub dsr: bool,
39 pub ri: bool,
40 pub cd: bool,
41}
42
43pub trait Driver: Send {
45 fn open(&mut self, transport: &SharedTransport) -> Result<()>;
46 fn close(&mut self) -> Result<()>;
47 fn write(&mut self, data: &[u8]) -> Result<usize>;
48 fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
49 fn set_line_config(&mut self, cfg: LineConfig) -> Result<()>;
50 fn set_flow_control(&mut self, flow: FlowControl) -> Result<()>;
51 fn set_dtr(&mut self, value: bool) -> Result<()>;
52 fn set_rts(&mut self, value: bool) -> Result<()>;
53 fn set_break(&mut self, enabled: bool) -> Result<()>;
54 fn purge(&mut self, kind: PurgeKind) -> Result<()>;
55 fn modem_status(&mut self) -> Result<ModemStatus>;
56 fn bulk_in_mps(&self) -> u16;
57 fn take_bulk_in(&mut self) -> Option<Box<dyn BulkIn>>;
58 fn rx_filters(&self) -> Vec<Box<dyn RxFilter>> {
59 Vec::new()
60 }
61 fn start_reader(&mut self) -> Result<SerialReader> {
62 let bulk = self
63 .take_bulk_in()
64 .ok_or_else(|| crate::error::UsbSerialError::Io("no bulk in".into()))?;
65 Ok(SerialReader::start(
66 bulk,
67 self.bulk_in_mps(),
68 200,
69 self.rx_filters(),
70 ))
71 }
72}
73
74pub fn create_driver(driver_type: DriverType, port_index: usize) -> Box<dyn Driver> {
76 match driver_type {
77 DriverType::CdcAcm => Box::new(CdcAcmDriver::new(port_index)),
78 DriverType::Ftdi => Box::new(FtdiDriver::new(port_index)),
79 DriverType::Cp21xx => Box::new(Cp21xxDriver::new(port_index)),
80 DriverType::Ch34x => Box::new(Ch34xDriver::new(port_index)),
81 DriverType::Prolific => Box::new(ProlificDriver::new(port_index)),
82 DriverType::GsmModem => Box::new(GsmModemDriver::new(port_index)),
83 DriverType::ChromeCcd => Box::new(ChromeCcdDriver::new(port_index)),
84 }
85}
86
87pub fn line_coding_bytes(cfg: &LineConfig) -> [u8; 7] {
88 let stop = match cfg.stop_bits {
89 crate::config::StopBits::One => 0u8,
90 crate::config::StopBits::OnePointFive => 1,
91 crate::config::StopBits::Two => 2,
92 };
93 let parity = match cfg.parity {
94 crate::config::Parity::None => 0,
95 crate::config::Parity::Odd => 1,
96 crate::config::Parity::Even => 2,
97 crate::config::Parity::Mark => 3,
98 crate::config::Parity::Space => 4,
99 };
100 let data = match cfg.data_bits {
101 crate::config::DataBits::Five => 5,
102 crate::config::DataBits::Six => 6,
103 crate::config::DataBits::Seven => 7,
104 crate::config::DataBits::Eight => 8,
105 };
106 [
107 (cfg.baud_rate & 0xff) as u8,
108 ((cfg.baud_rate >> 8) & 0xff) as u8,
109 ((cfg.baud_rate >> 16) & 0xff) as u8,
110 ((cfg.baud_rate >> 24) & 0xff) as u8,
111 stop,
112 parity,
113 data,
114 ]
115}
116
117struct EndpointPair {
118 bulk_in: Option<Box<dyn BulkIn>>,
119 bulk_out: Option<Box<dyn BulkOut>>,
120 in_ep: u8,
121 out_ep: u8,
122 mps: u16,
123}
124
125impl EndpointPair {
126 pub(crate) fn from_addresses(in_ep: u8, out_ep: u8, mps: u16) -> Self {
127 Self {
128 bulk_in: None,
129 bulk_out: None,
130 in_ep,
131 out_ep,
132 mps,
133 }
134 }
135
136 fn open(transport: &SharedTransport, iface: u8) -> Result<Self> {
137 let eps = transport.endpoints(iface);
138 let in_ep = eps
139 .iter()
140 .find(|e| e.is_bulk_in())
141 .ok_or_else(|| crate::error::UsbSerialError::ProbeFailed("no bulk in".into()))?;
142 let out_ep = eps
143 .iter()
144 .find(|e| e.is_bulk_out())
145 .ok_or_else(|| crate::error::UsbSerialError::ProbeFailed("no bulk out".into()))?;
146 Ok(Self {
147 bulk_in: None,
148 bulk_out: None,
149 in_ep: in_ep.address,
150 out_ep: out_ep.address,
151 mps: in_ep.max_packet_size,
152 })
153 }
154
155 fn ensure_out(&mut self, transport: &SharedTransport) -> Result<()> {
156 if self.bulk_out.is_none() {
157 self.bulk_out = Some(transport.open_bulk_out(self.out_ep, self.mps)?);
158 }
159 Ok(())
160 }
161
162 fn ensure_in(&mut self, transport: &SharedTransport) -> Result<()> {
163 if self.bulk_in.is_none() {
164 self.bulk_in = Some(transport.open_bulk_in(self.in_ep, self.mps)?);
165 }
166 Ok(())
167 }
168
169 fn write(&mut self, transport: &SharedTransport, data: &[u8]) -> Result<usize> {
170 self.ensure_out(transport)?;
173 self.bulk_out
174 .as_mut()
175 .unwrap()
176 .write(data, WRITE_TIMEOUT_MS)
177 }
178
179 fn take_in(&mut self, transport: &SharedTransport) -> Option<Box<dyn BulkIn>> {
180 self.ensure_in(transport).ok()?;
181 self.bulk_in.take()
182 }
183}