mod define;
use std::fmt::{Debug, Formatter};
use std::future::Future;
use std::time::Duration;
pub use eusb::prelude::*;
use log::debug;
pub mod error;
use crate::define::*;
use crate::error::*;
const HACKRF_USB_VID: u64 = 0x1d50;
const HACKRF_JAWBREAKER_USB_PID: u64 = 0x604b;
const HACKRF_ONE_USB_PID : u64= 0x6089;
const RAD1O_USB_PID: u64 = 0xcc15;
pub struct Manager{
pub usb: UsbManager,
}
impl From<UsbManager> for Manager{
fn from(value: UsbManager) -> Self {
Self{
usb: value
}
}
}
fn is_hackrf(pid: u16)->bool{
let pid = pid as u64;
pid == HACKRF_JAWBREAKER_USB_PID
|| pid == HACKRF_ONE_USB_PID
|| pid == RAD1O_USB_PID
}
pub struct HackRF{
pub usb: Device,
interface: Interface,
}
impl Debug for HackRF {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, r"
HackRF:
pid: {:04x}
vid: {:04x}
",
self.usb.pid(), self.usb.vid())
}
}
impl Manager {
pub async fn open_one(&self)->Result<HackRF>{
let list = self.usb.device_list().await?;
for device in &list {
if is_hackrf(device.pid()) {
let rf = HackRF::new(device.clone()).await?;
return Ok(rf)
}
}
Err(HackRFError::NoDevice)
}
pub async fn device_list(&self)-> Result<Vec<HackRF>>{
let list = self.usb.device_list().await?;
let mut out = Vec::with_capacity(list.len());
for device in &list {
if is_hackrf(device.pid()) {
let rf = HackRF::new(device.clone()).await?;
out.push(rf);
}
}
Ok(out)
}
pub async fn open_by_sn(&self, sn: String)-> Result<HackRF>{
let list = self.usb.device_list().await?;
let want = sn.trim();
for device in &list {
match device.serial_number().await{
Ok(d_sn) => {
let sn_str = d_sn.trim();
if want == sn_str{
let rf = HackRF::new(device.clone()).await?;
return Ok(rf)
}
}
Err(_) => {}
}
}
Err(HackRFError::NoDevice)
}
}
struct ControlTransferRequest{
recipient: UsbControlRecipient,
control_transfer_type: UsbControlTransferType,
request: u8,
value: u16,
index: u16,
timeout: Duration,
}
fn new_request(cmd: Cmd) ->ControlTransferRequest{
ControlTransferRequest{
recipient: UsbControlRecipient::Device,
control_transfer_type: UsbControlTransferType::Vendor,
request: cmd.0,
value: 0,
index: 0,
timeout: Default::default(),
}
}
impl HackRF{
async fn new(device: Device)->Result<Self>{
device.set_config_by_value(1)?;
let interface = device.claim_interface_by_num(0)?;
let s = Self{
usb: device,
interface
};
s.set_mode_off().await?;
Ok(s)
}
async fn control_transfer_out(&self, request: ControlTransferRequest, data: &mut[u8]) -> Result<()>{
let mut r = self.usb.control_transfer_out(
request.recipient,
request.control_transfer_type,
request.request,
request.value,
request.index,
request.timeout,
data
).await?;
if r.data().len() < data.len(){
return Err(HackRFError::Usb(format!("usb len error: {}", r.data().len())));
}
Ok(())
}
async fn control_transfer_in(&self, request: ControlTransferRequest, capacity: usize) -> Result<Vec<u8>>{
let mut result = self.usb.control_transfer_in(
request.recipient,
request.control_transfer_type,
request.request,
request.value,
request.index,
request.timeout,
capacity
).await?;
Ok(result.data().to_vec())
}
pub async fn sn(&self)->Result<String>{
let sn = self.usb.serial_number().await?;
Ok(sn)
}
pub async fn version_string_read(&self, len: usize)->Result<Vec<u8>>{
let request = new_request(Cmd::VERSION_STRING_READ);
self.control_transfer_in(request, len).await
}
async fn set_transceiver_mode(&self, mode: TransceiverMode)->Result<()>{
let mut request = new_request(Cmd::SET_TRANSCEIVER_MODE);
request.value=mode.0;
self.control_transfer_out(request, vec![].as_mut_slice()).await
}
pub fn rx_request(&self)->Result<Request>{
let r = self.interface.bulk_request(
EndpointDescriptor::new(1, Direction::In),
vec![0; TRANSFER_BUFFER_SIZE],
Default::default())?;
Ok(r)
}
pub async fn start_rx_channel(&self, buffer_size: usize)->Result<(RequestSender, RequestReceiver)>{
self.set_transceiver_mode(TransceiverMode::RECEIVE).await?;
let r = self.usb.request_channel(buffer_size);
Ok(r)
}
pub async fn set_mode_off(&self)->Result<()>{
self.set_transceiver_mode(TransceiverMode::OFF).await
}
async fn set_baseband_filter_bandwidth(&self, bandwidth_hz: usize)->Result<()>{
let mut request = new_request(Cmd::BASEBAND_FILTER_BANDWIDTH_SET);
let bandwidth_hz = compute_baseband_filter_bw(bandwidth_hz);
request.value = (bandwidth_hz & 0xffff) as u16;
request.index = (bandwidth_hz >> 16) as u16;
debug!("set baseband: {}", bandwidth_hz);
self.control_transfer_out(request,vec![].as_mut_slice()).await
}
async fn set_sample_rate_manual(&self,freq_hz: u32, divider: u32) -> Result<()>{
let mut data = freq_hz.to_le_bytes().to_vec();
let mut divider_bytes = divider.to_le_bytes().to_vec();
data.append(&mut divider_bytes);
let request = new_request(Cmd::SAMPLE_RATE_SET);
debug!("set sample rate: {}", freq_hz / divider);
self.control_transfer_out(request,data.as_mut_slice()).await?;
let freq = 0.75 * freq_hz as f64 / (divider as f64);
self.set_baseband_filter_bandwidth(freq as usize).await
}
pub async fn set_sample_rate(&self, freq_hz: f64) ->Result<()>{
self.set_sample_rate_manual(freq_hz as u32, 1).await
}
pub async fn set_freq(&self, freq_hz: f64) -> Result<()>{
let freq_hz = freq_hz as u64;
let l_freq_mhz = (freq_hz / ONE_MHZ) as u32;
let l_freq_hz = (freq_hz % ONE_MHZ) as u32;
let mut data = Vec::with_capacity(8);
let mut data1 = l_freq_mhz.to_le_bytes().to_vec();
let mut data2 = l_freq_hz.to_le_bytes().to_vec();
data.append(&mut data1);
data.append(&mut data2);
let request = new_request(Cmd::SET_FREQ);
debug!("set freq: {}.{} MHz", l_freq_mhz, l_freq_hz);
self.control_transfer_out(request,data.as_mut_slice()).await
}
pub async fn set_lna_gain(&self, value: u32) -> Result<()>{
debug!("set lna gain: {}", value);
let mut value = value as u16;
if value > 40 {
return Err( HackRFError::ParamErr(format!("lna >40")))
}
value &= !0x07;
let mut request = new_request(Cmd::SET_LNA_GAIN);
request.index = value;
let data = self.control_transfer_in(request, 1).await?;
if data[0] == 0 {
Err(HackRFError::ParamErr(format!("lna set fail")))
}else {
Ok(())
}
}
pub async fn set_vga_gain(&self, value: u32) -> Result<()>{
debug!("set vga gain: {}", value);
let mut value_16 = value as u16;
if value_16 > 62 {
return Err( HackRFError::ParamErr(format!("vga >62")))
}
value_16 &= !0x01;
let mut request = new_request(Cmd::SET_VGA_GAIN);
request.index = value_16;
let data = self.control_transfer_in(request, 1).await?;
if data[0] == 0 {
Err(HackRFError::ParamErr(format!("vga set fail")))
}else {
Ok(())
}
}
async fn set_amp_enable(&self, enable: bool) -> Result<()>{
debug!("set amp enable: {}", enable);
let value = enable as u16;
let mut request = new_request(Cmd::AMP_ENABLE);
request.value = value;
self.control_transfer_out(request, vec![].as_mut_slice()).await
}
pub async fn amp_enable(&self) -> Result<()>{
self.set_amp_enable(true).await
}
pub async fn amp_disable(&self) -> Result<()>{
self.set_amp_enable(false).await
}
}
#[cfg(test)]
mod tests {
use std::time::{Duration, Instant};
use log::{info, LevelFilter};
use tokio::select;
use futures::StreamExt;
use super::*;
fn init() {
let _ = env_logger::builder().filter_level(LevelFilter::Debug).is_test(true).try_init();
}
#[tokio::test]
async fn device_list() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.device_list().await.unwrap();
for one in sdr {
info!("{:?}", one);
}
}
#[tokio::test]
async fn open_by_sn() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
let sn = sdr.sn().await.unwrap();
drop(sdr);
info!("sn: {}", sn);
let sdr = manager.open_by_sn(sn).await.unwrap();
info!("open sn ok: {}", sdr.sn().await.unwrap());
}
#[tokio::test]
async fn set_transceiver_mode() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
sdr.set_transceiver_mode(TransceiverMode::OFF).await.unwrap();
info!("finish");
}
#[tokio::test]
async fn version_string() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
let version = sdr.version_string_read(30).await.unwrap();
let version = String::from_utf8(version).unwrap();
info!("version: {}", version);
}
#[tokio::test]
async fn set_bandwidth() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
sdr.set_baseband_filter_bandwidth(25_000_000).await.unwrap();
}
#[tokio::test]
async fn set_sample_rate() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
info!("{:?}", sdr);
sdr.set_sample_rate(20e6).await.unwrap();
}
#[tokio::test]
async fn set_freq() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
info!("{:?}", sdr);
sdr.set_freq(88.7e6).await.unwrap();
}
#[tokio::test]
async fn set_lna_gain() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
sdr.set_lna_gain(38).await.unwrap();
}
#[tokio::test]
async fn set_vga_gain() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
sdr.set_vga_gain(24).await.unwrap();
}
#[tokio::test]
async fn rx_data() {
init();
let manager = Manager::from(UsbManager::init_default().unwrap());
let sdr = manager.open_one().await.unwrap();
let start = Instant::now();
sdr.amp_enable().await.unwrap();
sdr.set_vga_gain(24).await.unwrap();
sdr.set_lna_gain(24).await.unwrap();
sdr.set_freq(400e6).await.unwrap();
sdr.set_sample_rate(20e6).await.unwrap();
let duration = Instant::now().duration_since(start);
info!("指令时间:{:?}", duration);
let request1 = sdr.rx_request().unwrap();
let request2 = sdr.rx_request().unwrap();
let (mut tx, mut rx) = sdr.start_rx_channel(4).await.unwrap();
let (stop_tx, mut stop_rx) = tokio::sync::oneshot::channel();
tx.send(request1).unwrap();
tx.send(request2).unwrap();
tokio::spawn(async move{
let mut data = vec![0u8; 1024];
let mut all = 0usize;
let start = Instant::now();
loop{
select! {
res = rx.next() => {
match res{
Some(r)=> {
let mut result = r.unwrap();
data = result.data().to_vec();
all += result.data().len();
let r = tx.send(result);
if r.is_err(){
break;
}
}
None=>break,
}
}
_ = (&mut stop_rx) => {
break;
}
}
}
let duration = Instant::now().duration_since(start);
let bits = (all) as f64;
let seconds = duration.as_secs_f64();
let mb = (bits / seconds) / 1_000_000.0;
info!("速度:{}", mb);
info!("接收停止");
});
tokio::time::sleep(Duration::from_secs(5)).await;
info!("send stop");
stop_tx.send(1).unwrap();
tokio::time::sleep(Duration::from_secs(1)).await;
info!("finish");
}
}