brlapi 0.4.1

Safe Rust bindings for the BrlAPI library
// SPDX-License-Identifier: LGPL-2.1

//! Raw mode demonstration for BrlAPI
//!
//! **DANGER**: This example demonstrates raw mode operations that can
//! permanently damage braille devices if used incorrectly!
//!
//! This example shows:
//! 1. How to safely check for raw mode support
//! 2. How to enter and exit raw mode properly
//! 3. How to send and receive raw data with timeouts
//! 4. How to handle errors and edge cases
//!
//! **IMPORTANT**: This example uses safe, non-destructive operations only.
//! Real firmware updates or device modifications require device-specific
//! protocols and should only be attempted by experienced developers.
//!
//! Run with: cargo run --example raw_mode_demo

use brlapi::{Connection, Result, raw::RawMode};

fn main() -> Result<()> {
    println!("BrlAPI Raw Mode Demonstration");
    println!("============================");
    println!("WARNING: Raw mode can damage devices if misused!");
    println!("This demo uses safe, non-destructive operations only.\n");

    // Step 1: Connect and get device information
    println!("1. Connecting to BrlAPI and checking device...");
    let connection = match Connection::open() {
        Ok(conn) => {
            println!("   [SUCCESS] Connected to BrlAPI successfully");
            conn
        }
        Err(e) => {
            println!("   [ERROR] Failed to connect: {}", e);
            println!("   Make sure BRLTTY is running with a braille device");
            return Err(e);
        }
    };

    // Get device information
    let driver = connection.display_driver()?;
    let (width, height) = connection.display_size()?;
    println!("   Device: {} driver, {}x{} cells", driver, width, height);

    // Step 2: Check raw mode support
    println!("\n2. Checking raw mode support...");
    if !RawMode::is_driver_supported(&driver) {
        println!("   [ERROR] Driver '{}' does not support raw mode", driver);
        println!("   Raw mode requires hardware drivers like alva, baum, hims, etc.");
        println!("   Dummy/virtual drivers typically don't support raw mode.");
        return Ok(());
    }
    println!("   [SUCCESS] Driver '{}' supports raw mode", driver);

    // Step 3: Demonstrate safe raw mode operations
    println!("\n3. Entering raw mode (this may fail if device doesn't support it)...");
    let raw_mode = match RawMode::enter(&connection, &driver) {
        Ok(raw_mode) => {
            println!("   [SUCCESS] Entered raw mode successfully");
            raw_mode
        }
        Err(e) => {
            println!("   [ERROR] Failed to enter raw mode: {}", e);
            println!("   This is normal for virtual/testing devices");
            println!("   Real hardware may support raw mode");
            return Ok(());
        }
    };

    // Step 4: Demonstrate safe data operations
    println!("\n4. Demonstrating safe raw mode operations...");

    // Send a safe "ping" command (most devices ignore unknown commands safely)
    println!("   Sending safe test data...");
    let test_data = b"\x00\x01\x02"; // Generic test pattern
    match raw_mode.send_data(test_data) {
        Ok(bytes_sent) => {
            println!("   [SUCCESS] Sent {} bytes: {:?}", bytes_sent, test_data);
        }
        Err(e) => {
            println!("   WARNING: Send failed (this is normal): {}", e);
        }
    }

    // Try to receive response (this will block indefinitely if no data)
    println!("   Note: receive_data() blocks indefinitely - skipping for safety");
    println!("   In real applications, implement external timeout handling as needed");

    // Step 5: Demonstrate information queries
    println!("\n5. Raw mode session information...");
    println!("   Driver: {}", raw_mode.driver_name());
    println!("   Connection: active");

    // Step 6: Automatic cleanup demonstration
    println!("\n6. Exiting raw mode...");
    drop(raw_mode); // Explicitly drop to show cleanup
    println!("   [SUCCESS] Raw mode exited automatically (RAII cleanup)");

    // Step 7: Safety reminders
    println!("\n7. Safety Summary");
    println!("   ================");
    println!("   [SUCCESS] Always check driver support before entering raw mode");
    println!("   [SUCCESS] Use timeouts for receive operations");
    println!("   [SUCCESS] Let RAII handle cleanup automatically");
    println!("   [SUCCESS] Test with safe, non-destructive commands first");
    println!("   WARNING: Real firmware updates require device-specific protocols");
    println!("   WARNING: Always have recovery procedures ready");
    println!("   WARNING: Consider using development/backup devices for testing");

    println!("\n[SUCCESS] Raw mode demonstration completed safely!");

    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_raw_mode_demo_structure() {
        // Verify the example is well-structured
        // We can't run the actual demo in tests without hardware
        assert!(true);
        println!("[SUCCESS] Raw mode demo structure test passed");
    }
}