mirror of
https://github.com/30hours/blah2.git
synced 2024-11-18 12:33:58 +00:00
Fix hackrf parameters in config
This commit is contained in:
parent
0ef2649827
commit
9070d9a6db
7 changed files with 342 additions and 2 deletions
85
config/config-hackrf.yml
Normal file
85
config/config-hackrf.yml
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
capture:
|
||||||
|
fs: 2000000
|
||||||
|
fc: 204640000
|
||||||
|
device:
|
||||||
|
type: "HackRF"
|
||||||
|
serial:
|
||||||
|
- "FIRST_DEVICE_SERIAL_NUMBER"
|
||||||
|
- "SECOND_DEVICE_SERIAL_NUMBER"
|
||||||
|
gain_lna: [32, 32]
|
||||||
|
gain_vga: [30, 30]
|
||||||
|
amp_enable: [false, false]
|
||||||
|
|
||||||
|
replay:
|
||||||
|
state: false
|
||||||
|
loop: true
|
||||||
|
file: '/opt/blah2/replay/file.rspduo'
|
||||||
|
|
||||||
|
process:
|
||||||
|
data:
|
||||||
|
cpi: 0.5
|
||||||
|
buffer: 1.5
|
||||||
|
overlap: 0
|
||||||
|
ambiguity:
|
||||||
|
delayMin: -10
|
||||||
|
delayMax: 400
|
||||||
|
dopplerMin: -200
|
||||||
|
dopplerMax: 200
|
||||||
|
clutter:
|
||||||
|
delayMin: -10
|
||||||
|
delayMax: 400
|
||||||
|
detection:
|
||||||
|
pfa: 0.00001
|
||||||
|
nGuard: 2
|
||||||
|
nTrain: 6
|
||||||
|
minDelay: 5
|
||||||
|
minDoppler: 15
|
||||||
|
nCentroid: 6
|
||||||
|
tracker:
|
||||||
|
initiate:
|
||||||
|
M: 3
|
||||||
|
N: 5
|
||||||
|
maxAcc: 10
|
||||||
|
delete: 10
|
||||||
|
smooth: "none"
|
||||||
|
|
||||||
|
network:
|
||||||
|
ip: 0.0.0.0
|
||||||
|
ports:
|
||||||
|
api: 3000
|
||||||
|
map: 3001
|
||||||
|
detection: 3002
|
||||||
|
track: 3003
|
||||||
|
timestamp: 4000
|
||||||
|
timing: 4001
|
||||||
|
iqdata: 4002
|
||||||
|
config: 4003
|
||||||
|
|
||||||
|
truth:
|
||||||
|
adsb:
|
||||||
|
enabled: false
|
||||||
|
tar1090: 'adsb.30hours.dev'
|
||||||
|
adsb2dd: 'adsb2dd.30hours.dev'
|
||||||
|
ais:
|
||||||
|
enabled: false
|
||||||
|
ip: 0.0.0.0
|
||||||
|
port: 30001
|
||||||
|
|
||||||
|
location:
|
||||||
|
rx:
|
||||||
|
latitude: -34.9286
|
||||||
|
longitude: 138.5999
|
||||||
|
altitude: 50
|
||||||
|
name: "Adelaide"
|
||||||
|
tx:
|
||||||
|
latitude: -34.9810
|
||||||
|
longitude: 138.7081
|
||||||
|
altitude: 750
|
||||||
|
name: "Mount Lofty"
|
||||||
|
|
||||||
|
save:
|
||||||
|
iq: true
|
||||||
|
map: false
|
||||||
|
detection: false
|
||||||
|
timing: false
|
||||||
|
path: "/blah2/save/"
|
|
@ -1,12 +1,13 @@
|
||||||
#include "Capture.h"
|
#include "Capture.h"
|
||||||
#include "rspduo/RspDuo.h"
|
#include "rspduo/RspDuo.h"
|
||||||
#include "usrp/Usrp.h"
|
#include "usrp/Usrp.h"
|
||||||
|
#include "hackrf/HackRf.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <httplib.h>
|
#include <httplib.h>
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
const std::string Capture::VALID_TYPE[2] = {"RspDuo", "Usrp"};
|
const std::string Capture::VALID_TYPE[3] = {"RspDuo", "Usrp", "HackRF"};
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
Capture::Capture(std::string _type, uint32_t _fs, uint32_t _fc, std::string _path)
|
Capture::Capture(std::string _type, uint32_t _fs, uint32_t _fc, std::string _path)
|
||||||
|
@ -90,6 +91,34 @@ std::unique_ptr<Source> Capture::factory_source(const std::string& type, c4::yml
|
||||||
return std::make_unique<Usrp>(type, fc, fs, path, &saveIq,
|
return std::make_unique<Usrp>(type, fc, fs, path, &saveIq,
|
||||||
address, subdev, antenna, gain);
|
address, subdev, antenna, gain);
|
||||||
}
|
}
|
||||||
|
else if (type == VALID_TYPE[2])
|
||||||
|
{
|
||||||
|
std::vector<std::string> serial;
|
||||||
|
std::vector<uint8_t> gainLna, gainVga;
|
||||||
|
std::vector<bool> ampEnable;
|
||||||
|
std::string _serial;
|
||||||
|
uint8_t _gainLna, _gainVga;
|
||||||
|
bool _ampEnable;
|
||||||
|
config["serial"][0] >> _serial;
|
||||||
|
serial.push_back(_serial);
|
||||||
|
config["serial"][1] >> _serial;
|
||||||
|
serial.push_back(_serial);
|
||||||
|
config["gain_lna"][0] >> _gainLna;
|
||||||
|
gainLna.push_back(_gainLna);
|
||||||
|
config["gain_lna"][1] >> _gainLna;
|
||||||
|
gainLna.push_back(_gainLna);
|
||||||
|
config["gain_vga"][0] >> _gainVga;
|
||||||
|
gainVga.push_back(_gainVga);
|
||||||
|
config["gain_vga"][1] >> _gainVga;
|
||||||
|
gainVga.push_back(_gainVga);
|
||||||
|
config["amp_enable"][0] >> _ampEnable;
|
||||||
|
ampEnable.push_back(_ampEnable);
|
||||||
|
config["amp_enable"][1] >> _ampEnable;
|
||||||
|
ampEnable.push_back(_ampEnable);
|
||||||
|
|
||||||
|
return std::make_unique<HackRf>(type, fc, fs, path, &saveIq,
|
||||||
|
serial, gainLna, gainVga, ampEnable);
|
||||||
|
}
|
||||||
// Handle unknown type
|
// Handle unknown type
|
||||||
std::cerr << "Error: Source type does not exist." << std::endl;
|
std::cerr << "Error: Source type does not exist." << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Capture
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/// @brief The valid capture devices.
|
/// @brief The valid capture devices.
|
||||||
static const std::string VALID_TYPE[2];
|
static const std::string VALID_TYPE[3];
|
||||||
|
|
||||||
/// @brief The capture device type.
|
/// @brief The capture device type.
|
||||||
std::string type;
|
std::string type;
|
||||||
|
|
135
src/capture/hackrf/HackRf.cpp
Normal file
135
src/capture/hackrf/HackRf.cpp
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
#include "HackRf.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <complex>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
HackRf::HackRf(std::string _type, uint32_t _fc, uint32_t _fs,
|
||||||
|
std::string _path, bool *_saveIq, std::vector<std::string> _serial,
|
||||||
|
std::vector<uint8_t> _gainLna, std::vector<uint8_t> _gainVga,
|
||||||
|
std::vector<bool> _ampEnable)
|
||||||
|
: Source(_type, _fc, _fs, _path, _saveIq)
|
||||||
|
{
|
||||||
|
serial = _serial;
|
||||||
|
ampEnable = _ampEnable;
|
||||||
|
|
||||||
|
// validate LNA gain
|
||||||
|
std::unordered_set<uint8_t> validLna;
|
||||||
|
for (uint8_t gain = 0; gain <= 40; gain += 8) {
|
||||||
|
validLna.insert(gain);
|
||||||
|
}
|
||||||
|
for (uint8_t gain : _gainLna) {
|
||||||
|
if (validLna.find(gain) == validLna.end()) {
|
||||||
|
throw std::invalid_argument("Invalid LNA gain value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gainLna = _gainLna;
|
||||||
|
|
||||||
|
// validate VGA gain
|
||||||
|
std::unordered_set<uint8_t> validVga;
|
||||||
|
for (uint8_t gain = 0; gain <= 62; gain += 2) {
|
||||||
|
validVga.insert(gain);
|
||||||
|
}
|
||||||
|
for (uint8_t gain : _gainVga) {
|
||||||
|
if (validVga.find(gain) == validVga.end()) {
|
||||||
|
throw std::invalid_argument("Invalid LNA gain value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gainVga = _gainVga;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackRf::check_status(uint8_t status, std::string message)
|
||||||
|
{
|
||||||
|
if (status != HACKRF_SUCCESS)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("[HackRF] " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackRf::start()
|
||||||
|
{
|
||||||
|
// global hackrf config
|
||||||
|
int status;
|
||||||
|
status = hackrf_init();
|
||||||
|
check_status(status, "Failed to initialise HackRF");
|
||||||
|
hackrf_device_list_t *list;
|
||||||
|
list = hackrf_device_list();
|
||||||
|
if (list->devicecount < 2)
|
||||||
|
{
|
||||||
|
check_status(-1, "Failed to find 2 HackRF devices.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// reference config
|
||||||
|
status = hackrf_open_by_serial(serial[0].c_str(), &dev[0]);
|
||||||
|
check_status(status, "Failed to open device.");
|
||||||
|
status = hackrf_set_freq(dev[0], fc);
|
||||||
|
check_status(status, "Failed to set frequency.");
|
||||||
|
status = hackrf_set_sample_rate(dev[0], fs);
|
||||||
|
check_status(status, "Failed to set sample rate.");
|
||||||
|
status = hackrf_set_amp_enable(dev[0], ampEnable[0] ? 1 : 0);
|
||||||
|
check_status(status, "Failed to set AMP status.");
|
||||||
|
status = hackrf_set_lna_gain(dev[0], gainLna[0]);
|
||||||
|
check_status(status, "Failed to set LNA gain.");
|
||||||
|
status = hackrf_set_vga_gain(dev[0], gainVga[0]);
|
||||||
|
check_status(status, "Failed to set VGA gain.");
|
||||||
|
|
||||||
|
// surveillance config
|
||||||
|
status = hackrf_open_by_serial(serial[1].c_str(), &dev[1]);
|
||||||
|
check_status(status, "Failed to open device.");
|
||||||
|
status = hackrf_set_freq(dev[1], fc);
|
||||||
|
check_status(status, "Failed to set frequency.");
|
||||||
|
status = hackrf_set_sample_rate(dev[1], fs);
|
||||||
|
check_status(status, "Failed to set sample rate.");
|
||||||
|
status = hackrf_set_amp_enable(dev[1], ampEnable[1] ? 1 : 0);
|
||||||
|
check_status(status, "Failed to set AMP status.");
|
||||||
|
status = hackrf_set_lna_gain(dev[1], gainLna[1]);
|
||||||
|
check_status(status, "Failed to set LNA gain.");
|
||||||
|
status = hackrf_set_vga_gain(dev[1], gainVga[1]);
|
||||||
|
check_status(status, "Failed to set VGA gain.");
|
||||||
|
status = hackrf_set_hw_sync_mode(dev[1], 1);
|
||||||
|
check_status(status, "Failed to enable hardware synchronising.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackRf::stop()
|
||||||
|
{
|
||||||
|
hackrf_stop_rx(dev[0]);
|
||||||
|
hackrf_stop_rx(dev[1]);
|
||||||
|
hackrf_close(dev[0]);
|
||||||
|
hackrf_close(dev[1]);
|
||||||
|
hackrf_exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackRf::process(IqData *buffer1, IqData *buffer2)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
status = hackrf_start_rx(dev[1], &rx_callback, buffer2);
|
||||||
|
check_status(status, "Failed to start RX streaming.");
|
||||||
|
status = hackrf_start_rx(dev[0], &rx_callback, buffer1);
|
||||||
|
check_status(status, "Failed to start RX streaming.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int HackRf::rx_callback(hackrf_transfer* transfer)
|
||||||
|
{
|
||||||
|
IqData* buffer_blah2 = (IqData*)transfer->rx_ctx;
|
||||||
|
int8_t* buffer_hackrf = (int8_t*) transfer->buffer;
|
||||||
|
|
||||||
|
buffer_blah2->lock();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < transfer->valid_length; i+2)
|
||||||
|
{
|
||||||
|
double iqi = static_cast<double>(buffer_hackrf[i]);
|
||||||
|
double iqq = static_cast<double>(buffer_hackrf[i+1]);
|
||||||
|
buffer_blah2->push_back({iqi, iqq});
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_blah2->unlock();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HackRf::replay(IqData *buffer1, IqData *buffer2, std::string _file, bool _loop)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
84
src/capture/hackrf/HackRf.h
Normal file
84
src/capture/hackrf/HackRf.h
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/// @file HackRf.h
|
||||||
|
/// @class HackRf
|
||||||
|
/// @brief A class to capture data on the HackRF.
|
||||||
|
/// @author sdn-ninja
|
||||||
|
/// @author 30hours
|
||||||
|
/// @todo Replay functionality.
|
||||||
|
|
||||||
|
#ifndef HACKRF_H
|
||||||
|
#define HACKRF_H
|
||||||
|
|
||||||
|
#include "capture/Source.h"
|
||||||
|
#include "data/IqData.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <libhackrf/hackrf.h>
|
||||||
|
|
||||||
|
class HackRf : public Source
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// @brief Vector of serial numbers.
|
||||||
|
/// @details Serial as given by hackrf_info.
|
||||||
|
std::vector<std::string> serial;
|
||||||
|
|
||||||
|
/// @brief RX LNA (IF) gain, 0-40dB, 8dB steps.
|
||||||
|
std::vector<uint8_t> gainLna;
|
||||||
|
|
||||||
|
/// @brief RX VGA (baseband) gain, 0-62dB, 2dB steps.
|
||||||
|
std::vector<uint8_t> gainVga;
|
||||||
|
|
||||||
|
/// @brief Enable extra amplifier U13 on receive.
|
||||||
|
std::vector<bool> ampEnable;
|
||||||
|
|
||||||
|
/// @brief Vector of pointers to HackRF devices.
|
||||||
|
std::vector<hackrf_device*> dev;
|
||||||
|
|
||||||
|
/// @brief Check status of HackRF API returns.
|
||||||
|
/// @param status Return code of API call.
|
||||||
|
/// @param message Message if API call error.
|
||||||
|
void check_status(uint8_t status, std::string message);
|
||||||
|
|
||||||
|
/// @brief Callback function for HackRF samples.
|
||||||
|
/// @param transfer HackRF transfer object.
|
||||||
|
/// @return Void.
|
||||||
|
static int rx_callback(hackrf_transfer* transfer);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// @brief Constructor.
|
||||||
|
/// @param fc Center frequency (Hz).
|
||||||
|
/// @param path Path to save IQ data.
|
||||||
|
/// @return The object.
|
||||||
|
HackRf(std::string type, uint32_t fc, uint32_t fs, std::string path,
|
||||||
|
bool *saveIq, std::vector<std::string> serial,
|
||||||
|
std::vector<uint8_t> gainLna, std::vector<uint8_t> gainVga,
|
||||||
|
std::vector<bool> ampEnable);
|
||||||
|
|
||||||
|
/// @brief Implement capture function on HackRF.
|
||||||
|
/// @param buffer1 Pointer to reference buffer.
|
||||||
|
/// @param buffer2 Pointer to surveillance buffer.
|
||||||
|
/// @return Void.
|
||||||
|
void process(IqData *buffer1, IqData *buffer2);
|
||||||
|
|
||||||
|
/// @brief Call methods to start capture.
|
||||||
|
/// @return Void.
|
||||||
|
void start();
|
||||||
|
|
||||||
|
/// @brief Call methods to gracefully stop capture.
|
||||||
|
/// @return Void.
|
||||||
|
void stop();
|
||||||
|
|
||||||
|
/// @brief Implement replay function on HackRF.
|
||||||
|
/// @param buffer1 Pointer to reference buffer.
|
||||||
|
/// @param buffer2 Pointer to surveillance buffer.
|
||||||
|
/// @param file Path to file to replay data from.
|
||||||
|
/// @param loop True if samples should loop at EOF.
|
||||||
|
/// @return Void.
|
||||||
|
void replay(IqData *buffer1, IqData *buffer2, std::string file, bool loop);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
7
src/capture/hackrf/README.md
Normal file
7
src/capture/hackrf/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# HackRF setup for blah2
|
||||||
|
|
||||||
|
This requires 2 HackRF units with a shared clock signal and a shared hardware trigger.
|
||||||
|
|
||||||
|
# Instructions
|
||||||
|
|
||||||
|
TODO
|
Loading…
Reference in a new issue