From a55d1f1cbec3032f64ef105bb67a93c9f5891fd0 Mon Sep 17 00:00:00 2001 From: G2-Games Date: Sat, 23 Sep 2023 11:41:33 -0500 Subject: [PATCH] Cleaned up some functions, implemeted `read_bulk` --- src/main.rs | 4 ++ src/netmd/base.rs | 49 ++++++++----- src/netmd/interface.rs | 151 +++++++++++++++++++++++++++++++---------- src/netmd/utils.rs | 2 +- 4 files changed, 151 insertions(+), 55 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3825e1f..6b7e162 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,6 +32,10 @@ fn main() { 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)); player_controller.stop(); diff --git a/src/netmd/base.rs b/src/netmd/base.rs index 37d0c84..9e42393 100644 --- a/src/netmd/base.rs +++ b/src/netmd/base.rs @@ -10,6 +10,8 @@ const STANDARD_SEND: u8 = const STANDARD_RECV: u8 = rusb::request_type(Direction::In, RequestType::Vendor, Recipient::Interface); +pub const CHUNKSIZE: u32 = 0x10000; + // TODO: I think this sucks, figure out a better way pub static DEVICE_IDS: Lazy> = Lazy::new(|| nofmt::pls!{ Vec::from([ @@ -134,7 +136,7 @@ impl NetMD { /// Poll the device to get either the result /// of the previous command, or the status - fn poll(&self, tries: usize) -> Result<(usize, [u8; 4]), Box> { + fn poll(&self, tries: usize) -> Result<(u16, [u8; 4]), Box> { // Create an array to store the result of the poll let mut poll_result = [0u8; 4]; @@ -152,8 +154,10 @@ impl NetMD { Err(error) => return Err(error.into()), }; + let length_bytes = [poll_result[2], poll_result[3]]; + 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 { @@ -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 @@ -179,14 +185,14 @@ impl NetMD { Err(error) => return Err(error), }; - let _ = match use_factory_command { + let request = match use_factory_command { false => 0x80, true => 0xff, }; match self.device_connection.write_control( STANDARD_SEND, - 0x80, + request, 0, 0, &command, @@ -211,7 +217,7 @@ impl NetMD { }; // Create a buffer to fill with the result - let mut buf: [u8; 255] = [0; 255]; + let mut buf: Vec = vec![0; poll_result.0 as usize]; match self.device_connection.read_control( STANDARD_RECV, @@ -221,27 +227,34 @@ impl NetMD { &mut buf, DEFAULT_TIMEOUT, ) { - Ok(_) => Ok(buf[0..poll_result.0].to_vec()), + Ok(_) => Ok(buf), Err(error) => return Err(error.into()), } } - // TODO: Implement these properly, they will NOT work as is - pub fn read_bulk(&self, chunksize: u32) -> Result, Box> { - let result = self.read_bulk_to_array::(chunksize)?; + // Default chunksize should be 0x10000 + pub fn read_bulk(&self, length: u32, chunksize: u32) -> Result, Box> { + let result = self.read_bulk_to_array(length, chunksize)?; Ok(result.to_vec()) } - pub fn read_bulk_to_array(&self, chunksize: u32) -> Result<[u8; S], Box> { - let mut buffer: [u8; S] = [0u8; S]; + pub fn read_bulk_to_array(&self, length: u32, chunksize: u32) -> Result, Box> { + let final_result: Vec = Vec::new(); + let mut done = 0; - self.device_connection.read_bulk( - 1, - &mut buffer, - DEFAULT_TIMEOUT - )?; + while done < length { + let to_read = std::cmp::min(chunksize, length - done); + let mut buffer: Vec = vec![0; to_read as usize]; - Ok(buffer) + done += self.device_connection.read_bulk( + 1, + &mut buffer, + DEFAULT_TIMEOUT + )? as u32; + + } + + Ok(final_result) } } diff --git a/src/netmd/interface.rs b/src/netmd/interface.rs index 479affd..bc2c944 100644 --- a/src/netmd/interface.rs +++ b/src/netmd/interface.rs @@ -188,7 +188,7 @@ impl NetMDInterface { u32::from_le_bytes(bytes) } - fn get_disc_subunit_identifier(&self) -> Result> { + fn disc_subunit_identifier(&self) -> Result> { self.change_descriptor_state( Descriptor::DiscSubunitIdentifier, DescriptorAction::OpenRead, @@ -267,42 +267,10 @@ impl NetMDInterface { Err("No supported media types found".into()) } - fn playback_control(&self, action: Action) -> Result<(), Box> { - let mut query = vec![0x18, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00]; + fn net_md_level(&self) -> Result> { + let result = self.disc_subunit_identifier()?; - 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> { - self.playback_control(Action::Play) - } - - pub fn fast_forward(&self) -> Result<(), Box> { - self.playback_control(Action::FastForward) - } - - pub fn rewind(&self) -> Result<(), Box> { - self.playback_control(Action::Rewind) - } - - pub fn pause(&self) -> Result<(), Box> { - self.playback_control(Action::Pause) - } - - pub fn stop(&self) -> Result<(), Box> { - 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(()) + Ok(result) } 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 Err("The max retries is set to 0".into()) } + + fn playback_control(&self, action: Action) -> Result<(), Box> { + 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> { + self.playback_control(Action::Play) + } + + pub fn fast_forward(&self) -> Result<(), Box> { + self.playback_control(Action::FastForward) + } + + pub fn rewind(&self) -> Result<(), Box> { + self.playback_control(Action::Rewind) + } + + pub fn pause(&self) -> Result<(), Box> { + self.playback_control(Action::Pause) + } + + pub fn stop(&self) -> Result<(), Box> { + 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, Box> { + 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> { + let status = self.status()?; + + println!("{:X?}", status); + + Ok(status[4] == 0x40) + } + + fn full_operating_status(&self) -> Result<(u8, u16), Box> { + 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> { + let status = self.full_operating_status()?.1; + + Ok(status) + } + + fn playback_status_query(&self, p1: [u8; 2], p2: [u8; 2]) -> Result, Box> { + 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, Box> { + self.playback_status_query([0x88, 0x01], [0x88, 0x07]) + } + + pub fn playback_status2(&self) -> Result, Box> { + self.playback_status_query([0x88, 0x02], [0x88, 0x06]) + } } diff --git a/src/netmd/utils.rs b/src/netmd/utils.rs index 6998147..df19c34 100644 --- a/src/netmd/utils.rs +++ b/src/netmd/utils.rs @@ -3,6 +3,6 @@ use std::error::Error; pub fn check_result(result: Vec, expected: &[u8]) -> Result<(), Box> { match result.as_slice().eq(expected) { true => Ok(()), - false => Err("Response was not expected!".into()), + false => Err("Response was not as expected!".into()), } }