Skip to content

Loading builds...

Changes

#616 (Jul 29, 2026, 12:57:02 PM)

libosmo-trx/trxc: enlarge the params buffer

The SETFH command (implemented by trxcon and fake_trx) carries the
whole Mobile Allocation as pairs of Rx/Tx frequencies in kHz:

  CMD SETFH <HSN> <MAIO> <RXF1> <TXF1> [... <RXFN> <TXFN>]

With up to 64 ARFCNs in the Mobile Allocation, the parameters string
alone can exceed 1000 characters, far beyond the old 128 byte limit.

Derive OSMO_TRXC_PARAMS_LEN_MAX from OSMO_TRXC_MSG_BUF_SIZE, so that
any message ("RSP " + verb + status + params) still fits the
recommended socket buffer size.  Also add the OSMO_TRXC_CMD_SETFH
verb constant and a regression test doing a round-trip of a maximum
size SETFH command (64 ARFCNs).

Change-Id: I2f65b213f5ada499eea4abae87d3727057e03e22
Vadim Yanitskiy at

#615 (Jul 29, 2026, 12:57:01 PM)

libosmo-trx/trxc: add SETSLOT parameter parser/builder

Add struct osmo_trxc_setslot plus osmo_trxc_setslot_parse()/_build()
for the "<tn> <chan_comb> [C<tsc>/S<tsc_set> ...]" SETSLOT parameters,
including VAMOS combinations (VFF/VHH/VFH/HVHH) with per-sub-channel
TSC overrides.

Change-Id: I17a1176b1418edd0caf750d50acda0482d4ad04a
Vadim Yanitskiy at

#614 (Jul 29, 2026, 12:57:01 PM)

libosmo-trx: add TRXC/TRXD message codec

Introduce libosmo-trx: a shared implementation of the TRXC/TRXD
(OpenBTS-style TRX) protocol, to be used by osmo-trx, osmo-bts,
trxcon, and the upcoming C rewrite of fake_trx.

This initial version provides two I/O-free codec modules:

* trxd: TRXD PDU codec for BURST.ind and BURST.req
* trxc: verb-agnostic TRXC message codec (CMD/RSP/IND)

The codec logic is based on the existing implementations in
osmo-bts (f0ee51997470e1c3020ddb85082385ed43ba0c68).

Change-Id: I933fc417a67d0043f74b04626b7643c79e381492
Vadim Yanitskiy at

#613 (Jul 29, 2026, 12:57:01 PM)

libosmo-trx/ep: add TRX endpoint module

Add the osmo_trx_ep module, encapsulating the clock/ctrl/data UDP
socket management of the TRX protocol on top of osmo_io.  One endpoint
serves an (optional) clock socket plus N channels, each channel being
a ctrl + data socket pair.

The module is role-neutral: struct osmo_trx_ep_cfg carries a mode
(OSMO_TRX_EP_MODE_{L1,TRX}) selecting which side of the protocol the
endpoint implements.  The mode is needed to parse datagrams received
on the data sockets, as the wire format alone does not identify the
direction (BURST.ind vs BURST.req).  All local and remote ports are
derived from a single base port (default: 5700).

To avoid indirect calls on the hot path, the decoded Rx handlers
(osmo_trx_ep_rx_*) are plain function prototypes bound at link-time,
not function pointers.  The library provides weak default stubs to
stay link-complete (-no-undefined), so applications only implement
the handlers for the directions they consume, overriding the stubs.

The Tx path implements TRXDv2 PDU batching for burst requests:
osmo_trx_ep_send_burst_req() accumulates PDUs until it is called
with br == NULL (the batching breaker), like in osmo-bts-trx.

osmo-trx itself will not adopt this module: its per-channel/thread
socket ownership model (dedicated blocking-read threads per socket)
is incompatible with osmo_io's single-select-loop dispatch. It is
meant for osmo-bts, osmocom-bb/trxcon, and the upcoming C rewrite
of fake_trx.

