mirror of
https://github.com/G2-Games/minidisc-cli.git
synced 2025-05-01 01:02:53 -05:00
Ran cargo fmt
This commit is contained in:
parent
3f91302ba2
commit
e4268056d2
5 changed files with 235 additions and 117 deletions
|
@ -6,8 +6,8 @@ use std::time::Duration;
|
||||||
|
|
||||||
// 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::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient};
|
use cross_usb::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient};
|
||||||
|
use cross_usb::{UsbDevice, UsbInterface};
|
||||||
|
|
||||||
use super::utils::cross_sleep;
|
use super::utils::cross_sleep;
|
||||||
//use nusb::{Device, DeviceInfo, Interface};
|
//use nusb::{Device, DeviceInfo, Interface};
|
||||||
|
@ -191,9 +191,9 @@ impl NetMD {
|
||||||
// First poll to ensure the device is ready
|
// First poll to ensure the device is ready
|
||||||
match self.poll().await {
|
match self.poll().await {
|
||||||
Ok(buffer) => match buffer.1[2] {
|
Ok(buffer) => match buffer.1[2] {
|
||||||
0 => 0,
|
0 => 0,
|
||||||
_ => return Err("Device not ready!".into()),
|
_ => return Err("Device not ready!".into()),
|
||||||
},
|
},
|
||||||
Err(error) => return Err(error),
|
Err(error) => return Err(error),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,12 +249,11 @@ impl NetMD {
|
||||||
length = self.poll().await?.0;
|
length = self.poll().await?.0;
|
||||||
|
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back off while trying again
|
// Back off while trying again
|
||||||
let sleep_time = Self::READ_REPLY_RETRY_INTERVAL
|
let sleep_time = Self::READ_REPLY_RETRY_INTERVAL * (u32::pow(2, attempt) - 1);
|
||||||
* (u32::pow(2, attempt) - 1);
|
|
||||||
|
|
||||||
cross_sleep(sleep_time).await;
|
cross_sleep(sleep_time).await;
|
||||||
}
|
}
|
||||||
|
@ -323,6 +322,9 @@ impl NetMD {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn write_bulk(&mut self, data: &[u8]) -> Result<usize, Box<dyn Error>> {
|
pub async fn write_bulk(&mut self, data: &[u8]) -> Result<usize, Box<dyn Error>> {
|
||||||
Ok(self.usb_interface.bulk_out(BULK_WRITE_ENDPOINT, data).await?)
|
Ok(self
|
||||||
|
.usb_interface
|
||||||
|
.bulk_out(BULK_WRITE_ENDPOINT, data)
|
||||||
|
.await?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
#![cfg_attr(debug_assertions, allow(dead_code))]
|
#![cfg_attr(debug_assertions, allow(dead_code))]
|
||||||
use std::error::Error;
|
|
||||||
use num_derive::FromPrimitive;
|
use num_derive::FromPrimitive;
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
|
use std::error::Error;
|
||||||
|
|
||||||
use super::interface::{NetMDInterface, MDTrack, MDSession};
|
use super::interface::{MDSession, MDTrack, NetMDInterface};
|
||||||
use super::utils::cross_sleep;
|
use super::utils::cross_sleep;
|
||||||
|
|
||||||
#[derive(FromPrimitive)]
|
#[derive(FromPrimitive, PartialEq)]
|
||||||
#[derive(PartialEq)]
|
pub enum OperatingStatus {
|
||||||
pub enum OperatingStatus{
|
|
||||||
Ready = 50687,
|
Ready = 50687,
|
||||||
Playing = 50037,
|
Playing = 50037,
|
||||||
Paused = 50045,
|
Paused = 50045,
|
||||||
|
@ -49,17 +48,27 @@ pub async fn device_status(interface: &mut NetMDInterface) -> Result<DeviceStatu
|
||||||
state = Some(OperatingStatus::Ready);
|
state = Some(OperatingStatus::Ready);
|
||||||
}
|
}
|
||||||
|
|
||||||
let time = Time{
|
let time = Time {
|
||||||
minute: position[2],
|
minute: position[2],
|
||||||
second: position[3],
|
second: position[3],
|
||||||
frame: position[4],
|
frame: position[4],
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(DeviceStatus { disc_present, state, track, time })
|
Ok(DeviceStatus {
|
||||||
|
disc_present,
|
||||||
|
state,
|
||||||
|
track,
|
||||||
|
time,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
cross_sleep(200).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,11 +81,20 @@ pub async fn prepare_download(interface: &mut NetMDInterface) -> Result<(), Box<
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn download<F>(interface: &mut NetMDInterface, track: MDTrack, progress_callback: F) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>> where F: Fn(usize, usize){
|
pub async fn download<F>(
|
||||||
|
interface: &mut NetMDInterface,
|
||||||
|
track: MDTrack,
|
||||||
|
progress_callback: F,
|
||||||
|
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>>
|
||||||
|
where
|
||||||
|
F: Fn(usize, usize),
|
||||||
|
{
|
||||||
prepare_download(interface).await?;
|
prepare_download(interface).await?;
|
||||||
let mut session = MDSession::new(interface);
|
let mut session = MDSession::new(interface);
|
||||||
session.init().await?;
|
session.init().await?;
|
||||||
let result = session.download_track(track, progress_callback, None).await?;
|
let result = session
|
||||||
|
.download_track(track, progress_callback, None)
|
||||||
|
.await?;
|
||||||
session.close().await?;
|
session.close().await?;
|
||||||
interface.release().await?;
|
interface.release().await?;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
use std::thread;
|
|
||||||
use cbc::cipher::block_padding::NoPadding;
|
use cbc::cipher::block_padding::NoPadding;
|
||||||
use cbc::cipher::{KeyInit, BlockDecryptMut, KeyIvInit, BlockEncryptMut};
|
use cbc::cipher::{BlockDecryptMut, BlockEncryptMut, KeyInit, KeyIvInit};
|
||||||
use tokio::sync::mpsc::{UnboundedReceiver, unbounded_channel};
|
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
|
use std::thread;
|
||||||
|
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
|
||||||
|
|
||||||
use super::interface::DataEncryptorInput;
|
use super::interface::DataEncryptorInput;
|
||||||
|
|
||||||
type DesEcbEnc = ecb::Decryptor<des::Des>;
|
type DesEcbEnc = ecb::Decryptor<des::Des>;
|
||||||
type DesCbcEnc = cbc::Encryptor<des::Des>;
|
type DesCbcEnc = cbc::Encryptor<des::Des>;
|
||||||
|
|
||||||
pub fn new_thread_encryptor(_input: DataEncryptorInput) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)> {
|
pub fn new_thread_encryptor(
|
||||||
|
_input: DataEncryptorInput,
|
||||||
|
) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)> {
|
||||||
let (tx, rx) = unbounded_channel::<(Vec<u8>, Vec<u8>, Vec<u8>)>();
|
let (tx, rx) = unbounded_channel::<(Vec<u8>, Vec<u8>, Vec<u8>)>();
|
||||||
let input = Box::from(_input);
|
let input = Box::from(_input);
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
@ -21,14 +23,16 @@ pub fn new_thread_encryptor(_input: DataEncryptorInput) -> UnboundedReceiver<(Ve
|
||||||
|
|
||||||
// Encrypt it with the kek
|
// Encrypt it with the kek
|
||||||
let mut encrypted_random_key = random_key.clone();
|
let mut encrypted_random_key = random_key.clone();
|
||||||
match DesEcbEnc::new(&input.kek.into()).decrypt_padded_mut::<NoPadding>(&mut encrypted_random_key){
|
match DesEcbEnc::new(&input.kek.into())
|
||||||
|
.decrypt_padded_mut::<NoPadding>(&mut encrypted_random_key)
|
||||||
|
{
|
||||||
Err(x) => panic!("Cannot create main key {:?}", x),
|
Err(x) => panic!("Cannot create main key {:?}", x),
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
let default_chunk_size = match input.chunk_size{
|
let default_chunk_size = match input.chunk_size {
|
||||||
0 => 0x00100000,
|
0 => 0x00100000,
|
||||||
e => e
|
e => e,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut packet_count = 0u32;
|
let mut packet_count = 0u32;
|
||||||
|
@ -51,12 +55,19 @@ pub fn new_thread_encryptor(_input: DataEncryptorInput) -> UnboundedReceiver<(Ve
|
||||||
|
|
||||||
current_chunk_size = std::cmp::min(current_chunk_size, input_data_length - offset);
|
current_chunk_size = std::cmp::min(current_chunk_size, input_data_length - offset);
|
||||||
|
|
||||||
let this_data_chunk = &mut input_data[offset..offset+current_chunk_size];
|
let this_data_chunk = &mut input_data[offset..offset + current_chunk_size];
|
||||||
DesCbcEnc::new(&random_key.into(), &iv.into()).encrypt_padded_mut::<NoPadding>(this_data_chunk, current_chunk_size).unwrap();
|
DesCbcEnc::new(&random_key.into(), &iv.into())
|
||||||
|
.encrypt_padded_mut::<NoPadding>(this_data_chunk, current_chunk_size)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
tx.send((encrypted_random_key.to_vec(), iv.to_vec(), this_data_chunk.to_vec())).unwrap();
|
tx.send((
|
||||||
|
encrypted_random_key.to_vec(),
|
||||||
|
iv.to_vec(),
|
||||||
|
this_data_chunk.to_vec(),
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
iv.copy_from_slice(&this_data_chunk[this_data_chunk.len()-8..]);
|
iv.copy_from_slice(&this_data_chunk[this_data_chunk.len() - 8..]);
|
||||||
|
|
||||||
packet_count += 1;
|
packet_count += 1;
|
||||||
offset += current_chunk_size;
|
offset += current_chunk_size;
|
||||||
|
|
|
@ -6,13 +6,13 @@ use crate::netmd::utils::{
|
||||||
sanitize_half_width_title, time_to_duration,
|
sanitize_half_width_title, time_to_duration,
|
||||||
};
|
};
|
||||||
use cbc::cipher::block_padding::NoPadding;
|
use cbc::cipher::block_padding::NoPadding;
|
||||||
use cbc::cipher::{KeyIvInit, BlockEncryptMut, BlockDecryptMut, KeyInit};
|
use cbc::cipher::{BlockDecryptMut, BlockEncryptMut, KeyInit, KeyIvInit};
|
||||||
use encoding_rs::SHIFT_JIS;
|
use encoding_rs::SHIFT_JIS;
|
||||||
use num_derive::FromPrimitive;
|
use num_derive::FromPrimitive;
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use tokio::sync::mpsc::UnboundedReceiver;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use tokio::sync::mpsc::UnboundedReceiver;
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
@ -226,7 +226,8 @@ impl NetMDInterface {
|
||||||
self.change_descriptor_state(
|
self.change_descriptor_state(
|
||||||
&Descriptor::DiscSubunitIdentifier,
|
&Descriptor::DiscSubunitIdentifier,
|
||||||
&DescriptorAction::OpenRead,
|
&DescriptorAction::OpenRead,
|
||||||
).await;
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let mut query = format_query("1809 00 ff00 0000 0000".to_string(), vec![])?;
|
let mut query = format_query("1809 00 ff00 0000 0000".to_string(), vec![])?;
|
||||||
|
|
||||||
|
@ -294,7 +295,8 @@ impl NetMDInterface {
|
||||||
let _manufacturer_dep_data =
|
let _manufacturer_dep_data =
|
||||||
&buffer[buffer_offset..buffer_offset + manufacturer_dep_length as usize];
|
&buffer[buffer_offset..buffer_offset + manufacturer_dep_length as usize];
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::DiscSubunitIdentifier, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::DiscSubunitIdentifier, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
for media in supported_media_type_specifications {
|
for media in supported_media_type_specifications {
|
||||||
if media.supported_media_type != 0x301 {
|
if media.supported_media_type != 0x301 {
|
||||||
|
@ -324,7 +326,11 @@ impl NetMDInterface {
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
async 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();
|
let mut query = format_query("1808".to_string(), vec![]).unwrap();
|
||||||
|
|
||||||
query.append(&mut descriptor.get_array());
|
query.append(&mut descriptor.get_array());
|
||||||
|
@ -392,7 +398,6 @@ impl NetMDInterface {
|
||||||
let sleep_time = Self::INTERIM_RESPONSE_RETRY_INTERVAL
|
let sleep_time = Self::INTERIM_RESPONSE_RETRY_INTERVAL
|
||||||
* (u32::pow(2, current_attempt as u32) - 1);
|
* (u32::pow(2, current_attempt as u32) - 1);
|
||||||
|
|
||||||
|
|
||||||
cross_sleep(sleep_time).await;
|
cross_sleep(sleep_time).await;
|
||||||
|
|
||||||
current_attempt += 1;
|
current_attempt += 1;
|
||||||
|
@ -475,7 +480,8 @@ impl NetMDInterface {
|
||||||
self.change_descriptor_state(
|
self.change_descriptor_state(
|
||||||
&Descriptor::OperatingStatusBlock,
|
&Descriptor::OperatingStatusBlock,
|
||||||
&DescriptorAction::OpenRead,
|
&DescriptorAction::OpenRead,
|
||||||
).await;
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1809 8001 0230 8800 0030 8804 00 ff00 00000000".to_string(),
|
"1809 8001 0230 8800 0030 8804 00 ff00 00000000".to_string(),
|
||||||
|
@ -489,7 +495,8 @@ impl NetMDInterface {
|
||||||
"1809 8001 0230 8800 0030 8804 00 1000 00090000 %x".to_string(),
|
"1809 8001 0230 8800 0030 8804 00 1000 00090000 %x".to_string(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
let final_array = res[0].to_vec().unwrap();
|
let final_array = res[0].to_vec().unwrap();
|
||||||
|
|
||||||
|
@ -509,7 +516,8 @@ impl NetMDInterface {
|
||||||
self.change_descriptor_state(
|
self.change_descriptor_state(
|
||||||
&Descriptor::OperatingStatusBlock,
|
&Descriptor::OperatingStatusBlock,
|
||||||
&DescriptorAction::OpenRead,
|
&DescriptorAction::OpenRead,
|
||||||
).await;
|
)
|
||||||
|
.await;
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1809 8001 0330 8802 0030 8805 0030 8806 00 ff00 00000000".to_string(),
|
"1809 8001 0330 8802 0030 8805 0030 8806 00 ff00 00000000".to_string(),
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -525,7 +533,8 @@ impl NetMDInterface {
|
||||||
let operating_status = result[1].to_vec().unwrap();
|
let operating_status = result[1].to_vec().unwrap();
|
||||||
let status_mode = result[0].to_i64().unwrap() as u8;
|
let status_mode = result[0].to_i64().unwrap() as u8;
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
if operating_status.len() < 2 {
|
if operating_status.len() < 2 {
|
||||||
return Err("Unparsable operating system".into());
|
return Err("Unparsable operating system".into());
|
||||||
|
@ -547,7 +556,8 @@ impl NetMDInterface {
|
||||||
self.change_descriptor_state(
|
self.change_descriptor_state(
|
||||||
&Descriptor::OperatingStatusBlock,
|
&Descriptor::OperatingStatusBlock,
|
||||||
&DescriptorAction::OpenRead,
|
&DescriptorAction::OpenRead,
|
||||||
).await;
|
)
|
||||||
|
.await;
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1809 8001 0330 %w 0030 8805 0030 %w 00 ff00 00000000".to_string(),
|
"1809 8001 0330 %w 0030 8805 0030 %w 00 ff00 00000000".to_string(),
|
||||||
vec![QueryValue::Number(p1 as i64), QueryValue::Number(p2 as i64)],
|
vec![QueryValue::Number(p1 as i64), QueryValue::Number(p2 as i64)],
|
||||||
|
@ -561,7 +571,8 @@ impl NetMDInterface {
|
||||||
"1809 8001 0330 %?%? %?%? %?%? %?%? %?%? %? 1000 00%?0000 %x %?".to_string(),
|
"1809 8001 0330 %?%? %?%? %?%? %?%? %?%? %? 1000 00%?0000 %x %?".to_string(),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(res.unwrap()[0].to_vec().unwrap())
|
Ok(res.unwrap()[0].to_vec().unwrap())
|
||||||
}
|
}
|
||||||
|
@ -578,7 +589,8 @@ impl NetMDInterface {
|
||||||
self.change_descriptor_state(
|
self.change_descriptor_state(
|
||||||
&Descriptor::OperatingStatusBlock,
|
&Descriptor::OperatingStatusBlock,
|
||||||
&DescriptorAction::OpenRead,
|
&DescriptorAction::OpenRead,
|
||||||
).await;
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1809 8001 0430 8802 0030 8805 0030 0003 0030 0002 00 ff00 00000000".to_string(),
|
"1809 8001 0430 8802 0030 8805 0030 0003 0030 0002 00 ff00 00000000".to_string(),
|
||||||
|
@ -602,7 +614,8 @@ impl NetMDInterface {
|
||||||
result[4].to_i64().unwrap() as u16,
|
result[4].to_i64().unwrap() as u16,
|
||||||
];
|
];
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(final_result)
|
Ok(final_result)
|
||||||
}
|
}
|
||||||
|
@ -709,21 +722,24 @@ impl NetMDInterface {
|
||||||
// TODO: Ensure this is returning the correct value, it
|
// TODO: Ensure this is returning the correct value, it
|
||||||
// looks like it actually might be a 16 bit integer
|
// looks like it actually might be a 16 bit integer
|
||||||
pub async fn disc_flags(&mut self) -> Result<u8, Box<dyn Error>> {
|
pub async fn disc_flags(&mut self) -> Result<u8, Box<dyn Error>> {
|
||||||
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead).await;
|
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead)
|
||||||
|
.await;
|
||||||
let mut query = format_query("1806 01101000 ff00 0001000b".to_string(), vec![]).unwrap();
|
let mut query = format_query("1806 01101000 ff00 0001000b".to_string(), vec![]).unwrap();
|
||||||
|
|
||||||
let reply = self.send_query(&mut query, false, false).await?;
|
let reply = self.send_query(&mut query, false, false).await?;
|
||||||
|
|
||||||
let res = scan_query(reply, "1806 01101000 1000 0001000b %b".to_string()).unwrap();
|
let res = scan_query(reply, "1806 01101000 1000 0001000b %b".to_string()).unwrap();
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(res[0].to_i64().unwrap() as u8)
|
Ok(res[0].to_i64().unwrap() as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The number of tracks on the disc
|
/// The number of tracks on the disc
|
||||||
pub async fn track_count(&mut self) -> Result<u16, Box<dyn Error>> {
|
pub async fn track_count(&mut self) -> Result<u16, Box<dyn Error>> {
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
|
||||||
|
.await;
|
||||||
|
|
||||||
let mut query =
|
let mut query =
|
||||||
format_query("1806 02101001 3000 1000 ff00 00000000".to_string(), vec![]).unwrap();
|
format_query("1806 02101001 3000 1000 ff00 00000000".to_string(), vec![]).unwrap();
|
||||||
|
@ -736,14 +752,17 @@ impl NetMDInterface {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(res[0].to_i64().unwrap() as u16)
|
Ok(res[0].to_i64().unwrap() as u16)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn raw_disc_title(&mut self, wchar: bool) -> Result<String, Box<dyn Error>> {
|
async fn raw_disc_title(&mut self, wchar: bool) -> Result<String, Box<dyn Error>> {
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
|
||||||
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead).await;
|
.await;
|
||||||
|
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead)
|
||||||
|
.await;
|
||||||
|
|
||||||
let mut done: i32 = 0;
|
let mut done: i32 = 0;
|
||||||
let mut remaining: i32 = 0;
|
let mut remaining: i32 = 0;
|
||||||
|
@ -797,8 +816,10 @@ impl NetMDInterface {
|
||||||
|
|
||||||
let res = result.join("");
|
let res = result.join("");
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close)
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
|
.await;
|
||||||
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
@ -931,7 +952,8 @@ impl NetMDInterface {
|
||||||
false => Descriptor::AudioUTOC1TD,
|
false => Descriptor::AudioUTOC1TD,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.change_descriptor_state(&descriptor_type, &DescriptorAction::OpenRead).await;
|
self.change_descriptor_state(&descriptor_type, &DescriptorAction::OpenRead)
|
||||||
|
.await;
|
||||||
|
|
||||||
let mut track_titles: Vec<String> = vec![];
|
let mut track_titles: Vec<String> = vec![];
|
||||||
for i in tracks {
|
for i in tracks {
|
||||||
|
@ -960,7 +982,8 @@ impl NetMDInterface {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.change_descriptor_state(&descriptor_type, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&descriptor_type, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(track_titles)
|
Ok(track_titles)
|
||||||
}
|
}
|
||||||
|
@ -976,11 +999,7 @@ impl NetMDInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the title of the disc
|
// Sets the title of the disc
|
||||||
pub async fn set_disc_title(
|
pub async fn set_disc_title(&mut self, title: &str, wchar: bool) -> Result<(), Box<dyn Error>> {
|
||||||
&mut self,
|
|
||||||
title: &str,
|
|
||||||
wchar: bool,
|
|
||||||
) -> Result<(), Box<dyn Error>> {
|
|
||||||
let current_title = self.raw_disc_title(wchar).await?;
|
let current_title = self.raw_disc_title(wchar).await?;
|
||||||
if current_title == title {
|
if current_title == title {
|
||||||
return Err("Title is already the same".into());
|
return Err("Title is already the same".into());
|
||||||
|
@ -1003,10 +1022,13 @@ impl NetMDInterface {
|
||||||
let new_len = new_title.len();
|
let new_len = new_title.len();
|
||||||
|
|
||||||
if self.net_md_device.vendor_id().await == &0x04dd {
|
if self.net_md_device.vendor_id().await == &0x04dd {
|
||||||
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::OpenWrite).await
|
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::OpenWrite)
|
||||||
|
.await
|
||||||
} else {
|
} else {
|
||||||
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close)
|
||||||
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenWrite).await
|
.await;
|
||||||
|
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenWrite)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
|
@ -1022,11 +1044,15 @@ impl NetMDInterface {
|
||||||
let _ = self.send_query(&mut query, false, false).await;
|
let _ = self.send_query(&mut query, false, false).await;
|
||||||
|
|
||||||
if self.net_md_device.vendor_id().await == &0x04dd {
|
if self.net_md_device.vendor_id().await == &0x04dd {
|
||||||
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::Close).await
|
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::Close)
|
||||||
|
.await
|
||||||
} else {
|
} else {
|
||||||
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close)
|
||||||
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead).await;
|
.await;
|
||||||
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(())
|
Ok(())
|
||||||
|
@ -1064,7 +1090,8 @@ impl NetMDInterface {
|
||||||
Err(error) => return Err(error),
|
Err(error) => return Err(error),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.change_descriptor_state(&descriptor, &DescriptorAction::OpenWrite).await;
|
self.change_descriptor_state(&descriptor, &DescriptorAction::OpenWrite)
|
||||||
|
.await;
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1807 022018%b %w 3000 0a00 5000 %w 0000 %w %*".to_string(),
|
"1807 022018%b %w 3000 0a00 5000 %w 0000 %w %*".to_string(),
|
||||||
vec![
|
vec![
|
||||||
|
@ -1081,7 +1108,8 @@ impl NetMDInterface {
|
||||||
reply,
|
reply,
|
||||||
"1807 022018%? %?%? 3000 0a00 5000 %?%? 0000 %?%?".to_string(),
|
"1807 022018%? %?%? 3000 0a00 5000 %?%? 0000 %?%?".to_string(),
|
||||||
);
|
);
|
||||||
self.change_descriptor_state(&descriptor, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&descriptor, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1119,7 +1147,8 @@ impl NetMDInterface {
|
||||||
p1: i32,
|
p1: i32,
|
||||||
p2: i32,
|
p2: i32,
|
||||||
) -> Result<Vec<u8>, Box<dyn Error>> {
|
) -> Result<Vec<u8>, Box<dyn Error>> {
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
|
||||||
|
.await;
|
||||||
|
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1806 02201001 %w %w %w ff00 00000000".to_string(),
|
"1806 02201001 %w %w %w ff00 00000000".to_string(),
|
||||||
|
@ -1136,7 +1165,8 @@ impl NetMDInterface {
|
||||||
"1806 02201001 %?%? %?%? %?%? 1000 00%?0000 %x".to_string(),
|
"1806 02201001 %?%? %?%? %?%? 1000 00%?0000 %x".to_string(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(res[0].to_vec().unwrap())
|
Ok(res[0].to_vec().unwrap())
|
||||||
}
|
}
|
||||||
|
@ -1148,7 +1178,8 @@ impl NetMDInterface {
|
||||||
) -> Result<Vec<std::time::Duration>, Box<dyn Error>> {
|
) -> Result<Vec<std::time::Duration>, Box<dyn Error>> {
|
||||||
let mut times: Vec<std::time::Duration> = vec![];
|
let mut times: Vec<std::time::Duration> = vec![];
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
|
||||||
|
.await;
|
||||||
for track in tracks {
|
for track in tracks {
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1806 02201001 %w %w %w ff00 00000000".to_string(),
|
"1806 02201001 %w %w %w ff00 00000000".to_string(),
|
||||||
|
@ -1180,7 +1211,8 @@ impl NetMDInterface {
|
||||||
times.push(length);
|
times.push(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(times)
|
Ok(times)
|
||||||
}
|
}
|
||||||
|
@ -1211,7 +1243,8 @@ impl NetMDInterface {
|
||||||
|
|
||||||
/// Gets a track's flags
|
/// Gets a track's flags
|
||||||
pub async fn track_flags(&mut self, track: u16) -> Result<u8, Box<dyn Error>> {
|
pub async fn track_flags(&mut self, track: u16) -> Result<u8, Box<dyn Error>> {
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
|
||||||
|
.await;
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1806 01201001 %w ff00 00010008".to_string(),
|
"1806 01201001 %w ff00 00010008".to_string(),
|
||||||
vec![QueryValue::Number(track as i64)],
|
vec![QueryValue::Number(track as i64)],
|
||||||
|
@ -1220,14 +1253,16 @@ impl NetMDInterface {
|
||||||
|
|
||||||
let res = scan_query(reply, "1806 01201001 %?%? 10 00 00010008 %b".to_string())?;
|
let res = scan_query(reply, "1806 01201001 %?%? 10 00 00010008 %b".to_string())?;
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(res[0].to_i64().unwrap() as u8)
|
Ok(res[0].to_i64().unwrap() as u8)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the disc capacity as a `std::time::Duration`
|
/// Gets the disc capacity as a `std::time::Duration`
|
||||||
pub async fn disc_capacity(&mut self) -> Result<[std::time::Duration; 3], Box<dyn Error>> {
|
pub async fn disc_capacity(&mut self) -> Result<[std::time::Duration; 3], Box<dyn Error>> {
|
||||||
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead).await;
|
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead)
|
||||||
|
.await;
|
||||||
let mut query = format_query("1806 02101000 3080 0300 ff00 00000000".to_string(), vec![])?;
|
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 reply = self.send_query(&mut query, false, false).await?;
|
||||||
let mut result: [std::time::Duration; 3] = [std::time::Duration::from_secs(0); 3];
|
let mut result: [std::time::Duration; 3] = [std::time::Duration::from_secs(0); 3];
|
||||||
|
@ -1250,7 +1285,8 @@ impl NetMDInterface {
|
||||||
result[i] = std::time::Duration::from_micros(time_micros);
|
result[i] = std::time::Duration::from_micros(time_micros);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close).await;
|
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
@ -1259,7 +1295,8 @@ impl NetMDInterface {
|
||||||
self.change_descriptor_state(
|
self.change_descriptor_state(
|
||||||
&Descriptor::OperatingStatusBlock,
|
&Descriptor::OperatingStatusBlock,
|
||||||
&DescriptorAction::OpenRead,
|
&DescriptorAction::OpenRead,
|
||||||
).await;
|
)
|
||||||
|
.await;
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1809 8001 0330 8801 0030 8805 0030 8807 00 ff00 00000000".to_string(),
|
"1809 8001 0330 8801 0030 8805 0030 8807 00 ff00 00000000".to_string(),
|
||||||
vec![],
|
vec![],
|
||||||
|
@ -1269,7 +1306,8 @@ 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())?;
|
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).await;
|
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
|
||||||
|
.await;
|
||||||
|
|
||||||
Ok(res.into_iter().map(|x| x.to_i64().unwrap() as u8).collect())
|
Ok(res.into_iter().map(|x| x.to_i64().unwrap() as u8).collect())
|
||||||
}
|
}
|
||||||
|
@ -1448,7 +1486,9 @@ impl NetMDInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut message = [vec![1, 1, 1, 1], contentid.to_vec(), keyenckey.to_vec()].concat();
|
let mut message = [vec![1, 1, 1, 1], contentid.to_vec(), keyenckey.to_vec()].concat();
|
||||||
DesCbcEnc::new(hex_session_key.into(), &[0u8; 8].into()).encrypt_padded_mut::<NoPadding>(message.as_mut_slice(), 32).unwrap();
|
DesCbcEnc::new(hex_session_key.into(), &[0u8; 8].into())
|
||||||
|
.encrypt_padded_mut::<NoPadding>(message.as_mut_slice(), 32)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1800 080046 f0030103 22 ff 0000 %*".to_string(),
|
"1800 080046 f0030103 22 ff 0000 %*".to_string(),
|
||||||
|
@ -1472,7 +1512,9 @@ impl NetMDInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut message = [0u8; 8];
|
let mut message = [0u8; 8];
|
||||||
DesEcbEnc::new(hex_session_key.into()).encrypt_padded_mut::<NoPadding>(&mut message, 8).unwrap();
|
DesEcbEnc::new(hex_session_key.into())
|
||||||
|
.encrypt_padded_mut::<NoPadding>(&mut message, 8)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1800 080046 f0030103 48 ff 00 1001 %w %*".to_string(),
|
"1800 080046 f0030103 48 ff 00 1001 %w %*".to_string(),
|
||||||
|
@ -1498,8 +1540,11 @@ impl NetMDInterface {
|
||||||
// key // iv // data
|
// key // iv // data
|
||||||
mut packets: UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>,
|
mut packets: UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>,
|
||||||
hex_session_key: &[u8],
|
hex_session_key: &[u8],
|
||||||
progress_callback: F
|
progress_callback: F,
|
||||||
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>> where F: Fn(usize, usize) {
|
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>>
|
||||||
|
where
|
||||||
|
F: Fn(usize, usize),
|
||||||
|
{
|
||||||
if hex_session_key.len() != 8 {
|
if hex_session_key.len() != 8 {
|
||||||
return Err("Supplied Session Key length wrong".into());
|
return Err("Supplied Session Key length wrong".into());
|
||||||
}
|
}
|
||||||
|
@ -1556,7 +1601,9 @@ impl NetMDInterface {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut encrypted_data = res[1].to_vec().unwrap();
|
let mut encrypted_data = res[1].to_vec().unwrap();
|
||||||
DesCbcDec::new(hex_session_key.into(), &[0u8; 8].into()).decrypt_padded_mut::<NoPadding>(&mut encrypted_data).unwrap();
|
DesCbcDec::new(hex_session_key.into(), &[0u8; 8].into())
|
||||||
|
.decrypt_padded_mut::<NoPadding>(&mut encrypted_data)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let part1 = encrypted_data[0..8].to_vec();
|
let part1 = encrypted_data[0..8].to_vec();
|
||||||
let part2 = encrypted_data[12..32].to_vec();
|
let part2 = encrypted_data[12..32].to_vec();
|
||||||
|
@ -1598,14 +1645,18 @@ pub fn retailmac(key: &[u8], value: &[u8], iv: &[u8; 8]) -> Vec<u8> {
|
||||||
let mut end = [0u8; 8];
|
let mut end = [0u8; 8];
|
||||||
end.clone_from_slice(&value[8..]);
|
end.clone_from_slice(&value[8..]);
|
||||||
|
|
||||||
DesCbcEnc::new(&subkey_a.into(), iv.into()).encrypt_padded_mut::<NoPadding>(&mut beginning, 8).unwrap();
|
DesCbcEnc::new(&subkey_a.into(), iv.into())
|
||||||
|
.encrypt_padded_mut::<NoPadding>(&mut beginning, 8)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let iv2 = &beginning[beginning.len() - 8..];
|
let iv2 = &beginning[beginning.len() - 8..];
|
||||||
|
|
||||||
let mut wonky_key = [0u8; 24];
|
let mut wonky_key = [0u8; 24];
|
||||||
wonky_key[0..16].clone_from_slice(&key);
|
wonky_key[0..16].clone_from_slice(&key);
|
||||||
wonky_key[16..].clone_from_slice(&key[0..8]);
|
wonky_key[16..].clone_from_slice(&key[0..8]);
|
||||||
TDesCbcEnc::new(&wonky_key.into(), iv2.into()).encrypt_padded_mut::<NoPadding>(&mut end, 8).unwrap();
|
TDesCbcEnc::new(&wonky_key.into(), iv2.into())
|
||||||
|
.encrypt_padded_mut::<NoPadding>(&mut end, 8)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
end[..8].to_vec()
|
end[..8].to_vec()
|
||||||
}
|
}
|
||||||
|
@ -1642,13 +1693,19 @@ impl EKBOpenSource {
|
||||||
pub fn ekb_data_for_leaf_id(&self) -> EKBData {
|
pub fn ekb_data_for_leaf_id(&self) -> EKBData {
|
||||||
EKBData {
|
EKBData {
|
||||||
chains: [
|
chains: [
|
||||||
[0x25, 0x45, 0x06, 0x4d, 0xea, 0xca, 0x14, 0xf9, 0x96, 0xbd, 0xc8, 0xa4, 0x06, 0xc2, 0x2b, 0x81],
|
[
|
||||||
[0xfb, 0x60, 0xbd, 0xdd, 0x0d, 0xbc, 0xab, 0x84, 0x8a, 0x00, 0x5e, 0x03, 0x19, 0x4d, 0x3e, 0xda],
|
0x25, 0x45, 0x06, 0x4d, 0xea, 0xca, 0x14, 0xf9, 0x96, 0xbd, 0xc8, 0xa4, 0x06,
|
||||||
|
0xc2, 0x2b, 0x81,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0xfb, 0x60, 0xbd, 0xdd, 0x0d, 0xbc, 0xab, 0x84, 0x8a, 0x00, 0x5e, 0x03, 0x19,
|
||||||
|
0x4d, 0x3e, 0xda,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
depth: 9,
|
depth: 9,
|
||||||
signature: [
|
signature: [
|
||||||
0x8f, 0x2b, 0xc3, 0x52, 0xe8, 0x6c, 0x5e, 0xd3, 0x06, 0xdc, 0xae, 0x18,
|
0x8f, 0x2b, 0xc3, 0x52, 0xe8, 0x6c, 0x5e, 0xd3, 0x06, 0xdc, 0xae, 0x18, 0xd2, 0xf3,
|
||||||
0xd2, 0xf3, 0x8c, 0x7f, 0x89, 0xb5, 0xe1, 0x85, 0x55, 0xa1, 0x05, 0xea,
|
0x8c, 0x7f, 0x89, 0xb5, 0xe1, 0x85, 0x55, 0xa1, 0x05, 0xea,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1660,7 +1717,8 @@ pub struct MDTrack {
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
pub chunk_size: usize,
|
pub chunk_size: usize,
|
||||||
pub full_width_title: Option<String>,
|
pub full_width_title: Option<String>,
|
||||||
pub encrypt_packets_iterator: Box<dyn Fn(DataEncryptorInput) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>>,
|
pub encrypt_packets_iterator:
|
||||||
|
Box<dyn Fn(DataEncryptorInput) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DataEncryptorInput {
|
pub struct DataEncryptorInput {
|
||||||
|
@ -1715,12 +1773,12 @@ impl MDTrack {
|
||||||
[0x14, 0xe3, 0x83, 0x4e, 0xe2, 0xd3, 0xcc, 0xa5]
|
[0x14, 0xe3, 0x83, 0x4e, 0xe2, 0xd3, 0xcc, 0xa5]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_encrypting_iterator(&mut self) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>{
|
pub fn get_encrypting_iterator(&mut self) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)> {
|
||||||
(self.encrypt_packets_iterator)(DataEncryptorInput {
|
(self.encrypt_packets_iterator)(DataEncryptorInput {
|
||||||
kek: self.get_kek().clone(),
|
kek: self.get_kek().clone(),
|
||||||
frame_size: self.frame_size(),
|
frame_size: self.frame_size(),
|
||||||
chunk_size: self.chunk_size(),
|
chunk_size: self.chunk_size(),
|
||||||
data: std::mem::take(&mut self.data)
|
data: std::mem::take(&mut self.data),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1732,12 +1790,19 @@ pub struct MDSession<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> MDSession<'a> {
|
impl<'a> MDSession<'a> {
|
||||||
pub async fn init(&mut self) -> Result<(), Box<dyn Error>>{
|
pub async fn init(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
self.md.enter_secure_session().await?;
|
self.md.enter_secure_session().await?;
|
||||||
self.md.leaf_id().await?;
|
self.md.leaf_id().await?;
|
||||||
|
|
||||||
let ekb = self.ekb_object.ekb_data_for_leaf_id();
|
let ekb = self.ekb_object.ekb_data_for_leaf_id();
|
||||||
self.md.send_key_data(self.ekb_object.ekb_id(), ekb.chains, ekb.depth, ekb.signature).await?;
|
self.md
|
||||||
|
.send_key_data(
|
||||||
|
self.ekb_object.ekb_id(),
|
||||||
|
ekb.chains,
|
||||||
|
ekb.depth,
|
||||||
|
ekb.signature,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
let mut nonce = vec![0u8; 8];
|
let mut nonce = vec![0u8; 8];
|
||||||
rand::thread_rng().fill_bytes(&mut nonce);
|
rand::thread_rng().fill_bytes(&mut nonce);
|
||||||
|
|
||||||
|
@ -1757,30 +1822,52 @@ impl<'a> MDSession<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn download_track<F>(&mut self, mut track: MDTrack, progress_callback: F, disc_format: Option<DiscFormat>) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>> where F: Fn(usize, usize) {
|
pub async fn download_track<F>(
|
||||||
if let None = self.hex_session_key{
|
&mut self,
|
||||||
|
mut track: MDTrack,
|
||||||
|
progress_callback: F,
|
||||||
|
disc_format: Option<DiscFormat>,
|
||||||
|
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>>
|
||||||
|
where
|
||||||
|
F: Fn(usize, usize),
|
||||||
|
{
|
||||||
|
if let None = self.hex_session_key {
|
||||||
return Err("Cannot download a track using a non-init()'ed session!".into());
|
return Err("Cannot download a track using a non-init()'ed session!".into());
|
||||||
|
|
||||||
}
|
}
|
||||||
self.md.setup_download(&track.content_id(), &track.get_kek(), &self.hex_session_key.as_ref().unwrap()).await?;
|
self.md
|
||||||
|
.setup_download(
|
||||||
|
&track.content_id(),
|
||||||
|
&track.get_kek(),
|
||||||
|
&self.hex_session_key.as_ref().unwrap(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
let data_format = track.data_format();
|
let data_format = track.data_format();
|
||||||
let final_disc_format = disc_format.unwrap_or(*DISC_FOR_WIRE.get(&data_format).unwrap());
|
let final_disc_format = disc_format.unwrap_or(*DISC_FOR_WIRE.get(&data_format).unwrap());
|
||||||
|
|
||||||
let (track_index, uuid, ccid) = self.md.send_track(
|
let (track_index, uuid, ccid) = self
|
||||||
data_format as u8,
|
.md
|
||||||
final_disc_format as u8,
|
.send_track(
|
||||||
track.frame_count() as u32,
|
data_format as u8,
|
||||||
track.total_size() as u32,
|
final_disc_format as u8,
|
||||||
track.get_encrypting_iterator(),
|
track.frame_count() as u32,
|
||||||
self.hex_session_key.as_ref().unwrap().as_slice(),
|
track.total_size() as u32,
|
||||||
progress_callback
|
track.get_encrypting_iterator(),
|
||||||
).await?;
|
self.hex_session_key.as_ref().unwrap().as_slice(),
|
||||||
|
progress_callback,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
self.md.set_track_title(track_index, &track.title, false).await?;
|
self.md
|
||||||
|
.set_track_title(track_index, &track.title, false)
|
||||||
|
.await?;
|
||||||
if let Some(full_width) = track.full_width_title {
|
if let Some(full_width) = track.full_width_title {
|
||||||
self.md.set_track_title(track_index, &full_width, true).await?;
|
self.md
|
||||||
|
.set_track_title(track_index, &full_width, true)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
self.md.commit_track(track_index, &self.hex_session_key.as_ref().unwrap()).await?;
|
self.md
|
||||||
|
.commit_track(track_index, &self.hex_session_key.as_ref().unwrap())
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok((track_index, uuid, ccid))
|
Ok((track_index, uuid, ccid))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mod base;
|
mod base;
|
||||||
|
pub mod commands;
|
||||||
|
pub mod encryption;
|
||||||
pub mod interface;
|
pub mod interface;
|
||||||
mod mappings;
|
mod mappings;
|
||||||
mod query_utils;
|
mod query_utils;
|
||||||
mod utils;
|
mod utils;
|
||||||
pub mod commands;
|
|
||||||
pub mod encryption;
|
|
||||||
|
|
Loading…
Reference in a new issue