Compare commits

..

No commits in common. "0d9646c5a0334e7cff51afb6b28aae7612c95e70" and "4aee02c1509a05c92aa269a00a36d483d3dcf557" have entirely different histories.

7 changed files with 44 additions and 46 deletions

View file

@ -10,8 +10,11 @@ license = "AGPL-3.0"
[dependencies] [dependencies]
hex = "0.4.3" hex = "0.4.3"
cross_usb = "0.1" cross_usb = { path = "/home/g2/Documents/projects/code/rust/cross-usb/" }
tokio = { version = "1.35.1", features = ["macros", "rt", "rt-multi-thread"] } [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" path = "minidisc-rs"

View file

@ -21,7 +21,7 @@ unicode-normalization = "0.1.22"
hex = "0.4.3" hex = "0.4.3"
regex = "1.10.2" regex = "1.10.2"
lazy_static = "1.4.0" lazy_static = "1.4.0"
cross_usb = "0.1" cross_usb = { path = "../../cross-usb/" }
num-derive = "0.3.3" num-derive = "0.3.3"
num-traits = "0.2.14" num-traits = "0.2.14"
rand = "0.8.5" rand = "0.8.5"

View file

@ -4,12 +4,16 @@ use once_cell::sync::Lazy;
use std::error::Error; use std::error::Error;
use std::time::Duration; use std::time::Duration;
#[cfg(target_family = "wasm")]
use gloo::{
timers::future::TimeoutFuture,
console::log,
};
// USB stuff // USB stuff
//use nusb::transfer::{Control, ControlIn, ControlOut, ControlType, Recipient, RequestBuffer}; //use nusb::transfer::{Control, ControlIn, ControlOut, ControlType, Recipient, RequestBuffer};
use cross_usb::{UsbDevice, UsbInterface}; use cross_usb::context::{UsbDevice, UsbInterface};
use cross_usb::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient}; use cross_usb::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient};
use super::utils::cross_sleep;
//use nusb::{Device, DeviceInfo, Interface}; //use nusb::{Device, DeviceInfo, Interface};
const DEFAULT_TIMEOUT: Duration = Duration::new(10000, 0); const DEFAULT_TIMEOUT: Duration = Duration::new(10000, 0);
@ -239,24 +243,26 @@ impl NetMD {
use_factory_command: bool, use_factory_command: bool,
override_length: Option<i32>, override_length: Option<i32>,
) -> Result<Vec<u8>, Box<dyn Error>> { ) -> Result<Vec<u8>, Box<dyn Error>> {
let mut length = 0; let mut length = self.poll().await?.0;
for attempt in 0..40 { for attempt in 0..75 {
if attempt == 39 { if attempt == 75 {
return Err("Failed to get response length".into()); return Err("Failed to get response length".into());
} }
// Back off while trying again
let sleep_time = Self::READ_REPLY_RETRY_INTERVAL as u64
* (u64::pow(2, 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; length = self.poll().await?.0;
if length > 0 { if length > 0 {
break break
} }
// Back off while trying again
let sleep_time = Self::READ_REPLY_RETRY_INTERVAL
* (u32::pow(2, attempt / 10) - 1);
cross_sleep(sleep_time).await;
} }
if let Some(value) = override_length { if let Some(value) = override_length {
@ -322,7 +328,7 @@ impl NetMD {
Ok(final_result) Ok(final_result)
} }
pub async fn write_bulk(&mut self, data: &[u8]) -> Result<usize, Box<dyn Error>> { pub async fn write_bulk(&mut self, data: Vec<u8>) -> Result<usize, Box<dyn Error>> {
self.usb_interface.bulk_out(BULK_WRITE_ENDPOINT, data).await self.usb_interface.bulk_out(BULK_WRITE_ENDPOINT, data).await
} }
} }

View file

@ -1,10 +1,9 @@
#![cfg_attr(debug_assertions, allow(dead_code))] #![cfg_attr(debug_assertions, allow(dead_code))]
use std::error::Error; use std::{error::Error, thread::sleep, time::Duration};
use num_derive::FromPrimitive; use num_derive::FromPrimitive;
use num_traits::FromPrimitive; use num_traits::FromPrimitive;
use super::interface::{NetMDInterface, MDTrack}; use super::interface::{NetMDInterface, MDTrack};
use super::utils::cross_sleep;
#[derive(FromPrimitive)] #[derive(FromPrimitive)]
#[derive(PartialEq)] #[derive(PartialEq)]
@ -60,7 +59,7 @@ pub async fn device_status(interface: &mut NetMDInterface) -> Result<DeviceStatu
pub async fn prepare_download(interface: &mut NetMDInterface) -> Result<(), Box<dyn Error>>{ pub async fn prepare_download(interface: &mut NetMDInterface) -> Result<(), Box<dyn Error>>{
while ![OperatingStatus::DiscBlank, OperatingStatus::Ready].contains(&device_status(interface).await?.state.unwrap_or(OperatingStatus::NoDisc)) { while ![OperatingStatus::DiscBlank, OperatingStatus::Ready].contains(&device_status(interface).await?.state.unwrap_or(OperatingStatus::NoDisc)) {
cross_sleep(200).await; sleep(Duration::from_millis(200));
} }
let _ = interface.session_key_forget().await; let _ = interface.session_key_forget().await;

View file

@ -13,8 +13,8 @@ use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use std::thread::sleep;
use super::utils::cross_sleep; use std::time::Duration;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
enum Action { enum Action {
@ -204,7 +204,7 @@ impl NetMDInterface {
const MAX_INTERIM_READ_ATTEMPTS: u8 = 4; const MAX_INTERIM_READ_ATTEMPTS: u8 = 4;
const INTERIM_RESPONSE_RETRY_INTERVAL: u32 = 100; const INTERIM_RESPONSE_RETRY_INTERVAL: u32 = 100;
pub async fn new(device: &cross_usb::UsbDevice) -> Result<Self, Box<dyn Error>> { pub async fn new(device: &cross_usb::context::UsbDevice) -> Result<Self, Box<dyn Error>> {
let net_md_device = base::NetMD::new(device).await?; let net_md_device = base::NetMD::new(device).await?;
Ok(NetMDInterface { net_md_device }) Ok(NetMDInterface { net_md_device })
} }
@ -387,11 +387,10 @@ impl NetMDInterface {
NetmdStatus::NotImplemented => return Err("Not implemented".into()), NetmdStatus::NotImplemented => return Err("Not implemented".into()),
NetmdStatus::Rejected => return Err("Rejected".into()), NetmdStatus::Rejected => return Err("Rejected".into()),
NetmdStatus::Interim if !accept_interim => { NetmdStatus::Interim if !accept_interim => {
let sleep_time = Self::INTERIM_RESPONSE_RETRY_INTERVAL let sleep_time = Self::INTERIM_RESPONSE_RETRY_INTERVAL as u64
* (u32::pow(2, current_attempt as u32) - 1); * (u64::pow(2, current_attempt as u32) - 1);
let sleep_dur = std::time::Duration::from_millis(sleep_time);
cross_sleep(sleep_time).await; std::thread::sleep(sleep_dur); // Sleep to wait before retrying
current_attempt += 1; current_attempt += 1;
continue; // Retry! continue; // Retry!
} }
@ -988,7 +987,7 @@ impl NetMDInterface {
let wchar_value = match wchar { let wchar_value = match wchar {
true => { true => {
new_title = sanitize_full_width_title(title, false); new_title = sanitize_full_width_title(&title, false);
1 1
} }
false => { false => {
@ -1039,11 +1038,11 @@ impl NetMDInterface {
let new_title: Vec<u8>; let new_title: Vec<u8>;
let (wchar_value, descriptor) = match wchar { let (wchar_value, descriptor) = match wchar {
true => { true => {
new_title = sanitize_full_width_title(title, false); new_title = sanitize_full_width_title(&title, false);
(3, Descriptor::AudioUTOC4TD) (3, Descriptor::AudioUTOC4TD)
} }
false => { false => {
new_title = sanitize_half_width_title(title); new_title = sanitize_half_width_title(title.clone());
(2, Descriptor::AudioUTOC1TD) (2, Descriptor::AudioUTOC1TD)
} }
}; };
@ -1504,7 +1503,7 @@ impl NetMDInterface {
} }
// Sharps are slow // Sharps are slow
cross_sleep(200).await; sleep(Duration::from_millis(200));
let total_bytes = pkt_size + 24; //framesizedict[wireformat] * frames + pktcount * 24; let total_bytes = pkt_size + 24; //framesizedict[wireformat] * frames + pktcount * 24;
@ -1524,7 +1523,7 @@ impl NetMDInterface {
)?; )?;
// Sharps are slow // Sharps are slow
cross_sleep(200).await; sleep(Duration::from_millis(200));
let mut _written_bytes = 0; let mut _written_bytes = 0;
for (packet_count, (key, iv, data)) in packets.into_iter().enumerate() { for (packet_count, (key, iv, data)) in packets.into_iter().enumerate() {
@ -1534,7 +1533,7 @@ impl NetMDInterface {
} else { } else {
data.clone() data.clone()
}; };
self.net_md_device.write_bulk(&binpack).await?; self.net_md_device.write_bulk(binpack).await?;
_written_bytes += data.len(); _written_bytes += data.len();
} }

View file

@ -8,15 +8,6 @@ use unicode_normalization::UnicodeNormalization;
extern crate kana; extern crate kana;
use kana::*; use kana::*;
/// Sleep for a specified number of milliseconds on any platform
pub async fn cross_sleep(millis: u32) {
#[cfg(not(target_family = "wasm"))]
std::thread::sleep(std::time::Duration::from_millis(millis as u64));
#[cfg(target_family = "wasm")]
gloo::timers::future::TimeoutFuture::new(millis).await;
}
pub fn bcd_to_int(mut bcd: i32) -> i32 { pub fn bcd_to_int(mut bcd: i32) -> i32 {
let mut value = 0; let mut value = 0;
let mut nibble = 0; let mut nibble = 0;
@ -99,7 +90,7 @@ fn check(string: String) -> Option<String> {
} }
pub fn sanitize_half_width_title(title: &str) -> Vec<u8> { pub fn sanitize_half_width_title(title: &str) -> Vec<u8> {
let mut string_title = wide2ascii(title); let mut string_title = wide2ascii(&title);
string_title = nowidespace(&string_title); string_title = nowidespace(&string_title);
string_title = hira2kata(&string_title); string_title = hira2kata(&string_title);
string_title = combine(&string_title); string_title = combine(&string_title);
@ -116,7 +107,7 @@ pub fn sanitize_half_width_title(title: &str) -> Vec<u8> {
let sjis_string = SHIFT_JIS.encode(&new_title).0; let sjis_string = SHIFT_JIS.encode(&new_title).0;
if validate_shift_jis(sjis_string.clone().into()) { if validate_shift_jis(sjis_string.clone().into()) {
return agressive_sanitize_title(title).into(); return agressive_sanitize_title(&title).into();
} }
sjis_string.into() sjis_string.into()

View file

@ -3,7 +3,7 @@ use cross_usb::usb::Device;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let device = cross_usb::get_device(0x054c, 0x0186).await.unwrap(); let device = cross_usb::context::get_device(0x054c, 0x0186).await.unwrap();
dbg!(device.vendor_id().await); dbg!(device.vendor_id().await);