Skip to content

Commit 869d68b

Browse files
committed
refactoring with desperado
1 parent 8ab811e commit 869d68b

File tree

10 files changed

+439
-218
lines changed

10 files changed

+439
-218
lines changed

Cargo.lock

Lines changed: 268 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/jet1090/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ homepage.workspace = true
1212

1313
[features]
1414
rtlsdr = ['rs1090/rtlsdr']
15+
pluto = ['rs1090/pluto']
16+
soapy = ['rs1090/soapy']
1517
sero = ['rs1090/sero']
1618
ssh = ['rs1090/ssh']
1719

@@ -22,6 +24,7 @@ clap_complete = "4.5.62"
2224
clap_complete_nushell = "4.5.10"
2325
crossterm = { version = "0.29.0", features = ["event-stream"] }
2426
deku = "0.20.2"
27+
desperado = "0.1.2"
2528
dirs = "6.0.0"
2629
dotenv = "0.15.0"
2730
futures = "0.3.31"

crates/jet1090/src/main.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,6 @@ struct Options {
114114
/// More details are available at: <https://mode-s.org/jet1090/sources>
115115
sources: Vec<source::Source>,
116116

117-
#[cfg(feature = "rtlsdr")]
118-
/// List the detected devices, for now, only --discover rtlsdr is fully supported
119-
#[arg(long, value_name = "ARGS")]
120-
discover: Option<String>,
121-
122117
/// logging file, use "-" for stdout (only in non-interactive mode)
123118
#[arg(short, long, value_name = "FILE")]
124119
log_file: Option<String>,
@@ -262,12 +257,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
262257
}
263258
}
264259

