mirror of
https://github.com/Dangoware/cd_reader.git
synced 2025-04-19 01:42:55 -05:00
Initally working!
This commit is contained in:
commit
20965bbafc
6 changed files with 418 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
109
Cargo.lock
generated
Normal file
109
Cargo.lock
generated
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cd_read"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"nix",
|
||||||
|
"num-derive",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg_aliases"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.169"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.29.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-derive"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.93"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.38"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.96"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "11cd88e12b17c6494200a9c1b683a04fcac9573ed74cd1b62aeb2727c5592243"
|
9
Cargo.toml
Normal file
9
Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "cd_read"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nix = { version = "0.29.0", features = ["ioctl"] }
|
||||||
|
num-derive = "0.4.2"
|
||||||
|
num-traits = "0.2.19"
|
157
src/constants.rs
Normal file
157
src/constants.rs
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
//! Read more about the meanings of the below bytes here:
|
||||||
|
//! <https://docs.kernel.org/userspace-api/ioctl/cdrom.html>
|
||||||
|
|
||||||
|
use num_traits::ToPrimitive;
|
||||||
|
|
||||||
|
/// CDROM ioctl byte, from <linux/cdrom.h>
|
||||||
|
pub const IOC_BYTE: u8 = 0x53;
|
||||||
|
|
||||||
|
#[repr(u8)]
|
||||||
|
#[derive(FromPrimitive, ToPrimitive)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum Operations {
|
||||||
|
/// Pause Audio Operation
|
||||||
|
Pause = 0x01,
|
||||||
|
/// Resume paused Audio Operation
|
||||||
|
Resume = 0x02,
|
||||||
|
/// Play Audio MSF (struct cdrom_msf)
|
||||||
|
PlayMsf = 0x03,
|
||||||
|
/// Play Audio Track/index (struct cdrom_ti)
|
||||||
|
PlayTrackIndex = 0x04,
|
||||||
|
/// Read TOC header (struct cdrom_tochdr)
|
||||||
|
ReadTocHeader = 0x05,
|
||||||
|
/// Read TOC entry (struct cdrom_tocentry)
|
||||||
|
ReadTocEntry = 0x06,
|
||||||
|
/// Stop the cdrom drive
|
||||||
|
Stop = 0x07,
|
||||||
|
/// Start the cdrom drive
|
||||||
|
Start = 0x08,
|
||||||
|
/// Ejects the cdrom media
|
||||||
|
Eject = 0x09,
|
||||||
|
/// Control output volume (struct cdrom_volctrl)
|
||||||
|
VolumeControl = 0x0a,
|
||||||
|
/// Read subchannel data (struct cdrom_subchnl)
|
||||||
|
SubChannel = 0x0b,
|
||||||
|
/// Read CDROM mode 2 data (2336 Bytes) (struct cdrom_subchnl)
|
||||||
|
ReadMode2 = 0x0c,
|
||||||
|
/// Read CDROM mode 1 data (2048 Bytes) (struct cdrom_read)
|
||||||
|
ReadMode1 = 0x0d,
|
||||||
|
/// (struct cdrom_read_audio)
|
||||||
|
ReadAudio = 0x0e,
|
||||||
|
/// Enable (1)/Disable (0) auto-ejecting
|
||||||
|
EjectSoftware = 0x0f,
|
||||||
|
/// Obtain the start-of-last-session address of multi session disks (struct cdrom_multisession)
|
||||||
|
MultiSession = 0x10,
|
||||||
|
/// Obtain the "Universal Product Code" if available (struct cdrom_mcn)
|
||||||
|
GetMcn = 0x11,
|
||||||
|
/// Hard-reset the drive
|
||||||
|
Reset = 0x12,
|
||||||
|
/// Get the drive's volume setting (struct cdrom_volctrl)
|
||||||
|
VolumeRead = 0x13,
|
||||||
|
/// Read data in raw mode (2352 Bytes) (struct cdrom_read)
|
||||||
|
ReadRaw = 0x14,
|
||||||
|
|
||||||
|
|
||||||
|
// These ioctls are only used in aztcd.c and optcd.c
|
||||||
|
|
||||||
|
/// Read data in cooked mode (???)
|
||||||
|
ReadCooked = 0x15,
|
||||||
|
/// Seek msf address
|
||||||
|
Seek = 0x16,
|
||||||
|
|
||||||
|
|
||||||
|
// This ioctl is only used by the scsi-cd driver.
|
||||||
|
// It is for playing audio in logtal block addresing mode.
|
||||||
|
|
||||||
|
/// (struct cdrom_blk)
|
||||||
|
PlayBlock = 0x17,
|
||||||
|
|
||||||
|
|
||||||
|
// These ioctls are only used in optcd.c
|
||||||
|
|
||||||
|
/// Read all 2646 bytes
|
||||||
|
ReadAll = 0x18,
|
||||||
|
|
||||||
|
|
||||||
|
// These ioctls were only in (now removed) ide-cd.c for controlling
|
||||||
|
// drive spindown time. They should be implemented in the
|
||||||
|
// Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10,
|
||||||
|
// GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE...
|
||||||
|
// -Erik
|
||||||
|
GetSpindown = 0x1d,
|
||||||
|
SetSpindown = 0x1e,
|
||||||
|
|
||||||
|
// These ioctls are implemented through the uniform CD-ROM driver
|
||||||
|
// They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM
|
||||||
|
// drivers are eventually ported to the uniform CD-ROM driver interface.
|
||||||
|
|
||||||
|
/// Pendant of [`Operations::Eject`]
|
||||||
|
CloseTray = 0x19,
|
||||||
|
/// Set behavior options
|
||||||
|
SetOptions = 0x20,
|
||||||
|
/// Clear behavior options
|
||||||
|
ClearOptions = 0x21,
|
||||||
|
/// Set the CD-ROM speed
|
||||||
|
SelectSpeed = 0x22,
|
||||||
|
/// Select disc (for juke-boxes)
|
||||||
|
SelectDisk = 0x23,
|
||||||
|
/// Check is media changed
|
||||||
|
MediaChanged = 0x25,
|
||||||
|
/// Get tray position, etc
|
||||||
|
DriveStatus = 0x26,
|
||||||
|
/// Get disc type, etc
|
||||||
|
DiscStatus = 0x27,
|
||||||
|
/// Get number of slots
|
||||||
|
ChangerNslots = 0x28,
|
||||||
|
/// Lock or unlock door
|
||||||
|
LockDoor = 0x29,
|
||||||
|
/// Turn debug messages on/off
|
||||||
|
Debug = 0x30,
|
||||||
|
/// Get capabilities
|
||||||
|
GetCapability = 0x31,
|
||||||
|
|
||||||
|
// Note that scsi/scsi_ioctl.h also uses 0x5382 - 0x5386.
|
||||||
|
// Future CDROM ioctls should be kept below 0x537F
|
||||||
|
|
||||||
|
/// Set the audio buffer size
|
||||||
|
/// conflict with SCSI_IOCTL_GET_IDLUN
|
||||||
|
AudioBufferSize = 0x82,
|
||||||
|
|
||||||
|
// DVD-ROM Specific ioctls
|
||||||
|
|
||||||
|
/// Read structure
|
||||||
|
DvdReadStructure = 0x90,
|
||||||
|
/// Write structure
|
||||||
|
DvdWriteStructure = 0x91,
|
||||||
|
/// Authentication
|
||||||
|
DvdAuthenticate = 0x92,
|
||||||
|
|
||||||
|
/// Send a packet to the drive
|
||||||
|
SendPacket = 0x93,
|
||||||
|
/// Get next writable block
|
||||||
|
NextWritable = 0x94,
|
||||||
|
/// Get last block written on disc
|
||||||
|
LastWritten = 0x95,
|
||||||
|
/// Get the timestamp of the last media change
|
||||||
|
TimedMediaChange = 0x96,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Operations {
|
||||||
|
/// Turns the byte into its full IOCTL representation
|
||||||
|
pub fn to_full(&self) -> u64 {
|
||||||
|
let value = self.to_u8().unwrap();
|
||||||
|
|
||||||
|
((IOC_BYTE as u64) << 8) + value as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Drive status possibilities returned by CDROM_DRIVE_STATUS ioctl
|
||||||
|
#[derive(FromPrimitive, ToPrimitive)]
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub enum Status {
|
||||||
|
NoInfo = 0,
|
||||||
|
NoDisc = 1,
|
||||||
|
TrayOpen = 2,
|
||||||
|
DriveNotReady = 3,
|
||||||
|
DiscOK = 4
|
||||||
|
}
|
65
src/main.rs
Normal file
65
src/main.rs
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
mod constants;
|
||||||
|
mod structures;
|
||||||
|
|
||||||
|
use std::os::{fd::IntoRawFd, unix::fs::OpenOptionsExt};
|
||||||
|
use std::fs::OpenOptions;
|
||||||
|
|
||||||
|
use constants::{Operations, IOC_BYTE};
|
||||||
|
use nix::{ioctl_none, ioctl_none_bad, ioctl_readwrite_bad, libc};
|
||||||
|
|
||||||
|
use nix::libc::c_int;
|
||||||
|
use num_traits::FromPrimitive as _;
|
||||||
|
use structures::{Addr, Msf0, ReadAudio};
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate num_derive;
|
||||||
|
|
||||||
|
ioctl_none_bad!(cdrom_stop, Operations::to_full(&Operations::Stop));
|
||||||
|
ioctl_none_bad!(cdrom_start, Operations::to_full(&Operations::Start));
|
||||||
|
ioctl_none_bad!(cdrom_eject, Operations::to_full(&Operations::Eject));
|
||||||
|
ioctl_none_bad!(cdrom_close_tray, Operations::to_full(&Operations::CloseTray));
|
||||||
|
ioctl_none_bad!(cdrom_status, Operations::to_full(&Operations::DriveStatus));
|
||||||
|
ioctl_readwrite_bad!(cdrom_read_audio, Operations::to_full(&Operations::ReadAudio), structures::ReadAudio);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
const FRAMES: i32 = 75;
|
||||||
|
const BYTES_PER_FRAME: i32 = 2352;
|
||||||
|
|
||||||
|
let time = Msf0 {
|
||||||
|
minute: 2,
|
||||||
|
second: 45,
|
||||||
|
frame: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let address = Addr {
|
||||||
|
msf: time,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buff = [0u8; FRAMES as usize * BYTES_PER_FRAME as usize]; //Frames per second (75) * bytes per frame (2352)
|
||||||
|
|
||||||
|
let mut ra = ReadAudio {
|
||||||
|
addr: address,
|
||||||
|
addr_format: 0x02,
|
||||||
|
nframes: FRAMES,
|
||||||
|
buf: buff.as_mut_ptr()
|
||||||
|
};
|
||||||
|
|
||||||
|
let cdrom = OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.custom_flags(libc::O_NONBLOCK | libc::O_RDONLY)
|
||||||
|
.open("/dev/sr0")
|
||||||
|
.unwrap();
|
||||||
|
let cdrom_fd: c_int = cdrom.into_raw_fd();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let result = constants::Status::from_i32(cdrom_status(cdrom_fd).unwrap()).unwrap();
|
||||||
|
dbg!(result);
|
||||||
|
//dbg!(cdrom_start(cdrom_fd).unwrap_or_default());
|
||||||
|
|
||||||
|
//std::thread::sleep(std::time::Duration::from_secs(1));
|
||||||
|
|
||||||
|
dbg!(cdrom_read_audio(cdrom_fd, std::ptr::addr_of_mut!(ra)).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:02X?}", &buff[0..10]);
|
||||||
|
}
|
77
src/structures.rs
Normal file
77
src/structures.rs
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
use std::ffi::c_int;
|
||||||
|
|
||||||
|
/// Address in MSF format
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Msf0 {
|
||||||
|
pub minute: u8,
|
||||||
|
pub second: u8,
|
||||||
|
pub frame: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Address in either MSF or logical format
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub union Addr {
|
||||||
|
pub lba: c_int,
|
||||||
|
pub msf: Msf0,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This struct is used by [`crate::constants::PLAY_MSF`]
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct Msf {
|
||||||
|
/// Start minute
|
||||||
|
pub min0: u8,
|
||||||
|
/// Start second
|
||||||
|
pub sec0: u8,
|
||||||
|
/// Start frame
|
||||||
|
pub frame0: u8,
|
||||||
|
/// End minute
|
||||||
|
pub min1: u8,
|
||||||
|
/// End second
|
||||||
|
pub sec1: u8,
|
||||||
|
/// End frame
|
||||||
|
pub frame1: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub union RawResult {
|
||||||
|
pub cdrom_msf: Msf,
|
||||||
|
pub buffer: [u8; 2646],
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This struct is used by [`crate::constants::PLAY_TRACK_INDEX`]
|
||||||
|
struct TrackIndex {
|
||||||
|
/// Start track
|
||||||
|
trk0: u8,
|
||||||
|
/// Start index
|
||||||
|
ind0: u8,
|
||||||
|
/// End track
|
||||||
|
trk1: u8,
|
||||||
|
/// End index
|
||||||
|
ind1: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This struct is used by [`crate::constants::READ_TOC_HEADER`]
|
||||||
|
struct TocHeader {
|
||||||
|
trk0: u8,
|
||||||
|
trk1: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VolCtl {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct ReadAudio {
|
||||||
|
/// Frame address
|
||||||
|
pub addr: Addr,
|
||||||
|
/// CDROM_LBA or CDROM_MSF
|
||||||
|
pub addr_format: u8,
|
||||||
|
/// Number of 2352-byte-frames to read at once
|
||||||
|
pub nframes: i32,
|
||||||
|
/// Pointer to frame buffer (size: nframes*2352 bytes)
|
||||||
|
pub buf: *mut u8,
|
||||||
|
}
|
Loading…
Reference in a new issue