waverave_hackrf/error.rs
1use std::ops::Range;
2
3use crate::HackRf;
4
5/// An error from operating the HackRF.
6///
7/// Some errors are recoverable:
8///
9/// - `Io` & `Transfer` may just be a failed packet operation on the USB cable,
10/// and can potentially be recovered from without giving up on the HackRF.
11/// - `AddressRange`, `ValueRange`, `TuningRange`, and `InvalidParameter` all
12/// mean the arguments to a function were out of range, and may even provide a
13/// hint of how to fix them.
14/// - `ReturnData` means the HackRF replied to a USB transaction with something
15/// unintelligible. If this is for a bulk transfer during Sweep mode, it
16/// *might* be possible to recover by stopping and re-entering sweep mode, but
17/// most of the time this means something is seriously wrong and
18/// nonrecoverable.
19/// - `ApiVersion` indicates the firmware on the HackRF is too old to support
20/// this function. Bail out, and advise the user to update their HackRF's
21/// firmware.
22#[derive(Debug, thiserror::Error)]
23#[non_exhaustive]
24pub enum Error {
25 /// Underlying OS I/O error.
26 #[error("I/O error")]
27 Io(#[from] std::io::Error),
28
29 /// Transfer error from `nusb`.
30 #[error("USB transfer error")]
31 Transfer(#[from] nusb::transfer::TransferError),
32
33 /// The provided address (usually for register I/O) is out of range.
34 #[error("Address (0x{addr:x}) out of range (0x{}..0x{})", .range.start, .range.end)]
35 #[allow(missing_docs)]
36 AddressRange { range: Range<u32>, addr: u32 },
37
38 /// The provided argument value is out of range.
39 #[error("Value (0x{val:x}) out of range (0x{}..0x{})", .range.start, .range.end)]
40 #[allow(missing_docs)]
41 ValueRange { range: Range<u32>, val: u32 },
42
43 /// The provided tuning frequency is out of range.
44 #[error("Tuning Value ({val:x} Hz) out of range ({}..{} Hz)", .range.start, .range.end)]
45 #[allow(missing_docs)]
46 TuningRange { range: Range<u64>, val: u64 },
47
48 /// Some argument to a function is invalid in a way not easily expressed as
49 /// a range.
50 #[error("Invalid Parameter: {0}")]
51 InvalidParameter(&'static str),
52
53 /// The API version of the opened HackRF is too old for this function.
54 #[error(
55 "Requires API >= 0x{:x}, but device has API 0x{:x}. Consider updating the firmware",
56 needed,
57 actual
58 )]
59 #[allow(missing_docs)]
60 ApiVersion { needed: u16, actual: u16 },
61
62 /// Returned data from a HackRF didn't make any sense.
63 #[error("Invalid return data")]
64 ReturnData,
65}
66
67/// An error from trying to change HackRF states and failing.
68///
69/// Always contains the HackRF instance, but in an unknown state. To try and
70/// return to a known state, try calling [`HackRf::turn_off`].
71pub struct StateChangeError {
72 /// The error that occurred while trying to change state.
73 pub err: Error,
74 /// The HackRF instance.
75 pub rf: HackRf,
76}
77
78impl core::error::Error for StateChangeError {
79 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
80 Some(&self.err)
81 }
82}
83
84impl core::fmt::Display for StateChangeError {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 f.write_str("Failed to change state")
87 }
88}
89
90impl core::fmt::Debug for StateChangeError {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 f.debug_struct("StateChangeError")
93 .field("err", &self.err)
94 .finish_non_exhaustive()
95 }
96}