1
0
Fork 0
mirror of https://codeberg.org/ral/rwedid.git synced 2024-08-16 09:59:49 +02:00

Add checksum check

This commit is contained in:
Ral 2023-06-06 05:21:29 +02:00
parent a1d0e66ec5
commit 71e9ff9441
7 changed files with 60 additions and 27 deletions

View file

@ -1,8 +1,8 @@
use clap::Parser; use clap::Parser;
use rwedid::args::*; use rwedid::args::Args;
use rwedid::i2c::*; use rwedid::i2c::read_from_bus;
use rwedid::misc::*; use rwedid::io::block_by_block_read;
use rwedid::std::*; use rwedid::std::write_to_stdout;
fn main() -> Result<(), std::io::Error> { fn main() -> Result<(), std::io::Error> {
// Parse command line arguments // Parse command line arguments
@ -14,5 +14,5 @@ fn main() -> Result<(), std::io::Error> {
})?; })?;
// Write binary blob to stdout // Write binary blob to stdout
write_to_std(&bytes) write_to_stdout(&bytes)
} }

View file

@ -1,16 +1,16 @@
use clap::Parser; use clap::Parser;
use rwedid::args::*; use rwedid::args::Args;
use rwedid::i2c::*; use rwedid::i2c::write_to_bus;
use rwedid::misc::*; use rwedid::io::block_by_block_read;
use rwedid::std::*; use rwedid::std::read_from_stdin;
fn main() -> Result<(), std::io::Error> { fn main() -> Result<(), std::io::Error> {
// Parse command line arguments // Parse command line arguments
let args = Args::parse(); let args = Args::parse();
// Read binary from stdin // Read binary blob from stdin
let data = block_by_block_read(args.blocks, |_, l| read_from_std(l))?; let data = block_by_block_read(args.blocks, |_, l| read_from_stdin(l))?;
// Write the data to the chip // 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())
} }

15
src/checksum.rs Normal file
View file

@ -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}");
}

View file

@ -1,6 +1,5 @@
use i2cdev::core::*; use i2cdev::core::{I2CMessage, I2CTransfer};
use i2cdev::linux::{LinuxI2CDevice, LinuxI2CMessage}; use i2cdev::linux::{LinuxI2CDevice, LinuxI2CMessage};
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
@ -29,19 +28,20 @@ pub fn read_from_bus(
pub fn write_to_bus( pub fn write_to_bus(
i2c_device: &str, i2c_device: &str,
slave_address: u16, slave_address: u16,
memory_address: u8,
data: &[u8], data: &[u8],
) -> Result<(), std::io::Error> { ) -> Result<(), std::io::Error> {
let mut dev = LinuxI2CDevice::new(i2c_device, slave_address)?; let mut dev = LinuxI2CDevice::new(i2c_device, slave_address)?;
// Write 8 bytes at a time // 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 // Memory address
let memory_address: u8 = (i as u8) * 8; let address = memory_address + (i as u8) * 8;
let mut msgs = [ let mut msgs = [
// Address to write to // Address to write to
LinuxI2CMessage::write(&[memory_address]), LinuxI2CMessage::write(&[address]),
// Write data to chip // Write data to chip
LinuxI2CMessage::write(&chunk), LinuxI2CMessage::write(chunk),
]; ];
dev.transfer(&mut msgs)?; dev.transfer(&mut msgs)?;

View file

@ -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 const BLOCK_SIZE: usize = 128;
pub fn block_by_block_read( pub fn block_by_block_read(
@ -10,22 +12,37 @@ pub fn block_by_block_read(
None => { None => {
// Read first block (128 bytes) // Read first block (128 bytes)
let data_base = read(0x00, BLOCK_SIZE)?; let data_base = read(0x00, BLOCK_SIZE)?;
print_checksum(data_base.as_slice());
// Try to read remaining bytes // Try to read remaining bytes
let data_extensions = match data_base.len() { let data_extensions = match data_base.len() {
// Proper 128 byte block // Proper first block (128 bytes)
BLOCK_SIZE => { BLOCK_SIZE => {
// Number of extension blocks that should follow // Number of extension blocks that should follow
let num_extensions: usize = data_base[BLOCK_SIZE - 2].into(); let num_extensions: usize = data_base[BLOCK_SIZE - 2].into();
// Read remaining blocks // 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![], _ => vec![],
}; };
data_extensions.chunks_exact(BLOCK_SIZE).for_each(print_checksum);
// Return complete byte stream // Return complete byte stream
Ok([data_base, data_extensions].concat()) Ok([data_base, data_extensions].concat())
} }
// Explicitly read as many blocks as specified by user // 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)
}
} }
} }

View file

@ -1,4 +1,5 @@
pub mod args; pub mod args;
pub mod checksum;
pub mod i2c; pub mod i2c;
pub mod misc; pub mod io;
pub mod std; pub mod std;

View file

@ -1,6 +1,6 @@
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
pub fn read_from_std(data_length: usize) -> Result<Vec<u8>, std::io::Error> { pub fn read_from_stdin(data_length: usize) -> Result<Vec<u8>, std::io::Error> {
// Buffer to read into // Buffer to read into
let mut data = vec![0; data_length]; let mut data = vec![0; data_length];
// Read from stdin // Read from stdin
@ -8,8 +8,8 @@ pub fn read_from_std(data_length: usize) -> Result<Vec<u8>, std::io::Error> {
Ok(data) 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 // Write data to stdout
let mut stdout = io::stdout().lock(); let mut stdout = io::stdout().lock();
stdout.write_all(&data) stdout.write_all(data)
} }