1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use core::{iter::Cycle, str::Lines};

use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex};
use embassy_time::{Duration, Timer};

use embedded_hal::prelude::_embedded_hal_blocking_rng_Read;

use hal::Rng;

pub static MOCK_SENTENCES: &'static str = include_str!("../../tests/nmea.log");

pub struct NmeaReceiver {
    mock_sentences: Mutex<CriticalSectionRawMutex, Cycle<Lines<'static>>>,
    rng: Mutex<CriticalSectionRawMutex, Rng<'static>>,
}

impl NmeaReceiver {
    pub fn new(rng: Mutex<CriticalSectionRawMutex, Rng<'static>>) -> Self {
        let sentences_iterator = MOCK_SENTENCES.lines().cycle();

        Self {
            mock_sentences: Mutex::new(sentences_iterator),
            rng,
        }
    }

    /// We can parse the `&str` and look for the following sentences which have
    /// longitude and latitude information:
    /// - GGA
    /// - RMC
    pub async fn receive(&self) -> &str {
        let milliseconds = {
            let mut rng = self.rng.lock().await;
            let mut random_bytes = [0_u8];
            rng.read(&mut random_bytes).expect("Should get random byte");

            255 - random_bytes[0]
        };
        
        Timer::after(Duration::from_millis(milliseconds.into())).await;
        let mut sentence_guard = self.mock_sentences.lock().await;


        sentence_guard.next().expect("Should always have a next sentence since we have a Cycle iterator")
    }
}