Temp got sim to work with tcp device by stripping out a lot of the logic.
This commit is contained in:
@@ -1,22 +1,26 @@
|
||||
mod rusb_rtl;
|
||||
mod tcp_rtl;
|
||||
mod rusb_device;
|
||||
mod tcp_device;
|
||||
|
||||
use crate::rusb_rtl::RusbRtl;
|
||||
use crate::tcp_rtl::TcpRtl;
|
||||
use crate::rusb_device::RusbDevice;
|
||||
use crate::tcp_device::TcpDevice;
|
||||
use adsb_lib::adsb::ADSBFrame;
|
||||
use adsb_lib::{hex_to_bytes, run};
|
||||
use adsb_lib::{hex_to_bytes, device::run};
|
||||
use clap::Parser;
|
||||
use std::io::Result;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
struct ReceiverArgs {
|
||||
#[arg(long)]
|
||||
sim: bool,
|
||||
#[arg(long, default_value = "127.0.0.1:9999", requires = "sim")]
|
||||
addr: String,
|
||||
#[arg(long)]
|
||||
decode: Option<String>,
|
||||
|
||||
#[arg(long)]
|
||||
net: bool,
|
||||
#[arg(long, default_value = "127.0.0.1:9999", requires = "net")]
|
||||
addr: String,
|
||||
|
||||
#[arg(long)]
|
||||
usb: bool,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
@@ -33,13 +37,16 @@ fn main() -> Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if args.sim {
|
||||
println!("Starting in SIMULATION mode, connecting to {}", args.addr);
|
||||
let mut device = TcpRtl::connect(&args.addr)?;
|
||||
if args.net {
|
||||
println!("Connecting to network {}", args.addr);
|
||||
let mut device = TcpDevice::connect(&args.addr)?;
|
||||
device.run()
|
||||
} else if args.usb {
|
||||
println!("Connecting to device");
|
||||
let mut device = RusbDevice::open()?;
|
||||
run(&mut device)
|
||||
} else {
|
||||
println!("Starting in REAL RTL‑SDR mode");
|
||||
let mut device = RusbRtl::open()?;
|
||||
run(&mut device)
|
||||
println!("No connection specified");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use adsb_lib::RtlDevice;
|
||||
use adsb_lib::device::Device;
|
||||
use rusb::{request_type, Context, DeviceHandle, Direction, Recipient, RequestType, UsbContext};
|
||||
use std::io::{Error, ErrorKind, Result};
|
||||
use std::time::Duration;
|
||||
@@ -11,11 +11,11 @@ const DATA_ENDPOINT_ADDRESS: u8 = 0x81;
|
||||
const USB_TRANSFER_TIMEOUT: Duration = Duration::from_secs(1);
|
||||
|
||||
/// rusb/libusb implementation of `RtlDevice`
|
||||
pub struct RusbRtl {
|
||||
pub struct RusbDevice {
|
||||
handle: DeviceHandle<Context>,
|
||||
}
|
||||
|
||||
impl RusbRtl {
|
||||
impl RusbDevice {
|
||||
/// Open the USB device, claim interface 0, and return a wrapper
|
||||
pub fn open() -> Result<Self> {
|
||||
// Create a new libusb context
|
||||
@@ -85,7 +85,7 @@ impl RusbRtl {
|
||||
}
|
||||
}
|
||||
|
||||
impl RtlDevice for RusbRtl {
|
||||
impl Device for RusbDevice {
|
||||
fn control_send(&mut self, b_request: u8, data: &[u8]) -> Result<()> {
|
||||
self
|
||||
.control_out(b_request, data)
|
||||
@@ -1,6 +1,7 @@
|
||||
use adsb_lib::RtlDevice;
|
||||
use adsb_lib::device::Device;
|
||||
use std::io::{Error, ErrorKind, Read, Result, Write};
|
||||
use std::net::TcpStream;
|
||||
use adsb_lib::adsb::ADSBFrame;
|
||||
|
||||
// Tags for framing requests/responses over the TCP socket
|
||||
const TAG_CTRL_OUT: u8 = 0x10;
|
||||
@@ -8,15 +9,55 @@ const TAG_CTRL_IN: u8 = 0x11;
|
||||
const TAG_BULK: u8 = 0x20;
|
||||
|
||||
/// A TCP-based implementation of `RtlDevice`
|
||||
pub struct TcpRtl {
|
||||
pub struct TcpDevice {
|
||||
socket: TcpStream,
|
||||
}
|
||||
|
||||
impl TcpRtl {
|
||||
impl TcpDevice {
|
||||
/// Connect to a remote RTL-SDR server at the given address
|
||||
pub fn connect(addr: &str) -> Result<Self> {
|
||||
let socket = TcpStream::connect(addr)?;
|
||||
Ok(TcpRtl { socket })
|
||||
Ok(TcpDevice { socket })
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> Result<()> {
|
||||
let request_len: u16 = 14;
|
||||
loop {
|
||||
// Send header: [tag][bRequest=0][length:2 bytes LE]
|
||||
let mut hdr = [0u8; 4];
|
||||
hdr[0] = TAG_BULK;
|
||||
hdr[1] = 0;
|
||||
hdr[2..4].copy_from_slice(&request_len.to_le_bytes());
|
||||
self.socket.write_all(&hdr)?;
|
||||
|
||||
// Read status
|
||||
let mut status = [0u8; 1];
|
||||
self.socket.read_exact(&mut status)?;
|
||||
if status[0] != 0 {
|
||||
eprintln!("Remote reported error status {}", status[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
// Read 4-byte payload length (LE)
|
||||
let mut len_bytes = [0u8; 4];
|
||||
self.socket.read_exact(&mut len_bytes)?;
|
||||
let actual_len = u32::from_le_bytes(len_bytes) as usize;
|
||||
|
||||
// Read payload (I/Q pairs)
|
||||
let mut iq = vec![0u8; actual_len];
|
||||
self.socket.read_exact(&mut iq)?;
|
||||
|
||||
// Extract I-samples (even indices) and print as ADS‑B hex
|
||||
let mut adsb = Vec::with_capacity(actual_len / 2);
|
||||
for chunk in iq.chunks_exact(2) {
|
||||
adsb.push(chunk[0]);
|
||||
}
|
||||
|
||||
let frame = ADSBFrame::decode(&adsb)?;
|
||||
println!("{}", frame);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Send a framed message
|
||||
@@ -75,7 +116,7 @@ impl TcpRtl {
|
||||
}
|
||||
}
|
||||
|
||||
impl RtlDevice for TcpRtl {
|
||||
impl Device for TcpDevice {
|
||||
fn control_send(&mut self, b_request: u8, data: &[u8]) -> Result<()> {
|
||||
self.send_message(TAG_CTRL_OUT, b_request, data)?;
|
||||
self.receive_status_ok()
|
||||
Reference in New Issue
Block a user