1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
use {Error, ResultExt};
use {command, protocol, sensor};
use std::ptr;
use std;
use std::time::Duration;
use libusb;
pub const PSVR_VID: u16 = 0x054c;
pub const PSVR_PID: u16 = 0x09af;
pub type ByteOrder = ::byteorder::LittleEndian;
#[allow(dead_code)]
mod usb_interfaces {
pub type InterfaceAddress = u8;
pub const AUDIO_3D: InterfaceAddress = 0;
pub const AUDIO_CONTROL: InterfaceAddress = 1;
pub const AUDIO_MIC: InterfaceAddress = 2;
pub const AUDIO_CHAT: InterfaceAddress = 3;
pub const HID_SENSOR: InterfaceAddress = 4;
pub const HID_CONTROL: InterfaceAddress = 5;
pub const VS_H264: InterfaceAddress = 6;
pub const VS_BULK_IN: InterfaceAddress = 7;
pub const HID_CONTROL2: InterfaceAddress = 8;
pub const INTERFACES_TO_CLAIM: &'static [InterfaceAddress] = &[
HID_SENSOR,
HID_CONTROL,
];
}
pub struct Psvr<'a> {
context: &'a libusb::Context,
device: libusb::Device<'a>,
device_desc: libusb::DeviceDescriptor,
handle: libusb::DeviceHandle<'a>,
}
#[derive(Debug)]
pub struct Endpoint {
config: u8,
iface: u8,
setting: u8,
address: u8
}
pub fn iter(context: &libusb::Context) -> Result<Iter, Error> {
let devices: Vec<_> = context.devices()?.iter().collect();
Ok(Iter {
context: context,
devices: devices.into_iter(),
})
}
pub struct Iter<'a> {
context: &'a libusb::Context,
devices: std::vec::IntoIter<libusb::Device<'a>>,
}
impl<'a> Iterator for Iter<'a> {
type Item = Result<Psvr<'a>, Error>;
fn next(&mut self) -> Option<Result<Psvr<'a>, Error>> {
loop {
match self.devices.next() {
Some(device) => {
let device_desc = match device.device_descriptor() {
Ok(device) => device,
Err(_) => continue
};
if device_desc.vendor_id() == PSVR_VID &&
device_desc.product_id() == PSVR_PID {
break Some(Psvr::open(self.context, device, device_desc));
}
},
None => break None,
}
}
}
}
impl<'a> Psvr<'a> {
pub fn open(context: &'a libusb::Context,
device: libusb::Device<'a>,
device_desc: libusb::DeviceDescriptor) -> Result<Self, Error> {
let handle = device.open()?;
let mut psvr = Psvr {
context, device, device_desc, handle,
};
psvr.initialize()?;
Ok(psvr)
}
pub fn print_information(&self) -> Result<(), Error> {
let timeout = Duration::from_secs(1);
let languages = self.handle.read_languages(timeout)?;
println!("Active configuration: {}", self.handle.active_configuration()?);
println!("Languages: {:?}", languages);
if languages.len() > 0 {
let language = languages[0];
println!("Manufacturer: {:?}", self.handle.read_manufacturer_string(language, &self.device_desc, timeout).ok());
println!("Product: {:?}", self.handle.read_product_string(language, &self.device_desc, timeout).ok());
println!("Serial Number: {:?}", self.handle.read_serial_number_string(language, &self.device_desc, timeout).ok());
}
Ok(())
}
pub fn send_command<C>(&mut self,
command: &C) -> Result<(), Error>
where C: command::Command {
let payload = command.payload_bytes();
assert!(payload.len() <= protocol::COMMAND_PAYLOAD_SIZE,
"command payload too large for protocol");
let mut temp_payload = [0; protocol::COMMAND_PAYLOAD_SIZE];
unsafe {
ptr::copy(payload.as_ptr(), temp_payload.as_mut_ptr(), 1);
}
let payload = temp_payload;
let command = protocol::Command {
header: protocol::CommandHeader {
id: C::ID,
magic: 0xAA,
status: 0,
length: payload.len() as u8,
},
payload: payload,
};
let raw_command = unsafe { ::std::slice::from_raw_parts(
&command as *const _ as *const u8,
::std::mem::size_of_val(&command))
};
self.send_raw(raw_command).chain_err(|| "could not send command")
}
fn initialize(&mut self) -> Result<(), Error> {
self.handle.reset()?;
let config_desc = self.config_desc();
for &interface_number in usb_interfaces::INTERFACES_TO_CLAIM {
let interface = config_desc.interfaces()
.nth(interface_number as usize)
.expect("could not find interface");
match self.handle.kernel_driver_active(interface.number()) {
Ok(true) => if self.context.supports_detach_kernel_driver() {
self.handle.detach_kernel_driver(interface.number()).ok();
} else {
eprintln!("cannot detach the kernel driver on this platform");
},
_ => ()
}
}
Ok(())
}
fn send_raw(&mut self,
data: &[u8]) -> Result<(), Error> {
let timeout = Duration::from_secs(1);
let config_desc = self.config_desc();
let interface = config_desc.interfaces()
.nth(usb_interfaces::HID_CONTROL as usize)
.expect("could not find interface");
let interface_desc = interface.descriptors()
.next()
.expect("could not find interface descriptor");
let endpoint_desc = interface_desc.endpoint_descriptors()
.filter(|e| e.direction() == libusb::Direction::Out)
.next()
.expect("could not get endpoint desc");
self.handle.write_bulk(endpoint_desc.address(), data, timeout)?;
Ok(())
}
pub fn receive_sensor(&mut self) -> Result<sensor::Frame, Error> {
use self::sensor::Readable;
let timeout = Duration::from_secs(1);
let config_desc = self.config_desc();
let interface = config_desc.interfaces()
.nth(usb_interfaces::HID_SENSOR as usize)
.expect("could not find interface");
let interface_desc = interface.descriptors()
.next()
.expect("could not find interface descriptor");
let endpoint_desc = interface_desc.endpoint_descriptors()
.filter(|e| e.direction() == libusb::Direction::In)
.next()
.expect("could not get endpoint desc");
let mut buf: [u8; sensor::FRAME_SIZE] = [0; sensor::FRAME_SIZE];
let bytes_read = self.handle.read_interrupt(endpoint_desc.address(), &mut buf, timeout).chain_err(|| "could not read from device")?;
if bytes_read != sensor::FRAME_SIZE {
panic!("not enough bytes read of sensor frame");
}
let frame = sensor::Frame::read_bytes(&mut buf)?;
Ok(frame)
}
pub fn set_power(&mut self, on: bool) -> Result<(), Error> {
self.send_command(&command::SetPower { on })
}
fn config_desc(&self) -> libusb::ConfigDescriptor {
self.device.config_descriptor(0).expect("could not get first config descriptor")
}
}