Amarisoft

SoapySDR - Package Installation

The purpose of this tutorial is to get the Amarisoft SoapySDR support module and its example programs working on a machine as quickly as possible, starting from a packaged release instead of from source you have to understand first. You copy one archive to the target, unpack it, and run a single script. The script checks the machine, installs whatever is missing, puts the tree in '/root/soapy_project', builds every component, and then confirms that the SoapySDR runtime has actually registered the 'amarisoft' factory. Taking it off again is one more script.

What you have once it is installed:

NOTE : This tutorial is about installing and keeping the package, not about how the support module works inside. If you want to understand what is in it and build it from the ground up yourself, read SoapySDR instead. Both describe the same module: this one hands it to you, that one explains it.

Table of Contents

Introduction

A SoapySDR support module is only useful once it is on the machine that owns the radio, and getting it there is a different problem from writing it. The module links the Amarisoft 'libsdr' library and records that library's location as an RPATH at build time, and it is loaded only by a SoapySDR runtime whose ABI version matches the one it was compiled against, so a binary produced on one machine will generally neither resolve nor load on another. The package described here therefore ships source rather than binaries: a single directory tree, a little over two hundred kilobytes, holding the support module, two C++ example programs, the Python and Octave examples, the probe programs that document 'libsdr' behaviour below the SoapySDR layer, and the scripts that build, exercise and remove all of it. Installing is a matter of unpacking that tree on the target and running one script, which establishes whether a radio is live on the machine, installs whatever distribution packages are missing, puts the tree in its permanent location, compiles every component in the order they depend on each other, and then asks the SoapySDR runtime whether the factory actually registered - a question worth asking separately, because a module can compile and install successfully and still fail to load. The same tree carries the script that packages it for the next machine and the script that removes what was installed, so a release can be moved, rebuilt, verified and withdrawn without any step being done by hand. This tutorial covers that lifecycle on a Fedora based Amarisoft callbox or UE simulator, including the deliberate separation between the unpacked release and the working tree that keeps your own files intact across upgrades, and the one class of dependency that no script can install for you: the licensed Amarisoft trx_sdr SDK and the 'sdr' kernel module that creates the '/dev/sdrN' nodes.

Summary of the Tutorial

This tutorial covers the whole deployment lifecycle of the 'soapy_project' package: unpacking it on a target machine, installing and building it there, proving the result against real hardware, packaging it again for the next machine, and removing it. Every listing shown on the page is the output of a real run on a bench machine rather than an illustration, including the ones where something is missing.

 

Installing/Uninstalling soapy_project package

Everything described in this tutorial - the support module, the two C++ programs, the Python and Octave examples and the probe programs - lives in a single directory tree called 'soapy_project'. This section covers moving that tree to another machine, building it there, and removing it again afterwards.

One rule governs the whole process: build on the machine that will run it. The support module links the Amarisoft libsdr and records that library's location as an RPATH at build time, so a binary compiled elsewhere will not resolve unless trx_sdr happens to sit at the identical path. The module is also loaded only by a SoapySDR runtime with a matching ABI. Both problems disappear if the source is shipped and compiled in place, which is what the scripts below do.

Manual Installation

Download the package here and copy it into '/root' on the machine that will run it. The archive is small, about two hundred kilobytes, because it holds source only and no build output. It expands into a single directory named after the archive itself, 'soapy-project-pack-xxxxxx', rather than into one called 'soapy_project'.

That naming is deliberate. The unpacked directory is the delivery, not the working tree: unpacking can never write into a release that is already there, and never into the tree you work in. Unpacking an archive over an existing directory merges the two rather than replacing it - tar overwrites the files it carries, leaves everything else where it was, and deletes nothing - so a shared name would produce a tree that is part one release and part another.

The working tree is '/root/soapy_project', and it is a real directory. Installing copies the release into it. The files the package carries are replaced; everything else in there is left exactly as it was, which is the whole point of copying rather than pointing a symlink at the unpacked release. A capture you left in the tree, a note, a script of your own, an example you edited - all of it is still there after the next release is installed. A symlink cannot do that: re-pointing it at a new release does not delete the old tree, but everything in it disappears from '/root/soapy_project', because that name now means somewhere else.