Change-Id: I767fa43a9ca88be40c385f6dcb9de22891a6afc3
Vadim Yanitskiy at

#612 (Jul 29, 2026, 12:57:01 PM)

debian: add packaging for libosmo-trx

Add the usual Debian packaging files, closely following the ones in
libosmocore.git: the shared library package libosmo-trx0, as well as
the -dev, -doc, and -dbg packages.

Change-Id: I56f0074ad121ecacb076b508d1adfdd71cce99ec
Vadim Yanitskiy at

#611 (Jul 29, 2026, 12:57:01 PM)

libosmo-trx/client: make public API operate on parsed messages

The TRXC client engine and the TRX endpoint module did not compose:
osmo_trx_ep_rx_ctrl_msg() delivers a parsed struct osmo_trxc_msg,
while osmo_trxc_client_rx() accepts a raw datagram only; likewise,
the tx_msg call-back used to emit a serialized string, while
osmo_trx_ep_send_ctrl_msg() takes the parsed structure.  An
osmo_trx_ep user would have to needlessly re-parse and re-serialize
TRXC messages when gluing both modules together.

Make struct osmo_trxc_msg the currency at both module boundaries:

* add osmo_trxc_client_rx_msg(), accepting a parsed message;
  osmo_trxc_client_rx() becomes a parse-first convenience wrapper
  for applications managing the TRXC socket themselves;
* change the tx_msg call-back to take a parsed message: it's now
  up to the transport to serialize it (osmo_trx_ep users simply
  call osmo_trx_ep_send_ctrl_msg(), others osmo_trxc_msg_build()).

This is a preparation for porting trxcon to libosmo-trx.

Change-Id: Idf53513d06be2337383601494b225b5722c93129
Vadim Yanitskiy at

#610 (Jul 29, 2026, 12:57:01 PM)

libosmo-trx/client: add optional limit for retransmissions

The client used to retransmit an unacknowledged command forever, like
osmo-bts-trx does.  trxcon, however, gives up after 3 retransmission
attempts, concluding that the transceiver is offline.  Add a new API
function osmo_trxc_client_set_max_retrans() enabling this behavior:
once a command has been retransmitted the given number of times
without a response, the client escalates to the fatal_error call-back
(with rsp == NULL) and freezes the command queue.  The default (0)
retains the old behavior (no limit).

This is a preparation for porting trxcon to libosmo-trx.

Change-Id: Ib90a032b38c69ae26023e726992d3f5f7e502fcf
Vadim Yanitskiy at

#609 (Jul 29, 2026, 12:57:01 PM)

libosmo-trx/client: add TRXC client (command queue) API

Add the osmo_trxc_client module: a transport-agnostic generalization
of the TRXC command handling logic in osmo-bts-trx (trx_if.c):

* command queue with a single command in flight;
* retransmission on response timeout (default: 2 s);
* suppression of consecutive duplicate commands;
* RSP<->CMD matching, optionally including the parameters;
* filtering of duplicate responses caused by retransmissions;
* escalation of NACKed critical commands (OSMO_TRXC_F_CRITICAL)
  to the fatal_error call-back;
* TRXD PDU version negotiation (SETFORMAT), incl. the fallback to
  version 0 for old transceivers rejecting it with 'RSP ERR 1'.

The client neither opens nor owns a socket: the application transmits
serialized messages in the tx_msg call-back and feeds received
datagrams into osmo_trxc_client_rx().  The response call-back may
return N > 0 to request a re-transmission of the same command after
N seconds (e.g. POWERON retry, as implemented in osmo-bts-trx).

Change-Id: I817e394f74a10e3adae4a0b58342c82acdf0794e
Vadim Yanitskiy at

#608 (Jul 29, 2026, 12:57:00 PM)

Transceiver52M: implement TRXDv2 support

