rx/
rx.rs

1use hackrfone::{
2    HackRfOne,
3    RxMode,
4    UnknownMode,
5    iq_to_cplx_f32,         // build this example with "--features num-complex"
6    num_complex::Complex32, // build this example with "--features num-complex"
7};
8use std::{
9    sync::mpsc::{self, TryRecvError},
10    thread,
11};
12
13fn main() {
14    let mut radio: HackRfOne<UnknownMode> = HackRfOne::new().expect("Failed to open HackRF One");
15
16    const FC: u64 = 915_000_000;
17    const FS: u32 = 10_000_000;
18    const DIV: u32 = 2;
19    radio
20        .set_sample_rate(FS * DIV, DIV)
21        .expect("Failed to set sample rate");
22    radio.set_freq(FC).expect("Failed to set frequency");
23    radio
24        .set_amp_enable(false)
25        .expect("Failed to disable amplifier");
26    radio
27        .set_antenna_enable(0)
28        .expect("Failed to disable antenna");
29    radio.set_lna_gain(20).expect("Failed to set LNA gain");
30    radio.set_vga_gain(32).expect("Failed to set VGA gain");
31    let mut radio: HackRfOne<RxMode> = radio.into_rx_mode().expect("Failed to enter RX mode");
32
33    let (data_tx, data_rx) = mpsc::channel();
34    let (exit_tx, exit_rx) = mpsc::channel();
35
36    let sample_thread = thread::Builder::new()
37        .name("sample".to_string())
38        .spawn(move || -> Result<(), hackrfone::Error> {
39            println!("Spawned sample thread");
40
41            loop {
42                let samples: Vec<u8> = radio.rx()?;
43                data_tx
44                    .send(samples)
45                    .expect("Failed to send buffer from sample thread");
46
47                match exit_rx.try_recv() {
48                    Ok(_) => {
49                        radio.stop_rx()?;
50                        return Ok(());
51                    }
52                    Err(TryRecvError::Disconnected) => {
53                        println!("Main thread disconnected");
54                        return Ok(());
55                    }
56                    Err(TryRecvError::Empty) => {}
57                }
58            }
59        })
60        .expect("Failed to spawn sample thread");
61
62    const NUM_SAMPLES: usize = 1024 * 1024;
63    let mut capture_buf: Vec<Complex32> = Vec::with_capacity(NUM_SAMPLES);
64
65    loop {
66        match data_rx.try_recv() {
67            Ok(buf) => buf.chunks_exact(2).for_each(|iq| {
68                capture_buf.push(iq_to_cplx_f32(iq[0], iq[1]));
69            }),
70            Err(TryRecvError::Disconnected) => {
71                println!("Sample thread disconnected");
72                break;
73            }
74            Err(TryRecvError::Empty) => {}
75        }
76
77        // ... do signal processing with capture buf in the loop
78
79        // ... or wait for the buffer to fill and do processing outside
80        if capture_buf.len() >= NUM_SAMPLES {
81            break;
82        }
83    }
84
85    println!("Shutting down sample thread");
86
87    if let Err(e) = exit_tx.send(()) {
88        println!("Failed to send exit event (receiver disconnected): {}", e);
89    }
90
91    sample_thread
92        .join()
93        .expect("Failed to join sample thread")
94        .expect("Sample thread returned an error");
95
96    println!("Done");
97}