Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CMakeLists.txt
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ include(GrVersion)

set(GR_REQUIRED_COMPONENTS RUNTIME ANALOG BLOCKS DIGITAL FILTER FFT PMT)
find_package(Gnuradio REQUIRED COMPONENTS runtime analog blocks digital filter fft)

if(Gnuradio_VERSION VERSION_LESS "3.8")
find_package(Volk)
endif()
Expand Down Expand Up @@ -140,6 +141,19 @@ find_package(GnuradioUHD)
find_package(GnuradioOsmosdr)
find_package(LibHackRF)
find_package(LibUHD)
find_library(IIO_LIBRARIES iio)
find_path(IIO_INCLUDE_DIRS iio.h)
find_package(GnuradioIIO)
if (GR_IIO_FOUND)
message(STATUS "GR-IIO Found! Adding IIO support")
set(BUILD_WITH_GR_IIO TRUE)
add_compile_definitions(GnuradioIIO_FOUND=1)
set(GR_REQUIRED_COMPONENTS RUNTIME ANALOG BLOCKS DIGITAL FILTER FFT PMT IIO)
find_package(Gnuradio REQUIRED COMPONENTS iio)
else()
message(STATUS "Gnuradio-IIO or a dependency Not Found! Skipping IIO support")
endif()

find_package(OpenSSL REQUIRED)
find_package(CURL REQUIRED)
if (STREAMER)
Expand Down Expand Up @@ -387,5 +401,8 @@ if(NOT Gnuradio_VERSION VERSION_LESS "3.8")
)
endif()

if (GR_IIO_FOUND)
target_link_libraries(trunk-recorder gnuradio::gnuradio-iio)
endif()

install(TARGETS trunk-recorder RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
9 changes: 7 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ RUN apt-get update && \
wget \
python3-six \
openssh-client \
ffmpeg
ffmpeg \
libiio-dev \
libiio-utils \
libad9361-dev \
libgnuradio-iio3.10.9t64

WORKDIR /src

Expand All @@ -50,7 +54,8 @@ RUN cmake .. && make -j$(nproc) && make DESTDIR=/newroot install
FROM ubuntu:24.04
RUN apt-get update && apt-get -y upgrade && apt-get install --no-install-recommends -y ca-certificates gr-funcube gr-iqbal curl wget libboost-log1.83.0 \
libboost-chrono1.83.0t64 libgnuradio-digital3.10.9t64 libgnuradio-analog3.10.9t64 libgnuradio-filter3.10.9t64 libgnuradio-network3.10.9t64 \
libgnuradio-uhd3.10.9t64 libgnuradio-osmosdr0.2.0t64 libsoapysdr0.8 soapysdr0.8-module-all libairspyhf1 libfreesrp0 librtlsdr2 libxtrx0 sox fdkaac docker.io && \
libgnuradio-uhd3.10.9t64 libgnuradio-osmosdr0.2.0t64 libiio-dev libiio-utils libad9361-dev libgnuradio-iio3.10.9t64 libsoapysdr0.8 \
soapysdr0.8-module-all libairspyhf1 libfreesrp0 librtlsdr2 libxtrx0 sox fdkaac docker.io && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /usr/share/{doc,man,info} && rm -rf /usr/local/share/{doc,man,info}

Expand Down
38 changes: 38 additions & 0 deletions cmake/Modules/FindGnuradioIIO.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
PKG_CHECK_MODULES(PC_GNURADIO_IIO gnuradio-iio)

FIND_PATH(
GNURADIO_IIO_INCLUDE_DIRS
NAMES gnuradio/iio/api.h
HINTS $ENV{GNURADIO_IIO_DIR}/include
${PC_GNURADIO_IIO_INCLUDEDIR}
PATHS /usr/local/include
/usr/include
)

FIND_LIBRARY(
GNURADIO_IIO_LIBRARIES
NAME gnuradio-iio
HINTS $ENV{GNURADIO_IIO_DIR}/lib
${PC_GNURADIO_IIO_LIBDIR}
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)

pkg_check_modules(PC_IIO libiio)

pkg_check_modules(PC_AD9361 libad9361)

# pkg_check_modules(PC_GR_IIO gnuradio-iio)

if (GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES AND PC_IIO_FOUND AND PC_AD9361_FOUND)
set(GR_IIO_FOUND TRUE CACHE INTERNAL "gnuradio-iio found")
message(STATUS "Found gnuradio-iio: ${GNURADIO_IIO_INCLUDE_DIRS}, ${GNURADIO_IIO_LIBRARIES}")
else(GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES AND PC_IIO_FOUND AND PC_AD9361_FOUND)
set(GR_IIO_FOUND FALSE CACHE INTERNAL "gnuradio-uhd found")
endif(GNURADIO_IIO_INCLUDE_DIRS AND GNURADIO_IIO_LIBRARIES AND PC_IIO_FOUND AND PC_AD9361_FOUND)

INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GnuradioIIO DEFAULT_MSG GNURADIO_IIO_LIBRARIES GNURADIO_IIO_INCLUDE_DIRS)
MARK_AS_ADVANCED(GNURADIO_IIO_LIBRARIES GNURADIO_IIO_INCLUDE_DIRS)
8 changes: 4 additions & 4 deletions docs/CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,12 @@ There is a list of available Plugins [here](./Plugins.md).