TRXDv2 was proposed and implemented in osmo-bts a while ago, but
osmo-trx was still stuck at TRXDv1.  This patch implements TRXDv2
and UL/DL burst batching using libosmo-trx API.

DL: driveTxPriorityQueue() now loops over osmo_trxd_burst_req_parse()
to handle datagrams potentially containing multiple batched BURST.req,
dispatching each via the new handleBurstReq().

UL: accumulate BURST.ind PDUs for the same FN into one msgb per channel
and flush as a single datagram once the next frame's PDU arrives or
the channel stops;  TRXDv0/v1 channels keep sending one PDU per
datagram via sendBurstInd().  Batching is unconditional for now;
making it configurable is left as a follow-up.

Change-Id: Ie6a33e3980b3ca4ab05a3d4221d5a8ba0132233d
Related: OS#5283
Vadim Yanitskiy at

#607 (Jul 29, 2026, 12:57:00 PM)

Transceiver52M: migrate to libosmo-trx

Replace the local TRXC/TRXD implementation with libosmo-trx's shared
osmo_trxc_msg/osmo_trxd_burst_{ind,req} API, including SETSLOT parsing
via osmo_trxc_setslot_parse()/_build().  Take a chance to fix SETSLOT
to always send a response, distinguishing bogus input from unsupported
VAMOS channel combinations.

Only the TRXC/TRXD build/parse API is used here, not the osmo_trx_ep
endpoint API: osmo-trx runs its socket I/O on dedicated threads that
don't drive osmo_select_main(), which osmo_trx_ep depends on.

Change-Id: I458ec85c56e2101d073c8c35f11c147191c4ea0c
Related: OS#5283
Vadim Yanitskiy at

#606 (Jul 29, 2026, 12:57:00 PM)

libosmo-trx: generate Doxygen API documentation

Add Doxyfile.trx.in (based on Doxyfile.core.in from libosmocore.git,
upgraded using 'doxygen -u' to get rid of obsolete tags) and the
usual rules to build and install the HTML documentation, as well as
the --disable-doxygen configure option, like in other libosmo-*
projects.

Change-Id: I54cf8c0c60215c666d8fa55dafec53379a2382d5
Vadim Yanitskiy at

#605 (Jul 29, 2026, 12:57:00 PM)

libosmo-trx/trxd: support NOPE.{ind,req} in TRXDv0/v1 PDUs

TRXDv0 (and TRXDv1 in the downlink direction) has no MTS field, but
NOPE indications/requests do exist there in practice: the burst payload
is simply omitted, i.e. a header-only PDU.  This is how osmocom-bb's
trxcon transmits NOPE.req (see trx_if_handle_phyif_burst_req()).

Change-Id: I1a59f31d0f00c8509a016dc2bac71b6aa467f3a4
Vadim Yanitskiy at

#604 (Jul 29, 2026, 12:57:00 PM)

Transceiver52M: make TRXDv2 burst batching configurable

Add a "trxd-batch (disable|enable)" VTY command under the TRX node
(default: enable) to allow disabling per-frame BURST.ind batching
even when TRXDv2 is negotiated, e.g. to trade datagram count for
latency.

Change-Id: I2f58f87d85de5254bae6d7a606dffcd0ad4069d5
Related: OS#5283
Vadim Yanitskiy at

#603 (Jul 28, 2026, 9:39:06 AM)

Transceiver52M: migrate to libosmo-trx

Replace the local TRXC/TRXD implementation with libosmo-trx's shared
osmo_trxc_msg/osmo_trxd_burst_{ind,req} API, including SETSLOT parsing
via osmo_trxc_setslot_parse()/_build().  Take a chance to fix SETSLOT
to always send a response, distinguishing bogus input from unsupported
VAMOS channel combinations.

Only the TRXC/TRXD build/parse API is used here, not the osmo_trx_ep
endpoint API: osmo-trx runs its socket I/O on dedicated threads that
don't drive osmo_select_main(), which osmo_trx_ep depends on.