The fixed location matters for a second reason as well. '/root/soapy_project' is the path in the tutorials, in the Octave 'addpath' line and in every example command, and each build directory records its own absolute path inside CMakeCache.txt. Keeping one real directory keeps all of that true, and keeps one set of build directories rather than one per release.

[root@target ~]# cd /root

[root@target ~]# tar xzf soapy-project-pack-20260921.tar.gz -C /root  //the package file name varies with the release

[root@target ~]# cd soapy-project-pack-20260921

[root@target soapy-project-pack-20260921]# ./install.sh

That is the whole deployment: unpack, enter the unpacked directory, run the script. Everything after that happens in '/root/soapy_project' - the copy, the build and the install - and the unpacked release can be deleted once it is in, or kept as a record of what was shipped.

'install.sh' establishes first whether a radio is live on the machine, then checks every dependency and installs the ones that are missing, reports where the tree is going and copies it there, builds everything that has something to compile - the support module, the two C++ programs, the Octave binding and the probe programs, in the order they depend on each other - and finishes by confirming that the SoapySDR runtime has actually registered the factory. That last step matters: a module can compile and install successfully and still fail to load, and the build reports success either way.

Run it a second time from '/root/soapy_project' itself and it recognises that it is already there, copies nothing, and rebuilds in place. That is the ordinary way to rebuild after editing something in the tree. A machine still carrying the older layout, where '/root/soapy_project' is a symlink to an unpacked release, is handled too: the link is replaced by a real directory holding this release, and the directory it pointed at is left alone, so anything in it can still be fetched afterwards.

NOTE : The copy is a merge, not a replacement, and the difference is worth being clear about. Files the package carries are overwritten - an example you edited in place is replaced by the shipped version, so keep a copy elsewhere if you have changed one. Files the package does not carry are untouched. Files that existed in an older release and have since been dropped from the package stay behind, because nothing deletes them; 'rm -rf /root/soapy_project' before installing is the way to get a tree that is exactly the release and nothing else.

The state of the bench is established before anything else, because two things here can disturb a running radio. A package transaction can pull a library out from under a live 'lteenb', and 'make install' copies the rebuilt module over the installed one in place rather than atomically, so a process holding it mapped can fault in the middle of a run. The script looks for an active lte service, for 'lteenb', 'lteue', 'ltemme' or 'ltembms', for any process holding a '/dev/sdrN' node, and for any process with the installed module mapped; any of those stops the run before the package manager is called, and names what to stop and how. '--ignore-running' overrides it, and '--check' reports the same state and carries on, since it changes nothing.

[root@target soapy_project]# ./install.sh  //rebuilding in place: no copy, this is already the tree

Several other modes are available. '--check' reports what is missing and stops, installing and building nothing, which is the safe way to find out whether a machine is ready; it runs to the end even on a machine that has none of the dependencies yet. '--no-deps' never calls the package manager: it builds with what is already installed, and stops only when something the build genuinely needs is absent - Python and Octave are treated as optional, because the build skips what they would have produced rather than failing. '--no-octave' leaves Octave out altogether, which is worth knowing because it is the one large dependency here: one package carries both front ends, pulls in a TeX installation, and costs roughly 750 MB.

./install.sh --check                # report only; install and build nothing

./install.sh --no-deps              # build with what is here; never call the package manager

./install.sh --no-octave            # skip octave/ and its ~750 MB of packages

./install.sh --ignore-running       # install even though a radio is live on this machine

 

# if trx_sdr is not at the default /root/trx_sdr:

TRX_SDR_ROOT=/root/trx_sdr-linux-2026-08-18 ./install.sh

 

# to keep the tree somewhere other than /root/soapy_project:

SOAPY_PROJECT_DIR=/opt/soapy_project ./install.sh

