MattJackson f07f8210c3 Fix variant B firmware upload: MODE SELECT not WRITE_BUFFER
B firmware upload () byte-level verification reveals:
- Step 1: MODE SELECT (0x55), NOT WRITE_BUFFER — sends 2496 bytes (0x9C0)
- Step 2: Check result == 2
- Step 3: READ_BUFFER mode=6 offset=0x3000 (16B firmware metadata)
- Step 4: WRITE_BUFFER mode=6 (16B from fw_write_data)
- Step 5: Vendor verify CDB (0xF1 opcode from blob)
- Step 6: do_unlock × 5 retries + 1 confirmation

Key differences from A:
- A uses WRITE_BUFFER (0x3B), B uses MODE SELECT (0x55)
- A sends 1888 bytes, B sends 2496 bytes
- B has extra READ metadata + WRITE 16B + vendor verify steps
- B retries unlock 5 times (A does 2)

Added profile fields: fw_write_data (16B), verify_cdb (10B) for B-only.
2026-04-08 20:40:37 -07:00
2026-04-06 12:50:47 -07:00

Crates.io docs.rs License: AGPL-3.0

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

S
Description
Internal mirror of libfreemkv 1.1-beta HEAD for private kdb builds (tag drops flate2; kdb needs HEAD symbols)
Readme MIT
9.7 MiB
Languages
Rust 99.6%
C 0.3%
Shell 0.1%