Cleaned up some functions, implemeted read_bulk

This commit is contained in:
G2-Games 2023-09-23 11:41:33 -05:00
parent ae22de0b03
commit a55d1f1cbe
4 changed files with 151 additions and 55 deletions

View file

@ -32,6 +32,10 @@ fn main() {
player_controller.play(); player_controller.play();
println!("{:?}", player_controller.playback_status2());
thread::sleep(Duration::from_secs(1));
println!("{:?}", player_controller.playback_status2());
thread::sleep(Duration::from_secs(1)); thread::sleep(Duration::from_secs(1));
player_controller.stop(); player_controller.stop();

View file

@ -10,6 +10,8 @@ const STANDARD_SEND: u8 =
const STANDARD_RECV: u8 = const STANDARD_RECV: u8 =
rusb::request_type(Direction::In, RequestType::Vendor, Recipient::Interface); rusb::request_type(Direction::In, RequestType::Vendor, Recipient::Interface);
pub const CHUNKSIZE: u32 = 0x10000;
// TODO: I think this sucks, figure out a better way // TODO: I think this sucks, figure out a better way
pub static DEVICE_IDS: Lazy<Vec<DeviceId>> = Lazy::new(|| nofmt::pls!{ pub static DEVICE_IDS: Lazy<Vec<DeviceId>> = Lazy::new(|| nofmt::pls!{
Vec::from([ Vec::from([
@ -134,7 +136,7 @@ impl NetMD {
/// Poll the device to get either the result /// Poll the device to get either the result
/// of the previous command, or the status /// of the previous command, or the status
fn poll(&self, tries: usize) -> Result<(usize, [u8; 4]), Box<dyn Error>> { fn poll(&self, tries: usize) -> Result<(u16, [u8; 4]), Box<dyn Error>> {
// Create an array to store the result of the poll // Create an array to store the result of the poll
let mut poll_result = [0u8; 4]; let mut poll_result = [0u8; 4];
@ -152,8 +154,10 @@ impl NetMD {
Err(error) => return Err(error.into()), Err(error) => return Err(error.into()),
}; };
let length_bytes = [poll_result[2], poll_result[3]];
if poll_result[0] != 0 { if poll_result[0] != 0 {
return Ok((poll_result[2] as usize, poll_result)); return Ok((u16::from_le_bytes(length_bytes), poll_result));
} }
if i > 0 { if i > 0 {
@ -161,7 +165,9 @@ impl NetMD {
} }
} }
Ok((poll_result[2] as usize, poll_result)) // This should not contain anything
let length_bytes = [poll_result[2], poll_result[3]];
Ok((u16::from_le_bytes(length_bytes), poll_result))
} }
/// Send a control message to the device /// Send a control message to the device
@ -179,14 +185,14 @@ impl NetMD {
Err(error) => return Err(error), Err(error) => return Err(error),
}; };
let _ = match use_factory_command { let request = match use_factory_command {
false => 0x80, false => 0x80,
true => 0xff, true => 0xff,
}; };
match self.device_connection.write_control( match self.device_connection.write_control(
STANDARD_SEND, STANDARD_SEND,
0x80, request,
0, 0,
0, 0,
&command, &command,
@ -211,7 +217,7 @@ impl NetMD {
}; };
// Create a buffer to fill with the result // Create a buffer to fill with the result
let mut buf: [u8; 255] = [0; 255]; let mut buf: Vec<u8> = vec![0; poll_result.0 as usize];
match self.device_connection.read_control( match self.device_connection.read_control(
STANDARD_RECV, STANDARD_RECV,
@ -221,27 +227,34 @@ impl NetMD {
&mut buf, &mut buf,
DEFAULT_TIMEOUT, DEFAULT_TIMEOUT,
) { ) {
Ok(_) => Ok(buf[0..poll_result.0].to_vec()), Ok(_) => Ok(buf),
Err(error) => return Err(error.into()), Err(error) => return Err(error.into()),
} }
} }
// TODO: Implement these properly, they will NOT work as is // Default chunksize should be 0x10000
pub fn read_bulk<const S: usize>(&self, chunksize: u32) -> Result<Vec<u8>, Box<dyn Error>> { pub fn read_bulk(&self, length: u32, chunksize: u32) -> Result<Vec<u8>, Box<dyn Error>> {
let result = self.read_bulk_to_array::<S>(chunksize)?; let result = self.read_bulk_to_array(length, chunksize)?;
Ok(result.to_vec()) Ok(result.to_vec())
} }
pub fn read_bulk_to_array<const S: usize>(&self, chunksize: u32) -> Result<[u8; S], Box<dyn Error>> { pub fn read_bulk_to_array(&self, length: u32, chunksize: u32) -> Result<Vec<u8>, Box<dyn Error>> {
let mut buffer: [u8; S] = [0u8; S]; let final_result: Vec<u8> = Vec::new();
let mut done = 0;
self.device_connection.read_bulk( while done < length {
let to_read = std::cmp::min(chunksize, length - done);
let mut buffer: Vec<u8> = vec![0; to_read as usize];
done += self.device_connection.read_bulk(
1, 1,
&mut buffer, &mut buffer,
DEFAULT_TIMEOUT DEFAULT_TIMEOUT
)?; )? as u32;
Ok(buffer) }
Ok(final_result)
} }
} }

View file

@ -188,7 +188,7 @@ impl NetMDInterface {
u32::from_le_bytes(bytes) u32::from_le_bytes(bytes)
} }
fn get_disc_subunit_identifier(&self) -> Result<NetMDLevel, Box<dyn Error>> { fn disc_subunit_identifier(&self) -> Result<NetMDLevel, Box<dyn Error>> {
self.change_descriptor_state( self.change_descriptor_state(
Descriptor::DiscSubunitIdentifier, Descriptor::DiscSubunitIdentifier,
DescriptorAction::OpenRead, DescriptorAction::OpenRead,
@ -267,42 +267,10 @@ impl NetMDInterface {
Err("No supported media types found".into()) Err("No supported media types found".into())
} }
fn playback_control(&self, action: Action) -> Result<(), Box<dyn Error>> { fn net_md_level(&self) -> Result<NetMDLevel, Box<dyn Error>> {
let mut query = vec![0x18, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00]; let result = self.disc_subunit_identifier()?;
query[3] = action as u8; Ok(result)
let result = self.send_query(&mut query, false, false)?;
utils::check_result(result, &[0x18, 0xc5, 0x00, action as u8, 0x00, 0x00, 0x00])?;
Ok(())
}
pub fn play(&self) -> Result<(), Box<dyn Error>> {
self.playback_control(Action::Play)
}
pub fn fast_forward(&self) -> Result<(), Box<dyn Error>> {
self.playback_control(Action::FastForward)
}
pub fn rewind(&self) -> Result<(), Box<dyn Error>> {
self.playback_control(Action::Rewind)
}
pub fn pause(&self) -> Result<(), Box<dyn Error>> {
self.playback_control(Action::Pause)
}
pub fn stop(&self) -> Result<(), Box<dyn Error>> {
let mut query = vec![0x18, 0xc5, 0xff, 0x00, 0x00, 0x00, 0x00];
let result = self.send_query(&mut query, false, false)?;
utils::check_result(result, &[0x18, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00])?;
Ok(())
} }
fn change_descriptor_state(&self, descriptor: Descriptor, action: DescriptorAction) { fn change_descriptor_state(&self, descriptor: Descriptor, action: DescriptorAction) {
@ -384,4 +352,115 @@ impl NetMDInterface {
// This should NEVER happen unless the code is changed wrongly // This should NEVER happen unless the code is changed wrongly
Err("The max retries is set to 0".into()) Err("The max retries is set to 0".into())
} }
fn playback_control(&self, action: Action) -> Result<(), Box<dyn Error>> {
let mut query = vec![0x18, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00];
query[3] = action as u8;
let result = self.send_query(&mut query, false, false)?;
utils::check_result(result, &[0x18, 0xc5, 0x00, action as u8, 0x00, 0x00, 0x00])?;
Ok(())
}
pub fn play(&self) -> Result<(), Box<dyn Error>> {
self.playback_control(Action::Play)
}
pub fn fast_forward(&self) -> Result<(), Box<dyn Error>> {
self.playback_control(Action::FastForward)
}
pub fn rewind(&self) -> Result<(), Box<dyn Error>> {
self.playback_control(Action::Rewind)
}
pub fn pause(&self) -> Result<(), Box<dyn Error>> {
self.playback_control(Action::Pause)
}
pub fn stop(&self) -> Result<(), Box<dyn Error>> {
let mut query = vec![0x18, 0xc5, 0xff, 0x00, 0x00, 0x00, 0x00];
let result = self.send_query(&mut query, false, false)?;
utils::check_result(result, &[0x18, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00])?;
Ok(())
}
fn status(&self) -> Result<Vec<u8>, Box<dyn Error>> {
self.change_descriptor_state(Descriptor::OperatingStatusBlock, DescriptorAction::OpenRead);
let mut query = vec![0x18, 0x09, 0x80, 0x01, 0x02, 0x30, 0x88, 0x00, 0x00, 0x30, 0x88, 0x04, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00];
let response = self.send_query(&mut query, false, false)?;
let res = response[22..].to_vec();
self.change_descriptor_state(Descriptor::OperatingStatusBlock, DescriptorAction::Close);
Ok(res)
}
pub fn is_disc_present(&self) -> Result<bool, Box<dyn Error>> {
let status = self.status()?;
println!("{:X?}", status);
Ok(status[4] == 0x40)
}
fn full_operating_status(&self) -> Result<(u8, u16), Box<dyn Error>> {
self.change_descriptor_state(Descriptor::OperatingStatusBlock, DescriptorAction::OpenRead);
let mut query = vec![0x18, 0x09, 0x80, 0x01, 0x03, 0x30, 0x88, 0x02, 0x00, 0x30, 0x88, 0x05, 0x00, 0x30, 0x88, 0x06, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00];
let response = self.send_query(&mut query, false, false)?;
let operating_status = response[27..].to_vec();
let status_mode = response[20];
self.change_descriptor_state(Descriptor::OperatingStatusBlock, DescriptorAction::Close);
if operating_status.len() < 2 {
return Err("Unparsable operating system".into())
}
let status_bytes = [operating_status[0], operating_status[1]];
let operating_status_number = u16::from_le_bytes(status_bytes);
Ok((status_mode, operating_status_number))
}
fn operating_status(&self) -> Result<u16, Box<dyn Error>> {
let status = self.full_operating_status()?.1;
Ok(status)
}
fn playback_status_query(&self, p1: [u8; 2], p2: [u8; 2]) -> Result<Vec<u8>, Box<dyn Error>> {
self.change_descriptor_state(Descriptor::OperatingStatusBlock, DescriptorAction::OpenRead);
let mut query = vec![0x18, 0x09, 0x80, 0x01, 0x03, 0x30, 0x00, 0x00, 0x00, 0x30, 0x88, 0x05, 0x00, 0x30, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00];
query[6] = p1[0];
query[7] = p1[1];
query[14] = p2[0];
query[15] = p2[1];
let response = self.send_query(&mut query, false, false)?;
let playback_status = response[24..].to_vec();
self.change_descriptor_state(Descriptor::OperatingStatusBlock, DescriptorAction::Close);
Ok(playback_status)
}
pub fn playback_status1(&self) -> Result<Vec<u8>, Box<dyn Error>> {
self.playback_status_query([0x88, 0x01], [0x88, 0x07])
}
pub fn playback_status2(&self) -> Result<Vec<u8>, Box<dyn Error>> {
self.playback_status_query([0x88, 0x02], [0x88, 0x06])
}
} }

View file

@ -3,6 +3,6 @@ use std::error::Error;
pub fn check_result(result: Vec<u8>, expected: &[u8]) -> Result<(), Box<dyn Error>> { pub fn check_result(result: Vec<u8>, expected: &[u8]) -> Result<(), Box<dyn Error>> {
match result.as_slice().eq(expected) { match result.as_slice().eq(expected) {
true => Ok(()), true => Ok(()),
false => Err("Response was not expected!".into()), false => Err("Response was not as expected!".into()),
} }
} }