From 766b4c68f70376437cc4c7ff11b5c3a7849b89ff Mon Sep 17 00:00:00 2001 From: G2-Games Date: Tue, 30 Jan 2024 18:04:46 -0600 Subject: [PATCH] Started work on WASM support --- .cargo/config.toml | 2 + Cargo.toml | 7 +- minidisc-rs/Cargo.toml | 11 ++- minidisc-rs/src/netmd/base.rs | 57 ++++++------- minidisc-rs/src/netmd/commands.rs | 11 +-- minidisc-rs/src/netmd/interface.rs | 133 +++++++++++++++-------------- minidisc-rs/src/netmd/utils.rs | 14 ++- src/main.rs | 83 +++++++++--------- 8 files changed, 162 insertions(+), 156 deletions(-) create mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..db7e33d --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.'cfg(target_family = "wasm")'] +rustflags = ["--cfg=web_sys_unstable_apis"] diff --git a/Cargo.toml b/Cargo.toml index adc8a11..447fd56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,9 +10,12 @@ license = "AGPL-3.0" [dependencies] hex = "0.4.3" -nusb = "0.1.4" +cross_usb = { path = "/home/g2/Documents/projects/code/rust/cross-usb/" } +[target.'cfg(target_family = "wasm")'.dependencies] +tokio = { version = "1.35.1", features = ["macros"] } +[target.'cfg(not(target_family = "wasm"))'.dependencies] tokio = { version = "1.35.1", features = ["full"] } -[dependencies.minidisc-rs] +[dependencies.minidisc_rs] path = "minidisc-rs" version = "0.0.1" diff --git a/minidisc-rs/Cargo.toml b/minidisc-rs/Cargo.toml index 36e45a6..b50dea1 100644 --- a/minidisc-rs/Cargo.toml +++ b/minidisc-rs/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "minidisc-rs" +name = "minidisc_rs" version = "0.0.1" homepage = "https://github.com/G2-Games/minidisc-cli/" repository = "https://github.com/G2-Games/minidisc-cli/minidisc-rs/" @@ -21,7 +21,7 @@ unicode-normalization = "0.1.22" hex = "0.4.3" regex = "1.10.2" lazy_static = "1.4.0" -nusb = "0.1.4" +cross_usb = { path = "../../cross-usb/" } num-derive = "0.3.3" num-traits = "0.2.14" rand = "0.8.5" @@ -31,5 +31,12 @@ getrandom = { version = "0.2.12", features = ["js"] } # Relying on this fork for now as it has up-to-date deps git = "https://github.com/uzabase/unicode-jp-rs.git" +[target.'cfg(target_family = "wasm")'.dependencies] +web-sys = { version = "0.3", features = ["console"] } +gloo = { version = "0.11.0", features = ["futures"] } + [lib] crate-type = ["cdylib", "rlib"] + +[package.metadata.wasm-pack.profile.dev.wasm-bindgen] +dwarf-debug-info = true diff --git a/minidisc-rs/src/netmd/base.rs b/minidisc-rs/src/netmd/base.rs index 3f05e02..3e5f0a5 100644 --- a/minidisc-rs/src/netmd/base.rs +++ b/minidisc-rs/src/netmd/base.rs @@ -1,11 +1,17 @@ +#![cfg_attr(debug_assertions, allow(dead_code))] use nofmt; use once_cell::sync::Lazy; use std::error::Error; use std::time::Duration; +#[cfg(target_family = "wasm")] +use gloo::timers::future::TimeoutFuture; + // USB stuff -use nusb::transfer::{Control, ControlIn, ControlOut, ControlType, Recipient, RequestBuffer}; -use nusb::{Device, DeviceInfo, Interface}; +//use nusb::transfer::{Control, ControlIn, ControlOut, ControlType, Recipient, RequestBuffer}; +use cross_usb::context::{UsbDevice, UsbInterface}; +use cross_usb::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient}; +//use nusb::{Device, DeviceInfo, Interface}; const DEFAULT_TIMEOUT: Duration = Duration::new(10000, 0); const BULK_WRITE_ENDPOINT: u8 = 0x02; @@ -85,8 +91,7 @@ pub struct DeviceId { /// A connection to a NetMD device pub struct NetMD { - usb_device: Device, - usb_interface: Interface, + usb_interface: UsbInterface, model: DeviceId, status: Option, } @@ -95,10 +100,10 @@ impl NetMD { const READ_REPLY_RETRY_INTERVAL: u32 = 10; /// Creates a new interface to a NetMD device - pub async fn new(device_info: &DeviceInfo) -> Result> { + pub async fn new(usb_device: &UsbDevice) -> Result> { let mut model = DeviceId { - vendor_id: device_info.vendor_id(), - product_id: device_info.product_id(), + vendor_id: usb_device.vendor_id().await, + product_id: usb_device.product_id().await, name: None, }; @@ -116,11 +121,9 @@ impl NetMD { Some(_) => (), } - let usb_device = device_info.open()?; - let usb_interface = usb_device.claim_interface(0)?; + let usb_interface = usb_device.open_interface(0).await?; Ok(Self { - usb_device, usb_interface, model, status: None, @@ -157,10 +160,9 @@ impl NetMD { length: 4, }) .await - .into_result() { Ok(size) => size, - Err(error) => return Err(error.into()), + Err(error) => return Err(error), }; let length_bytes = u16::from_le_bytes([poll_result[2], poll_result[3]]); @@ -190,9 +192,9 @@ impl NetMD { // First poll to ensure the device is ready match self.poll().await { Ok(buffer) => match buffer.1[2] { - 0 => 0, - _ => return Err("Device not ready!".into()), - }, + 0 => 0, + _ => return Err("Device not ready!".into()), + }, Err(error) => return Err(error), }; @@ -212,10 +214,9 @@ impl NetMD { data: &command, }) .await - .into_result() { Ok(_) => Ok(()), - Err(error) => Err(error.into()), + Err(error) => Err(error), } } @@ -242,12 +243,17 @@ impl NetMD { let mut length = self.poll().await?.0; let mut current_attempt = 0; - while length == 0 { + while length == 0 && current_attempt < 75 { // Back off while trying again let sleep_time = Self::READ_REPLY_RETRY_INTERVAL as u64 * (u64::pow(2, current_attempt as u32 / 10) - 1); + #[cfg(not(target_family = "wasm"))] std::thread::sleep(std::time::Duration::from_millis(sleep_time)); + + #[cfg(target_family = "wasm")] + TimeoutFuture::new(sleep_time as u32).await; + length = self.poll().await?.0; current_attempt += 1; } @@ -272,14 +278,12 @@ impl NetMD { index: 0, length, }) - .await - .into_result()?; + .await?; Ok(reply) } // Default chunksize should be 0x10000 - // TODO: Make these Async eventually pub async fn read_bulk( &mut self, length: usize, @@ -301,13 +305,11 @@ impl NetMD { while done < length { let to_read = std::cmp::min(chunksize, length - done); done -= to_read; - let buffer = RequestBuffer::new(to_read); let res = match self .usb_interface - .bulk_in(BULK_READ_ENDPOINT, buffer) + .bulk_in(BULK_READ_ENDPOINT, to_read) .await - .into_result() { Ok(result) => result, Err(error) => return Err(format!("USB error: {:?}", error).into()), @@ -320,11 +322,6 @@ impl NetMD { } pub async fn write_bulk(&mut self, data: Vec) -> Result> { - Ok(self - .usb_interface - .bulk_out(BULK_WRITE_ENDPOINT, data) - .await - .into_result()? - .actual_length()) + self.usb_interface.bulk_out(BULK_WRITE_ENDPOINT, data).await } } diff --git a/minidisc-rs/src/netmd/commands.rs b/minidisc-rs/src/netmd/commands.rs index b0d9e22..d1d5760 100644 --- a/minidisc-rs/src/netmd/commands.rs +++ b/minidisc-rs/src/netmd/commands.rs @@ -1,3 +1,4 @@ +#![cfg_attr(debug_assertions, allow(dead_code))] use std::{error::Error, thread::sleep, time::Duration}; use num_derive::FromPrimitive; use num_traits::FromPrimitive; @@ -57,20 +58,20 @@ pub async fn device_status(interface: &mut NetMDInterface) -> Result Result<(), Box>{ - while ![OperatingStatus::DiscBlank, OperatingStatus::Ready].contains(&device_status(interface).await?.state.or(Some(OperatingStatus::NoDisc)).unwrap()) { + while ![OperatingStatus::DiscBlank, OperatingStatus::Ready].contains(&device_status(interface).await?.state.unwrap_or(OperatingStatus::NoDisc)) { sleep(Duration::from_millis(200)); } - let _ = interface.session_key_forget(); - let _ = interface.leave_secure_session(); + let _ = interface.session_key_forget().await; + let _ = interface.leave_secure_session().await; interface.acquire().await?; - let _ = interface.disable_new_track_protection(1); + let _ = interface.disable_new_track_protection(1).await; Ok(()) } -pub async fn download(interface: &mut NetMDInterface, track: MDTrack) -> Result<(), Box>{ +pub async fn download(interface: &mut NetMDInterface, _track: MDTrack) -> Result<(), Box>{ prepare_download(interface).await?; Ok(()) diff --git a/minidisc-rs/src/netmd/interface.rs b/minidisc-rs/src/netmd/interface.rs index 1be318a..890ec9b 100644 --- a/minidisc-rs/src/netmd/interface.rs +++ b/minidisc-rs/src/netmd/interface.rs @@ -1,3 +1,4 @@ +#![cfg_attr(debug_assertions, allow(dead_code))] use crate::netmd::base; use crate::netmd::query_utils::{format_query, scan_query, QueryValue}; use crate::netmd::utils::{ @@ -137,7 +138,7 @@ enum DescriptorAction { } #[repr(u8)] -enum Status { +enum NetmdStatus { // NetMD Protocol return status (first byte of request) Control = 0x00, Status = 0x01, @@ -163,23 +164,23 @@ lazy_static! { ]); } -impl std::convert::TryFrom for Status { +impl std::convert::TryFrom for NetmdStatus { type Error = Box; fn try_from(item: u8) -> Result> { match item { - 0x00 => Ok(Status::Control), - 0x01 => Ok(Status::Status), - 0x02 => Ok(Status::SpecificInquiry), - 0x03 => Ok(Status::Notify), - 0x04 => Ok(Status::GeneralInquiry), - 0x08 => Ok(Status::NotImplemented), - 0x09 => Ok(Status::Accepted), - 0x0a => Ok(Status::Rejected), - 0x0b => Ok(Status::InTransition), - 0x0c => Ok(Status::Implemented), - 0x0d => Ok(Status::Changed), - 0x0f => Ok(Status::Interim), + 0x00 => Ok(NetmdStatus::Control), + 0x01 => Ok(NetmdStatus::Status), + 0x02 => Ok(NetmdStatus::SpecificInquiry), + 0x03 => Ok(NetmdStatus::Notify), + 0x04 => Ok(NetmdStatus::GeneralInquiry), + 0x08 => Ok(NetmdStatus::NotImplemented), + 0x09 => Ok(NetmdStatus::Accepted), + 0x0a => Ok(NetmdStatus::Rejected), + 0x0b => Ok(NetmdStatus::InTransition), + 0x0c => Ok(NetmdStatus::Implemented), + 0x0d => Ok(NetmdStatus::Changed), + 0x0f => Ok(NetmdStatus::Interim), _ => Err("Not a valid value".into()), } } @@ -203,7 +204,7 @@ impl NetMDInterface { const MAX_INTERIM_READ_ATTEMPTS: u8 = 4; const INTERIM_RESPONSE_RETRY_INTERVAL: u32 = 100; - pub async fn new(device: &nusb::DeviceInfo) -> Result> { + pub async fn new(device: &cross_usb::context::UsbDevice) -> Result> { let net_md_device = base::NetMD::new(device).await?; Ok(NetMDInterface { net_md_device }) } @@ -223,7 +224,7 @@ impl NetMDInterface { self.change_descriptor_state( &Descriptor::DiscSubunitIdentifier, &DescriptorAction::OpenRead, - ); + ).await; let mut query = format_query("1809 00 ff00 0000 0000".to_string(), vec![])?; @@ -291,7 +292,7 @@ impl NetMDInterface { let _manufacturer_dep_data = &buffer[buffer_offset..buffer_offset + manufacturer_dep_length as usize]; - self.change_descriptor_state(&Descriptor::DiscSubunitIdentifier, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::DiscSubunitIdentifier, &DescriptorAction::Close).await; for media in supported_media_type_specifications { if media.supported_media_type != 0x301 { @@ -321,7 +322,7 @@ impl NetMDInterface { Ok(result) } - fn change_descriptor_state(&mut self, descriptor: &Descriptor, action: &DescriptorAction) { + async fn change_descriptor_state(&mut self, descriptor: &Descriptor, action: &DescriptorAction) { let mut query = format_query("1808".to_string(), vec![]).unwrap(); query.append(&mut descriptor.get_array()); @@ -330,7 +331,7 @@ impl NetMDInterface { query.push(0x00); - let _ = self.send_query(&mut query, false, false); + let _ = self.send_query(&mut query, false, false).await; } /// Send a query to the NetMD player @@ -353,8 +354,8 @@ impl NetMDInterface { test: bool, ) -> Result<(), Box> { let status_byte = match test { - true => Status::GeneralInquiry, - false => Status::Control, + true => NetmdStatus::GeneralInquiry, + false => NetmdStatus::Control, }; let mut new_query = Vec::new(); @@ -377,15 +378,15 @@ impl NetMDInterface { Err(error) => return Err(error), }; - let status = match Status::try_from(data[0]) { + let status = match NetmdStatus::try_from(data[0]) { Ok(status) => status, Err(error) => return Err(error), }; match status { - Status::NotImplemented => return Err("Not implemented".into()), - Status::Rejected => return Err("Rejected".into()), - Status::Interim if !accept_interim => { + NetmdStatus::NotImplemented => return Err("Not implemented".into()), + NetmdStatus::Rejected => return Err("Rejected".into()), + NetmdStatus::Interim if !accept_interim => { let sleep_time = Self::INTERIM_RESPONSE_RETRY_INTERVAL as u64 * (u64::pow(2, current_attempt as u32) - 1); let sleep_dur = std::time::Duration::from_millis(sleep_time); @@ -393,7 +394,7 @@ impl NetMDInterface { current_attempt += 1; continue; // Retry! } - Status::Accepted | Status::Implemented | Status::Interim => { + NetmdStatus::Accepted | NetmdStatus::Implemented | NetmdStatus::Interim => { if current_attempt >= Self::MAX_INTERIM_READ_ATTEMPTS { return Err("Max interim retry attempts reached".into()); } @@ -470,7 +471,7 @@ impl NetMDInterface { self.change_descriptor_state( &Descriptor::OperatingStatusBlock, &DescriptorAction::OpenRead, - ); + ).await; let mut query = format_query( "1809 8001 0230 8800 0030 8804 00 ff00 00000000".to_string(), @@ -484,7 +485,7 @@ impl NetMDInterface { "1809 8001 0230 8800 0030 8804 00 1000 00090000 %x".to_string(), )?; - self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await; let final_array = res[0].to_vec().unwrap(); @@ -504,7 +505,7 @@ impl NetMDInterface { self.change_descriptor_state( &Descriptor::OperatingStatusBlock, &DescriptorAction::OpenRead, - ); + ).await; let mut query = format_query( "1809 8001 0330 8802 0030 8805 0030 8806 00 ff00 00000000".to_string(), vec![], @@ -520,7 +521,7 @@ impl NetMDInterface { let operating_status = result[1].to_vec().unwrap(); let status_mode = result[0].to_i64().unwrap() as u8; - self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await; if operating_status.len() < 2 { return Err("Unparsable operating system".into()); @@ -542,7 +543,7 @@ impl NetMDInterface { self.change_descriptor_state( &Descriptor::OperatingStatusBlock, &DescriptorAction::OpenRead, - ); + ).await; let mut query = format_query( "1809 8001 0330 %w 0030 8805 0030 %w 00 ff00 00000000".to_string(), vec![QueryValue::Number(p1 as i64), QueryValue::Number(p2 as i64)], @@ -556,7 +557,7 @@ impl NetMDInterface { "1809 8001 0330 %?%? %?%? %?%? %?%? %?%? %? 1000 00%?0000 %x %?".to_string(), ); - self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await; Ok(res.unwrap()[0].to_vec().unwrap()) } @@ -573,7 +574,7 @@ impl NetMDInterface { self.change_descriptor_state( &Descriptor::OperatingStatusBlock, &DescriptorAction::OpenRead, - ); + ).await; let mut query = format_query( "1809 8001 0430 8802 0030 8805 0030 0003 0030 0002 00 ff00 00000000".to_string(), @@ -597,7 +598,7 @@ impl NetMDInterface { result[4].to_i64().unwrap() as u16, ]; - self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await; Ok(final_result) } @@ -704,21 +705,21 @@ impl NetMDInterface { // TODO: Ensure this is returning the correct value, it // looks like it actually might be a 16 bit integer pub async fn disc_flags(&mut self) -> Result> { - self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead); + self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead).await; let mut query = format_query("1806 01101000 ff00 0001000b".to_string(), vec![]).unwrap(); let reply = self.send_query(&mut query, false, false).await?; let res = scan_query(reply, "1806 01101000 1000 0001000b %b".to_string()).unwrap(); - self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close).await; Ok(res[0].to_i64().unwrap() as u8) } /// The number of tracks on the disc pub async fn track_count(&mut self) -> Result> { - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await; let mut query = format_query("1806 02101001 3000 1000 ff00 00000000".to_string(), vec![]).unwrap(); @@ -731,14 +732,14 @@ impl NetMDInterface { ) .unwrap(); - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await; Ok(res[0].to_i64().unwrap() as u16) } async fn raw_disc_title(&mut self, wchar: bool) -> Result> { - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead); - self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await; + self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead).await; let mut done: i32 = 0; let mut remaining: i32 = 0; @@ -792,8 +793,8 @@ impl NetMDInterface { let res = result.join(""); - self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close); - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await; + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await; Ok(res) } @@ -926,7 +927,7 @@ impl NetMDInterface { false => Descriptor::AudioUTOC1TD, }; - self.change_descriptor_state(&descriptor_type, &DescriptorAction::OpenRead); + self.change_descriptor_state(&descriptor_type, &DescriptorAction::OpenRead).await; let mut track_titles: Vec = vec![]; for i in tracks { @@ -955,7 +956,7 @@ impl NetMDInterface { ) } - self.change_descriptor_state(&descriptor_type, &DescriptorAction::Close); + self.change_descriptor_state(&descriptor_type, &DescriptorAction::Close).await; Ok(track_titles) } @@ -973,7 +974,7 @@ impl NetMDInterface { // Sets the title of the disc pub async fn set_disc_title( &mut self, - title: String, + title: &str, wchar: bool, ) -> Result<(), Box> { let current_title = self.raw_disc_title(wchar).await?; @@ -998,10 +999,10 @@ impl NetMDInterface { let new_len = new_title.len(); if self.net_md_device.vendor_id().await == &0x04dd { - self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::OpenWrite) + self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::OpenWrite).await } else { - self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close); - self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenWrite) + self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await; + self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenWrite).await } let mut query = format_query( @@ -1014,14 +1015,14 @@ impl NetMDInterface { ], )?; - let _ = self.send_query(&mut query, false, false); + let _ = self.send_query(&mut query, false, false).await; if self.net_md_device.vendor_id().await == &0x04dd { - self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::Close) + self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::Close).await } else { - self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close); - self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead); - self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await; + self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead).await; + self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await; } Ok(()) @@ -1031,7 +1032,7 @@ impl NetMDInterface { pub async fn set_track_title( &mut self, track: u16, - title: String, + title: &str, wchar: bool, ) -> Result<(), Box> { let new_title: Vec; @@ -1059,7 +1060,7 @@ impl NetMDInterface { Err(error) => return Err(error), }; - self.change_descriptor_state(&descriptor, &DescriptorAction::OpenWrite); + self.change_descriptor_state(&descriptor, &DescriptorAction::OpenWrite).await; let mut query = format_query( "1807 022018%b %w 3000 0a00 5000 %w 0000 %w %*".to_string(), vec![ @@ -1076,7 +1077,7 @@ impl NetMDInterface { reply, "1807 022018%? %?%? 3000 0a00 5000 %?%? 0000 %?%?".to_string(), ); - self.change_descriptor_state(&descriptor, &DescriptorAction::Close); + self.change_descriptor_state(&descriptor, &DescriptorAction::Close).await; Ok(()) } @@ -1114,7 +1115,7 @@ impl NetMDInterface { p1: i32, p2: i32, ) -> Result, Box> { - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await; let mut query = format_query( "1806 02201001 %w %w %w ff00 00000000".to_string(), @@ -1131,7 +1132,7 @@ impl NetMDInterface { "1806 02201001 %?%? %?%? %?%? 1000 00%?0000 %x".to_string(), )?; - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await; Ok(res[0].to_vec().unwrap()) } @@ -1143,7 +1144,7 @@ impl NetMDInterface { ) -> Result, Box> { let mut times: Vec = vec![]; - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await; for track in tracks { let mut query = format_query( "1806 02201001 %w %w %w ff00 00000000".to_string(), @@ -1175,7 +1176,7 @@ impl NetMDInterface { times.push(length); } - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await; Ok(times) } @@ -1206,7 +1207,7 @@ impl NetMDInterface { /// Gets a track's flags pub async fn track_flags(&mut self, track: u16) -> Result> { - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await; let mut query = format_query( "1806 01201001 %w ff00 00010008".to_string(), vec![QueryValue::Number(track as i64)], @@ -1215,14 +1216,14 @@ impl NetMDInterface { let res = scan_query(reply, "1806 01201001 %?%? 10 00 00010008 %b".to_string())?; - self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await; Ok(res[0].to_i64().unwrap() as u8) } /// Gets the disc capacity as a `std::time::Duration` pub async fn disc_capacity(&mut self) -> Result<[std::time::Duration; 3], Box> { - self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead); + self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead).await; let mut query = format_query("1806 02101000 3080 0300 ff00 00000000".to_string(), vec![])?; let reply = self.send_query(&mut query, false, false).await?; let mut result: [std::time::Duration; 3] = [std::time::Duration::from_secs(0); 3]; @@ -1245,7 +1246,7 @@ impl NetMDInterface { result[i] = std::time::Duration::from_micros(time_micros); } - self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close).await; Ok(result) } @@ -1254,7 +1255,7 @@ impl NetMDInterface { self.change_descriptor_state( &Descriptor::OperatingStatusBlock, &DescriptorAction::OpenRead, - ); + ).await; let mut query = format_query( "1809 8001 0330 8801 0030 8805 0030 8807 00 ff00 00000000".to_string(), vec![], @@ -1264,7 +1265,7 @@ impl NetMDInterface { let res = scan_query(reply, "1809 8001 0330 8801 0030 8805 0030 8807 00 1000 000e0000 000c 8805 0008 80e0 0110 %b %b 4000".to_string())?; - self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close); + self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await; Ok(res.into_iter().map(|x| x.to_i64().unwrap() as u8).collect()) } diff --git a/minidisc-rs/src/netmd/utils.rs b/minidisc-rs/src/netmd/utils.rs index ced7644..db6b413 100644 --- a/minidisc-rs/src/netmd/utils.rs +++ b/minidisc-rs/src/netmd/utils.rs @@ -89,15 +89,13 @@ fn check(string: String) -> Option { None } -pub fn sanitize_half_width_title(mut title: String) -> Vec { - title = wide2ascii(&title); - title = nowidespace(&title); - title = hira2kata(&title); - title = combine(&title); +pub fn sanitize_half_width_title(title: &str) -> Vec { + let mut string_title = wide2ascii(&title); + string_title = nowidespace(&string_title); + string_title = hira2kata(&string_title); + string_title = combine(&string_title); - println!("{}", title); - - let new_title: String = title + let new_title: String = string_title .chars() .map(|c| { check(c.to_string()).unwrap_or( diff --git a/src/main.rs b/src/main.rs index e3b196b..df20b29 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,53 +1,50 @@ use minidisc_rs::netmd::interface; -use nusb; +use cross_usb::usb::Device; #[tokio::main] async fn main() { - let devices = nusb::list_devices().unwrap(); + let device = cross_usb::context::get_device(0x054c, 0x0186).await.unwrap(); - for device in devices { - // Ensure the player is a minidisc player and not some other random device - let mut player_controller = match interface::NetMDInterface::new(&device).await { - Ok(player) => player, - Err(err) => continue, - }; + dbg!(device.vendor_id().await); + // Ensure the player is a minidisc player and not some other random device + let mut player_controller = match interface::NetMDInterface::new(&device).await { + Ok(player) => player, + Err(err) => { + dbg!(err); + panic!(); + }, + }; + + println!( + "Player Model: {}", + player_controller + .net_md_device + .device_name() + .await + .clone() + .unwrap() + ); + + let now = std::time::Instant::now(); + let half_title = player_controller.disc_title(false).await.unwrap_or("".to_string()); + let full_title = player_controller.disc_title(true).await.unwrap_or("".to_string()); + println!( + "Disc Title: {} | {}", + half_title, + full_title + ); + + let track_count = player_controller.track_count().await.unwrap(); + println!("{}", track_count); + let track_titles = player_controller.track_titles((0..track_count).collect(), false).await.unwrap(); + let track_titlesw = player_controller.track_titles((0..track_count).collect(), true).await.unwrap(); + let track_lengths = player_controller.track_lengths((0..track_count).collect()).await.unwrap(); + for (i, track) in track_titles.iter().enumerate() { println!( - "Connected to VID: {:04x}, PID: {:04x}", - device.vendor_id(), - device.product_id(), + "Track {i} Info:\n Title: {track} | {}\n Length: {:?}", + track_titlesw[i], track_lengths[i] ); - - println!( - "Player Model: {}", - player_controller - .net_md_device - .device_name() - .await - .clone() - .unwrap() - ); - - let now = std::time::Instant::now(); - let half_title = player_controller.disc_title(false).await.unwrap_or("".to_string()); - let full_title = player_controller.disc_title(true).await.unwrap_or("".to_string()); - println!( - "Disc Title: {} | {}", - half_title, - full_title - ); - - let track_count = player_controller.track_count().await.unwrap(); - println!("{}", track_count); - let track_titles = player_controller.track_titles((0..track_count).collect(), false).await.unwrap(); - let track_titlesw = player_controller.track_titles((0..track_count).collect(), true).await.unwrap(); - let track_lengths = player_controller.track_lengths((0..track_count).collect()).await.unwrap(); - for (i, track) in track_titles.iter().enumerate() { - println!( - "Track {i} Info:\n Title: {track} | {}\n Length: {:?}", - track_titlesw[i], track_lengths[i] - ); - } - println!("{:?}", now.elapsed()); } + println!("{:?}", now.elapsed()); }