From 71e9ff9441e0a7d8ac74aaa44e485bf0be06ac4a Mon Sep 17 00:00:00 2001 From: Ral Date: Tue, 6 Jun 2023 05:21:29 +0200 Subject: [PATCH] Add checksum check --- src/bin/edidread.rs | 10 +++++----- src/bin/edidwrite.rs | 14 +++++++------- src/checksum.rs | 15 +++++++++++++++ src/i2c.rs | 12 ++++++------ src/{misc.rs => io.rs} | 27 ++++++++++++++++++++++----- src/lib.rs | 3 ++- src/std.rs | 6 +++--- 7 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 src/checksum.rs rename src/{misc.rs => io.rs} (56%) diff --git a/src/bin/edidread.rs b/src/bin/edidread.rs index 13ad739..60c716f 100644 --- a/src/bin/edidread.rs +++ b/src/bin/edidread.rs @@ -1,8 +1,8 @@ use clap::Parser; -use rwedid::args::*; -use rwedid::i2c::*; -use rwedid::misc::*; -use rwedid::std::*; +use rwedid::args::Args; +use rwedid::i2c::read_from_bus; +use rwedid::io::block_by_block_read; +use rwedid::std::write_to_stdout; fn main() -> Result<(), std::io::Error> { // Parse command line arguments @@ -14,5 +14,5 @@ fn main() -> Result<(), std::io::Error> { })?; // Write binary blob to stdout - write_to_std(&bytes) + write_to_stdout(&bytes) } diff --git a/src/bin/edidwrite.rs b/src/bin/edidwrite.rs index 0777320..7a0ef9a 100644 --- a/src/bin/edidwrite.rs +++ b/src/bin/edidwrite.rs @@ -1,16 +1,16 @@ use clap::Parser; -use rwedid::args::*; -use rwedid::i2c::*; -use rwedid::misc::*; -use rwedid::std::*; +use rwedid::args::Args; +use rwedid::i2c::write_to_bus; +use rwedid::io::block_by_block_read; +use rwedid::std::read_from_stdin; fn main() -> Result<(), std::io::Error> { // Parse command line arguments let args = Args::parse(); - // Read binary from stdin - let data = block_by_block_read(args.blocks, |_, l| read_from_std(l))?; + // Read binary blob from stdin + let data = block_by_block_read(args.blocks, |_, l| read_from_stdin(l))?; // Write the data to the chip - write_to_bus(&args.device, args.address, data.as_slice()) + write_to_bus(&args.device, args.address, 0x00, data.as_slice()) } diff --git a/src/checksum.rs b/src/checksum.rs new file mode 100644 index 0000000..a82d63f --- /dev/null +++ b/src/checksum.rs @@ -0,0 +1,15 @@ +// Compute and check the checksum over the bytes of a block. +pub fn checksum(bytes: &[u8]) -> u8 { + bytes.iter().fold(0u32, |x, y| x + (*y as u32)) as u8 +} + +// Validate the checksum +pub fn valid_checksum(bytes: &[u8]) -> bool { + checksum(bytes) == 0x00 +} + +// Print the checksum to stdout +pub fn print_checksum(bytes: &[u8]) { + let cs = checksum(bytes); + eprintln!(" Checksum is: {cs}"); +} diff --git a/src/i2c.rs b/src/i2c.rs index ba87bc5..840ee2c 100644 --- a/src/i2c.rs +++ b/src/i2c.rs @@ -1,6 +1,5 @@ -use i2cdev::core::*; +use i2cdev::core::{I2CMessage, I2CTransfer}; use i2cdev::linux::{LinuxI2CDevice, LinuxI2CMessage}; - use std::thread; use std::time::Duration; @@ -29,19 +28,20 @@ pub fn read_from_bus( pub fn write_to_bus( i2c_device: &str, slave_address: u16, + memory_address: u8, data: &[u8], ) -> Result<(), std::io::Error> { let mut dev = LinuxI2CDevice::new(i2c_device, slave_address)?; // Write 8 bytes at a time - for (i, chunk) in data.chunks_exact(8).into_iter().enumerate() { + for (i, chunk) in data.chunks_exact(8).enumerate() { // Memory address - let memory_address: u8 = (i as u8) * 8; + let address = memory_address + (i as u8) * 8; let mut msgs = [ // Address to write to - LinuxI2CMessage::write(&[memory_address]), + LinuxI2CMessage::write(&[address]), // Write data to chip - LinuxI2CMessage::write(&chunk), + LinuxI2CMessage::write(chunk), ]; dev.transfer(&mut msgs)?; diff --git a/src/misc.rs b/src/io.rs similarity index 56% rename from src/misc.rs rename to src/io.rs index 7876574..a4eddd6 100644 --- a/src/misc.rs +++ b/src/io.rs @@ -1,4 +1,6 @@ -// Size of EDID binary block +use crate::checksum::print_checksum; + +/// Size of an EDID block in bytes. pub const BLOCK_SIZE: usize = 128; pub fn block_by_block_read( @@ -10,22 +12,37 @@ pub fn block_by_block_read( None => { // Read first block (128 bytes) let data_base = read(0x00, BLOCK_SIZE)?; + print_checksum(data_base.as_slice()); + // Try to read remaining bytes let data_extensions = match data_base.len() { - // Proper 128 byte block + // Proper first block (128 bytes) BLOCK_SIZE => { // Number of extension blocks that should follow let num_extensions: usize = data_base[BLOCK_SIZE - 2].into(); // Read remaining blocks - read(BLOCK_SIZE as u8, num_extensions * BLOCK_SIZE)? + match num_extensions { + 0 => vec![], + _ => read(BLOCK_SIZE as u8, num_extensions * BLOCK_SIZE)?, + } } - // Something else, obviously broken + // Something else, probably broken _ => vec![], }; + data_extensions.chunks_exact(BLOCK_SIZE).for_each(print_checksum); + // Return complete byte stream Ok([data_base, data_extensions].concat()) } + // Explicitly read as many blocks as specified by user - Some(blocks) => read(0x00, blocks * BLOCK_SIZE), + Some(blocks) => { + // Read blocks + let data = read(0x00, blocks * BLOCK_SIZE)?; + data.chunks_exact(BLOCK_SIZE).for_each(print_checksum); + + // Return complete byte stream + Ok(data) + } } } diff --git a/src/lib.rs b/src/lib.rs index 918188e..13d5fdf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ pub mod args; +pub mod checksum; pub mod i2c; -pub mod misc; +pub mod io; pub mod std; diff --git a/src/std.rs b/src/std.rs index 7b8e8bd..273020b 100644 --- a/src/std.rs +++ b/src/std.rs @@ -1,6 +1,6 @@ use std::io::{self, Read, Write}; -pub fn read_from_std(data_length: usize) -> Result, std::io::Error> { +pub fn read_from_stdin(data_length: usize) -> Result, std::io::Error> { // Buffer to read into let mut data = vec![0; data_length]; // Read from stdin @@ -8,8 +8,8 @@ pub fn read_from_std(data_length: usize) -> Result, std::io::Error> { Ok(data) } -pub fn write_to_std(data: &[u8]) -> Result<(), std::io::Error> { +pub fn write_to_stdout(data: &[u8]) -> Result<(), std::io::Error> { // Write data to stdout let mut stdout = io::stdout().lock(); - stdout.write_all(&data) + stdout.write_all(data) }