hid/
handle.rs

1use std::time::Duration;
2
3use libc::c_int;
4use sys::*;
5use error::{self, Error};
6
7/// A device handle.
8pub struct Handle {
9	ptr: *mut hid_device,
10}
11
12impl Handle {
13	#[doc(hidden)]
14	pub unsafe fn new(ptr: *mut hid_device) -> Self {
15		Handle {
16			ptr: ptr,
17		}
18	}
19
20	#[doc(hidden)]
21	pub unsafe fn as_ptr(&self) -> *const hid_device {
22		self.ptr as *const _
23	}
24
25	#[doc(hidden)]
26	pub unsafe fn as_mut_ptr(&mut self) -> *mut hid_device {
27		self.ptr
28	}
29}
30
31impl Handle {
32	/// Set the handle in blocking or non-blocking mode.
33	pub fn blocking(&mut self, value: bool) -> error::Result<&mut Self> {
34		unsafe {
35			match hid_set_nonblocking(self.as_mut_ptr(), if value { 1 } else { 0 }) {
36				0 =>
37					Ok(self),
38
39				_ =>
40					Err(Error::General)
41			}
42		}
43	}
44
45	/// The data accessor.
46	pub fn data(&mut self) -> Data {
47		unsafe {
48			Data::new(self)
49		}
50	}
51
52	/// The feature accessor.
53	pub fn feature(&mut self) -> Feature {
54		unsafe {
55			Feature::new(self)
56		}
57	}
58}
59
60/// The data accessor.
61pub struct Data<'a> {
62	handle: &'a mut Handle,
63}
64
65impl<'a> Data<'a> {
66	#[doc(hidden)]
67	pub unsafe fn new(handle: &mut Handle) -> Data {
68		Data { handle: handle }
69	}
70
71	/// Write data to the device.
72	///
73	/// The first byte must be the report ID.
74	pub fn write<T: AsRef<[u8]>>(&mut self, data: T) -> error::Result<usize> {
75		let data = data.as_ref();
76
77		unsafe {
78			match hid_write(self.handle.as_mut_ptr(), data.as_ptr(), data.len()) {
79				-1 =>
80					Err(Error::Write),
81
82				length =>
83					Ok(length as usize)
84			}
85		}
86	}
87
88	/// Write data to the device with the given report ID.
89	pub fn write_to<T: AsRef<[u8]>>(&mut self, id: u8, data: T) -> error::Result<usize> {
90		let     data   = data.as_ref();
91		let mut buffer = vec![0u8; data.len() + 1];
92
93		buffer[0] = id;
94		(&mut buffer[1 ..]).copy_from_slice(data);
95
96		self.write(&buffer)
97	}
98
99	/// Read data from the device.
100	///
101	/// If the device supports reports the first byte will contain the report ID.
102	///
103	/// Returns the amount of read bytes or `None` if there was a timeout.
104	pub fn read<T: AsMut<[u8]>>(&mut self, mut data: T, timeout: Duration) -> error::Result<Option<usize>> {
105		let data   = data.as_mut();
106		let result = if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
107			unsafe {
108				hid_read(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len())
109			}
110		}
111		else {
112			unsafe {
113				// Timeout is in milliseconds.
114				hid_read_timeout(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len(),
115					timeout.as_secs() as c_int * 1_000 + timeout.subsec_nanos() as c_int / 1_000_000)
116			}
117		};
118
119		match result {
120			-1 =>
121				Err(Error::Read),
122
123			0 =>
124				Ok(None),
125
126			v =>
127				Ok(Some(v as usize))
128		}
129	}
130
131	/// Read data from the device.
132	///
133	/// Returns the report ID and the amount of read bytes or `None` if there was a timeout.
134	pub fn read_from<T: AsMut<[u8]>>(&mut self, mut data: T, timeout: Duration) -> error::Result<Option<(u8, usize)>> {
135		let     data   = data.as_mut();
136		let mut buffer = Vec::with_capacity(data.len() + 1);
137
138		if let Some(length) = self.read(&mut buffer, timeout)? {
139			data[0..length - 1].copy_from_slice(&buffer[1..length]);
140
141			Ok(Some((buffer[0], length - 1)))
142		}
143		else {
144			Ok(None)
145		}
146	}
147}
148
149/// The feature accessor.
150pub struct Feature<'a> {
151	handle: &'a mut Handle,
152}
153
154impl<'a> Feature<'a> {
155	#[doc(hidden)]
156	pub unsafe fn new(handle: &mut Handle) -> Feature {
157		Feature { handle: handle }
158	}
159
160	/// Send a feature request.
161	///
162	/// The first byte must be the report ID.
163	pub fn send<T: AsRef<[u8]>>(&mut self, data: T) -> error::Result<usize> {
164		let data = data.as_ref();
165
166		unsafe {
167			match hid_send_feature_report(self.handle.as_mut_ptr(), data.as_ptr(), data.len()) {
168				-1 =>
169					Err(Error::Write),
170
171				length =>
172					Ok(length as usize)
173			}
174		}
175	}
176
177	/// Send a feature request to the given report ID.
178	pub fn send_to<T: AsRef<[u8]>>(&mut self, id: u8, data: T) -> error::Result<usize> {
179		let     data   = data.as_ref();
180		let mut buffer = Vec::with_capacity(data.len() + 1);
181
182		buffer.push(id);
183		buffer.extend(data);
184
185		self.send(&buffer).map(|v| v - 1)
186	}
187
188	/// Get a feature request.
189	///
190	/// The first byte must be the report ID.
191	pub fn get<T: AsMut<[u8]>>(&mut self, mut data: T) -> error::Result<usize> {
192		let data = data.as_mut();
193
194		unsafe {
195			match hid_get_feature_report(self.handle.as_mut_ptr(), data.as_mut_ptr(), data.len()) {
196				-1 =>
197					Err(Error::Read),
198
199				length =>
200					Ok(length as usize)
201			}
202		}
203	}
204
205	/// Get a feature request from the given report ID.
206	pub fn get_from<T: AsMut<[u8]>>(&mut self, id: u8, mut data: T) -> error::Result<usize> {
207		let     data   = data.as_mut();
208		let mut buffer = vec![0u8; data.len() + 1];
209		buffer[0] = id;
210
211		let length = self.get(&mut buffer)?;
212		data[0..length - 1].copy_from_slice(&buffer[1..length]);
213
214		Ok(length - 1)
215	}
216}
217
218impl Drop for Handle {
219	fn drop(&mut self) {
220		unsafe {
221			hid_close(self.as_mut_ptr());
222		}
223	}
224}