The output below is a real deployment of this release onto a second machine, which differs from the development machine in several ways at once - half the cores, two SDR boards rather than four, and no Octave installed at all - and none of it needed adjusting for. It was run with '--no-deps', so the package manager was never called: Octave is the only thing missing there, it is optional, and the run says so and carries on to build everything else. That machine already had a '/root/soapy_project' from an earlier release, so the run reports that it is copying over it; on a machine that has never had one, the same line reads 'will be created'.

=== bench state ===
  [ ok ] nothing running: no lte process, no /dev/sdrN held, module not in use

=== dependencies ===
  [ ok ] SoapySDR runtime
  [ ok ] SoapySDR headers
  [ ok ] cmake
  [ ok ] C++ compiler
  [ ok ] C compiler (for probe/)
  [ ok ] make
  [ ok ] python3 interpreter (for python/)
  [ ok ] python3 SoapySDR bindings (for python/)
  [ ok ] python3 numpy (for python/)
  [ ok ] python3 matplotlib (for python/plot_spectrum.py)
  [ -- ] octave-cli, terminal front end (for octave/)  (package: octave)
  [ -- ] octave --gui, windowed front end  (package: octave)
  [ -- ] mkoctfile, to build octave/ (for octave/)  (package: octave-devel)

missing: octave octave-devel
--no-deps was given, so nothing will be installed.  None of these
is needed to build the tree; whatever uses them is skipped below.

=== SoapySDR version ===
  [ ok ] API v0.7.1, ABI v0.7 (the version this tree was tested against)

=== Amarisoft components ===
  [ ok ] trx_sdr SDK at /root/trx_sdr
  [ ok ] device nodes: /dev/sdr0 /dev/sdr1

=== install location ===
  [ ok ] /root/soapy_project exists - this release will be copied over it
         The files this package carries are replaced.  Anything else
         in there is left alone.

=== installing the tree into /root/soapy_project ===
  [ ok ] copied from /root/soapy-project-pack-20260921-5

=== building ===
  SoapyAmarisoft   ok
  hellosoapy       ok
  detectssb        ok
  octave           skipped (mkoctfile not installed)
  probe            ok (8 programs)
  python           ok (8 programs)

=== verify ===
  Module found: /usr/local/lib64/SoapySDR/modules0.7/libamarisoftSupport.so
  Available factories... amarisoft

Basic Operation Check

The obvious next step is to prove the installation against real hardware, which is what 'hellosoapy' is for. On that same machine, pinned to the second board because the first was in use, it passed nine checks and skipped the transmit group - those checks key the TX port, and are run only when '--tx' is given.

[root@target soapy_project]# ./hellosoapy/build/hellosoapy /dev/sdr1

-> PASS: 1. Module loaded and factory registered
-> PASS: 2. Device enumeration
   ...
   tuned to 2140     MHz in 141.766  ms | 6144000   samples | mean -52.5356 dBFS
-> PASS: 8. Retune while streaming

-- SKIP: TX and loopback (pass --tx to include them; they key the TX port)

-> PASS: 11. Out-of-range frequency guard

============================================================
  passed: 9   failed: 0   skipped: 1   device: /dev/sdr1
============================================================

The package was produced from a working tree by 'make_tarball.sh', which is included in it. If you modify the sources and want to move them to another machine, run that script and a dated archive appears alongside them, named 'soapy-project-pack-YYYYMMDD.tar.gz' and carrying a top level directory of that same name. A second pack on the same day gets a '-2' suffix rather than quietly taking the first one's name, since the name is also the directory it will unpack into on the target. The script finishes by printing the exact deploy commands for the pack it has just built - the 'scp', the 'tar', the 'cd' and the './install.sh' - with the real names filled in. The suffix only ever counts upward, so a pack never inherits the name of one that has been deleted here and may still be in somebody else's hands.

It excludes the build directories deliberately, because CMake writes absolute paths into its cache and a build tree carried to a different location refers to directories that no longer exist, failing in a way that is hard to read. The compiled artefacts are left out for the same reason: 'octave/build/soapy.oct' carries both the Octave and the SoapySDR ABI of the machine that built it and is loaded only by a matching pair, so it is rebuilt on the target rather than shipped.

