[[trx_backends]]
== OsmoTRX backend support

[[backend_uhd]]
=== `osmo-trx-uhd` for UHD based Transceivers

This OsmoTRX model uses _libuhd_ (UHD, USRP Hardware Driver) to drive the
device, that is configuring it and reading/writing samples from/to it.

So far, this backend has been mostly used to drive devices such as the Ettus
B200 family and Fairwaves UmTRX family, and used to be the default backend used
for legacy @osmo-trx@ binary when per-backend binaries didn't exist yet.

Any device providing generic support for UHD should theoretically be able to be
run through this backend without much effort, but practical experience showed
that some devices don't play well with it, such as the LimeSDR family of
devices, which showed far better results when using its native interface.

Related code can be found in the _Transceiver52M/device/uhd/_ directory in
_osmo-trx.git_.

[[backend_lms]]
=== `osmo-trx-lms` for LimeSuite based Transceivers

This OsmoTRX model uses LimeSuite API and library to drive the device, that is
configuring it and reading/writing samples from/to it.

This backend was developed in order to be used together with LimeSDR-USB and
LimeSDR-mini devices, due to to the poor results obtained with the UHD backend,
and to simplify the stack.

Related code can be found in the _Transceiver52M/device/lms/_ directory in
_osmo-trx.git_.

[[backend_usrp1]]
=== `osmo-trx-usrp1` for libusrp based Transceivers

This OsmoTRX model uses the legacy libusrp driver provided in GNU Radio 3.4.2.

As this code was dropped from GNU Radio at some point and was found very
difficult to build, some work was done to create a standalone libusrp which can
be nowadays found as a separate git repository together with other osmocom git
repositories, in https://git.osmocom.org/libusrp/

Related code can be found in the _Transceiver52M/device/usrp1/_ directory in
_osmo-trx.git_.

The USRPDevice module is basically a driver that reads/writes packets to a USRP
with two RFX900 daughterboards, board A is the Tx chain and board B is the Rx
chain.

The `radioInterface` module is basically an interface between the transceiver
and the USRP. It operates the basestation clock based upon the sample count of
received USRP samples.  Packets from the USRP are queued and segmented into GSM
bursts that are passed up to the transceiver; bursts from the transceiver are
passed down to the USRP.

The transceiver basically operates "layer 0" of the GSM stack, performing the
modulation, detection, and demodulation of GSM bursts.  It communicates with the
GSM stack via three UDP sockets, one socket for data, one for control messages,
and one socket to pass clocking information. The transceiver contains a priority
queue to sort to-be-transmitted bursts, and a filler table to fill in timeslots
that do not have bursts in the priority queue.  The transceiver tries to stay
ahead of the basestation clock, adapting its latency when underruns are reported
by the radioInterface/USRP. Received bursts (from the radioInterface) pass
through a simple energy detector, a RACH or midamble correlator, and a DFE-based
demodulator.

By default, osmo-trx-usrp1 will use daughterboard A for transmitting and
daughterboard B for receiving. Some USRP1 configurations use only a single
daughterboard for both TX and RX, and thus the receiver will not work as
daughterboard B does not exist. Daughterboard A can be configured to be used
for both TX and RX with `usrp1-singledb enable`.

NOTE: There's a `SWLOOPBACK` #define statement, where the USRP is replaced
with a memory buffer. In this mode, data written to the USRP is actually stored
in a buffer, and read commands to the USRP simply pull data from this buffer.
This was very useful in early testing, and still may be useful in testing basic
Transceiver and radioInterface functionality.


[[backend_ipc]]
=== `osmo-trx-ipc` Inter Process Communication backend

This OsmoTRX model provides its own Inter Process Communication (IPC) interface
to drive the radio device driver (from now on the Driver), allowing for third
party processes to implement the lowest layer device-specific bits without being
affected by copyleft licenses of OsmoTRX.

For more information on such interface, see section <<ipc_if>>.

[[fig-backend-ipc]]
.Architecture with _osmo-trx-ipc_ and its IPC _Driver_
[graphviz]
----
digraph G {
        rankdir=LR;
        MS0 [label="MS"];
        MS1 [label="MS"];
        OsmoTRX [label="osmo-trx-ipc", color=red];
        BTS;

        subgraph cluster_ipc_driver {
                label = "IPC Driver";
                color=red;
                RE [label = "Radio Equipment"];
                REC [label="Radio Equipment Controller"];
                RE->REC;
        }

        REC->OsmoTRX [label="IPC Interface", color=red];

        MS0->RE [label="Um"];
        MS1->RE [label="Um"];
        OsmoTRX->BTS [label="bursts over UDP"];

}
----

A sample config file for this OsmoTRX model can be found in _osmo-trx.git_ https://gitea.osmocom.org/cellular-infrastructure/osmo-trx/src/branch/master/doc/examples/osmo-trx-ipc/osmo-trx-ipc.cfg[doc/examples/osmo-trx-ipc/osmo-trx-ipc.cfg]

In the config file, the following VTY command can be used to set up the IPC UD Master Socket _osmo-trx-ipc_ will connect to at startup:

.Example: _osmo-trx-ipc_ will connect to UD Master Socket /tmp/ipc_sock0 upon startup
----
dev-args ipc_msock=/tmp/ipc_sock0
----

==== ipc-device-test

When built with `--with-ipc --with-uhd` configure options, _osmo-trx.git_ will
build the test program called _ipc-driver-test_. This program implements the
_Driver_ side of the osmo-trx-ipc interface (see <<ipc_if>> for more
information) on one side, and also interacts internally with UHD (eg B210 as
when using osmo-trx-uhd).

You can use this small program as a reference to:

* Test and experiment with _osmo-trx-ipc_.

* Write your own IPC _Driver_ connecting to osmo-trx-ipc.

[[fig-backend-ipc-device-test]]
.Architecture with _osmo-trx-ipc_ and ipc-device-test as IPC _Driver_
[graphviz]
----
digraph G {
        rankdir=LR;
        MS0 [label="MS"];
        MS1 [label="MS"];
        SDR;
        ipc_device_test[label = "ipc-device-test", color=red];
        OsmoTRX [label="osmo-trx-ipc", color=red];
        BTS;

        MS0->SDR [label="Um"];
        MS1->SDR [label="Um"];
        SDR->ipc_device_test [label="UHD"];
        ipc_device_test->OsmoTRX [label="IPC Interface", color=red];
        OsmoTRX->BTS [label="bursts over UDP"];
}
----

The code for this app is found here:

* https://gitea.osmocom.org/cellular-infrastructure/osmo-trx/src/branch/master/Transceiver52M/device/ipc/ipc-driver-test.h[Transceiver52M/device/ipc/ipc-driver-test.h]

* https://gitea.osmocom.org/cellular-infrastructure/osmo-trx/src/branch/master/Transceiver52M/device/ipc/ipc-driver-test.c[Transceiver52M/device/ipc/ipc-driver-test.c]

Those files use the server-side (_Driver_ side) code to operate the Posix Shared
Memory region implemented in files `shm.c`, `shm.h`, `ipc_shm.c` and `ipc_shm.h`
in the same directory.

Most of the code in that same directory is deliverately released under a BSD
license (unlike most of _osmo-trx.git_), allowing third parties to reuse/recycle
the code on their implemented _Driver_ program no matter it being proprietary or
under an open license. However, care must be taken with external dependencies,
as for instance shm.c uses the talloc memory allocator, which is GPL licensed
and hence cannot be used in a proprietary driver.
