@@ -4,18 +4,24 @@ use std::str::FromStr;
44
55use rs1090:: prelude:: * ;
66
7- #[ cfg( feature = "rtlsdr" ) ]
8- use rs1090:: source:: rtlsdr;
7+ use rs1090:: source:: iqread;
98#[ cfg( feature = "sero" ) ]
109use rs1090:: source:: sero;
1110#[ cfg( feature = "ssh" ) ]
1211use rs1090:: source:: ssh:: { TunnelledTcp , TunnelledWebsocket } ;
1312
13+ use desperado:: IqAsyncSource ;
1414use serde:: { Deserialize , Serialize } ;
1515use tokio:: sync:: mpsc:: Sender ;
1616use tracing:: error;
1717use 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" ) ]
7898pub 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 }
0 commit comments