DriveProfile now has every field traced from firmware: - drive_signature, unlock_init_value, unlock_response_size_minus_init - ld_microcode (base64, ~1888B firmware payload) - hardware_register_a_cdb, hardware_register_b_cdb (10B pre-built CDBs) - drive_nominal_speed_cdb (12B calibration speed) - speed_zone_table (28B), speed_calc_table (25B) drive.rs simplified: - open() calls init() instead of unlock() - init() is the ONLY entry point — handles full dispatch sequence internally - Removed read_config, read_register, maintain_speed, read_sectors from public API - Added set_read_speed() for per-zone speed during content reads - disc.rs updated to call init() instead of unlock() Compiles clean, all tests pass.
libfreemkv
Rust library for 4K UHD / Blu-ray optical drives. Drive access, disc scanning, stream labels, AACS decryption, KEYDB updates, and content reading in one crate. Bundled drive profiles — no external files needed.
Multi-lingual by design — the library outputs structured data and numeric error codes, never English text. Build any UI or localization on top.
API Documentation · Technical Docs
Part of the freemkv project.
Install
[dependencies]
libfreemkv = "0.4"
Quick Start
use libfreemkv::{DriveSession, Disc, ScanOptions};
use std::path::Path;
// Open drive — profiles are bundled, auto-identified
let mut session = DriveSession::open(Path::new("/dev/sr0"))?;
// Scan disc — UDF, playlists, streams, AACS (all automatic)
let disc = Disc::scan(&mut session, &ScanOptions::default())?;
for title in &disc.titles {
println!("{} — {} streams", title.duration_display(), title.streams.len());
}
// Read content (decrypted transparently if AACS keys available)
let mut reader = disc.open_title(&mut session, 0)?;
while let Some(unit) = reader.read_unit()? {
// 6144 bytes of content per aligned unit
}
What It Does
- Drive access — open, identify, unlock, eject
- Disc scanning — UDF 2.50 filesystem, MPLS playlists, CLPI clip info
- Stream labels — 5 BD-J format parsers (Paramount, Criterion, Pixelogic, CTRM, Deluxe)
- AACS decryption — transparent key resolution and content decrypt (1.0, 2.0 in progress)
- KEYDB updates — download, verify, save from any HTTP URL (zero deps, raw TCP)
- Content reading — sector reads with automatic decryption
AACS decryption requires a KEYDB.cfg file. If available at ~/.config/aacs/KEYDB.cfg or passed via ScanOptions, the library handles everything — handshake, key derivation, and per-sector decryption — without the application needing to know anything about encryption.
Architecture
DriveSession — open, identify, unlock, read sectors
├── ScsiTransport — SG_IO (Linux), IOKit (macOS)
├── DriveProfile — per-drive unlock parameters (bundled)
└── Platform — MediaTek (supported), Renesas (planned)
Disc — scan titles, streams, AACS state
├── UDF reader — Blu-ray UDF 2.50 with metadata partitions
├── MPLS parser — playlists → titles + clips + streams
├── CLPI parser — clip info → EP map → sector extents
├── Labels — 5 BD-J format parsers (detect + parse)
├── AACS — key resolution + content decryption
└── KEYDB — download + verify + save
See docs/ for detailed technical documentation on each module.
Error Codes
All errors are structured with numeric codes. No user-facing English text — applications format their own messages.
| Range | Category |
|---|---|
| E1xxx | Device errors (not found, permission) |
| E2xxx | Profile errors (unsupported drive) |
| E3xxx | Unlock errors (failed, signature) |
| E4xxx | SCSI errors (command failed, timeout) |
| E5xxx | I/O errors |
| E6xxx | Disc format errors |
| E7xxx | AACS errors |
| E8xxx | KEYDB update errors |
Platform Support
| Platform | Status | Backend |
|---|---|---|
| Linux | Supported | SG_IO ioctl |
| macOS | Supported | IOKit SCSITask |
| Windows | Planned | SPTI |
Contributing
Run freemkv info --share with the freemkv CLI to contribute your drive's profile.
License
AGPL-3.0-only