56 Commits
Author SHA1 Message Date
Matthew Jackson feacfbb10b ld: add public unlock-CDB seam for external consumers
Expose is_unlock_read_buffer() and UNLOCK_MARKER so consumers (bdemu)
can recognise and answer the LibreDrive unlock READ_BUFFER handshake
without open-coding the variant CDB shapes or the verification marker.
These handshake internals must live only in freemkv-unlock-ld.
2026-06-22 17:02:52 -07:00
Matthew Jackson dd5ebb599f docs: generic repo README; ld README keeps specifics + MakeMKV/Mike Chen credit 2026-06-22 16:53:14 -07:00
Matthew Jackson 607782ab64 Restructure into freemkv-unlock workspace (ld member + room for more)
libfreemkv owns the Unlocker trait + registry; this repo holds the concrete
unlocker plugins. LibreDrive moves to the ld/ member (package freemkv-unlock-ld
unchanged). Workspace root + repo README describe the general-unlocker model;
adding an unlocker = a new member + one register_unlocker line in the consumer.
libfreemkv dep is the crates.io version; local dev resolves it via the
gitignored .cargo/config.toml patch.
2026-06-22 16:02:57 -07:00
Matthew Jackson 47d5d1e0b9 Rename to the generic Unlocker contract; add set_max_read_speed
Track libfreemkv's finalized 3-capability Unlocker trait:

  - unlock(...)   -> unlock_drive(...)
  - read_vid(...) -> read_volume_id(...)
  - add set_max_read_speed(...)

set_max_read_speed issues the matched profile's set_speed_max_cdb
(0xBB SET CD SPEED, to max) over the raw transport; a profile without a
set_speed_max_cdb (or no matching profile) is a no-op so the drive stays at
its current speed. read_disc_keys_cdb is left untouched — inert profile data,
never issued, no trait method.

README: document the 3-method contract, the delete-to-comply fallback, and the
#2-only boundary (freemkv uploads RAM microcode to an already-bootloader-flashed
drive; the permanent bootloader flash #1 is the owner's one-time manual step,
never automated). Left a marked MakeMKV attribution placeholder for the
maintainer to author.

Tests: renamed read_vid tests; added set_max_read_speed tests (issues the CDB
when present, no-op when the profile carries none).
2026-06-22 11:05:30 -07:00
Matthew Jackson d6d79fc74c Implement LibreDrive::read_vid OEM Volume ID retrieval
Recover the per-drive READ_BUFFER OEM VID path that lived in libfreemkv
before the unlocker refactor (read_vid_oem in disc/encrypt.rs), now living
inside the unlocker where the per-drive read_vid_cdb template belongs.

read_vid finds the drive's profile; if it carries a read_vid_cdb, issues
it and parses the 36-byte response (signature 00 22 00, VID at [4..20]),
returning Some(vid). No matching profile or no OEM VID CDB returns Ok(None)
so libfreemkv falls back to the cert handshake. VID is thus obtained
without the host certificate + HRL.

Adds response-parse unit tests (well-formed, short response, bad header,
no-profile fallback).
2026-06-22 10:50:54 -07:00
Matthew Jackson 5cec84dfc6 Initial commit: LibreDrive unlocker plugin for libfreemkv
New crate freemkv-unlock-ld — the LibreDrive Unlocker implementation,
split out of libfreemkv so the library stays firmware-clean on crates.io.

Owns everything about HOW MediaTek MT1959 drives are firmware-unlocked:
  - profiles.json (the bundled drive-profile database + DriveProfile parse)
  - src/platform/mt1959/* (variant-A/B firmware upload + unlock handshake)
  - WRITE_BUFFER / MODE SELECT upload, unlock CDBs, disc-speed calibration

Exposes LibreDrive::new() implementing libfreemkv::Unlocker (name/matches/
unlock). Plug it in with one line at process start:

  libfreemkv::register_unlocker(Box::new(freemkv_unlock_ld::LibreDrive::new()));

Depends on libfreemkv (path-patched via gitignored .cargo/config.toml in
dev) for the trait, ScsiTransport, DriveId, and Result. README notes it's
the LibreDrive unlocker (attribution to be added by owner).
2026-06-22 10:32:00 -07:00