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();
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();

View file

@ -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<Vec<DeviceId>> = 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<dyn Error>> {
fn poll(&self, tries: usize) -> Result<(u16, [u8; 4]), Box<dyn Error>> {
// 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<u8> = 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<const S: usize>(&self, chunksize: u32) -> Result<Vec<u8>, Box<dyn Error>> {
let result = self.read_bulk_to_array::<S>(chunksize)?;
// Default chunksize should be 0x10000
pub fn read_bulk(&self, length: u32, chunksize: u32) -> Result<Vec<u8>, Box<dyn Error>> {
let result = self.read_bulk_to_array(length, chunksize)?;
Ok(result.to_vec())
}
pub fn read_bulk_to_array<const S: usize>(&self, chunksize: u32) -> Result<[u8; S], Box<dyn Error>> {
let mut buffer: [u8; S] = [0u8; S];
pub fn read_bulk_to_array(&self, length: u32, chunksize: u32) -> Result<Vec<u8>, Box<dyn Error>> {
let final_result: Vec<u8> = 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<u8> = vec![0; to_read as usize];
Ok(buffer)
done += self.device_connection.read_bulk(
1,
&mut buffer,
DEFAULT_TIMEOUT
)? as u32;
}
Ok(final_result)
}
}

View file

@ -188,7 +188,7 @@ impl NetMDInterface {
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(
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<dyn Error>> {
let mut query = vec![0x18, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00];
fn net_md_level(&self) -> Result<NetMDLevel, Box<dyn Error>> {
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<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(())
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<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>> {
match result.as_slice().eq(expected) {
true => Ok(()),
false => Err("Response was not expected!".into()),
false => Err("Response was not as expected!".into()),
}
}