NOTE : Only the Amarisoft parts cannot be installed automatically. The trx_sdr SDK is part of the licensed release, so 'install.sh' stops and tells you how to point at it; the 'sdr' kernel module has to be loaded by the Amarisoft installation, and its absence produces a warning rather than an error, because the tree still builds without hardware present.

Basic Health Check

What I wants to recommend to do as next step is try basic health check.

'hellosoapy' proves the module against the hardware; 'healthcheck_sw.sh' goes one step further and checks every program in the tree. It builds anything that is not yet built, then runs each program the way it is meant to be run and checks that it exits the way it is supposed to. It answers the question "does the software still work", not "is there a signal on the air", so nothing needs to be transmitting: the SSB detectors are expected to find nothing on a bare bench, and that counts as healthy. Run it from the working tree:

[root@target ~]# cd /root/soapy_project

[root@target soapy_project]# ./healthcheck_sw.sh

Without arguments the script picks the first board that no other process has open. If every board is busy, for example because a gNB is running on it, it stops and says so rather than interfering. The following options change what it does:

./healthcheck_sw.sh              # build if needed, then check everything

./healthcheck_sw.sh --quick      # only what needs no radio

./healthcheck_sw.sh --tx         # also run the checks that key the TX port

./healthcheck_sw.sh --no-build   # check what is already built; build nothing

./healthcheck_sw.sh /dev/sdr1    # pin a board instead of auto-selecting

The run below is from a machine with two AD9361 boards, both free, so '/dev/sdr0' was selected. The checks are grouped in the order they run: the build, the environment (SoapySDR finds the module, the Python and Octave bindings load), checks that need no radio (help text, DSP self tests), input validation (every program must reject a bad argument rather than hang or crash), and then the live checks on the board. The live part streams at every sample rate the board reports, runs the C++, Python and Octave programs against real hardware, and runs the 'probe' programs that pin down 'libsdr' behaviour. The whole run took just over a minute.