Change-Id: I458ec85c56e2101d073c8c35f11c147191c4ea0c
Related: OS#5283
Vadim Yanitskiy at

#602 (Jul 28, 2026, 9:39:06 AM)

libosmo-trx/ep: add TRX endpoint module

Add the osmo_trx_ep module, encapsulating the clock/ctrl/data UDP
socket management of the TRX protocol on top of osmo_io.  One endpoint
serves an (optional) clock socket plus N channels, each channel being
a ctrl + data socket pair.

The module is role-neutral: struct osmo_trx_ep_cfg carries a mode
(OSMO_TRX_EP_MODE_{L1,TRX}) selecting which side of the protocol the
endpoint implements.  The mode is needed to parse datagrams received
on the data sockets, as the wire format alone does not identify the
direction (BURST.ind vs BURST.req).  All local and remote ports are
derived from a single base port (default: 5700).

To avoid indirect calls on the hot path, the decoded Rx handlers
(osmo_trx_ep_rx_*) are plain function prototypes bound at link-time,
not function pointers.  The library provides weak default stubs to
stay link-complete (-no-undefined), so applications only implement
the handlers for the directions they consume, overriding the stubs.

The Tx path implements TRXDv2 PDU batching for burst requests:
osmo_trx_ep_send_burst_req() accumulates PDUs until it is called
with br == NULL (the batching breaker), like in osmo-bts-trx.

osmo-trx itself will not adopt this module: its per-channel/thread
socket ownership model (dedicated blocking-read threads per socket)
is incompatible with osmo_io's single-select-loop dispatch. It is
meant for osmo-bts, osmocom-bb/trxcon, and the upcoming C rewrite
of fake_trx.

Change-Id: I767fa43a9ca88be40c385f6dcb9de22891a6afc3
Vadim Yanitskiy at

#601 (Jul 28, 2026, 9:39:06 AM)

libosmo-trx/client: make public API operate on parsed messages

The TRXC client engine and the TRX endpoint module did not compose:
osmo_trx_ep_rx_ctrl_msg() delivers a parsed struct osmo_trxc_msg,
while osmo_trxc_client_rx() accepts a raw datagram only; likewise,
the tx_msg call-back used to emit a serialized string, while
osmo_trx_ep_send_ctrl_msg() takes the parsed structure.  An
osmo_trx_ep user would have to needlessly re-parse and re-serialize
TRXC messages when gluing both modules together.

Make struct osmo_trxc_msg the currency at both module boundaries:

* add osmo_trxc_client_rx_msg(), accepting a parsed message;
  osmo_trxc_client_rx() becomes a parse-first convenience wrapper
  for applications managing the TRXC socket themselves;
* change the tx_msg call-back to take a parsed message: it's now
  up to the transport to serialize it (osmo_trx_ep users simply
  call osmo_trx_ep_send_ctrl_msg(), others osmo_trxc_msg_build()).

This is a preparation for porting trxcon to libosmo-trx.

Change-Id: Idf53513d06be2337383601494b225b5722c93129
Vadim Yanitskiy at

#600 (Jul 28, 2026, 9:39:06 AM)

Transceiver52M: implement TRXDv2 support

TRXDv2 was proposed and implemented in osmo-bts a while ago, but
osmo-trx was still stuck at TRXDv1.  This patch implements TRXDv2
and UL/DL burst batching using libosmo-trx API.

DL: driveTxPriorityQueue() now loops over osmo_trxd_burst_req_parse()
to handle datagrams potentially containing multiple batched BURST.req,
dispatching each via the new handleBurstReq().

UL: accumulate BURST.ind PDUs for the same FN into one msgb per channel
and flush as a single datagram once the next frame's PDU arrives or
the channel stops;  TRXDv0/v1 channels keep sending one PDU per
datagram via sendBurstInd().  Batching is unconditional for now;
making it configurable is left as a follow-up.

