|
| 1 | +//! Fuzzing utilities. |
| 2 | +
|
| 3 | +use core::convert::Infallible; |
| 4 | + |
| 5 | +use crate::device::{id::Id, register::Register}; |
| 6 | + |
| 7 | +/// Fuzzing delay. |
| 8 | +/// |
| 9 | +/// Does nothing. |
| 10 | +pub struct FuzzDelay; |
| 11 | + |
| 12 | +impl embedded_hal::delay::DelayNs for FuzzDelay { |
| 13 | + fn delay_ns(&mut self, _: u32) {} |
| 14 | +} |
| 15 | + |
| 16 | +/// Fuzzing I2C. |
| 17 | +/// |
| 18 | +/// Responds with the correct id. Erverything else is random. |
| 19 | +pub struct FuzzI2C<'data> { |
| 20 | + /// Data to respond with. |
| 21 | + data: &'data [u8], |
| 22 | + |
| 23 | + /// Check if the current write is to the id register. |
| 24 | + is_id_write: bool, |
| 25 | +} |
| 26 | + |
| 27 | +impl<'data> FuzzI2C<'data> { |
| 28 | + /// Create a new `FuzzI2C`. |
| 29 | + pub fn new(data: &'data [u8]) -> Self { |
| 30 | + Self { |
| 31 | + data, |
| 32 | + is_id_write: false, |
| 33 | + } |
| 34 | + } |
| 35 | +} |
| 36 | + |
| 37 | +impl embedded_hal::i2c::ErrorType for FuzzI2C<'_> { |
| 38 | + type Error = Infallible; |
| 39 | +} |
| 40 | + |
| 41 | +impl embedded_hal::i2c::I2c for FuzzI2C<'_> { |
| 42 | + fn transaction( |
| 43 | + &mut self, |
| 44 | + _address: u8, |
| 45 | + operations: &mut [embedded_hal::i2c::Operation<'_>], |
| 46 | + ) -> Result<(), Self::Error> { |
| 47 | + for operation in operations { |
| 48 | + match operation { |
| 49 | + embedded_hal::i2c::Operation::Write(write) => { |
| 50 | + if write[0] == Register::ChipId as u8 { |
| 51 | + self.is_id_write = true; |
| 52 | + } else { |
| 53 | + self.is_id_write = false; |
| 54 | + } |
| 55 | + } |
| 56 | + embedded_hal::i2c::Operation::Read(read) => { |
| 57 | + if self.is_id_write { |
| 58 | + read[0] = Id::Valid as u8; |
| 59 | + } else { |
| 60 | + if self.data.len() == read.len() { |
| 61 | + read.copy_from_slice(self.data); |
| 62 | + } else if self.data.len() < read.len() { |
| 63 | + read[..self.data.len()].copy_from_slice(self.data); |
| 64 | + } else { |
| 65 | + read.copy_from_slice(&self.data[..read.len()]); |
| 66 | + } |
| 67 | + } |
| 68 | + } |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + Ok(()) |
| 73 | + } |
| 74 | +} |
0 commit comments