- Error codes as public constants (E_DEVICE_NOT_FOUND etc.) — single source of truth - SCSI opcodes as named constants (SCSI_READ_10, SCSI_REPORT_KEY, etc.) - AACS key class constant, MKB format constant - No magic numbers in CDB construction - docs/disc-to-rip.md — end-to-end flow from disc insert to decrypted content - Links all module docs together as a starting point
115 lines
4.0 KiB
Markdown
115 lines
4.0 KiB
Markdown
# Disc to Rip: End-to-End Flow
|
|
|
|
How libfreemkv goes from a disc in the drive to decrypted content ready for backup.
|
|
This is the starting point for understanding the library.
|
|
|
|
## The Pipeline
|
|
|
|
```
|
|
Insert disc
|
|
│
|
|
▼
|
|
1. Open drive (drive.rs)
|
|
│ INQUIRY → identify drive
|
|
│ Match bundled profile → chipset, unlock parameters
|
|
│
|
|
▼
|
|
2. AACS handshake (aacs_handshake.rs) — optional, separate transport
|
|
│ Allocate AGID
|
|
│ Exchange certificates + nonces (ECDH)
|
|
│ Derive bus key
|
|
│ Read Volume ID + read_data_key
|
|
│ (fails gracefully if drive doesn't support AACS for this disc)
|
|
│
|
|
▼
|
|
3. Unlock drive (drive.rs → platform/mt1959.rs)
|
|
│ Vendor-specific command activates raw read mode
|
|
│ Required — drive firmware blocks all reads without it
|
|
│
|
|
▼
|
|
4. Read UDF filesystem (udf.rs)
|
|
│ Sector 256: AVDP → find Volume Descriptor Sequence
|
|
│ VDS: Partition Descriptor (physical start) + Logical Volume (metadata start)
|
|
│ Metadata partition → File Set Descriptor → Root directory
|
|
│ Walk directory tree: BDMV/, AACS/, CERTIFICATE/
|
|
│ → docs/udf.md
|
|
│
|
|
▼
|
|
5. Read AACS files from disc (aacs.rs)
|
|
│ AACS/Unit_Key_RO.inf → SHA1 = disc hash
|
|
│ AACS/Content000.cer → AACS version (1.0 or 2.0), bus encryption flag
|
|
│ MKB via SCSI → for key derivation fallback
|
|
│
|
|
▼
|
|
6. Resolve AACS keys (aacs.rs → resolve_keys)
|
|
│ Path 1: disc hash → KEYDB.cfg → VUK (fast, 99% of discs)
|
|
│ Path 2: KEYDB media key + Volume ID → VUK
|
|
│ Path 3: MKB + processing keys → media key → VUK
|
|
│ Path 4: MKB + device keys → subset-difference tree → VUK
|
|
│ VUK → decrypt unit keys from Unit_Key_RO.inf
|
|
│ → docs/aacs.md
|
|
│
|
|
▼
|
|
7. Parse playlists (mpls.rs)
|
|
│ BDMV/PLAYLIST/*.mpls → titles with play items
|
|
│ Each play item: clip ID, in/out timestamps
|
|
│ STN table: video, audio, subtitle streams with codec + language
|
|
│ → docs/mpls.md
|
|
│
|
|
▼
|
|
8. Parse clip info (clpi.rs)
|
|
│ BDMV/CLIPINF/*.clpi → EP map (timestamp → sector mapping)
|
|
│ Coarse + fine entries → full PTS and SPN
|
|
│ SPN → byte offset → sector extents for reading
|
|
│ → docs/clpi.md
|
|
│
|
|
▼
|
|
9. Parse BD-J labels (jar.rs) — optional
|
|
│ BDMV/JAR/*.jar → Java class constant pool strings
|
|
│ Audio track labels: "English Descriptive Audio", "French 5.1", etc.
|
|
│
|
|
▼
|
|
10. Read + decrypt content (disc.rs → ContentReader)
|
|
│ For each aligned unit (6144 bytes = 3 sectors):
|
|
│ Read 3 sectors from disc
|
|
│ If AACS 2.0: bus decrypt (read_data_key, per-sector AES-CBC)
|
|
│ If encrypted: unit decrypt (per-unit key derivation + AES-CBC)
|
|
│ Output decrypted content
|
|
│
|
|
▼
|
|
Decrypted m2ts stream → ready for muxing/backup
|
|
```
|
|
|
|
## API Summary
|
|
|
|
```rust
|
|
// Steps 1 + 3 (open + unlock)
|
|
let mut session = DriveSession::open(Path::new("/dev/sr0"))?;
|
|
|
|
// Steps 2 + 4-9 (AACS + scan)
|
|
let disc = Disc::scan(&mut session, &ScanOptions::with_keydb("keydb.cfg"))?;
|
|
|
|
// Step 10 (read + decrypt)
|
|
let mut reader = disc.open_title(&mut session, 0)?;
|
|
while let Some(unit) = reader.read_unit()? {
|
|
output.write_all(&unit)?;
|
|
}
|
|
```
|
|
|
|
Three lines. Everything else is internal.
|
|
|
|
## Module Reference
|
|
|
|
| Module | Doc | Purpose |
|
|
|--------|-----|---------|
|
|
| drive.rs | [drive-access.md](drive-access.md) | Open, identify, unlock, read |
|
|
| scsi.rs | [drive-access.md](drive-access.md) | Platform SCSI transport |
|
|
| udf.rs | [udf.md](udf.md) | UDF 2.50 filesystem |
|
|
| mpls.rs | [mpls.md](mpls.md) | MPLS playlists + STN streams |
|
|
| clpi.rs | [clpi.md](clpi.md) | CLPI clip info + EP map |
|
|
| aacs.rs | [aacs.md](aacs.md) | Key resolution + content decrypt |
|
|
| aacs_handshake.rs | [aacs.md](aacs.md) | SCSI bus authentication |
|
|
| disc.rs | -- | High-level scan + read API |
|
|
| jar.rs | -- | BD-J audio track labels |
|
|
| error.rs | -- | Error codes (E1xxx-E7xxx) |
|