usb_gadget/function/
net.rs1use macaddr::MacAddr6;
4use std::{
5 ffi::{OsStr, OsString},
6 io::{Error, ErrorKind, Result},
7};
8
9use super::{
10 util::{FunctionDir, Status},
11 Function, Handle,
12};
13use crate::{gadget::Class, hex_u8_noprefix};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
17#[non_exhaustive]
18pub enum NetClass {
19 Ecm,
23 EcmSubset,
27 Eem,
31 Ncm,
35 Rndis,
39}
40
41impl NetClass {
42 fn driver(&self) -> &OsStr {
43 OsStr::new(match self {
44 NetClass::Ecm => "ecm",
45 NetClass::EcmSubset => "geth",
46 NetClass::Eem => "eem",
47 NetClass::Ncm => "ncm",
48 NetClass::Rndis => "rndis",
49 })
50 }
51}
52
53#[derive(Debug, Clone)]
55#[non_exhaustive]
56pub struct NetBuilder {
57 net_class: NetClass,
58 pub dev_addr: Option<MacAddr6>,
60 pub host_addr: Option<MacAddr6>,
62 pub qmult: Option<u32>,
64 pub interface_class: Option<Class>,
66}
67
68impl NetBuilder {
69 #[must_use]
73 pub fn build(self) -> (Net, Handle) {
74 let dir = FunctionDir::new();
75 (Net { dir: dir.clone() }, Handle::new(NetFunction { builder: self, dir }))
76 }
77}
78
79#[derive(Debug)]
80struct NetFunction {
81 builder: NetBuilder,
82 dir: FunctionDir,
83}
84
85impl Function for NetFunction {
86 fn driver(&self) -> OsString {
87 self.builder.net_class.driver().to_os_string()
88 }
89
90 fn dir(&self) -> FunctionDir {
91 self.dir.clone()
92 }
93
94 fn register(&self) -> Result<()> {
95 if let Some(dev_addr) = self.builder.dev_addr {
96 self.dir.write("dev_addr", dev_addr.to_string())?;
97 }
98
99 if let Some(host_addr) = self.builder.host_addr {
100 self.dir.write("host_addr", host_addr.to_string())?;
101 }
102
103 if let Some(qmult) = self.builder.qmult {
104 self.dir.write("qmult", qmult.to_string())?;
105 }
106
107 if let (NetClass::Rndis, Some(class)) = (self.builder.net_class, self.builder.interface_class) {
108 self.dir.write("class", hex_u8_noprefix(class.class))?;
109 self.dir.write("subclass", hex_u8_noprefix(class.sub_class))?;
110 self.dir.write("protocol", hex_u8_noprefix(class.protocol))?;
111 }
112
113 Ok(())
114 }
115}
116
117#[derive(Debug)]
119pub struct Net {
120 dir: FunctionDir,
121}
122
123impl Net {
124 pub fn new(net_class: NetClass) -> (Net, Handle) {
126 Self::builder(net_class).build()
127 }
128
129 pub fn builder(net_class: NetClass) -> NetBuilder {
131 NetBuilder { net_class, dev_addr: None, host_addr: None, qmult: None, interface_class: None }
132 }
133
134 pub fn status(&self) -> Status {
136 self.dir.status()
137 }
138
139 pub fn dev_addr(&self) -> Result<MacAddr6> {
141 self.dir.read_string("dev_addr")?.parse().map_err(|err| Error::new(ErrorKind::InvalidData, err))
142 }
143
144 pub fn host_addr(&self) -> Result<MacAddr6> {
146 self.dir.read_string("host_addr")?.parse().map_err(|err| Error::new(ErrorKind::InvalidData, err))
147 }
148
149 pub fn ifname(&self) -> Result<OsString> {
151 self.dir.read_os_string("ifname")
152 }
153}