--- build ---
PASS   build SoapyAmarisoft
PASS   build hellosoapy
PASS   build detectssb
PASS   build probe/*.c                                8 programs

--- environment ---
PASS   SoapySDR sees the module
PASS   python3 SoapySDR + numpy
PASS   python scripts parse
PASS   octave loads the soapy binding

--- self contained checks (no radio) ---
PASS   hellosoapy --help
PASS   detectssb --self-test (DSP)
   ...
PASS   gps_print.py --self-test

--- input validation (must reject, never hang or crash) ---
PASS   hellosoapy rejects --rate 25e6
PASS   hellosoapy rejects --rate 500e6
   ...
PASS   detect_ssb.m requires --arfcn

Using device: /dev/sdr0
  board rates  : 1.92 3.84 7.68 15.36 23.04 30.72 61.44 MHz
  using        : low=1.92 mid=15.36 scs=30
  reconfigure  : ~1s per stop/start cycle (measured)
  live checks  : roughly 4m22s (~82 reconfigures)

--- module test suite ---
PASS   SoapyAmarisoft run_tests.sh

--- hellosoapy ---
PASS   hellosoapy RX suite
PASS   hellosoapy at 1.92 Msps

--- sample rate sweep (every rate this board reports) ---
  board reports: 1.92 3.84 7.68 15.36 23.04 30.72 61.44 MHz
PASS   RX at 1.92 Msps
   ...
PASS   RX at 61.44 Msps

--- detectssb (live) ---
PASS   detectssb live RX

--- python (live) ---
PASS   rx_minimal.py
PASS   detect_ssb.py
PASS   detect_ssb_fast.py
PASS   plot_spectrum.py

--- octave (live) ---
PASS   rx_minimal.m
PASS   detect_ssb.m

--- probe programs ---
PASS   probe  (libsdr basics)
PASS   probe2 (start params)
PASS   probe4 (min read count)
PASS   probe5 (channel counts)
PASS   probe6 (5 start/stop cycles)

--- probe programs that fail on purpose ---
PASS   probe3 (invalid freq is fatal in libsdr)       died as designed (exit 1)
PASS   probe7 (dump_info before start segfaults)      died as designed (exit 139)
PASS   probe8 (gain limits before start segfault)     died as designed (exit 139)

============================================================
  passed: 59   failed: 0   skipped: 0   device: /dev/sdr0
  detail: /root/soapy_project/healthcheck_sw.log
============================================================

NOTE : Pay special caution to "--- sample rate sweep (every rate this board reports) ---" since you will see the great differences depending on sdr type (sdr 50 vs sdr 100).

The live checks are timed from the board itself. Before they start, the script measures how long one stop and restart of the board takes and sets every timeout from that figure. This matters because the boards differ widely: an AD9361 board does it in about a second, as here, while an SDR100 runs a full AD9371 initialisation each time and takes about 32 seconds. Fixed timeouts that suit one board would make the other look as if it had hung. The time estimate printed under 'live checks' is an upper bound built from that measurement, which is why this run finished well inside it.

Three results in the last group are crashes, and they are reported as PASS on purpose. 'probe3' tunes to an out-of-range frequency to show that 'libsdr' ends the process, and 'probe7' and 'probe8' call 'libsdr' functions before the board is started to show that they segfault. These are the 'libsdr' limits the module guards against, so a clean exit from one of them would mean the limit has changed, and that is reported as a failure.

The script exits with status 0 only when nothing failed, so it can be used in scripts as well as by hand. The full output of every check, including the build logs, is written to '/root/soapy_project/healthcheck_sw.log'. Look there first when a check fails.

NOTE : As with 'hellosoapy', the transmit checks run only when '--tx' is given, because they key the TX port. Without it 'hellosoapy' runs its RX suite only, which is why the run above shows no skipped checks. Only use '--tx' when the TX port is terminated or cabled to something that can take the signal.

Install with AI Agent

The scripts were written so that a coding agent with shell access can carry out the whole procedure without further instruction, which is worth mentioning because it is how this package was developed and tested in the first place. Given the tarball and an SSH login, an agent such as Claude Code can copy it across, install it, run the checks and report back.

Copy soapy-project-pack-20260921.tar.gz to root@aaa.bbb.ccc.ddd (password: ****),

unpack it under /root, run ./install.sh from the unpacked directory, and run

hellosoapy on /dev/sdr1 to confirm it works. /dev/sdr0 is in use.

Three properties of the scripts make this work reliably rather than by luck. Every failure message names the thing to fix rather than merely reporting that something went wrong, so an agent can act on it instead of guessing. Every step has a non-destructive form - 'install.sh --check' and 'uninstall.sh --check' - which lets an agent establish the state of a machine before changing it. And every script ends by verifying the result independently of the step that produced it, so success is confirmed rather than assumed.

The same properties help a human, and the workflow is worth using in reverse as well: when something does go wrong, the build logs are left in '/tmp/build_*.log' and the checks can be re-run individually, which gives an agent enough to diagnose the problem rather than simply reporting a failure.

NOTE : An agent asked to install software will modify the machine, so the usual care applies. Give it a specific target rather than a general instruction, prefer '--check' first on a machine you care about, and remember that 'install.sh' installs packages with the system package manager. Nothing in this package touches the Amarisoft installation itself, but that is a property of these scripts rather than a guarantee about agents in general.

Uninstalling the package

'uninstall.sh' reverses what 'install.sh' did. 'install.sh' puts exactly one file on the system - the support module - and by default that one file is all this removes. The build directories stay unless '--build' or '--all' asks for them, and the distribution packages are never removed at all.

[root@target ~]# cd /root/soapy_project

[root@target soapy_project]# ./uninstall.sh

=== installed module ===
  /usr/local/lib64/SoapySDR/modules0.7/libamarisoftSupport.so

removed /usr/local/lib64/SoapySDR/modules0.7/libamarisoftSupport.so

=== verify ===
  SoapySDR no longer lists an amarisoft factory
  clean

Reinstall with: ./install.sh

The file to remove is taken from 'install_manifest.txt', which CMake writes at install time listing exactly what it placed on the system. That is more dependable than guessing a path, and it is why the build directories are removed last rather than first. If the build tree has already been deleted the script falls back to searching the SoapySDR module directories by name.

Packages are deliberately not touched, and there is no option to remove them. Other software on the machine is likely to depend on the same ones, and removing the SoapySDR runtime in particular would take the whole module system with it, including modules this package never installed. Anything 'install.sh' added - SoapySDR, SoapySDR-devel, cmake, gcc-c++, make, the python3 modules, Octave - has to be removed by hand if that is really wanted.

./uninstall.sh --check          # list what would be removed, remove nothing

./uninstall.sh --build          # also delete the build/ directories

./uninstall.sh --all            # module and build directories together

 

# the tree itself is never removed by the script, because what is in it

# is yours. To remove it, and the unpacked release it came from:

rm -rf /root/soapy_project

rm -rf /root/soapy-project-pack-YYYYMMDD

The script finishes by asking SoapySDR whether the factory is still registered, which is the same check the installation used and confirms the removal from the runtime's point of view rather than the filesystem's. If a copy of the module survives somewhere else on the search path, this is where it shows up.

Using the Module from an Application

Once the module is installed, an application opens the card the same way it would open any other SoapySDR device. The only Amarisoft specific element is the 'driver=amarisoft' argument, and optionally a 'device' argument naming which board to use. If 'device' is omitted, the first '/dev/sdrN' node found is used.

SoapySDR::Kwargs args;

args["driver"] = "amarisoft";

args["device"] = "/dev/sdr2";

auto *dev = SoapySDR::Device::make(args);

 

dev->setSampleRate(SOAPY_SDR_RX, 0, 23.04e6);

dev->setFrequency  (SOAPY_SDR_RX, 0, 2140e6);

dev->setGain       (SOAPY_SDR_RX, 0, 40);

 

auto *rx = dev->setupStream(SOAPY_SDR_RX, SOAPY_SDR_CF32, {0});

dev->activateStream(rx);

 

std::vector<std::complex<float>> buf(dev->getStreamMTU(rx));

void *buffs[] = { buf.data() };

int flags; long long timeNs;

int n = dev->readStream(rx, buffs, buf.size(), flags, timeNs, 1000000);

Because SoapySDR device arguments are themselves comma separated key and value pairs, the 'libsdr' multi-board syntax composes naturally. Passing 'dev0' and 'dev1' opens two boards as a single synchronised device, exactly as the underlying library expects.

driver=amarisoft,dev0=/dev/sdr0,dev1=/dev/sdr1

The device arguments below are recognised at construction time. Most of them mirror a normal setter and exist so that a device can be fully configured from a single argument string, which is convenient for applications such as GQRX that only offer one device string field.

device / path / node   single board to open (default: first found)

dev0, dev1, ...        multi-board form passed to msdr_open

rx_channels / tx_channels   channels advertised (default 2 / 2)

probe_info             allow a brief start to read board identity

sample_rate, frequency, rx_freq, tx_freq, rx_gain, tx_gain,

bandwidth, rx_antenna, clock_source, time_source, log_level

At run time, the settings interface exposes the knobs specific to this hardware. They are listed by 'SoapySDRUtil --probe' and can be changed with 'writeSetting'. The two most useful are 'auto_restart', which controls whether a configuration change while streaming triggers an immediate restart, and 'tx_max_lead_us', which controls the transmit throttle described earlier.

Supported Capabilities

Driver key         amarisoft

Hardware key       AD9361

Channels           2 RX, 2 TX per board, full duplex

Stream formats     CF32 (native, full scale 1.0), CS16

Frequency range    300 MHz .. 6 GHz accepted  (specified: 500 / 400 MHz up)

Sample rate        1 MHz .. 122.88 MHz continuous;

                  ladder n x 1.92 MHz, n = 1,2,3,6,9,12,16,18,24,32

RX gain            3 .. 71 dB below 4 GHz, 0 .. 62 dB above; AGC supported

TX gain            0 .. 89.75 dB

Antennas           RX: RX, TX_RX   TX: TX

Clock sources      internal, external, external_10mhz

Time sources       none, internal, gps, external, ptm, external_50

Sensors            fpga_temp, rx_overflow_count, tx_underflow_count,

                  abs_rx_power, abs_tx_power, gps_locked, info

The gain and bandwidth figures above are read from the board at run time and agree exactly with the values published in trx_sdr.doc: 0 to 89.75 dB of transmit gain, 3 to 71 dB of receive gain below 4 GHz narrowing to 0 to 62 dB above it, and an analogue bandwidth from under 200 kHz to 56 MHz. The frequency range is the one exception, and is discussed above: the figure quoted here is what the driver accepts, which is wider than the coverage specified in trx_sdr.doc and trx_sdr100.doc.

Limitations

The following limits are inherent to the current implementation or to the underlying library. They are listed here so that they are discovered before rather than during an experiment.

Directory Structure

The following summarises where everything ends up after a successful build and install, and which files are mandatory at run time.

NOTE : The tree above is the current release. The breakdown below it covers the support module in detail and was written at an early phase of the development, so the list of files there is the shorter one; it grows as the module does.

## 1. Project source tree

 

/root/soapy-project-pack-20260921-5/          the unpacked release: the delivery,

                                              which install.sh copies from and which

                                              can be deleted afterwards

 

/root/soapy_project/                          the working tree: a real directory,

                                              where everything below is built and kept

|  +-- install.sh, uninstall.sh               install and remove the module

|  +-- make_tarball.sh                        pack this tree for another machine

|  +-- healthcheck_sw.sh                      build and exercise everything

|  +-- SoapyAmarisoft/                        the support module, detailed below

|  +-- hellosoapy/                            hardware checks over the public API

|  +-- detectssb/                             real time SSB detector

|  +-- python/                                python examples

|  +-- octave/                                octave binding and examples

|  +-- probe/                                 libsdr behaviour probes

|  +-- anything you put here                  yours - captures, notes, your own

|                                             programs.  install.sh does not touch it

 

/root/soapy_project/SoapyAmarisoft/

|  +-- CMakeLists.txt                [MANDATORY] build definition

|  +-- SoapyAmarisoft.hpp            [MANDATORY] class + HW constants

|  +-- Registration.cpp              [MANDATORY] factory registration

|  +-- Settings.cpp                  [MANDATORY] control plane

|  +-- Streaming.cpp                 [MANDATORY] data plane

|  +-- build.sh, run_tests.sh       helper scripts

|  +-- README.md                     design + measured HW behaviour

|  +-- tests/soapy_amarisoft_test.cpp   test tool source

|  +-- build/                        created by cmake

|      +-- libamarisoftSupport.so     the module (before install)

|      +-- tests/soapy_amarisoft_test  test tool binary

 

## 2. Installed module

 

/usr/local/lib64/SoapySDR/modules0.7/

   +-- libamarisoftSupport.so       [MANDATORY] scanned by SoapySDR

                                         at library load time

 

## 3. SoapySDR files (from SoapySDR / SoapySDR-devel)

 

/usr/include/SoapySDR/             [MANDATORY] headers to build against

/usr/lib64/libSoapySDR.so          [MANDATORY] runtime library

/usr/share/cmake/SoapySDR/         [MANDATORY] SOAPY_SDR_MODULE_UTIL macro

 

## 4. Amarisoft SDK files required to build and run

 

/root/trx_sdr/                     symlink to the trx_sdr release

|  +-- api/libsdr.h                [MANDATORY] msdr_* API declarations

|  +-- api/libsdr.so               [MANDATORY] linked, and found via RPATH

|  +-- kernel/flags.h              [MANDATORY] included by libsdr.h

 

/dev/sdr0 .. /dev/sdr3             [MANDATORY] created by the sdr kernel

                                         module (lsmod | grep sdr)

                                         a board already opened by lteue or

                                         lteenb cannot be opened by SoapySDR