Skip to main content

android_usb_serial/drivers/
chrome_ccd.rs

1//! Google Chrome OS CCD (3 ports — interface N = port N, no CDC init).
2
3use super::{Driver, EndpointPair, ModemStatus};
4use crate::config::{FlowControl, LineConfig, PurgeKind};
5use crate::error::{Result, UsbSerialError};
6use crate::reader::SerialReader;
7use crate::transport::SharedTransport;
8
9pub struct ChromeCcdDriver {
10    port_index: usize,
11    iface: u8,
12    endpoints: Option<EndpointPair>,
13    transport: Option<SharedTransport>,
14    reader: Option<SerialReader>,
15}
16
17impl ChromeCcdDriver {
18    pub fn new(port_index: usize) -> Self {
19        Self {
20            port_index,
21            iface: port_index as u8,
22            endpoints: None,
23            transport: None,
24            reader: None,
25        }
26    }
27}
28
29impl Driver for ChromeCcdDriver {
30    fn open(&mut self, transport: &SharedTransport) -> Result<()> {
31        self.transport = Some(transport.clone());
32        self.iface = self.port_index as u8;
33        transport.claim_interface(self.iface)?;
34        self.endpoints = Some(EndpointPair::open(transport, self.iface)?);
35        Ok(())
36    }
37
38    fn close(&mut self) -> Result<()> {
39        if let Some(mut r) = self.reader.take() {
40            r.stop();
41        }
42        if let Some(t) = &self.transport {
43            let _ = t.release_interface(self.iface);
44        }
45        self.endpoints = None;
46        Ok(())
47    }
48
49    fn write(&mut self, data: &[u8]) -> Result<usize> {
50        let t = self.transport.as_ref().unwrap();
51        self.endpoints.as_mut().unwrap().write(t, data)
52    }
53
54    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
55        if let Some(reader) = &mut self.reader {
56            return reader.try_read(buf);
57        }
58        Ok(0)
59    }
60
61    fn set_line_config(&mut self, _cfg: LineConfig) -> Result<()> {
62        Err(UsbSerialError::Unsupported("line config".into()))
63    }
64
65    fn set_flow_control(&mut self, flow: FlowControl) -> Result<()> {
66        if flow != FlowControl::None {
67            return Err(UsbSerialError::Unsupported("flow control".into()));
68        }
69        Ok(())
70    }
71
72    fn set_dtr(&mut self, _value: bool) -> Result<()> {
73        Err(UsbSerialError::Unsupported("dtr".into()))
74    }
75
76    fn set_rts(&mut self, _value: bool) -> Result<()> {
77        Err(UsbSerialError::Unsupported("rts".into()))
78    }
79
80    fn set_break(&mut self, _enabled: bool) -> Result<()> {
81        Err(UsbSerialError::Unsupported("break".into()))
82    }
83
84    fn purge(&mut self, _kind: PurgeKind) -> Result<()> {
85        Err(UsbSerialError::Unsupported("purge".into()))
86    }
87
88    fn modem_status(&mut self) -> Result<ModemStatus> {
89        Ok(ModemStatus::default())
90    }
91
92    fn bulk_in_mps(&self) -> u16 {
93        self.endpoints.as_ref().map(|e| e.mps).unwrap_or(64)
94    }
95
96    fn take_bulk_in(&mut self) -> Option<Box<dyn crate::transport::BulkIn>> {
97        let transport = self.transport.as_ref()?;
98        self.endpoints.as_mut()?.take_in(transport)
99    }
100}