Change-Id: Ie6a33e3980b3ca4ab05a3d4221d5a8ba0132233d
Related: OS#5283
Vadim Yanitskiy at

#599 (Jul 28, 2026, 9:39:06 AM)

tests: speed up InterthreadTest by shrinking the fuzz sleep

qWriter()/mapWriter() each had a 50% chance per iteration (20
iterations) of sleep(1), making the test take up to ~13s just to
exercise thread interleaving. The delay only needs to be long enough
to encourage preemption, not a full second.

Change-Id: Id6bc453f9217ae392dcd3288dfa6784c533f8eb6
Vadim Yanitskiy at

#598 (Jul 28, 2026, 9:39:06 AM)

libosmo-trx/trxc: enlarge the params buffer

The SETFH command (implemented by trxcon and fake_trx) carries the
whole Mobile Allocation as pairs of Rx/Tx frequencies in kHz:

  CMD SETFH <HSN> <MAIO> <RXF1> <TXF1> [... <RXFN> <TXFN>]

With up to 64 ARFCNs in the Mobile Allocation, the parameters string
alone can exceed 1000 characters, far beyond the old 128 byte limit.

Derive OSMO_TRXC_PARAMS_LEN_MAX from OSMO_TRXC_MSG_BUF_SIZE, so that
any message ("RSP " + verb + status + params) still fits the
recommended socket buffer size.  Also add the OSMO_TRXC_CMD_SETFH
verb constant and a regression test doing a round-trip of a maximum
size SETFH command (64 ARFCNs).

Change-Id: I2f65b213f5ada499eea4abae87d3727057e03e22
Vadim Yanitskiy at

#597 (Jul 28, 2026, 9:39:06 AM)

libosmo-trx/ep: flush pending TRXC messages on endpoint teardown

osmo_iofd_write_msgb() only enqueues the message; the actual
transmission happens asynchronously from within osmo_select_main().
An application sending a 'goodbye' command (like "CMD POWEROFF")
immediately before tearing down the endpoint would thus lose it:
osmo_iofd_free() discards the pending Tx queue.

Flush the TRXC Tx queue (best-effort) in osmo_trx_ep_close(), using
the new osmo_iofd_flush() API.  Pending Tx data batches are still
dropped, since queued bursts are worthless at teardown time.

Depends: libosmocore.git I4e09e91e472a4441977a2c199c07c2cb8005632f
Change-Id: I69e6a3bcf49afc3cfca4a72afdf459625cb91e56
Vadim Yanitskiy at

#596 (Jul 28, 2026, 9:39:06 AM)

libosmo-trx/client: add optional limit for retransmissions

The client used to retransmit an unacknowledged command forever, like
osmo-bts-trx does.  trxcon, however, gives up after 3 retransmission
attempts, concluding that the transceiver is offline.  Add a new API
function osmo_trxc_client_set_max_retrans() enabling this behavior:
once a command has been retransmitted the given number of times
without a response, the client escalates to the fatal_error call-back
(with rsp == NULL) and freezes the command queue.  The default (0)
retains the old behavior (no limit).

This is a preparation for porting trxcon to libosmo-trx.

Change-Id: Ib90a032b38c69ae26023e726992d3f5f7e502fcf
Vadim Yanitskiy at

#595 (Jul 28, 2026, 9:39:06 AM)

libosmo-trx: add TRXC/TRXD message codec

Introduce libosmo-trx: a shared implementation of the TRXC/TRXD
(OpenBTS-style TRX) protocol, to be used by osmo-trx, osmo-bts,
trxcon, and the upcoming C rewrite of fake_trx.

This initial version provides two I/O-free codec modules:

* trxd: TRXD PDU codec for BURST.ind and BURST.req
* trxc: verb-agnostic TRXC message codec (CMD/RSP/IND)

The codec logic is based on the existing implementations in
osmo-bts (f0ee51997470e1c3020ddb85082385ed43ba0c68).