265-
#[cfg(feature = "rtlsdr")]
266-
if let Some(args) = cli_options.discover {
267-
rtlsdr::enumerate(&args.to_string());
268-
return Ok(());
269-
}
270-
271260
if options.sources.is_empty() {
272261
eprintln!(
273262
"No source of data specified, use --help for more information"

crates/jet1090/src/sensor.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ pub async fn sensors(value: &Source) -> Vec<Sensor> {
3434
Address::Tcp(_)
3535
| Address::Udp(_)
3636
| Address::Websocket(_)
37-
| Address::Rtlsdr(_) => {
37+
| Address::Rtlsdr(_)
38+
| Address::Pluto(_)
39+
| Address::Soapy(_) => {
3840
vec![Sensor {
3941
serial: value.serial(),
4042
name: value.name.clone(),

crates/jet1090/src/source.rs

Lines changed: 123 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,24 @@ use std::str::FromStr;
44

55
use rs1090::prelude::*;
66

7-
#[cfg(feature = "rtlsdr")]
8-
use rs1090::source::rtlsdr;
7+
use rs1090::source::iqread;
98
#[cfg(feature = "sero")]
109
use rs1090::source::sero;
1110
#[cfg(feature = "ssh")]
1211
use rs1090::source::ssh::{TunnelledTcp, TunnelledWebsocket};
1312

13+
use desperado::IqAsyncSource;
1414
use serde::{Deserialize, Serialize};
1515
use tokio::sync::mpsc::Sender;
1616
use tracing::error;
1717
use url::Url;
1818

19+
const MODES_FREQ: f64 = 1.09e9;
20+
const RATE_2_4M: f64 = 2.4e6;
21+
22+
#[cfg(feature = "rtlsdr")]
23+
const RTLSDR_GAIN: f64 = 49.6;
24+
1925
/**
2026
* A structure to describe the endpoint to access data.
2127
*
@@ -73,6 +79,20 @@ pub enum WebsocketPath {
7379
Long(WebsocketStruct),
7480
}
7581

82+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
83+
pub struct PlutoConfig {
84+
pub uri: String,
85+
pub sample_rate: i64,
86+
pub gain: f64,
87+
}
88+
89+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
90+
pub struct SoapyConfig {
91+
pub args: Option<String>,
92+
pub sample_rate: u32,
93+
pub gain: Option<f64>,
94+
}
95+
7696
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7797
#[serde(rename_all = "lowercase")]
7898
pub enum Address {
@@ -84,6 +104,10 @@ pub enum Address {
84104
Websocket(WebsocketPath),
85105
/// A RTL-SDR dongle (require feature `rtlsdr`): the parameter can be empty, or use other specifiers, e.g. `rtlsdr://serial=00000001`
86106
Rtlsdr(Option<String>),
107+
/// A Pluto-ADAF SDR (require feature `pluto`): the parameter can be empty, or use other specifiers, e.g. `pluto://ip=192.168.2.1`
108+
Pluto(PlutoConfig),
109+
/// A SoapySDR device (require feature `soapy`): the parameter can be empty, or use other specifiers, e.g. `soapy://driver=rtlsdr`
110+
Soapy(SoapyConfig),
87111
/// A token-based access to Sero Systems (require feature `sero`).
88112
Sero(SeroParams),
89113
}
@@ -148,6 +172,16 @@ impl FromStr for Source {
148172
url.port_or_known_default().unwrap()
149173
)),
150174
"rtlsdr" => Address::Rtlsdr(url.host_str().map(|s| s.to_string())),
175+
"pluto" => Address::Pluto(PlutoConfig {
176+
uri: format!("ip:{}", url.host_str().unwrap()),
177+
sample_rate: RATE_2_4M as i64,
178+
gain: 50.,
179+
}),
180+
"soapy" => Address::Soapy(SoapyConfig {
181+
args: url.host_str().map(|s| s.to_string()),
182+
sample_rate: RATE_2_4M as u32,
183+
gain: Some(49.6),
184+
}),
151185
"ws" => Address::Websocket(WebsocketPath::Short(format!(
152186
"ws://{}:{}/{}",
153187
url.host_str().unwrap_or("0.0.0.0"),
@@ -200,6 +234,14 @@ impl Source {
200234
let name = reference.clone().unwrap_or("rtlsdr".to_string());
201235
build_serial(&name)
202236
}
237+
Address::Pluto(config) => {
238+
let name = config.uri.clone();
239+
build_serial(&name)
240+
}
241+
Address::Soapy(config) => {
242+
let name = config.args.clone().unwrap_or("soapy".to_string());
243+
build_serial(&name)
244+
}
203245
Address::Sero(_) => 0,
204246
}
205247
}
@@ -226,14 +268,88 @@ impl Source {
226268
#[cfg(feature = "rtlsdr")]
227269
{
228270
let args = args.clone();
271+
// TODO that's temporary fix for now, discussion in PR
272+
let device_index = if let Some(ref args_str) = args {
273+
// Parse args string for "device_index=xx" or "index=xx"
274+
let mut index = 0;
275+
for part in args_str.split(',') {
276+
let part = part.trim();
277+
if let Some(val) =
278+
part.strip_prefix("device_index=")
279+
{
280+
if let Ok(idx) = val.parse::<usize>() {
281+
index = idx;
282+
break;
283+
}
284+
} else if let Some(val) =
285+
part.strip_prefix("index=")
286+
{
287+
if let Ok(idx) = val.parse::<usize>() {
288+
index = idx;
289+
break;
290+
}
291+
}
292+
}
293+
index
294+
} else {
295+
0
296+
};
297+
tokio::spawn(async move {
298+
let source = IqAsyncSource::from_rtlsdr(
299+
device_index,
300+
MODES_FREQ as u32,
301+
RATE_2_4M as u32,
302+
Some(10 * RTLSDR_GAIN as i32),
303+
)
304+
.await
305+
.expect("Failed to create RTL-SDR source");
306+
iqread::receiver(tx, source, serial, 2.4e6, name).await
307+
});
308+
}
309+
}
310+
Address::Pluto(config) => {
311+
#[cfg(not(feature = "pluto"))]
312+
{
313+
error!("Compile jet1090 with the pluto feature, {:?} argument ignored", uri);
314+
std::process::exit(127);
315+
}
316+
#[cfg(feature = "pluto")]
317+
{
318+
let config = config.clone();
319+
tokio::spawn(async move {
320+
let source = IqAsyncSource::from_pluto(
321+
&config.uri,
322+
MODES_FREQ as i64,
323+
config.sample_rate,
324+
config.gain,
325+
)
326+
.await
327+
.expect("Failed to create PlutoSDR source");
328+
iqread::receiver(tx, source, serial, 2.4e6, name).await
329+
});
330+
}
331+
}
332+
Address::Soapy(config) => {
333+
#[cfg(not(feature = "soapy"))]
334+
{
335+
error!("Compile jet1090 with the soapy feature, {:?} argument ignored", args);
336+
std::process::exit(127);
337+
}
338+
#[cfg(feature = "soapy")]
339+
{
340+
let args = config.clone();
229341
tokio::spawn(async move {
230-
rtlsdr::receiver::<&str>(
231-
tx,
232-
args.as_deref(),
233-
serial,
234-
name,
342+
let source = IqAsyncSource::from_soapy(
343+
&args.args.unwrap_or("".to_string()),
344+
0,
345+
MODES_FREQ as u32,
346+
args.sample_rate,
347+
args.gain,
348+
"TUNER",
235349
)
236350
.await
351+
.expect("Failed to create SoapySDR source");
352+
iqread::receiver(tx, source, serial, 2.4e6, name).await
237353
});
238354
}
239355
}

crates/rs1090/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ edition.workspace = true
1111

1212
[features]
1313
aircraft = ['dirs', 'reqwest', 'rusqlite', 'zip']
14-
rtlsdr = ['soapysdr']
14+
rtlsdr = ['desperado/rtlsdr']
15+
pluto = ['desperado/pluto']
16+
soapy = ['desperado/soapy']
1517
sero = ['prost', 'tonic', 'tonic-prost', 'dirs', 'reqwest']
1618
ssh = ['async-recursion', 'bytes', 'dirs', 'http', 'hyper-util', 'makiko', 'ssh2-config', 'tower']
1719

@@ -20,6 +22,7 @@ ansi_term = "0.12.1"
2022
async-recursion = { version = "1.1.1", optional = true }
2123
async-stream = "0.3.6"
2224
bytes = { version = "1.11.0", optional = true }
25+
desperado = "0.1.2"
2326
deku = { version = "0.20.2", features = ["logging"] }
2427
dirs = { version = "6.0.0", optional = true }
2528
futures = "0.3.31"
@@ -39,7 +42,6 @@ reqwest = { version = "0.12.26", optional = true, default-features = false, feat
3942
rusqlite = { version = "0.37.0", features = ["bundled"], optional = true }
4043
serde = { version = "1.0.228", features = ["derive"] }
4144
serde_json = "1.0.143"
42-
soapysdr = { version = "0.4.4", optional = true }
4345
ssh2-config = { version = "0.6.0", optional = true }
4446
tonic = { version = "0.14.2", features = ["_tls-any"], optional = true }
4547
tonic-prost = { version = "0.14.2", optional = true }

crates/rs1090/examples/rtlsdr.rs

Lines changed: 0 additions & 28 deletions
This file was deleted.

crates/rs1090/src/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ pub mod prelude {
3131
#[cfg(not(target_arch = "wasm32"))]
3232
pub use crate::source::beast;
3333

34-
#[cfg(feature = "rtlsdr")]
35-
pub use crate::source::rtlsdr;
34+
pub use crate::source::iqread;
3635

3736
#[cfg(feature = "sero")]
3837
pub use crate::source::sero;

0 commit comments

Comments
 (0)