1use crate::{Error, HackRf, HackRfType, consts::ControlRequest};
2
3#[repr(C)]
7#[derive(Clone, Copy, Debug, bytemuck::Zeroable, bytemuck::Pod)]
8pub struct SerialNumber {
9 pub part_id: [u32; 2],
10 pub serial_no: [u32; 4],
11}
12
13impl SerialNumber {
14 fn le_convert(&mut self) {
15 for x in self.part_id.iter_mut() {
16 *x = x.to_le();
17 }
18 for x in self.serial_no.iter_mut() {
19 *x = x.to_le();
20 }
21 }
22}
23
24#[derive(Clone, Copy, Debug)]
26pub enum BoardRev {
27 Old,
28 R6,
29 R7,
30 R8,
31 R9,
32 R10,
33 GsgR6,
34 GsgR7,
35 GsgR8,
36 GsgR9,
37 GsgR10,
38 Unknown(u8),
39}
40
41impl std::fmt::Display for BoardRev {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 match self {
44 Self::Old => f.write_str("Older than r6"),
45 Self::R6 => f.write_str("r6"),
46 Self::R7 => f.write_str("r7"),
47 Self::R8 => f.write_str("r8"),
48 Self::R9 => f.write_str("r9"),
49 Self::R10 => f.write_str("r10"),
50 Self::GsgR6 => f.write_str("Great Scott Gadgets r6"),
51 Self::GsgR7 => f.write_str("Great Scott Gadgets r7"),
52 Self::GsgR8 => f.write_str("Great Scott Gadgets r8"),
53 Self::GsgR9 => f.write_str("Great Scott Gadgets r9"),
54 Self::GsgR10 => f.write_str("Great Scott Gadgets r10"),
55 Self::Unknown(v) => write!(f, "unknown (0x{:x})", v),
56 }
57 }
58}
59
60impl BoardRev {
61 fn from_u8(v: u8) -> Self {
62 use BoardRev::*;
63 match v {
64 0 => Old,
65 1 => R6,
66 2 => R7,
67 3 => R8,
68 4 => R9,
69 5 => R10,
70 0x81 => GsgR6,
71 0x82 => GsgR7,
72 0x83 => GsgR8,
73 0x84 => GsgR9,
74 0x85 => GsgR10,
75 v => Unknown(v),
76 }
77 }
78}
79
80#[derive(Clone, Copy, Debug)]
82pub enum BoardId {
83 Jellybean,
84 Jawbreaker,
85 HackRf1Og,
86 Rad1o,
87 HackRf1R9,
88 Unknown(u8),
89}
90
91impl std::fmt::Display for BoardId {
92 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93 match self {
94 Self::Jellybean => f.write_str("Jellybean"),
95 Self::Jawbreaker => f.write_str("Jawbreaker"),
96 Self::HackRf1Og => f.write_str("HackRF One"),
97 Self::Rad1o => f.write_str("rad1o"),
98 Self::HackRf1R9 => f.write_str("HackRF One Rev9"),
99 Self::Unknown(v) => write!(f, "Unknown (0x{:x})", v),
100 }
101 }
102}
103
104impl BoardId {
105 fn from_u8(v: u8) -> Self {
106 use BoardId::*;
107 match v {
108 0 => Jellybean,
109 1 => Jawbreaker,
110 2 => HackRf1Og,
111 3 => Rad1o,
112 4 => HackRf1R9,
113 v => Unknown(v),
114 }
115 }
116}
117
118#[derive(Clone, Copy, Debug)]
120pub struct SupportedPlatform {
121 pub jawbreaker: bool,
122 pub hackrf1_og: bool,
123 pub rad1o: bool,
124 pub hackrf1_r9: bool,
125}
126
127impl SupportedPlatform {
128 fn from_u32(v: u32) -> Self {
129 Self {
130 jawbreaker: v & 1 != 0,
131 hackrf1_og: v & 2 != 0,
132 rad1o: v & 4 != 0,
133 hackrf1_r9: v & 8 != 0,
134 }
135 }
136}
137
138pub struct Info<'a> {
142 inner: &'a HackRf,
143}
144
145impl<'a> Info<'a> {
146 pub(crate) fn new(inner: &'a HackRf) -> Info<'a> {
147 Self { inner }
148 }
149
150 pub fn api_version(&self) -> u16 {
153 self.inner.version
154 }
155
156 pub fn radio_type(&self) -> HackRfType {
158 self.inner.ty
159 }
160
161 pub async fn board_id_read(&self) -> Result<BoardId, Error> {
162 let ret = self.inner.read_u8(ControlRequest::BoardIdRead, 0).await?;
163 Ok(BoardId::from_u8(ret))
164 }
165
166 pub async fn version_string_read(&self) -> Result<String, Error> {
167 let resp = self
168 .inner
169 .read_bytes(ControlRequest::VersionStringRead, 255)
170 .await?;
171 String::from_utf8(resp).map_err(|_| Error::ReturnData)
172 }
173
174 pub async fn read_serial(&self) -> Result<SerialNumber, Error> {
175 let mut v: SerialNumber = self
176 .inner
177 .read_struct(ControlRequest::BoardPartidSerialnoRead)
178 .await?;
179 v.le_convert();
180 Ok(v)
181 }
182
183 pub async fn rev_read(&self) -> Result<BoardRev, Error> {
186 self.inner.api_check(0x0106)?;
187 let rev = self.inner.read_u8(ControlRequest::BoardRevRead, 0).await?;
188 Ok(BoardRev::from_u8(rev))
189 }
190
191 pub async fn supported_platform_read(&self) -> Result<SupportedPlatform, Error> {
194 self.inner.api_check(0x0106)?;
195 let ret = self
196 .inner
197 .read_bytes(ControlRequest::SupportedPlatformRead, 4)
198 .await?;
199 let ret: [u8; 4] = ret.as_slice().try_into().map_err(|_| Error::ReturnData)?;
200 let val = u32::from_be_bytes(ret);
201 Ok(SupportedPlatform::from_u32(val))
202 }
203}