## Source Object

### USRP or OSMOSDR Sources
### USRP, OSMOSDR or IIO Sources

| Key | Required | Default Value | Type | Description |
| :--------------- | :------: | :-----------: | --------------------------- | ------------------------------------------------------------ |
| driver | ✓ | | **"usrp"**, **"osmosdr"** | The GNURadio block you wish to use for the SDR. |
| device | | | **string**<br /> See the [osmosdr page](http://sdr.osmocom.org/trac/wiki/GrOsmoSDR) for supported devices and parameters. | Osmosdr device name and possibly serial number or index of the device. <br /> You only need to do add this key if there are more than one osmosdr devices being used.<br /> Example: `bladerf=00001` for BladeRF with serial 00001 or `rtl=00923838` for RTL-SDR with serial 00923838, just `airspy` for an airspy.<br />It seems that when you have 5 or more RTLSDRs on one system you need to decrease the buffer size. I think it has something to do with the driver. Try adding buflen: `"device": "rtl=serial_num,buflen=65536"`, there should be no space between the comma and `buflen`. |
| driver | ✓ | | **"usrp"**, **"osmosdr"**, **"iio"** | The GNURadio block you wish to use for the SDR. |
| device | | | **string**<br /> See the [osmosdr page](http://sdr.osmocom.org/trac/wiki/GrOsmoSDR) for supported devices and parameters. | Osmosdr device name and possibly serial number or index of the device. <br /> You only need to do add this key if there are more than one osmosdr devices being used.<br /> Example: `bladerf=00001` for BladeRF with serial 00001 or `rtl=00923838` for RTL-SDR with serial 00923838, just `airspy` for an airspy.<br />It seems that when you have 5 or more RTLSDRs on one system you need to decrease the buffer size. I think it has something to do with the driver. Try adding buflen: `"device": "rtl=serial_num,buflen=65536"`, there should be no space between the comma and `buflen`. <br/>For iio devices, `"ip:192.168.1.5,65536"` or `"usb:1.3.5,65536"` can be used, depending on if you are connecting over ethernet or USB. `iio_info -S` will scan for iio devices and give you the ip address or usb device number. The number after the comma is the buffer length.|
| center | ✓ | | number | The center frequency in Hz to tune the SDR to |
| rate | ✓ | | number | The sampling rate to set the SDR to, in samples / second |
| error | | 0 | number | The tuning error for the SDR, in Hz. This is the difference between the target value and the actual value. So if you wanted to recv 856MHz but you had to tune your SDR to 855MHz (when set to 0ppm) to actually receive it, you would set this to -1000000. You should also probably get a new SDR if it is off by this much. |
Expand All @@ -169,7 +169,7 @@ There is a list of available Plugins [here](./Plugins.md).
| analogRecorders | | | number | The number of Analog Recorder to have attached to this source. The same as Digital Recorders except for Analog Voice channels. *This is only required for Trunk systems. Channels in Conventional systems have dedicated recorders and do not need to be included here.* |
| signalDetectorThreshold | | | number | If set, a static threshold will be used for the Signal Detector on all conventional recorder. Otherwise, the threshold value for the noise floor will be automatically be determined. Only set this is you are having problems. The value is in dB, but is generally higher than the Squelch value because the power is measured differently |
| ppm | | 0 | number | The tuning error for the SDR in ppm (parts per million), as an alternative to `error` above. Use a program like GQRX to find an accurate value. |
| agc | | false | **true** / **false** | Whether or not to enable the SDR's automatic gain control (if supported). This is false by default. It is not recommended to set this as it often yields worse performance compared to a manual gain setting. |
| agc | | false | **true** / **false** | Whether or not to enable the SDR's automatic gain control (if supported). This is false by default. It is not recommended to set this as it often yields worse performance compared to a manual gain setting. On iio devices this will enable "fast_attack" agc mode. |
| gainSettings | | | { "stageName": value} | Set the gain for any stage. The value for this setting should be passed as an object, where the key specifies the name of the gain stage and the value is the amount of gain in dB. For example:<br /> ````"gainSettings": { "IF": 10, "BB": 11.9},```` |
| ifGain | | | number | *AirSpy/hackrf only* sets the **IF** gain. |
| bbGain | | | number | *hackrf only* sets the **BB** gain. |
Expand Down
17 changes: 17 additions & 0 deletions docs/Install/INSTALL-LINUX.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ If you are using a HackRF:
sudo apt install -y hackrf libhackrf-dev libhackrf0
```

If you are using an IIO device (Pluto, LibreSDR, fmcomms2/3/4, etc):
```bash
sudo apt install -y libad9361-dev libiio-dev libiio-utils libgnuradio-iio*
```

### Ubuntu 22.04

Expand All @@ -36,6 +40,10 @@ If you are using a HackRF:
sudo apt install -y hackrf libhackrf-dev libhackrf0
```

If you are using an IIO device (Pluto, LibreSDR, fmcomms2/3/4, etc):
```bash
sudo apt install -y libad9361-dev libiio-dev libiio-utils libgnuradio-iio*
```


### Ubuntu 21.04
Expand All @@ -50,6 +58,10 @@ If you are using a HackRF:
sudo apt install -y hackrf libhackrf-dev libhackrf0
```

If you are using an IIO device (Pluto, LibreSDR, fmcomms2/3/4, etc):
```bash
sudo apt install -y libad9361-dev libiio-dev libiio-utils libgnuradio-iio*
```

### Ubuntu 20.x

Expand All @@ -63,6 +75,11 @@ If you are using a HackRF:
sudo apt install -y hackrf libhackrf-dev libhackrf0
```

If you are using an IIO device (Pluto, LibreSDR, fmcomms2/3/4, etc):
```bash
sudo apt install -y libad9361-dev libiio-dev libiio-utils libgnuradio-iio*
```

### Older Ubuntu Versions...

These instructions should work on Ubuntu 16.x to 17.x, including Debian 9 and 10.
Expand Down
32 changes: 32 additions & 0 deletions examples/config-iio.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"ver": 2,
"sources": [
{
"center": 857000000.0,
"rate": 8000000,
"error": 0,
"gain": 65,
"digitalRecorders": 6,
"driver": "iio",
"device": "ip:10.10.1.222,1048576"
},
{
"center": 773000000.0,
"rate": 8000000,
"error": 0,
"gain": 65,
"digitalRecorders": 6,
"driver": "iio",
"device": "usb:1.3.5,1048576"
}

],
"systems": [
{
"type": "p25",
"control_channels": [ 772281250 ],
"talkgroupsFile": "talkgroups.csv",
"modulation": "qpsk"
}
]
}
4 changes: 2 additions & 2 deletions trunk-recorder/config.cc
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -451,8 +451,8 @@ bool load_config(string config_file, Config &config, gr::top_block_sptr &tb, std
bool gain_set = false;
std::string driver = element.value("driver", "");

if ((driver != "osmosdr") && (driver != "usrp") && (driver != "sigmf") && (driver != "iqfile")) {
BOOST_LOG_TRIVIAL(error) << "Driver specified in config.json not recognized, needs to be osmosdr, sigmf, iqfile or usrp";
if ((driver != "osmosdr") && (driver != "usrp") && (driver != "sigmf") && (driver != "iqfile") && (driver != "iio")) {
BOOST_LOG_TRIVIAL(error) << "Driver specified in config.json not recognized, needs to be osmosdr, sigmf, iqfile, usrp, or iio";
return false;
}

Expand Down
5 changes: 5 additions & 0 deletions trunk-recorder/recorders/p25_recorder_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ void p25_recorder_impl::initialize(Source *src) {
timestamp = time(NULL);
starttime = time(NULL);

BOOST_LOG_TRIVIAL(info) << "p25_recorder.cc: Initializing P25 Recorder Num [" << rec_num << "]\tType: " << (conventional ? "Conventional" : "Trunked") << "\tQPSK: " << qpsk_mod;
BOOST_LOG_TRIVIAL(info) << "p25_recorder.cc: Center Freq:\t" << format_freq(center_freq) << "\tInput Rate: " << input_rate;
BOOST_LOG_TRIVIAL(info) << "p25_recorder.cc: Silence Frames: " << silence_frames << "\tSoft Vocoder: " << d_soft_vocoder;
BOOST_LOG_TRIVIAL(info) << "p25_recorder.cc: Squelch DB: " << squelch_db;

if (config == NULL) {
this->set_enable_audio_streaming(false);
} else {
Expand Down
72 changes: 72 additions & 0 deletions trunk-recorder/source.cc
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Source::Source(double c, double r, double e, std::string drv, std::string dev, C
rate = r;
center = c;
error = e;
bufLength = 0;
set_min_max();
driver = drv;
device = dev;
Expand All @@ -68,6 +69,7 @@ Source::Source(double c, double r, double e, std::string drv, std::string dev, C
autotune_source = false;
autotune_manager = new AutotuneManager(this);


recorder_selector = gr::blocks::selector::make(sizeof(gr_complex), 0, 0);

// parameters for signal_detector_cvf
Expand Down Expand Up @@ -146,6 +148,51 @@ Source::Source(double c, double r, double e, std::string drv, std::string dev, C

source_block = usrp_src;
}

#ifdef GnuradioIIO_FOUND
if (driver == "iio") {
std::vector<bool> enable_channels{1,1,0,0};
BOOST_LOG_TRIVIAL(info) << "SOURCE TYPE IIO";

// check to see if device string has bufferLength, and if so, split them
std::string dev = device;
bufLength = 32768;

if (device.find(",")) {
dev = device.substr(0,device.find(","));
bufLength = std::stoul(device.substr(device.find(",") + 1, device.length()));
}

BOOST_LOG_TRIVIAL(info) << "Device: " << dev;
BOOST_LOG_TRIVIAL(info) << "Buffer Length: " << bufLength;

gr::iio::fmcomms2_source<gr_complex>::sptr iio_src;
iio_src = gr::iio::fmcomms2_source<gr_complex>::make(dev, enable_channels, bufLength);
iio_src->set_len_tag_key("");
iio_src->set_gain_mode(0, "manual");
iio_src->set_gain(0, gain);

BOOST_LOG_TRIVIAL(info) << "Tuning to " << format_freq(center + error);
iio_src->set_frequency(center + error);


BOOST_LOG_TRIVIAL(info) << "Setting sample rate to: " << FormatSamplingRate(rate);
iio_src->set_samplerate(rate);
actual_rate = rate;

iio_src->set_quadrature(true);
iio_src->set_rfdc(true);
iio_src->set_bbdc(true);
iio_src->set_filter_params("Auto", "", 0.0, 0.0);



source_block = iio_src;
}
#else // GnuradioIIO_FOUND
BOOST_LOG_TRIVIAL(fatal) << "Trunk-recorder was not compiled with IIO enabled.";
exit(1);
#endif //GnuradioIIO_FOUND
}

void Source::set_iq_source(std::string iq_file, bool repeat, double center, double rate) {
Expand Down Expand Up @@ -329,6 +376,17 @@ void Source::set_gain(double r) {
gain = r;
cast_to_usrp_sptr(source_block)->set_gain(gain);
}

#ifdef GnuradioIIO_FOUND
if (driver == "iio") {
gain = r;
cast_to_iio_sptr(source_block)->set_gain(0, gain);
BOOST_LOG_TRIVIAL(info) << "Gain set to: " << gain;
}
#else // GnuradioIIO_FOUND
BOOST_LOG_TRIVIAL(fatal) << "Trunk-recorder was not compiled with IIO enabled.";
exit(1);
#endif //GnuradioIIO_FOUND
}

void Source::add_gain_stage(std::string stage_name, double value) {
Expand Down Expand Up @@ -380,7 +438,21 @@ void Source::set_gain_mode(bool m) {
} else {
BOOST_LOG_TRIVIAL(info) << "Auto gain control is OFF";
}

}
#ifdef GnuradioIIO_FOUND
else if (driver == "iio") {
gain_mode = m;
if (gain_mode) {
cast_to_iio_sptr(source_block)->set_gain_mode(0, "fast_attack");
} else {
cast_to_iio_sptr(source_block)->set_gain_mode(0, "manual");
}
}
#else // GnuradioIIO_FOUND
BOOST_LOG_TRIVIAL(fatal) << "Trunk-recorder was not compiled with IIO enabled.";
exit(1);
#endif
}

double Source::get_if_gain() {
Expand Down
15 changes: 15 additions & 0 deletions trunk-recorder/source.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include <gnuradio/basic_block.h>
#include <gnuradio/top_block.h>
#include <gnuradio/uhd/usrp_source.h>
#ifdef GnuradioIIO_FOUND
#include <gnuradio/iio/fmcomms2_source.h>
#endif
#include <iostream>
#include <numeric>
#include <osmosdr/source.h>
Expand Down Expand Up @@ -53,6 +56,7 @@ class Source {
int debug_recorder_port;
int next_selector_port;
int silence_frames;
unsigned long bufLength;
Config *config;
bool autotune_source;

Expand Down Expand Up @@ -167,13 +171,24 @@ class Source {
inline gr::uhd::usrp_source::sptr cast_to_usrp_sptr(gr::basic_block_sptr p) {
return boost::dynamic_pointer_cast<gr::uhd::usrp_source, gr::basic_block>(p);
}
#ifdef GnuradioIIO_FOUND
inline gr::iio::fmcomms2_source<gr_complex>::sptr cast_to_iio_sptr(gr::basic_block_sptr p) {
return boost::dynamic_pointer_cast<gr::iio::fmcomms2_source<gr_complex>, gr::basic_block>(p);
}
#endif // GnuradioIIO_FOUND
#else
inline osmosdr::source::sptr cast_to_osmo_sptr(gr::basic_block_sptr p) {
return std::dynamic_pointer_cast<osmosdr::source, gr::basic_block>(p);
}
inline gr::uhd::usrp_source::sptr cast_to_usrp_sptr(gr::basic_block_sptr p) {
return std::dynamic_pointer_cast<gr::uhd::usrp_source, gr::basic_block>(p);
}
#ifdef GnuradioIIO_FOUND
inline gr::iio::fmcomms2_source<gr_complex>::sptr cast_to_iio_sptr(gr::basic_block_sptr p) {
return std::dynamic_pointer_cast<gr::iio::fmcomms2_source<gr_complex>, gr::basic_block>(p);
}
#endif // GnuradioIIO_FOUND

#endif
};
#endif
Loading