Change-Id: I933fc417a67d0043f74b04626b7643c79e381492
Vadim Yanitskiy at

#594 (Jul 28, 2026, 9:39:06 AM)

libosmo-trx/trxd: support NOPE.{ind,req} in TRXDv0/v1 PDUs

TRXDv0 (and TRXDv1 in the downlink direction) has no MTS field, but
NOPE indications/requests do exist there in practice: the burst payload
is simply omitted, i.e. a header-only PDU.  This is how osmocom-bb's
trxcon transmits NOPE.req (see trx_if_handle_phyif_burst_req()).

Change-Id: I1a59f31d0f00c8509a016dc2bac71b6aa467f3a4
Vadim Yanitskiy at

#593 (Jul 28, 2026, 9:39:05 AM)

libosmo-trx/trxc: add SETSLOT parameter parser/builder

Add struct osmo_trxc_setslot plus osmo_trxc_setslot_parse()/_build()
for the "<tn> <chan_comb> [C<tsc>/S<tsc_set> ...]" SETSLOT parameters,
including VAMOS combinations (VFF/VHH/VFH/HVHH) with per-sub-channel
TSC overrides.

Change-Id: I17a1176b1418edd0caf750d50acda0482d4ad04a
Vadim Yanitskiy at

#592 (Jul 28, 2026, 9:39:05 AM)

libosmo-trx: generate Doxygen API documentation

Add Doxyfile.trx.in (based on Doxyfile.core.in from libosmocore.git,
upgraded using 'doxygen -u' to get rid of obsolete tags) and the
usual rules to build and install the HTML documentation, as well as
the --disable-doxygen configure option, like in other libosmo-*
projects.  Also document the missing buf/len parameters of
osmo_trxc_clock_ind_parse(), fixing the only Doxygen warning.

Change-Id: I54cf8c0c60215c666d8fa55dafec53379a2382d5
Vadim Yanitskiy at

#591 (Jul 28, 2026, 9:39:05 AM)

debian: add packaging for libosmo-trx

Add the usual Debian packaging files, closely following the ones in
libosmocore.git: the shared library package libosmotrx0, as well as
the -dev, -doc, and -dbg packages.

Change-Id: I56f0074ad121ecacb076b508d1adfdd71cce99ec
Vadim Yanitskiy at

#590 (Jul 28, 2026, 9:39:05 AM)

libosmo-trx/client: add TRXC client (command queue) API

Add the osmo_trxc_client module: a transport-agnostic generalization
of the TRXC command handling logic in osmo-bts-trx (trx_if.c):

* command queue with a single command in flight;
* retransmission on response timeout (default: 2 s);
* suppression of consecutive duplicate commands;
* RSP<->CMD matching, optionally including the parameters;
* filtering of duplicate responses caused by retransmissions;
* escalation of NACKed critical commands (OSMO_TRXC_F_CRITICAL)
  to the fatal_error call-back;
* TRXD PDU version negotiation (SETFORMAT), incl. the fallback to
  version 0 for old transceivers rejecting it with 'RSP ERR 1'.

The client neither opens nor owns a socket: the application transmits
serialized messages in the tx_msg call-back and feeds received
datagrams into osmo_trxc_client_rx().  The response call-back may
return N > 0 to request a re-transmission of the same command after
N seconds (e.g. POWERON retry, as implemented in osmo-bts-trx).

Change-Id: I817e394f74a10e3adae4a0b58342c82acdf0794e
Vadim Yanitskiy at

#589 (Jul 28, 2026, 9:39:05 AM)

Transceiver52M: make TRXDv2 burst batching configurable

Add a "trxd-batch (disable|enable)" VTY command under the TRX node
(default: enable) to allow disabling per-frame BURST.ind batching
even when TRXDv2 is negotiated, e.g. to trade datagram count for
latency.

Change-Id: I2f58f87d85de5254bae6d7a606dffcd0ad4069d5
Related: OS#5283
Vadim Yanitskiy at