Skip to content

Commit 3c8243d

Browse files
committed
[Cosmos] Read configuration ok.
1 parent cc807d5 commit 3c8243d

File tree

2 files changed

+132
-26
lines changed

2 files changed

+132
-26
lines changed

bin/driver-proxy/src/server/driver_host.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::os::raw::c_char;
77
use std::rc::Rc;
88
use tracing::{error, info};
99
use valve_pm::{StationCommand, StationControl, StationState};
10-
use vive_hid::{SteamDevice, ViveDevice};
10+
use vive_hid::{SteamDevice, ViveCosmosDevice};
1111

1212
use crate::driver_context::DRIVER_CONTEXT;
1313
use crate::factory::TOKIO_RUNTIME;
@@ -46,7 +46,7 @@ impl IVRServerDriverHost for DriverHost {
4646
// Steam part is opened for checking if this is really a needed HMD device
4747
let _steam = Rc::new(SteamDevice::open(&sn)?);
4848
// We don't know for sure this device serial
49-
let vive = Rc::new(ViveDevice::open_first()?);
49+
let vive = Rc::new(ViveCosmosDevice::open_first()?);
5050

5151
let mode = {
5252
let res = HMD_RESOLUTION.get();
@@ -62,24 +62,24 @@ impl IVRServerDriverHost for DriverHost {
6262
.clone();
6363
HMD_RESOLUTION.set(mode.id as i32);
6464

65-
vive.set_mode(mode.id)?;
65+
// vive.set_mode(mode.id)?;
6666
mode
6767
};
68-
{
69-
let nc = NOISE_CANCEL.get();
70-
NOISE_CANCEL.set(nc);
71-
72-
vive.toggle_noise_canceling(nc)?;
73-
}
74-
{
75-
let mut brightness = BRIGHTNESS.get();
76-
if brightness == 0 {
77-
brightness = 130;
78-
}
79-
BRIGHTNESS.set(brightness);
80-
81-
vive.set_brightness(brightness as u8)?;
82-
}
68+
// {
69+
// let nc = NOISE_CANCEL.get();
70+
// NOISE_CANCEL.set(nc);
71+
72+
// vive.toggle_noise_canceling(nc)?;
73+
// }
74+
// {
75+
// let mut brightness = BRIGHTNESS.get();
76+
// if brightness == 0 {
77+
// brightness = 130;
78+
// }
79+
// BRIGHTNESS.set(brightness);
80+
81+
// vive.set_brightness(brightness as u8)?;
82+
// }
8383

8484
let config = vive.read_config()?;
8585

crates/vive-hid/src/lib.rs

Lines changed: 114 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::{io::Read, result};
22

3-
use flate2::read::ZlibDecoder;
3+
use flate2::{ read::{ZlibDecoder, GzDecoder}, DecompressError };
44
use hidapi::{HidApi, HidDevice, HidError};
55
use once_cell::sync::OnceCell;
66
use serde::Deserialize;
77
use serde_json::Value;
8-
use tracing::error;
8+
use tracing::{ error, info };
99

1010
#[derive(thiserror::Error, Debug)]
1111
pub enum Error {
@@ -21,6 +21,10 @@ pub enum Error {
2121
ConfigReadFailed,
2222
#[error("protocol error: {0}")]
2323
ProtocolError(&'static str),
24+
#[error("deflate error: {0}")]
25+
DeflateError(#[from] DecompressError),
26+
#[error("IO error: {0}")]
27+
IOError(#[from] std::io::Error),
2428
}
2529

2630
type Result<T, E = Error> = result::Result<T, E>;
@@ -134,7 +138,8 @@ impl SteamDevice {
134138
}
135139

136140
const VIVE_VID: u16 = 0x0bb4;
137-
const VIVE_PID: u16 = 0x0342;
141+
const VIVE_PRO_2_PID: u16 = 0x0342;
142+
const VIVE_COSMOS_PID: u16 = 0x0313;
138143

139144
#[derive(Deserialize, Debug)]
140145
pub struct ViveConfig {
@@ -175,11 +180,11 @@ const VIVE_PRO_2_MODES: [Mode; 6] = [
175180
Mode::new(5, 2896, 2448, 120.0),
176181
];
177182

178-
pub struct ViveDevice(HidDevice);
179-
impl ViveDevice {
183+
pub struct VivePro2Device(HidDevice);
184+
impl VivePro2Device {
180185
pub fn open_first() -> Result<Self> {
181186
let api = get_hidapi()?;
182-
let device = api.open(VIVE_VID, VIVE_PID)?;
187+
let device = api.open(VIVE_VID, VIVE_PRO_2_PID)?;
183188
Ok(Self(device))
184189
}
185190
pub fn open(sn: &str) -> Result<Self> {
@@ -188,7 +193,7 @@ impl ViveDevice {
188193
.device_list()
189194
.find(|dev| dev.serial_number() == Some(sn))
190195
.ok_or(Error::DeviceNotFound)?;
191-
if device.vendor_id() != VIVE_VID || device.product_id() != VIVE_PID {
196+
if device.vendor_id() != VIVE_VID || device.product_id() != VIVE_PRO_2_PID {
192197
return Err(Error::NotAVive);
193198
}
194199
let open = api.open_serial(device.vendor_id(), device.product_id(), sn)?;
@@ -285,7 +290,7 @@ impl ViveDevice {
285290

286291
serde_json::from_str(&string).map_err(|_| Error::ConfigReadFailed)
287292
}
288-
/// Always returns at least one mode
293+
// Always returns at least one mode
289294
pub fn query_modes(&self) -> Vec<Mode> {
290295
VIVE_PRO_2_MODES.into_iter().collect()
291296
}
@@ -328,3 +333,104 @@ impl ViveDevice {
328333
Ok(())
329334
}
330335
}
336+
337+
const VIVE_COSMOS_MODES: [Mode; 1] = [
338+
Mode::new(0, 2880, 1700, 90.0),
339+
];
340+
341+
pub struct ViveCosmosDevice(HidDevice);
342+
use std::fs::File;
343+
use std::io::prelude::*;
344+
impl ViveCosmosDevice {
345+
346+
pub fn open_first() -> Result<Self> {
347+
let api = get_hidapi()?;
348+
let device = api.open(VIVE_VID, VIVE_COSMOS_PID)?;
349+
Ok(Self(device))
350+
}
351+
pub fn open(sn: &str) -> Result<Self> {
352+
let api = get_hidapi()?;
353+
let device = api
354+
.device_list()
355+
.find(|dev| dev.serial_number() == Some(sn))
356+
.ok_or(Error::DeviceNotFound)?;
357+
if device.vendor_id() != VIVE_VID || device.product_id() != VIVE_COSMOS_PID {
358+
return Err(Error::NotAVive);
359+
}
360+
let open = api.open_serial(device.vendor_id(), device.product_id(), sn)?;
361+
Ok(Self(open))
362+
}
363+
// Always returns at least one mode
364+
pub fn query_modes(&self) -> Vec<Mode> {
365+
VIVE_COSMOS_MODES.into_iter().collect()
366+
}
367+
pub fn read_config(&self) -> Result<ViveConfig> {
368+
let gz_file_buffer = self.read_stream(b"HMD_JSON.gz")?;
369+
370+
info!("received gzipped config file");
371+
372+
let mut dec = GzDecoder::new(gz_file_buffer.as_slice());
373+
let mut config = String::new();
374+
dec.read_to_string(&mut config)?;
375+
376+
info!("config: {config}");
377+
378+
serde_json::from_str(&config).map_err(|_| Error::ConfigReadFailed)
379+
}
380+
pub fn read_stream(&self, filename: &[u8]) -> Result<Vec::<u8>> {
381+
let mut report = [0u8; 65];
382+
383+
report[0] = 0x00; // id 0 -> root of the Application collection.
384+
report[1] = 0x10; // the command I presume ?
385+
report[2] = 0x00; // commant 2nd part ?
386+
report[3] = filename.len() as u8; // payload size
387+
report[4] = 0xff; // separator ?
388+
report[5..][..filename.len()].copy_from_slice(filename);
389+
390+
let total_len = {
391+
self.0.send_feature_report(&report)?;
392+
393+
loop {
394+
self.0.get_feature_report(&mut report)?;
395+
if report[0] != 0x00 { return Err(Error::ProtocolError("unknown data received.")) }
396+
if report[1] == 0x10 { break; }
397+
}
398+
399+
let mut total_len = [0u8; 4];
400+
total_len.copy_from_slice(&report[5..9]);
401+
u32::from_le_bytes(total_len) as usize
402+
};
403+
info!("config read length : {total_len}");
404+
405+
let mut position = 0x0 as usize;
406+
let mut out = Vec::<u8>::with_capacity(total_len);
407+
408+
while position < total_len {
409+
report = [0u8;65];
410+
report[1] = 0x11;
411+
report[2] = 0x00;
412+
report[3] = 0x08; //payload size;
413+
report[4] = 0x80; // separator ?
414+
report[5..9].copy_from_slice(&u32::to_le_bytes(position as u32)); // start position
415+
report[9] = 0x38 ;
416+
417+
self.0.send_feature_report(&report)?;
418+
loop {
419+
self.0.get_feature_report(&mut report)?;
420+
if report[0] != 0x00 { return Err(Error::ProtocolError("unknown data received.")) }
421+
if report[1] == 0x11 { break; }
422+
}
423+
424+
let size = (report[3] - 0x04) as usize;
425+
out.extend_from_slice(&report[5..5 + size]);
426+
427+
position = position + size;
428+
info!("position: {position}, size: {size}");
429+
}
430+
if position != total_len {
431+
return Err(Error::ProtocolError("config size mismatch"));
432+
}
433+
434+
Ok(out)
435+
}
436+
}

0 commit comments

Comments
 (0)