blob: 5311dbe1b299b29a580bd78daebbfea96792fec9 [file] [log] [blame]
Pau Espin Pedrolf570b4a2018-09-20 15:02:03 +02001[[code_architecture]]
2== Code Architecture
3
4[[fig-code-architecture-general]]
5.General overview of main OsmoTRX components
6[graphviz]
7----
8digraph hierarchy {
9node[shape=record,style=filled,fillcolor=gray95]
10edge[dir=back, arrowtail=empty]
11
Pau Espin Pedrol8fd51cb2024-03-26 18:14:08 +0100122[label = "{Transceiver|+ constructor()\l+ destructor()\l+ init()\l+ numChans()\l+ receiveFIFO()\l+ setSignalHandler()\l}"]
Pau Espin Pedrolf570b4a2018-09-20 15:02:03 +0200133[label = "{RadioInterface|...}"]
144[label = "{RadioInterfaceResamp|...}"]
155[label = "{RadioInterfaceMulti|...}"]
166[label = "{RadioDevice|...}"]
177[label = "{UHDDevice|...}"]
188[label = "{LMSDevice|...}"]
199[label = "{USRPDevice|...}"]
Pau Espin Pedrolc5f623f2024-03-26 16:17:59 +01002010[label = "{IPCDevice|...}"]
Pau Espin Pedrolf570b4a2018-09-20 15:02:03 +020021
222->3[arrowtail=odiamond]
233->4[constraint=false]
243->5[constraint=false]
253->6[arrowtail=odiamond]
266->7
276->8
286->9
Pau Espin Pedrolc5f623f2024-03-26 16:17:59 +0100296->10
Pau Espin Pedrolf570b4a2018-09-20 15:02:03 +020030}
31----
32
33[[fig-code-architecture-threads]]
34.Example of thread architecture with OsmoTRX configured to use 2 logical RF channels (Trx=Transceiver, RI=RadioIface)
35[graphviz]
36----
37digraph hierarchy {
38node[shape=record,style=filled,fillcolor=gray95]
39
40trans [label="Transceiver"];
41radioiface [label="RadioInterface"];
42radiodev [label="RadioDevice"];
43
Pau Espin Pedrolc62a0512020-07-01 12:24:52 +020044trans:nw->trans:ne [label="Main"];
Pau Espin Pedrolf570b4a2018-09-20 15:02:03 +020045trans:w->radioiface:w [label="Trx.TxPriorityQueueServiceLoop_0"];
46trans:w->radioiface:w [label="Trx.TxPriorityQueueServiceLoop_1"];
47radioiface:e->trans:e [label="Trx.RxServiceLoop_0"];
48radioiface:e->trans:e [label="Trx.RxServiceLoop_1"];
49radioiface->radiodev[label="RI.AlignRadioServiceLoop"];
50radioiface:sw->radiodev:nw [label="Trx.TxLowerLoop"];
51radiodev:ne->radioiface:se [label="Trx.RxLowerLoop"];
52}
53----
54
55[[code_component_transceiver]]
56=== Transceiver
57
58The Transceiver is the main component managing the other components running in
59the OsmoTRX process. There's a unique instance per process.
60
61This class is quite complex from code point of view, as it starts lots of
62different threads and hence the interaction with this class from the outside is
63quite limited. Only interaction possible is to:
64
65* `Transceiver()`: Create an instance through its constructor, at this time most
66 configuration is handed to it.
67* `init()`: Start running all the threads.
68* `receiveFIFO()`: Attach a `radioInterface` channel FIFO in order to use it.
69* `setSignalHandler()`: Used to set up a callback to receive certain events
70 asynchronously from the Transceiver. No assumptions can be made about from
71 which thread is the callback being called, which means multi-thread locking
72 precautions may be required in certain cases, similar to usual signal handler
73 processing. One important event received through this path is for instance
74 when the Transceiver detected a fatal error which requires it to stop. Since
75 it cannot stop itself (see destructor below), stopping procedure must be
76 delegated to the user who created the instance.
77* `~Transceiver()`: The destructor, which stops all running threads created at
78 `init()` time. Destroying the object is the only way to stop the `Transceiver`
79 completely, and must be called from a thread not managed by the
80 `Transceiver`, otherwise it will deadlock. Usually it is stopped from the main
81 thread, the one that called the constructor during startup.
82
83During `init()` time, `Transceiver` will create a noticeable amount of threads,
84which may vary depending on the amount of RF channels requested.
85
86Static amount of Threads (1 per `Transceiver` instance):
87
88* `RxLowerLoop`: This thread is responsible for reading bursts from the
89 `RadioInterface`, storing them into its FIFO and sending Clock Indications
90 (<<trx_if_clock_ind>>) to _osmo-bts_trx_.
91* `TxLowerLoop`: Manages pushing bursts from buffers in the FIFO into the
92 `RadioInterface` at expected correct time based on the Transceiver clock.
93
94Dynamic amount of Threads (1 per RF logical channel on the `Transceiver` instance):
95
Pau Espin Pedrolf570b4a2018-09-20 15:02:03 +020096* `RxServiceLoop`: Each thread of this type pulls bursts from the
97 `RadioInterface` FIFO for one specific logical RF channel and handles it
98 according to the slot and burst correlation type, finally sending proper data
99 over the TRX Manager UDP socket (<<trx_if>>).
100* `TxPriorityQueueServiceLoop`: Blocks reading from one ARFCN specific TRX
101 Manager UDP socket (<<trx_if>>), and fills the `RadioInterface` with it
102 setting clock related information.
103
Pau Espin Pedrolc62a0512020-07-01 12:24:52 +0200104All the Per-ARFCN Control Interface socket (<<trx_if_control>>) commands are
105handled by the event loop runnnig on the main thread. This is the only thread
106expected to use the private `start()` and `stop()` methods.
107
Pau Espin Pedrolf570b4a2018-09-20 15:02:03 +0200108[[code_component_radioiface]]
109=== RadioInterface
110
111The `RadioInterface` sits between the `Transceiver` and the `RadioDevice`, and
112provides extra features to the pipe like channelizers, resamplers, Tx/Rx
113synchronization on some devices, etc.
114
115If the `RadioDevice` it drives requires it (only _USRP1_ so far), the
116`RadioIntercace` will start and manage a thread internally called
117`AlignRadioServiceLoop` which will align current RX and TX timestamps.
118
119Different features are offered through different `RadioInterface` subclasses
120which are selected based on configuration and device detected at runtime. Using
121these features may impact on the amount of CPU required to run the entire pipe.
122
123==== RadioInterfaceResamp
124
125This subclass of `RadioInterface` is automatically selected when some known
126specific UHD are to be used, since they require resampling to work properly.
127Some of this devices are for instance Ettus B100, USRP2 and X3XX models.
128
129==== RadioInterfaceMulti
130
131This subclass of `RadioInterface` is used when <<multiarfcn_mode>> is requested.
132
133[[code_component_radiodev]]
134=== RadioDevice
135
136The `RadioDevice` class is responsible for driving the actual Hardware device.
137It is actually only an interface, and it is implemented in each backend which in
138turn becomes a specific OsmoTRX binary, see <<trx_backends>>.