usb_gadget/function/
serial.rs1use std::{
4 ffi::{OsStr, OsString},
5 io::{Error, ErrorKind, Result},
6 path::PathBuf,
7};
8
9use super::{
10 util::{FunctionDir, Status},
11 Function, Handle,
12};
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16#[non_exhaustive]
17pub enum SerialClass {
18 Acm,
22 Generic,
26}
27
28impl SerialClass {
29 fn driver(&self) -> &OsStr {
30 OsStr::new(match self {
31 SerialClass::Acm => "acm",
32 SerialClass::Generic => "gser",
33 })
34 }
35}
36
37#[derive(Debug, Clone)]
39#[non_exhaustive]
40pub struct SerialBuilder {
41 serial_class: SerialClass,
42 pub console: Option<bool>,
44}
45
46impl SerialBuilder {
47 #[must_use]
51 pub fn build(self) -> (Serial, Handle) {
52 let dir = FunctionDir::new();
53 (Serial { dir: dir.clone() }, Handle::new(SerialFunction { builder: self, dir }))
54 }
55}
56
57#[derive(Debug)]
58struct SerialFunction {
59 builder: SerialBuilder,
60 dir: FunctionDir,
61}
62
63impl Function for SerialFunction {
64 fn driver(&self) -> OsString {
65 self.builder.serial_class.driver().to_os_string()
66 }
67
68 fn dir(&self) -> FunctionDir {
69 self.dir.clone()
70 }
71
72 fn register(&self) -> Result<()> {
73 if let Some(console) = self.builder.console {
74 let _ = self.dir.write("console", if console { "1" } else { "0" });
76 }
77
78 Ok(())
79 }
80}
81
82#[derive(Debug)]
84pub struct Serial {
85 dir: FunctionDir,
86}
87
88impl Serial {
89 pub fn new(serial_class: SerialClass) -> (Serial, Handle) {
91 Self::builder(serial_class).build()
92 }
93
94 pub fn builder(serial_class: SerialClass) -> SerialBuilder {
96 SerialBuilder { serial_class, console: None }
97 }
98
99 pub fn status(&self) -> Status {
101 self.dir.status()
102 }
103
104 pub fn tty(&self) -> Result<PathBuf> {
106 let port_num: u32 =
107 self.dir.read_string("port_num")?.parse().map_err(|err| Error::new(ErrorKind::InvalidData, err))?;
108 Ok(format!("/dev/ttyGS{port_num}").into())
109 }
110}