Skip to main content

android_usb_serial/drivers/
gsm_modem.rs

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