capsules_core/test/
virtual_rng.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Test virtual rng for a single device
6//! Gets a specified number of random numbers by making sequential calls to get()
7//! Full test harness for this can be found in nano33ble/test/virtual_rng_test
8
9use crate::virtualizers::virtual_rng::VirtualRngMasterDevice;
10
11use core::cell::Cell;
12
13use kernel::debug;
14use kernel::hil::rng::{Client, Continue, Rng};
15use kernel::ErrorCode;
16
17const NUM_REQUESTS: usize = 2;
18
19// Use this test to test an Rng
20pub struct TestRng<'a> {
21    device_id: usize,
22    device: &'a VirtualRngMasterDevice<'a>,
23    num_requests: Cell<usize>,
24}
25
26impl<'a> TestRng<'a> {
27    pub fn new(device_id: usize, device: &'a VirtualRngMasterDevice<'a>) -> TestRng<'a> {
28        TestRng {
29            device_id,
30            device,
31            num_requests: Cell::new(NUM_REQUESTS),
32        }
33    }
34
35    pub fn get_random_nums(&self) {
36        match self.device.get() {
37            Ok(()) => debug!("Virtual RNG device {}: get Ok(())", self.device_id),
38            _ => panic!("Virtual RNG test: unable to get random numbers"),
39        }
40    }
41}
42
43impl Client for TestRng<'_> {
44    fn randomness_available(
45        &self,
46        randomness: &mut dyn Iterator<Item = u32>,
47        error: Result<(), ErrorCode>,
48    ) -> Continue {
49        let val = randomness.next();
50        if error != Ok(()) {
51            panic!(
52                "Virtual RNG device {}: randomness_available called with error {:?}",
53                self.device_id, error
54            );
55        }
56
57        let num_requests_remaining = self.num_requests.get();
58        let data = val.unwrap();
59        debug!("Random Number from device {}: {:08x}", self.device_id, data);
60        self.num_requests.set(num_requests_remaining - 1);
61        if num_requests_remaining == 1 {
62            Continue::Done
63        } else {
64            let _ = self.device.get();
65            Continue::More
66        }
67    }
68}