Skip to content

About

Vendor SCSI command catalogue for MediaTek MT1959/MT1939 optical (BD/DVD) drives

Topics

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

mediatek-optical

CI crates.io docs.rs License: MIT

A Rust library for working with MediaTek MT1959/MT1939 BD/DVD optical drives and their firmware. It encodes vendor SCSI commands, decodes drive identity, checks firmware integrity, reconstructs OEM images from drive reads, and prepares and executes receiver-bound firmware updates.

Use it to build drive utilities, firmware inspection tools, backup workflows, or update applications. You provide the operating-system SCSI transport; the library supplies protocol logic and typed results.

Its sister library, pioneer-optical, uses the same transport conventions and development workflow. See the sibling API map when moving between them. Both have a dependency-free no_std core, an allocation-free drive feature, optional firmware analysis, and typed update preparation and verification.

Install

[dependencies]
mediatek-optical = { version = "1.0", features = ["drive"] }

Rust 1.75 or newer is required. The default build has no enabled features. Enable drive for live commands, or select the analysis features below for working with files without connecting a drive.

Identify a drive

Pass an existing transport to drive::identify. This example reads identity without entering update mode or changing settings:

use mediatek_optical::{drive, Identity};

pub fn identify<T: drive::Transport>(
    transport: &mut T,
) -> Result<Identity, drive::Error<T::Error>> {
    let identity = drive::identify(transport)?;
    println!("{} {} {}", identity.vendor(), identity.product(), identity.revision());
    Ok(identity)
}

Implement drive::Transport for your SCSI pass-through adapter. Its exec method receives the command bytes and a drive::Data value describing the data phase, then returns the actual transferred byte count. sense exposes the most recent failed command's sense triplet. Preserve Data::None, Data::In and Data::Out exactly, including zero-length data-out commands. Do not retry firmware writes automatically.

The library handles command construction and bounded transfers. Your application opens the device, supplies timeouts and exclusive access, and persists backups. drive::read_memory reads into a caller-owned buffer; firmware-derived layouts and protocol bounds determine which addresses are meaningful.

Choose features

Feature Use it for Environment
none cdb, Identity, controller types and protocol constants no_std, no allocation
drive Identification, reads and command sequences over Transport no_std, no allocation
image Controller detection, hardware families and AES-CMAC integrity std
enc Low-level AES-128-ECB transport encoding no_std, no allocation
oem Reconstruct OEM images from drive reads with byte provenance std; includes image
std Standard-library error integration without firmware features std

Enable both image and enc for envelope; add drive for receiver-bound execution and recovery. Operational controller detection uses the boot banner; identity tags are retained as labels and never override that result.

Inspect firmware files

Enable image and enc. Loading recognizes plaintext or encrypted input, checks integrity and retains the original and canonical-image hashes:

use mediatek_optical::envelope::{Envelope, Error};

pub fn inspect(bytes: &[u8]) -> Result<(), Error> {
    let envelope = Envelope::load(bytes)?;
    println!("{}: {} bytes", envelope.chip(), envelope.image().len());
    Ok(())
}

The supported image is exactly 2 MiB with a recognized controller banner and a nonempty valid AES-CMAC table. Raw drive reads need reconstruction before they can be loaded as stored update images. With oem, oem::rebuild uses a caller-supplied factory catalog and reports the provenance of substituted bytes. Loading or reconstruction does not authorize a device write.

Prepare and execute an update

Enable drive, image and enc. Bind captured installed firmware to live identity, detect the active receiver, then prepare the target separately:

use mediatek_optical::{drive, envelope::Envelope, receiver, update::InstalledFirmware};

pub fn prepare<T: drive::Transport>(
    transport: &mut T, current_image: &[u8], target_image: &[u8],
) -> Result<receiver::PreparedUpdate, Box<dyn std::error::Error>>
where T::Error: 'static,
{
    let identity = drive::identify(transport)?;
    let installed = InstalledFirmware::new(identity, current_image)?;
    let mode = receiver::detect_mode(transport)?;
    let receiver = receiver::detect(transport, &mode)?;
    let target = Envelope::load(target_image)?;
    Ok(receiver.prepare(&target, &installed)?)
}

Detection reads the receiver. Preparation validates integrity, controller and hardware-family compatibility without writing, and builds an immutable entry and encoding plan. Execution revalidates before writes; file encoding never chooses the transfer encoding. Unknown or conflicting contracts are errors.

PreparedUpdate::flash requires complete protected-region readback. flash_completed returns a Completion with exact target-startup evidence and explicit complete or limited ReadbackQuality. Every readable mismatch and failed data write remains an error. recovery::PreparedRecovery is the explicit recovery path and still requires confirmed target startup.

examples/flash.rs provides a compiled host integration with FlashRuntime and FlashTransport. Its executable does not access hardware. Low-level drive::Session is a protocol primitive and does not supply the complete update procedure. Explicit unavailable-installed and Current-reference paths retain their evidence limitations; see the protocol guide.

Before execution, the host must capture a backup, obtain the required consent, check tray conditions, and ensure both transports address the same physical drive exclusively. Interrupted or incompatible firmware writes can make a drive unusable. No hardware writes are performed by the examples or test suite.

Handle errors

Import mediatek_optical::CodedError for stable machine-readable identifiers:

use mediatek_optical::CodedError;
use mediatek_optical::drive::Error;

let error = Error::<()>::Short { expected: 36, actual: 8 };
assert_eq!(error.code(), "mediatek.drive.short");

Use codes for translation or routing, match typed variants for parameters, and preserve nested causes in diagnostics. English Display wording is not a parsing contract. Handle unknown future codes and non-exhaustive enums.

Develop and test

cargo fmt --all --check
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo test --locked --all-targets --all-features
cargo test --locked --doc --all-features
python3 .github/scripts/check-features.py test
python3 .github/scripts/check-features.py doc

The Python checks require Python 3.11+. CI exercises every distinct feature configuration, Rust 1.75 library builds, bare-metal no_std, doctests and packaged sources before publication. README Rust examples are compiled by doctests with their required features enabled.

Firmware corpus tests require external, hash-pinned files; skipped or unavailable inputs are not counted as passes. See tests/OEM_FACTS.md, the protocol guide, and release audit for reproduction and evidence limits. Simulated transports and offline firmware analysis do not certify physical programming or power-loss recovery.

License

MIT. See LICENSE-MIT.

About

Vendor SCSI command catalogue for MediaTek MT1959/MT1939 optical (BD/DVD) drives

Topics

Resources

Code of conduct

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages