1use std::fs;
2use std::io;
3use std::net;
4use std::path;
5
6use rusb::Direction;
7use rusb::TransferType;
8use rusb::UsbContext;
9use rusb::{Context, DeviceHandle};
10
11pub struct Usb {
12 _vendor_id: u16,
13 _product_id: u16,
14 connection: DeviceHandle<Context>,
15 endpoint: u8,
16}
17
18pub struct Serial {}
19
20#[derive(Debug)]
21pub struct Network {
22 _host: String,
23 _port: u16,
24 stream: net::TcpStream,
25}
26
27impl Network {
28 pub fn new(host: &str, port: u16) -> io::Result<Network> {
29 let stream = net::TcpStream::connect((host, port))?;
30 Ok(Network {
31 _host: host.to_string(),
32 _port: port,
33 stream,
34 })
35 }
36}
37
38impl io::Write for Network {
39 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
40 self.stream.write(buf)
41 }
42
43 fn flush(&mut self) -> io::Result<()> {
44 self.stream.flush()
45 }
46}
47
48#[derive(Debug)]
51pub struct File<W> {
52 fobj: W,
53}
54
55impl<W: io::Write> File<W> {
56 pub fn from_path<P: AsRef<path::Path> + ToString>(path: P) -> io::Result<File<fs::File>> {
57 let fobj = fs::OpenOptions::new()
58 .write(true)
59 .create(true)
60 .truncate(true)
61 .open(&path)?;
62 Ok(File { fobj })
63 }
64
65 pub fn from(fobj: W) -> File<W> {
76 File { fobj }
77 }
78}
79
80impl<W: io::Write> io::Write for File<W> {
81 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
82 self.fobj.write(buf)
83 }
84
85 fn flush(&mut self) -> io::Result<()> {
86 self.fobj.flush()
87 }
88}
89
90impl Usb {
91 pub fn new(vendor_id: u16, product_id: u16) -> io::Result<Usb> {
104 let context = Context::new().map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
105 let devices = context
106 .devices()
107 .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
108
109 for device in devices.iter() {
110 let device_desc = device
111 .device_descriptor()
112 .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
113
114 if device_desc.vendor_id() == vendor_id && device_desc.product_id() == product_id {
115 let config_descriptor = device
116 .active_config_descriptor()
117 .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
118
119 let endpoint = config_descriptor
120 .interfaces()
121 .flat_map(|interface| interface.descriptors())
122 .flat_map(|descriptor| descriptor.endpoint_descriptors())
123 .find_map(|endpoint| {
124 if let (TransferType::Bulk, Direction::Out) =
125 (endpoint.transfer_type(), endpoint.direction())
126 {
127 Some(endpoint.number())
128 } else {
129 None
130 }
131 })
132 .ok_or_else(|| {
133 io::Error::new(io::ErrorKind::Other, "No suitable endpoint found")
134 })?;
135
136 match device.open() {
137 Ok(dvc) => {
138 if let Ok(active) = dvc.kernel_driver_active(0) {
139 if active {
140 if let Err(e) = dvc.detach_kernel_driver(0) {
141 return Err(io::Error::new(io::ErrorKind::Other, e));
142 }
143 }
144 } else {
145 return Err(io::Error::new(
146 io::ErrorKind::Other,
147 "Error checking kernel driver",
148 ));
149 };
150
151 return dvc
152 .claim_interface(0)
153 .map(|_| Usb {
154 _vendor_id: vendor_id,
155 _product_id: product_id,
156 connection: dvc,
157 endpoint,
158 })
159 .map_err(|e| io::Error::new(io::ErrorKind::Other, e));
160 }
161 Err(_) => return Err(io::Error::new(io::ErrorKind::Other, "Device busy")),
162 }
163 }
164 }
165
166 Err(io::Error::new(io::ErrorKind::Other, "USB not found"))
167 }
168}
169
170impl io::Write for Usb {
171 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
172 match self
173 .connection
174 .write_bulk(self.endpoint, buf, std::time::Duration::from_secs(5))
175 {
176 Ok(_) => Ok(buf.len()),
177 Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
178 }
179 }
180
181 fn flush(&mut self) -> io::Result<()> {
182 Ok(())
183 }
184}